github.com/cilium/cilium@v1.16.2/test/controlplane/node/ciliumnodes/ciliumnodes.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package ciliumnode
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"os"
    10  	"path"
    11  	"reflect"
    12  	"testing"
    13  
    14  	v1 "k8s.io/api/core/v1"
    15  	"k8s.io/apimachinery/pkg/runtime/schema"
    16  
    17  	v2 "github.com/cilium/cilium/pkg/k8s/apis/cilium.io/v2"
    18  	"github.com/cilium/cilium/pkg/option"
    19  	"github.com/cilium/cilium/test/controlplane"
    20  	"github.com/cilium/cilium/test/controlplane/suite"
    21  )
    22  
    23  type step struct {
    24  	filename       string
    25  	expectedLabels map[string]string
    26  }
    27  
    28  var steps = []step{
    29  	{
    30  		"state1.yaml",
    31  		map[string]string{
    32  			"cilium.io/ci-node":      "k8s1",
    33  			"kubernetes.io/arch":     "amd64",
    34  			"kubernetes.io/hostname": "cilium-nodes-worker",
    35  			"kubernetes.io/os":       "linux",
    36  			"test-label":             "test-value",
    37  		},
    38  	},
    39  
    40  	{
    41  		"state2.yaml",
    42  		map[string]string{
    43  			"cilium.io/ci-node":      "k8s1",
    44  			"kubernetes.io/arch":     "amd64",
    45  			"kubernetes.io/hostname": "cilium-nodes-worker",
    46  			"kubernetes.io/os":       "linux",
    47  		},
    48  	},
    49  
    50  	{
    51  		"state3.yaml",
    52  		map[string]string{
    53  			"cilium.io/ci-node":      "k8s1",
    54  			"kubernetes.io/arch":     "amd64",
    55  			"kubernetes.io/hostname": "cilium-nodes-worker",
    56  			"kubernetes.io/os":       "linux",
    57  			"another-test-label":     "another-test-value",
    58  		},
    59  	},
    60  
    61  	{
    62  		"state4.yaml",
    63  		map[string]string{
    64  			"cilium.io/ci-node":      "k8s1",
    65  			"kubernetes.io/arch":     "amd64",
    66  			"kubernetes.io/hostname": "cilium-nodes-worker",
    67  			"kubernetes.io/os":       "linux",
    68  			"another-test-label":     "changed-test-value",
    69  		},
    70  	},
    71  }
    72  
    73  func init() {
    74  	suite.AddTestCase("CiliumNodes", func(t *testing.T) {
    75  		cwd, err := os.Getwd()
    76  		if err != nil {
    77  			t.Fatal(err)
    78  		}
    79  
    80  		modConfig := func(cfg *option.DaemonConfig) {
    81  			cfg.EnableNodePort = true
    82  		}
    83  		for _, version := range controlplane.K8sVersions() {
    84  			abs := func(f string) string { return path.Join(cwd, "node", "ciliumnodes", "v"+version, f) }
    85  
    86  			t.Run("v"+version, func(t *testing.T) {
    87  				test := suite.NewControlPlaneTest(t, "cilium-nodes-worker", version)
    88  
    89  				// Feed in initial state and start the agent.
    90  				test.
    91  					UpdateObjectsFromFile(abs("init.yaml")).
    92  					SetupEnvironment().
    93  					StartAgent(modConfig).
    94  					EnsureWatchers("nodes")
    95  
    96  				// Run through the test steps
    97  				for _, step := range steps {
    98  					test.UpdateObjectsFromFile(abs(step.filename))
    99  					test.Eventually(func() error { return validateLabels(test, step.expectedLabels) })
   100  				}
   101  
   102  				test.StopAgent().
   103  					ClearEnvironment()
   104  			})
   105  		}
   106  	})
   107  }
   108  
   109  func validateLabels(test *suite.ControlPlaneTest, expectedLabels map[string]string) error {
   110  	nodeLabels, err := getTestNodeLabels(test, "cilium-nodes-worker")
   111  	if err != nil {
   112  		return fmt.Errorf("failed to get Node labels: %w", err)
   113  	}
   114  	if !reflect.DeepEqual(expectedLabels, nodeLabels) {
   115  		return fmt.Errorf("Node labels mismatch, expected: %v, found: %v",
   116  			nodeLabels, expectedLabels)
   117  	}
   118  	ciliumNodeLabels, err := getTestCiliumNodeLabels(test, "cilium-nodes-worker")
   119  	if err != nil {
   120  		return fmt.Errorf("failed to get CiliumNode labels: %w", err)
   121  	}
   122  	if !reflect.DeepEqual(expectedLabels, ciliumNodeLabels) {
   123  		return fmt.Errorf("CiliumNode labels mismatch, expected: %v, found: %v",
   124  			ciliumNodeLabels, expectedLabels)
   125  	}
   126  	return nil
   127  }
   128  
   129  func getTestNodeLabels(test *suite.ControlPlaneTest, name string) (map[string]string, error) {
   130  	nodeObj, err := test.Get(
   131  		schema.GroupVersionResource{Group: "", Version: "v1", Resource: "nodes"},
   132  		"",
   133  		name,
   134  	)
   135  	if err != nil {
   136  		return nil, fmt.Errorf("unable to get %q Node: %w", name, err)
   137  	}
   138  	node, ok := nodeObj.(*v1.Node)
   139  	if !ok {
   140  		return nil, errors.New("type assertion failed for Node obj")
   141  	}
   142  
   143  	return node.GetLabels(), nil
   144  }
   145  
   146  func getTestCiliumNodeLabels(test *suite.ControlPlaneTest, name string) (map[string]string, error) {
   147  	ciliumNodeObj, err := test.Get(
   148  		schema.GroupVersionResource{Group: "cilium.io", Version: "v2", Resource: "ciliumnodes"},
   149  		"",
   150  		name,
   151  	)
   152  	if err != nil {
   153  		return nil, fmt.Errorf("unable to get %q CiliumNode: %w", name, err)
   154  	}
   155  	ciliumNode, ok := ciliumNodeObj.(*v2.CiliumNode)
   156  	if !ok {
   157  		return nil, errors.New("type assertion failed for CiliumNode obj")
   158  	}
   159  
   160  	return ciliumNode.GetLabels(), nil
   161  }