|
package main |
|
|
|
import ( |
|
"fmt" |
|
"os" |
|
"strings" |
|
) |
|
|
|
// GeneratePorts creates a YAML section for the ports in NetworkPolicy. |
|
func GeneratePorts(ports []RulePort) string { |
|
if len(ports) == 0 { |
|
return "" |
|
} |
|
|
|
var portStrs []string |
|
for _, port := range ports { |
|
portStrs = append(portStrs, fmt.Sprintf(" - protocol: %s\n port: %d", port.Protocol, port.Port)) |
|
} |
|
return "ports:\n" + strings.Join(portStrs, "\n") |
|
} |
|
|
|
// GenerateLabels converts label map to string. |
|
func GenerateLabels(labels map[string]string) string { |
|
var labelStrs []string |
|
for key, value := range labels { |
|
labelStrs = append(labelStrs, fmt.Sprintf("%s: %s", key, value)) |
|
} |
|
return strings.Join(labelStrs, "\n ") |
|
} |
|
|
|
// GenerateTrafficRuleSection creates a YAML section for either ingress or egress. |
|
// TODO: Check the final section... not happy with the results here |
|
func GenerateTrafficRuleSection(rule NetworkRule, direction string) string { |
|
var selectors []string |
|
|
|
if direction == "ingress" && len(rule.From.Labels) > 0 { |
|
fromLabelsStr := GenerateLabels(rule.From.Labels) |
|
selectors = append(selectors, fmt.Sprintf(`- from: |
|
- namespaceSelector: |
|
matchLabels: |
|
name: %s |
|
podSelector: |
|
matchLabels: |
|
%s`, rule.From.Namespace, fromLabelsStr)) |
|
} |
|
|
|
toLabelsStr := GenerateLabels(rule.To.Labels) |
|
selectors = append(selectors, fmt.Sprintf(` |
|
- podSelector: |
|
matchLabels: |
|
%s`, toLabelsStr)) |
|
|
|
ports := GeneratePorts(rule.Ports) |
|
|
|
// Attach ports to the selectors. |
|
if ports != "" { |
|
selectors[len(selectors)-1] += "\n " + ports |
|
} |
|
|
|
return fmt.Sprintf("\n %s:\n%s", direction, strings.Join(selectors, "\n")) |
|
} |
|
|
|
|
|
// CreateNetworkPolicyFile generates and writes NetworkPolicy in YAML format to the outputs directory. |
|
func CreateNetworkPolicyFile(policyYAML, fileName string) { |
|
outputDir := "outputs" |
|
if _, err := os.Stat(outputDir); os.IsNotExist(err) { |
|
os.Mkdir(outputDir, 0755) // Create the directory with read-write permissions |
|
} |
|
|
|
filePath := fmt.Sprintf("%s/%s", outputDir, fileName) |
|
|
|
file, err := os.Create(filePath) |
|
if err != nil { |
|
fmt.Println("Error creating file:", err) |
|
return |
|
} |
|
defer file.Close() |
|
|
|
file.WriteString(policyYAML) |
|
fmt.Printf("Generated policy: %s\n", filePath) |
|
} |
|
|
|
func GenerateSimpleLabel(labelMap map[string]string) string { |
|
var labels []string |
|
for k, v := range labelMap { |
|
labels = append(labels, k+"-"+v) |
|
} |
|
return strings.Join(labels, "-") |
|
} |
|
|
|
func GenerateFileName(rule NetworkRule) string { |
|
fromLabel := GenerateSimpleLabel(rule.From.Labels) |
|
toLabel := GenerateSimpleLabel(rule.To.Labels) |
|
return fmt.Sprintf("%s-to-%s-policy.yaml", fromLabel, toLabel) |
|
} |
|
|
|
// GenerateNetworkPolicyYAML generates the YAML string for the NetworkPolicy. |
|
func GenerateNetworkPolicyYAML(rule NetworkRule) string { |
|
ingress := GenerateTrafficRuleSection(rule, "ingress") |
|
egress := GenerateTrafficRuleSection(rule, "egress") |
|
|
|
fromLabel := GenerateSimpleLabel(rule.From.Labels) |
|
toLabel := GenerateSimpleLabel(rule.To.Labels) |
|
|
|
networkPolicyYAML := fmt.Sprintf(` |
|
apiVersion: networking.k8s.io/v1 |
|
kind: NetworkPolicy |
|
metadata: |
|
name: %s-to-%s-policy |
|
namespace: %s |
|
spec: |
|
podSelector: |
|
matchLabels: |
|
%s |
|
%s |
|
%s |
|
`, fromLabel, toLabel, rule.To.Namespace, toLabel, ingress, egress) |
|
|
|
return networkPolicyYAML |
|
} |
|
|
|
|
|
// ProcessRules generates a NetworkPolicy YAML for all rules and saves it to a file. |
|
func ProcessRules() { |
|
for _, rule := range Rules { |
|
networkPolicyYAML := GenerateNetworkPolicyYAML(rule) |
|
fileName := GenerateFileName(rule) |
|
CreateNetworkPolicyFile(networkPolicyYAML, fileName) |
|
} |
|
} |
|
|
|
func main() { |
|
ProcessRules() |
|
} |
|
|