Skip to content

Commit 0828d1a

Browse files
committed
npm to cilium validator script
1 parent c670d53 commit 0828d1a

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
"fmt"
7+
"log"
8+
9+
corev1 "k8s.io/api/core/v1"
10+
networkingv1 "k8s.io/api/networking/v1"
11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/client-go/kubernetes"
13+
"k8s.io/client-go/tools/clientcmd"
14+
)
15+
16+
// FOR DEMO
17+
// kubectl delete networkpolicy --all --all-namespaces
18+
// k apply -f network-polices
19+
// k get networkpolicies -A -o wide
20+
// cd AzureRepo/azure-container-networking/tools
21+
// go run azure-npm-to-cilium-validator.go --kubeconfig ~/.kube/config
22+
func main() {
23+
// Parse the kubeconfig flag
24+
kubeconfig := flag.String("kubeconfig", "~/.kube/config", "absolute path to the kubeconfig file")
25+
flag.Parse()
26+
27+
// Build the Kubernetes client config
28+
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
29+
if err != nil {
30+
log.Fatalf("Error building kubeconfig: %v", err)
31+
}
32+
33+
// Create a Kubernetes client
34+
clientset, err := kubernetes.NewForConfig(config)
35+
if err != nil {
36+
log.Fatalf("Error creating Kubernetes client: %v", err)
37+
}
38+
39+
// Get all network policies in the cluster
40+
networkPolicies, err := clientset.NetworkingV1().NetworkPolicies("").List(context.TODO(), metav1.ListOptions{})
41+
if err != nil {
42+
log.Fatalf("Error fetching network policies: %v", err)
43+
}
44+
45+
// Get all services in the cluster
46+
services, err := clientset.CoreV1().Services("").List(context.TODO(), metav1.ListOptions{})
47+
if err != nil {
48+
log.Fatalf("Error fetching services: %v", err)
49+
}
50+
51+
// Store network policies by namespace
52+
policiesByNamespace := make(map[string][]networkingv1.NetworkPolicy)
53+
54+
// Store network policies in the map
55+
for _, policy := range networkPolicies.Items {
56+
namespace := policy.Namespace
57+
policiesByNamespace[namespace] = append(policiesByNamespace[namespace], policy)
58+
}
59+
60+
// Store services by namespace
61+
servicesByNamespace := make(map[string][]corev1.Service)
62+
63+
// Store services in the map
64+
for _, service := range services.Items {
65+
namespace := service.Namespace
66+
servicesByNamespace[namespace] = append(servicesByNamespace[namespace], service)
67+
}
68+
69+
fmt.Println("Migration Summary:")
70+
fmt.Println("+------------------------------+-------------------------------+")
71+
fmt.Printf("%-30s | %-30s \n", "Breaking Change", "No Impact / Safe to Migrate")
72+
fmt.Println("+------------------------------+-------------------------------+")
73+
74+
// Check the endports of the network policies
75+
checkEndportNetworkPolicies(policiesByNamespace)
76+
77+
fmt.Println("+------------------------------+-------------------------------+")
78+
79+
// Check the cidr of the network policies
80+
checkCIDRNetworkPolicies(policiesByNamespace)
81+
82+
fmt.Println("+------------------------------+-------------------------------+")
83+
84+
// Check services that have externalTrafficPolicy!=Local
85+
checkExternalTrafficPolicyServices(servicesByNamespace, policiesByNamespace)
86+
87+
fmt.Println("+------------------------------+-------------------------------+")
88+
fmt.Println("Please see aka.ms/azurenpmtocilium for instructions on how to evaluate/assess the above warnings marked by ❌.")
89+
fmt.Println("NOTE: rerun this script if any modifications (create/update/delete) are made to services or policies.")
90+
}
91+
92+
func checkEndportNetworkPolicies(policiesByNamespace map[string][]networkingv1.NetworkPolicy) {
93+
networkPolicyWithEndport := false
94+
for namespace, policies := range policiesByNamespace {
95+
for _, policy := range policies {
96+
foundEndPort := false
97+
for _, egress := range policy.Spec.Egress {
98+
for _, port := range egress.Ports {
99+
if port.EndPort != nil {
100+
foundEndPort = true
101+
break // Exit egress.port loop
102+
}
103+
}
104+
if foundEndPort {
105+
break // Exit egress loop
106+
}
107+
}
108+
if foundEndPort {
109+
if !networkPolicyWithEndport {
110+
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with endPort", "❌")
111+
fmt.Println("Details:")
112+
networkPolicyWithEndport = true
113+
}
114+
fmt.Printf("❌ Found NetworkPolicy: %s with endPort field in namespace: %s\n", policy.Name, namespace)
115+
}
116+
}
117+
}
118+
// Print no impact if no network policy has endport
119+
if !networkPolicyWithEndport {
120+
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with endPort", "✅")
121+
}
122+
}
123+
124+
func checkCIDRNetworkPolicies(policiesByNamespace map[string][]networkingv1.NetworkPolicy) {
125+
networkPolicyWithCIDR := false
126+
for namespace, policies := range policiesByNamespace {
127+
for _, policy := range policies {
128+
foundCIDRIngress := false
129+
foundCIDREgress := false
130+
// Check the ingress field for cidr
131+
for _, ingress := range policy.Spec.Ingress {
132+
for _, from := range ingress.From {
133+
if from.IPBlock != nil {
134+
if from.IPBlock.CIDR != "" {
135+
foundCIDRIngress = true
136+
break // Exit ingress.from.ipBlock loop
137+
}
138+
}
139+
}
140+
if foundCIDRIngress {
141+
break // Exit ingress loop
142+
}
143+
}
144+
// Print the network policy if it has an ingress cidr
145+
if foundCIDRIngress {
146+
if !networkPolicyWithCIDR {
147+
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with cidr", "❌")
148+
fmt.Println("Details:")
149+
networkPolicyWithCIDR = true
150+
}
151+
fmt.Printf("❌ Found NetworkPolicy: %s with ingress cidr field in namespace: %s\n", policy.Name, namespace)
152+
}
153+
// Check the egress field for cidr
154+
for _, egress := range policy.Spec.Egress {
155+
for _, to := range egress.To {
156+
if to.IPBlock != nil {
157+
if to.IPBlock.CIDR != "" {
158+
foundCIDREgress = true
159+
break // Exit egress.to.ipBlock loop
160+
}
161+
}
162+
}
163+
if foundCIDREgress {
164+
break // Exit egress loop
165+
}
166+
}
167+
// Print the network policy if it has an egress cidr
168+
if foundCIDREgress {
169+
if !networkPolicyWithCIDR {
170+
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with cidr", "❌")
171+
fmt.Println("Details:")
172+
networkPolicyWithCIDR = true
173+
}
174+
fmt.Printf("❌ Found NetworkPolicy: %s with egress cidr field in namespace: %s\n", policy.Name, namespace)
175+
}
176+
}
177+
}
178+
// Print no impact if no network policy has cidr
179+
if !networkPolicyWithCIDR {
180+
fmt.Printf("%-30s | %-30s \n", "NetworkPolicy with cidr", "✅")
181+
}
182+
}
183+
184+
func checkExternalTrafficPolicyServices(servicesByNamespace map[string][]corev1.Service, policiesByNamespace map[string][]networkingv1.NetworkPolicy) {
185+
// Check 0: are there ingress policies in the namespace?
186+
policiesByNamespaceAtRisk := map[string][]networkingv1.NetworkPolicy{}
187+
serviceByNamespaceAtRisk := map[string][]corev1.Service{}
188+
for namespace, services := range servicesByNamespace {
189+
for _, service := range services {
190+
for _, policy := range policiesByNamespace[namespace] {
191+
// TODO: DO I NEED TO CHECK FOR policyTypes: Ingress as well? I.E default-deny-ingress
192+
if len(policy.Spec.Ingress) > 0 {
193+
policiesByNamespaceAtRisk[namespace] = append(policiesByNamespaceAtRisk[namespace], policy)
194+
serviceByNamespaceAtRisk[namespace] = append(serviceByNamespaceAtRisk[namespace], service)
195+
}
196+
}
197+
}
198+
}
199+
}
200+
201+
// func printMigrationSummary(endPortPoliciesOutput string) {
202+
// fmt.Println("Migration Summary:")
203+
// fmt.Println("+--------------------------------+-------------------------------+")
204+
// fmt.Printf("| %-30s | %-30s |\n", "Breaking Change", "No Impact / Safe to Migrate")
205+
// fmt.Println("+--------------------------------+-------------------------------+")
206+
// fmt.Printf("| %-30s | %-30s |\n", "NetworkPolicy with endPort", endPortPoliciesOutput)
207+
// fmt.Println("+--------------------------------+-------------------------------+")
208+
// fmt.Println("Please see aka.ms/azurenpmtocilium for instructions on how to evaluate/assess the above warnings marked by ❌.")
209+
// fmt.Println("NOTE: rerun this script if any modifications (create/update/delete) are made to services or policies.")
210+
// }

0 commit comments

Comments
 (0)