1
16
17 package kubeadm
18
19 import (
20 "context"
21 "strings"
22
23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24 "k8s.io/kubernetes/test/e2e/framework"
25 e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
26 admissionapi "k8s.io/pod-security-admission/api"
27 netutils "k8s.io/utils/net"
28
29 "github.com/onsi/ginkgo/v2"
30 )
31
32 var (
33 dualStack bool
34 podSubnetInKubeadmConfig bool
35 serviceSubnetInKubeadmConfig bool
36 )
37
38
39
40
41 var _ = Describe("networking [setup-networking]", func() {
42
43
44 f := framework.NewDefaultFramework("networking")
45 f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
46
47
48
49 f.SkipNamespaceCreation = true
50
51
52
53
54 ginkgo.BeforeEach(func() {
55
56 cc := getClusterConfiguration(f.ClientSet)
57
58
59
60 if _, ok := cc["networking"]; ok {
61 netCC := cc["networking"].(map[interface{}]interface{})
62 if ps, ok := netCC["podSubnet"]; ok {
63
64
65 podSubnetInKubeadmConfig = true
66 cidrs := strings.Split(ps.(string), ",")
67 if len(cidrs) > 1 {
68 dualStack = true
69 }
70 }
71 if _, ok := netCC["serviceSubnet"]; ok {
72
73 serviceSubnetInKubeadmConfig = true
74 }
75 }
76 })
77
78 ginkgo.Context("single-stack", func() {
79 ginkgo.Context("podSubnet", func() {
80 ginkgo.It("should be properly configured if specified in kubeadm-config", func(ctx context.Context) {
81 if dualStack {
82 e2eskipper.Skipf("Skipping because cluster is dual-stack")
83 }
84 if !podSubnetInKubeadmConfig {
85 e2eskipper.Skipf("Skipping because podSubnet was not specified in kubeadm-config")
86 }
87 cc := getClusterConfiguration(f.ClientSet)
88 if _, ok := cc["networking"]; ok {
89 netCC := cc["networking"].(map[interface{}]interface{})
90 if ps, ok := netCC["podSubnet"]; ok {
91
92 nodes, err := f.ClientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
93 framework.ExpectNoError(err, "error listing nodes")
94 for _, node := range nodes.Items {
95 if !subnetWithinSubnet(ps.(string), node.Spec.PodCIDR) {
96 framework.Failf("failed due to node(%v) IP %v not inside configured pod subnet: %s", node.Name, node.Spec.PodCIDR, ps)
97 }
98 }
99 }
100 }
101 })
102 })
103 ginkgo.Context("serviceSubnet", func() {
104 ginkgo.It("should be properly configured if specified in kubeadm-config", func(ctx context.Context) {
105 if dualStack {
106 e2eskipper.Skipf("Skipping because cluster is dual-stack")
107 }
108 if !serviceSubnetInKubeadmConfig {
109 e2eskipper.Skipf("Skipping because serviceSubnet was not specified in kubeadm-config")
110 }
111 cc := getClusterConfiguration(f.ClientSet)
112 if _, ok := cc["networking"]; ok {
113 netCC := cc["networking"].(map[interface{}]interface{})
114 if ss, ok := netCC["serviceSubnet"]; ok {
115
116
117 svc, err := f.ClientSet.CoreV1().Services("default").Get(ctx, "kubernetes", metav1.GetOptions{})
118 framework.ExpectNoError(err, "error getting Service %q from namespace %q", "kubernetes", "default")
119 if !ipWithinSubnet(ss.(string), svc.Spec.ClusterIP) {
120 framework.Failf("failed due to service(%v) cluster-IP %v not inside configured service subnet: %s", svc.Name, svc.Spec.ClusterIP, ss)
121 }
122 }
123 }
124 })
125 })
126 })
127 ginkgo.Context("dual-stack", func() {
128 ginkgo.Context("podSubnet", func() {
129 ginkgo.It("should be properly configured if specified in kubeadm-config", func(ctx context.Context) {
130 if !dualStack {
131 e2eskipper.Skipf("Skipping because cluster is not dual-stack")
132 }
133 if !podSubnetInKubeadmConfig {
134 e2eskipper.Skipf("Skipping because podSubnet was not specified in kubeadm-config")
135 }
136 cc := getClusterConfiguration(f.ClientSet)
137 if _, ok := cc["networking"]; ok {
138 netCC := cc["networking"].(map[interface{}]interface{})
139 if ps, ok := netCC["podSubnet"]; ok {
140 nodes, err := f.ClientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
141 framework.ExpectNoError(err, "error listing nodes")
142
143 var found bool
144 configCIDRs := strings.Split(ps.(string), ",")
145 for _, node := range nodes.Items {
146 for _, nCIDR := range node.Spec.PodCIDRs {
147 found = false
148 for _, cCIDR := range configCIDRs {
149 if subnetWithinSubnet(cCIDR, nCIDR) {
150 found = true
151 break
152 }
153 }
154 if !found {
155 framework.Failf("failed due to the PodCIDRs (%v) of Node %q not being inside the configuration podSubnet CIDR %q", node.Spec.PodCIDRs, node.Name, configCIDRs)
156 }
157 }
158 }
159 }
160 }
161 })
162 })
163 })
164 })
165
166
167 func ipWithinSubnet(refIPNet, targetIP string) bool {
168 _, rNet, _ := netutils.ParseCIDRSloppy(refIPNet)
169 tIP := netutils.ParseIPSloppy(targetIP)
170 return rNet.Contains(tIP)
171 }
172
173
174 func subnetWithinSubnet(refIPNet, targetNet string) bool {
175 _, rNet, _ := netutils.ParseCIDRSloppy(refIPNet)
176 tNet, _, _ := netutils.ParseCIDRSloppy(targetNet)
177 return rNet.Contains(tNet)
178 }
179
View as plain text