-
Notifications
You must be signed in to change notification settings - Fork 240
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"flag" | ||
"fmt" | ||
"log" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
networkingv1 "k8s.io/api/networking/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/client-go/kubernetes" | ||
"k8s.io/client-go/tools/clientcmd" | ||
) | ||
|
||
// FOR DEMO | ||
// kubectl delete networkpolicy --all --all-namespaces | ||
// k apply -f network-polices | ||
// k get networkpolicies -A -o wide | ||
// cd AzureRepo/azure-container-networking/tools | ||
// go run azure-npm-to-cilium-validator.go --kubeconfig ~/.kube/config | ||
func main() { | ||
// Parse the kubeconfig flag | ||
kubeconfig := flag.String("kubeconfig", "~/.kube/config", "absolute path to the kubeconfig file") | ||
flag.Parse() | ||
|
||
// Build the Kubernetes client config | ||
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig) | ||
if err != nil { | ||
log.Fatalf("Error building kubeconfig: %v", err) | ||
} | ||
|
||
// Create a Kubernetes client | ||
clientset, err := kubernetes.NewForConfig(config) | ||
if err != nil { | ||
log.Fatalf("Error creating Kubernetes client: %v", err) | ||
} | ||
|
||
// Get all network policies in the cluster | ||
networkPolicies, err := clientset.NetworkingV1().NetworkPolicies("").List(context.TODO(), metav1.ListOptions{}) | ||
if err != nil { | ||
log.Fatalf("Error fetching network policies: %v", err) | ||
} | ||
|
||
// Get all services in the cluster | ||
services, err := clientset.CoreV1().Services("").List(context.TODO(), metav1.ListOptions{}) | ||
if err != nil { | ||
log.Fatalf("Error fetching services: %v", err) | ||
} | ||
|
||
// Store network policies by namespace | ||
policiesByNamespace := make(map[string][]networkingv1.NetworkPolicy) | ||
|
||
// Store network policies in the map | ||
for _, policy := range networkPolicies.Items { | ||
Check failure on line 55 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.23.x, ubuntu-latest)
Check failure on line 55 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, ubuntu-latest)
Check failure on line 55 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, windows-latest)
|
||
namespace := policy.Namespace | ||
policiesByNamespace[namespace] = append(policiesByNamespace[namespace], policy) | ||
} | ||
|
||
// Store services by namespace | ||
servicesByNamespace := make(map[string][]corev1.Service) | ||
|
||
// Store services in the map | ||
for _, service := range services.Items { | ||
Check failure on line 64 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.23.x, ubuntu-latest)
Check failure on line 64 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, ubuntu-latest)
Check failure on line 64 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, windows-latest)
|
||
namespace := service.Namespace | ||
servicesByNamespace[namespace] = append(servicesByNamespace[namespace], service) | ||
} | ||
|
||
fmt.Println("Migration Summary:") | ||
fmt.Println("+------------------------------+-------------------------------+") | ||
fmt.Printf("%-30s | %-30s \n", "Breaking Change", "No Impact / Safe to Migrate") | ||
fmt.Println("+------------------------------+-------------------------------+") | ||
|
||
// Check the endports of the network policies | ||
checkEndportNetworkPolicies(policiesByNamespace) | ||
|
||
fmt.Println("+------------------------------+-------------------------------+") | ||
|
||
// Check the cidr of the network policies | ||
checkCIDRNetworkPolicies(policiesByNamespace) | ||
|
||
fmt.Println("+------------------------------+-------------------------------+") | ||
|
||
// Check services that have externalTrafficPolicy!=Local | ||
checkExternalTrafficPolicyServices(servicesByNamespace, policiesByNamespace) | ||
|
||
fmt.Println("+------------------------------+-------------------------------+") | ||
fmt.Println("Please see aka.ms/azurenpmtocilium for instructions on how to evaluate/assess the above warnings marked by ❌.") | ||
fmt.Println("NOTE: rerun this script if any modifications (create/update/delete) are made to services or policies.") | ||
} | ||
|
||
func checkEndportNetworkPolicies(policiesByNamespace map[string][]networkingv1.NetworkPolicy) { | ||
networkPolicyWithEndport := false | ||
for namespace, policies := range policiesByNamespace { | ||
for _, policy := range policies { | ||
Check failure on line 95 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.23.x, ubuntu-latest)
Check failure on line 95 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, ubuntu-latest)
Check failure on line 95 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, windows-latest)
|
||
foundEndPort := false | ||
for _, egress := range policy.Spec.Egress { | ||
for _, port := range egress.Ports { | ||
if port.EndPort != nil { | ||
foundEndPort = true | ||
break // Exit egress.port loop | ||
} | ||
} | ||
if foundEndPort { | ||
break // Exit egress loop | ||
} | ||
} | ||
if foundEndPort { | ||
if !networkPolicyWithEndport { | ||
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with endPort", "❌") | ||
fmt.Println("Details:") | ||
networkPolicyWithEndport = true | ||
} | ||
fmt.Printf("❌ Found NetworkPolicy: %s with endPort field in namespace: %s\n", policy.Name, namespace) | ||
} | ||
} | ||
} | ||
// Print no impact if no network policy has endport | ||
if !networkPolicyWithEndport { | ||
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with endPort", "✅") | ||
} | ||
} | ||
|
||
func checkCIDRNetworkPolicies(policiesByNamespace map[string][]networkingv1.NetworkPolicy) { | ||
networkPolicyWithCIDR := false | ||
for namespace, policies := range policiesByNamespace { | ||
for _, policy := range policies { | ||
Check failure on line 127 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.23.x, ubuntu-latest)
Check failure on line 127 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, ubuntu-latest)
Check failure on line 127 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, windows-latest)
|
||
foundCIDRIngress := false | ||
foundCIDREgress := false | ||
// Check the ingress field for cidr | ||
for _, ingress := range policy.Spec.Ingress { | ||
for _, from := range ingress.From { | ||
if from.IPBlock != nil { | ||
if from.IPBlock.CIDR != "" { | ||
foundCIDRIngress = true | ||
break // Exit ingress.from.ipBlock loop | ||
} | ||
} | ||
} | ||
if foundCIDRIngress { | ||
break // Exit ingress loop | ||
} | ||
} | ||
// Print the network policy if it has an ingress cidr | ||
if foundCIDRIngress { | ||
if !networkPolicyWithCIDR { | ||
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with cidr", "❌") | ||
fmt.Println("Details:") | ||
networkPolicyWithCIDR = true | ||
} | ||
fmt.Printf("❌ Found NetworkPolicy: %s with ingress cidr field in namespace: %s\n", policy.Name, namespace) | ||
} | ||
// Check the egress field for cidr | ||
for _, egress := range policy.Spec.Egress { | ||
for _, to := range egress.To { | ||
if to.IPBlock != nil { | ||
if to.IPBlock.CIDR != "" { | ||
foundCIDREgress = true | ||
break // Exit egress.to.ipBlock loop | ||
} | ||
} | ||
} | ||
if foundCIDREgress { | ||
break // Exit egress loop | ||
} | ||
} | ||
// Print the network policy if it has an egress cidr | ||
if foundCIDREgress { | ||
if !networkPolicyWithCIDR { | ||
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with cidr", "❌") | ||
fmt.Println("Details:") | ||
networkPolicyWithCIDR = true | ||
} | ||
fmt.Printf("❌ Found NetworkPolicy: %s with egress cidr field in namespace: %s\n", policy.Name, namespace) | ||
} | ||
} | ||
} | ||
// Print no impact if no network policy has cidr | ||
if !networkPolicyWithCIDR { | ||
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with cidr", "✅") | ||
} | ||
} | ||
|
||
func checkExternalTrafficPolicyServices(servicesByNamespace map[string][]corev1.Service, policiesByNamespace map[string][]networkingv1.NetworkPolicy) { | ||
// Check 0: are there ingress policies in the namespace? | ||
policiesByNamespaceAtRisk := map[string][]networkingv1.NetworkPolicy{} | ||
serviceByNamespaceAtRisk := map[string][]corev1.Service{} | ||
for namespace, services := range servicesByNamespace { | ||
for _, service := range services { | ||
Check failure on line 189 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.23.x, ubuntu-latest)
Check failure on line 189 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, ubuntu-latest)
Check failure on line 189 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, windows-latest)
|
||
for _, policy := range policiesByNamespace[namespace] { | ||
Check failure on line 190 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.23.x, ubuntu-latest)
Check failure on line 190 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, ubuntu-latest)
Check failure on line 190 in tools/azure-npm-to-cilium-validator.go GitHub Actions / Lint (1.22.x, windows-latest)
|
||
// TODO: DO I NEED TO CHECK FOR policyTypes: Ingress as well? I.E default-deny-ingress | ||
if len(policy.Spec.Ingress) > 0 { | ||
policiesByNamespaceAtRisk[namespace] = append(policiesByNamespaceAtRisk[namespace], policy) | ||
serviceByNamespaceAtRisk[namespace] = append(serviceByNamespaceAtRisk[namespace], service) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
// func printMigrationSummary(endPortPoliciesOutput string) { | ||
// fmt.Println("Migration Summary:") | ||
// fmt.Println("+--------------------------------+-------------------------------+") | ||
// fmt.Printf("| %-30s | %-30s |\n", "Breaking Change", "No Impact / Safe to Migrate") | ||
// fmt.Println("+--------------------------------+-------------------------------+") | ||
// fmt.Printf("| %-30s | %-30s |\n", "NetworkPolicy with endPort", endPortPoliciesOutput) | ||
// fmt.Println("+--------------------------------+-------------------------------+") | ||
// fmt.Println("Please see aka.ms/azurenpmtocilium for instructions on how to evaluate/assess the above warnings marked by ❌.") | ||
// fmt.Println("NOTE: rerun this script if any modifications (create/update/delete) are made to services or policies.") | ||
// } |