From aa68f51f138e06d0787b29db4fa529b649bed618 Mon Sep 17 00:00:00 2001 From: michael mccune Date: Thu, 16 Feb 2023 16:00:18 -0500 Subject: [PATCH] UPSTREAM: : add machine api label and taint functionality This change re-adds the machine api support for labels and taints on node groups. The code was removed upstream as it is openshift specific, see this pull request[0]. [0]: https://github.com/kubernetes/autoscaler/pull/5249 --- .../clusterapi/clusterapi_nodegroup_test.go | 14 +++++-- .../clusterapi/clusterapi_unstructured.go | 41 ++++++++----------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/cluster-autoscaler/cloudprovider/clusterapi/clusterapi_nodegroup_test.go b/cluster-autoscaler/cloudprovider/clusterapi/clusterapi_nodegroup_test.go index 67f6184faa5..11da79534f0 100644 --- a/cluster-autoscaler/cloudprovider/clusterapi/clusterapi_nodegroup_test.go +++ b/cluster-autoscaler/cloudprovider/clusterapi/clusterapi_nodegroup_test.go @@ -1297,6 +1297,7 @@ func TestNodeGroupTemplateNodeInfo(t *testing.T) { type testCaseConfig struct { nodeLabels map[string]string + nodegroupLabels map[string]string includeNodes bool expectedErr error expectedCapacity map[corev1.ResourceName]int64 @@ -1359,10 +1360,11 @@ func TestNodeGroupTemplateNodeInfo(t *testing.T) { gpuapis.ResourceNvidiaGPU: 1, }, expectedNodeLabels: map[string]string{ - "kubernetes.io/os": "linux", - "kubernetes.io/arch": "arm64", "kubernetes.io/hostname": "random value", - "my-custom-label": "custom-value", + "kubernetes.io/os": "linux", + "kubernetes.io/arch": "amd64", + "nodeGroupLabel": "value", + "anotherLabel": "anotherValue", }, }, }, @@ -1396,6 +1398,12 @@ func TestNodeGroupTemplateNodeInfo(t *testing.T) { } test := func(t *testing.T, testConfig *testConfig, config testCaseConfig) { + if testConfig.machineDeployment != nil { + unstructured.SetNestedStringMap(testConfig.machineDeployment.Object, config.nodegroupLabels, "spec", "template", "spec", "metadata", "labels") + } else { + unstructured.SetNestedStringMap(testConfig.machineSet.Object, config.nodegroupLabels, "spec", "template", "spec", "metadata", "labels") + } + if config.includeNodes { for i := range testConfig.nodes { testConfig.nodes[i].SetLabels(config.nodeLabels) diff --git a/cluster-autoscaler/cloudprovider/clusterapi/clusterapi_unstructured.go b/cluster-autoscaler/cloudprovider/clusterapi/clusterapi_unstructured.go index 60409a33ba8..150d956947f 100644 --- a/cluster-autoscaler/cloudprovider/clusterapi/clusterapi_unstructured.go +++ b/cluster-autoscaler/cloudprovider/clusterapi/clusterapi_unstructured.go @@ -174,37 +174,28 @@ func (r unstructuredScalableResource) MarkMachineForDeletion(machine *unstructur } func (r unstructuredScalableResource) Labels() map[string]string { - annotations := r.unstructured.GetAnnotations() - // annotation value of the form "key1=value1,key2=value2" - if val, found := annotations[labelsKey]; found { - labels := strings.Split(val, ",") - kv := make(map[string]string, len(labels)) - for _, label := range labels { - split := strings.SplitN(label, "=", 2) - if len(split) == 2 { - kv[split[0]] = split[1] - } - } - return kv + labels, found, err := unstructured.NestedStringMap(r.unstructured.Object, "spec", "template", "spec", "metadata", "labels") + if !found || err != nil { + return nil } - return nil + return labels } func (r unstructuredScalableResource) Taints() []apiv1.Taint { - annotations := r.unstructured.GetAnnotations() - // annotation value the form of "key1=value1:condition,key2=value2:condition" - if val, found := annotations[taintsKey]; found { - taints := strings.Split(val, ",") - ret := make([]apiv1.Taint, 0, len(taints)) - for _, taintStr := range taints { - taint, err := parseTaint(taintStr) - if err == nil { - ret = append(ret, taint) - } + taints, found, err := unstructured.NestedSlice(r.unstructured.Object, "spec", "template", "spec", "taints") + if !found || err != nil { + return nil + } + ret := make([]apiv1.Taint, len(taints)) + for i, t := range taints { + if v, ok := t.(apiv1.Taint); ok { + ret[i] = v + } else { + // if we cannot convert the interface to a Taint, return early with zero value + return nil } - return ret } - return nil + return ret } // A node group can scale from zero if it can inform about the CPU and memory