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  }