github.com/nmstate/kubernetes-nmstate@v0.82.0/test/e2e/handler/node_selector_test.go (about) 1 /* 2 Copyright The Kubernetes NMState Authors. 3 4 5 Licensed under the Apache License, Version 2.0 (the "License"); 6 you may not use this file except in compliance with the License. 7 You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11 Unless required by applicable law or agreed to in writing, software 12 distributed under the License is distributed on an "AS IS" BASIS, 13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 See the License for the specific language governing permissions and 15 limitations under the License. 16 */ 17 18 package handler 19 20 import ( 21 "context" 22 "time" 23 24 . "github.com/onsi/ginkgo/v2" 25 . "github.com/onsi/gomega" 26 27 corev1 "k8s.io/api/core/v1" 28 "k8s.io/apimachinery/pkg/types" 29 30 "github.com/nmstate/kubernetes-nmstate/test/e2e/policy" 31 testenv "github.com/nmstate/kubernetes-nmstate/test/env" 32 33 "github.com/nmstate/kubernetes-nmstate/api/shared" 34 "github.com/nmstate/kubernetes-nmstate/pkg/enactment" 35 ) 36 37 var _ = Describe("NodeSelector", func() { 38 var ( 39 testNodeSelector = map[string]string{"testKey": "testValue"} 40 numberOfEnactmentsForPolicy = func(policyName string) int { 41 nncp := nodeNetworkConfigurationPolicy(policyName) 42 numberOfMatchingEnactments, _, err := enactment.CountByPolicy(testenv.Client, &nncp) 43 ExpectWithOffset(1, err).ToNot(HaveOccurred()) 44 return numberOfMatchingEnactments 45 } 46 ) 47 Context("when policy is set with node selector not matching any nodes", func() { 48 BeforeEach(func() { 49 Byf("Set policy %s with not matching node selector", bridge1) 50 // use linuxBrUpNoPorts to not affect the nodes secondary interfaces state 51 setDesiredStateWithPolicyAndNodeSelectorEventually(bridge1, linuxBrUpNoPorts(bridge1), testNodeSelector) 52 policy.WaitForAvailablePolicy(bridge1) 53 }) 54 55 AfterEach(func() { 56 Byf("Deleteting linux bridge %s at all nodes", bridge1) 57 setDesiredStateWithPolicyWithoutNodeSelector(bridge1, linuxBrAbsent(bridge1)) 58 policy.WaitForAvailablePolicy(bridge1) 59 deletePolicy(bridge1) 60 }) 61 62 It("should not update any nodes and have not enactments", func() { 63 for _, node := range allNodes { 64 interfacesNameForNodeEventually(node).ShouldNot(ContainElement(bridge1)) 65 } 66 Expect(numberOfEnactmentsForPolicy(bridge1)).To(Equal(0), "should not create any enactment") 67 }) 68 69 Context("and we remove the node selector", func() { 70 BeforeEach(func() { 71 Byf("Remove node selector at policy %s", bridge1) 72 // use linuxBrUpNoPorts to not affect the nodes secondary interfaces state 73 setDesiredStateWithPolicyWithoutNodeSelector(bridge1, linuxBrUpNoPorts(bridge1)) 74 policy.WaitForAvailablePolicy(bridge1) 75 }) 76 77 It("should update all nodes and have Matching enactment state", func() { 78 for _, node := range allNodes { 79 interfacesNameForNodeEventually(node).Should(ContainElement(bridge1)) 80 } 81 Expect(numberOfEnactmentsForPolicy(bridge1)).To(Equal(len(allNodes)), "should create all the enactments") 82 83 }) 84 85 }) 86 Context("and we add the label to the node", func() { 87 BeforeEach(func() { 88 By("Add test label to node") 89 addLabelsToNode(nodes[0], testNodeSelector) 90 //TODO: Remove this when webhook retest policy status when node labels are changed 91 time.Sleep(3 * time.Second) 92 policy.WaitForAvailablePolicy(bridge1) 93 }) 94 AfterEach(func() { 95 By("Remove test label from node") 96 removeLabelsFromNode(nodes[0], testNodeSelector) 97 }) 98 It("should apply the policy", func() { 99 By("Check that NNCE is created") 100 policy.NodeNetworkConfigurationEnactment(shared.EnactmentKey(nodes[0], bridge1)) 101 interfacesNameForNodeEventually(nodes[0]).Should(ContainElement(bridge1)) 102 }) 103 Context("and remove the label again", func() { 104 BeforeEach(func() { 105 removeLabelsFromNode(nodes[0], testNodeSelector) 106 //TODO: Remove this when webhook retest policy status when node labels are changed 107 time.Sleep(3 * time.Second) 108 policy.WaitForAvailablePolicy(bridge1) 109 }) 110 It("should remove the not matching enactment", func() { 111 Expect(numberOfEnactmentsForPolicy(bridge1)).To(Equal(0), "should remove the not matching enactment") 112 }) 113 }) 114 }) 115 }) 116 }) 117 118 func addLabelsToNode(nodeName string, labelsToAdd map[string]string) { 119 node := corev1.Node{} 120 err := testenv.Client.Get(context.TODO(), types.NamespacedName{Name: nodeName}, &node) 121 ExpectWithOffset(1, err).ToNot(HaveOccurred(), "should success retrieving node to change labels") 122 123 if len(node.Labels) == 0 { 124 node.Labels = labelsToAdd 125 } else { 126 for k, v := range labelsToAdd { 127 node.Labels[k] = v 128 } 129 } 130 err = testenv.Client.Update(context.TODO(), &node) 131 ExpectWithOffset(1, err).ToNot(HaveOccurred(), "should success updating node with new labels") 132 } 133 134 func removeLabelsFromNode(nodeName string, labelsToRemove map[string]string) { 135 node := corev1.Node{} 136 err := testenv.Client.Get(context.TODO(), types.NamespacedName{Name: nodeName}, &node) 137 ExpectWithOffset(1, err).ToNot(HaveOccurred(), "should success retrieving node to remove labels") 138 139 if len(node.Labels) == 0 { 140 return 141 } 142 143 for k := range labelsToRemove { 144 delete(node.Labels, k) 145 } 146 147 err = testenv.Client.Update(context.TODO(), &node) 148 ExpectWithOffset(1, err).ToNot(HaveOccurred(), "should success updating node with label delete") 149 }