From 0ac24197fe63d48be29a62c6b0cc8e2f129a4dd2 Mon Sep 17 00:00:00 2001 From: Aly Nathoo <98403872+anathoodell@users.noreply.github.com> Date: Fri, 6 Dec 2024 09:18:43 -0500 Subject: [PATCH] Detect Zone info in node labels (#811) * Adding GetMatchingNodes as a function to find Nodes that have labels that match label and label value. Signed-off-by: Aly Nathoo --------- Signed-off-by: Aly Nathoo --- controllers/csm_controller.go | 10 ++++++ controllers/csm_controller_test.go | 54 ++++++++++++++++++++++++++++++ tests/shared/common.go | 13 +++++++ tests/shared/crclient/client.go | 14 ++++++++ 4 files changed, 91 insertions(+) diff --git a/controllers/csm_controller.go b/controllers/csm_controller.go index 997a516c0..05a1054da 100644 --- a/controllers/csm_controller.go +++ b/controllers/csm_controller.go @@ -1517,3 +1517,13 @@ func (r *ContainerStorageModuleReconciler) GetUpdateCount() int32 { func (r *ContainerStorageModuleReconciler) GetK8sClient() kubernetes.Interface { return r.K8sClient } + +func (r *ContainerStorageModuleReconciler) GetMatchingNodes(ctx context.Context, labelKey string, labelValue string) (*corev1.NodeList, error) { + nodeList := &corev1.NodeList{} + opts := []client.ListOption{ + client.MatchingLabels{labelKey: labelValue}, + } + err := r.List(ctx, nodeList, opts...) + + return nodeList, err +} diff --git a/controllers/csm_controller_test.go b/controllers/csm_controller_test.go index 91e111651..3b80ecbe0 100644 --- a/controllers/csm_controller_test.go +++ b/controllers/csm_controller_test.go @@ -2382,3 +2382,57 @@ func (suite *CSMControllerTestSuite) makeFakeRevProxyCSM(name string, ns string, err = suite.fakeClient.Create(ctx, &csm) assert.Nil(suite.T(), err) } + +func (suite *CSMControllerTestSuite) TestGetNodeLabels() { + // TBD: crclient/client.go needs to be augmented to filter on labels during + // the List return for a viable thorough test. Since this functionality is + // missing, this test is quite elementary as a result. + + csm := shared.MakeCSM(csmName, suite.namespace, configVersion) + csm.Spec.Driver.CSIDriverType = csmv1.PowerScale + csm.Spec.Driver.Common.Image = "image" + csm.Annotations[configVersionKey] = configVersion + + sec := shared.MakeSecret(csmName+"-creds", suite.namespace, configVersion) + err := suite.fakeClient.Create(ctx, sec) + if err != nil { + panic(err) + } + + csm.ObjectMeta.Finalizers = []string{CSMFinalizerName} + err = suite.fakeClient.Create(ctx, &csm) + if err != nil { + panic(err) + } + + reconciler := suite.createReconciler() + + // create node object, add to fakeclient, reconcile.GetMatchingNodes + node := shared.MakeNode("node1", suite.namespace) + node.Labels["topology.kubernetes.io/zone"] = "US-EAST" + + err = suite.fakeClient.Create(ctx, &node) + assert.Nil(suite.T(), err) + + nodeList := &corev1.NodeList{} + err = suite.fakeClient.List(ctx, nodeList, nil) + assert.Nil(suite.T(), err) + + nodeListMatching, err := reconciler.GetMatchingNodes(ctx, "topology.kubernetes.io/zone", "US-EAST") + ctrl.Log.Info("node list response (1)", "number of nodes is: ", len(nodeListMatching.Items)) + + // Check the len to be 1 else fail + if len(nodeListMatching.Items) != 1 { + ctrl.Log.Error(err, "Unexpected length on node list.", "length", len(nodeListMatching.Items)) + panic(err) + } + + for _, node := range nodeListMatching.Items { + ctrl.Log.Info("Matching node item", "name ", node.ObjectMeta.GetName()) + } + if node.ObjectMeta.GetName() != "node1" { + ctrl.Log.Error(err, "Unmatched label on node.") + panic(err) + } + assert.Nil(suite.T(), err) +} diff --git a/tests/shared/common.go b/tests/shared/common.go index 2855cd45f..fc48d6ae4 100644 --- a/tests/shared/common.go +++ b/tests/shared/common.go @@ -195,6 +195,19 @@ func MakePod(name, ns string) corev1.Pod { return podObj } +// MakeNode returns a node object +func MakeNode(name, ns string) corev1.Node { + nodeObj := corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: ns, + Labels: map[string]string{}, + }, + } + + return nodeObj +} + // MakeReverseProxyModule returns a csireverseproxy object func MakeReverseProxyModule(_ string) csmv1.Module { revproxy := csmv1.Module{ diff --git a/tests/shared/crclient/client.go b/tests/shared/crclient/client.go index a6d1d0f42..ee6be3443 100644 --- a/tests/shared/crclient/client.go +++ b/tests/shared/crclient/client.go @@ -106,6 +106,8 @@ func (f Client) List(ctx context.Context, list client.ObjectList, _ ...client.Li switch l := list.(type) { case *corev1.PodList: return f.listPodList(l) + case *corev1.NodeList: + return f.listNodeList(l) case *appsv1.DeploymentList: return f.listDeploymentList(ctx, &appsv1.DeploymentList{}) default: @@ -122,6 +124,18 @@ func (f Client) listPodList(list *corev1.PodList) error { return nil } +func (f Client) listNodeList(list *corev1.NodeList) error { + for k, v := range f.Objects { + if k.Kind == "Node" { + node, ok := v.(*corev1.Node) + if ok { + list.Items = append(list.Items, *node) + } + } + } + return nil +} + func (f Client) listDeploymentList(_ context.Context, list *appsv1.DeploymentList) error { for k, v := range f.Objects { if k.Kind == "Deployment" {