diff --git a/cluster-autoscaler/cloudprovider/aws/aws_wrapper.go b/cluster-autoscaler/cloudprovider/aws/aws_wrapper.go index b8c1f71b661b..beba83acb32e 100644 --- a/cluster-autoscaler/cloudprovider/aws/aws_wrapper.go +++ b/cluster-autoscaler/cloudprovider/aws/aws_wrapper.go @@ -118,10 +118,14 @@ func (m *awsWrapper) getManagedNodegroupInfo(nodegroupName string, clusterName s taintList := r.Nodegroup.Taints for _, taint := range taintList { if taint != nil && taint.Effect != nil && taint.Key != nil && taint.Value != nil { + formattedEffect, err := taintEksTranslator(taint) + if err != nil { + return nil, nil, nil, err + } taints = append(taints, apiv1.Taint{ Key: *taint.Key, Value: *taint.Value, - Effect: apiv1.TaintEffect(*taint.Effect), + Effect: apiv1.TaintEffect(formattedEffect), }) } } @@ -780,3 +784,21 @@ func buildLaunchTemplateFromSpec(ltSpec *autoscaling.LaunchTemplateSpecification version: version, } } + +func taintEksTranslator(t *eks.Taint) (apiv1.TaintEffect, error) { + // Translation between AWS EKS and Kubernetes taints + // + // See: + // + // https://docs.aws.amazon.com/eks/latest/APIReference/API_Taint.html + switch effect := *t.Effect; effect { + case eks.TaintEffectNoSchedule: + return apiv1.TaintEffectNoSchedule, nil + case eks.TaintEffectNoExecute: + return apiv1.TaintEffectNoExecute, nil + case eks.TaintEffectPreferNoSchedule: + return apiv1.TaintEffectPreferNoSchedule, nil + default: + return "", fmt.Errorf("couldn't translate EKS DescribeNodegroup response taint %s into Kubernetes format", effect) + } +} diff --git a/cluster-autoscaler/cloudprovider/aws/aws_wrapper_test.go b/cluster-autoscaler/cloudprovider/aws/aws_wrapper_test.go index 63b5f23baea0..44b745014cf3 100644 --- a/cluster-autoscaler/cloudprovider/aws/aws_wrapper_test.go +++ b/cluster-autoscaler/cloudprovider/aws/aws_wrapper_test.go @@ -114,7 +114,8 @@ func TestGetManagedNodegroup(t *testing.T) { nodegroupName := "testNodegroup" clusterName := "testCluster" - taintEffect1 := "effect 1" + taintEffect1 := eks.TaintEffectNoSchedule + taintEffectTranslated1 := apiv1.TaintEffectNoSchedule taintKey1 := "key 1" taintValue1 := "value 1" taint1 := eks.Taint{ @@ -123,7 +124,8 @@ func TestGetManagedNodegroup(t *testing.T) { Value: &taintValue1, } - taintEffect2 := "effect 2" + taintEffect2 := eks.TaintEffectNoExecute + taintEffectTranslated2 := apiv1.TaintEffectNoExecute taintKey2 := "key 2" taintValue2 := "value 2" taint2 := eks.Taint{ @@ -163,10 +165,10 @@ func TestGetManagedNodegroup(t *testing.T) { taintList, labelMap, tagMap, err := awsWrapper.getManagedNodegroupInfo(nodegroupName, clusterName) assert.Nil(t, err) assert.Equal(t, len(taintList), 2) - assert.Equal(t, taintList[0].Effect, apiv1.TaintEffect(taintEffect1)) + assert.Equal(t, taintList[0].Effect, taintEffectTranslated1) assert.Equal(t, taintList[0].Key, taintKey1) assert.Equal(t, taintList[0].Value, taintValue1) - assert.Equal(t, taintList[1].Effect, apiv1.TaintEffect(taintEffect2)) + assert.Equal(t, taintList[1].Effect, taintEffectTranslated2) assert.Equal(t, taintList[1].Key, taintKey2) assert.Equal(t, taintList[1].Value, taintValue2) assert.Equal(t, len(labelMap), 7) @@ -735,3 +737,51 @@ func TestGetInstanceTypesFromInstanceRequirementsWithEmptyList(t *testing.T) { assert.EqualError(t, err, exp.Error()) assert.Equal(t, "", result) } + +func TestTaintEksTranslator(t *testing.T) { + key := "key" + value := "value" + + taintEffect1 := eks.TaintEffectNoSchedule + taintEffectTranslated1 := apiv1.TaintEffectNoSchedule + taint1 := eks.Taint{ + Effect: &taintEffect1, + Key: &key, + Value: &value, + } + + t1, err := taintEksTranslator(&taint1) + assert.Nil(t, err) + assert.Equal(t, t1, taintEffectTranslated1) + + taintEffect2 := eks.TaintEffectNoSchedule + taintEffectTranslated2 := apiv1.TaintEffectNoSchedule + taint2 := eks.Taint{ + Effect: &taintEffect2, + Key: &key, + Value: &value, + } + t2, err := taintEksTranslator(&taint2) + assert.Nil(t, err) + assert.Equal(t, t2, taintEffectTranslated2) + + taintEffect3 := eks.TaintEffectNoExecute + taintEffectTranslated3 := apiv1.TaintEffectNoExecute + taint3 := eks.Taint{ + Effect: &taintEffect3, + Key: &key, + Value: &value, + } + t3, err := taintEksTranslator(&taint3) + assert.Nil(t, err) + assert.Equal(t, t3, taintEffectTranslated3) + + taintEffect4 := "TAINT_NO_EXISTS" + taint4 := eks.Taint{ + Effect: &taintEffect4, + Key: &key, + Value: &value, + } + _, err = taintEksTranslator(&taint4) + assert.Error(t, err) +} diff --git a/cluster-autoscaler/cloudprovider/aws/managed_nodegroup_cache_test.go b/cluster-autoscaler/cloudprovider/aws/managed_nodegroup_cache_test.go index a944bf611ae2..84e950adb4f0 100644 --- a/cluster-autoscaler/cloudprovider/aws/managed_nodegroup_cache_test.go +++ b/cluster-autoscaler/cloudprovider/aws/managed_nodegroup_cache_test.go @@ -35,13 +35,13 @@ func TestManagedNodegroupCache(t *testing.T) { clusterName := "clusterName" labelKey := "label key 1" labelValue := "label value 1" - taintEffect := "effect 1" + taintEffect := apiv1.TaintEffectNoSchedule taintKey := "key 1" taintValue := "value 1" tagKey := "tag key 1" tagValue := "tag value 1" taint := apiv1.Taint{ - Effect: apiv1.TaintEffect(taintEffect), + Effect: taintEffect, Key: taintKey, Value: taintValue, } @@ -154,7 +154,8 @@ func TestGetManagedNodegroupWithTaintsAndLabels(t *testing.T) { labelValue1 := "testValue 1" labelValue2 := "testValue 2" - taintEffect1 := "effect 1" + taintEffect1 := eks.TaintEffectNoSchedule + taintEffectTranslated1 := apiv1.TaintEffectNoSchedule taintKey1 := "key 1" taintValue1 := "value 1" taint1 := eks.Taint{ @@ -163,7 +164,8 @@ func TestGetManagedNodegroupWithTaintsAndLabels(t *testing.T) { Value: &taintValue1, } - taintEffect2 := "effect 2" + taintEffect2 := eks.TaintEffectNoExecute + taintEffectTranslated2 := apiv1.TaintEffectNoExecute taintKey2 := "key 2" taintValue2 := "value 2" taint2 := eks.Taint{ @@ -202,10 +204,10 @@ func TestGetManagedNodegroupWithTaintsAndLabels(t *testing.T) { assert.Equal(t, cacheObj.name, nodegroupName) assert.Equal(t, cacheObj.clusterName, clusterName) assert.Equal(t, len(cacheObj.taints), 2) - assert.Equal(t, cacheObj.taints[0].Effect, apiv1.TaintEffect(taintEffect1)) + assert.Equal(t, cacheObj.taints[0].Effect, taintEffectTranslated1) assert.Equal(t, cacheObj.taints[0].Key, taintKey1) assert.Equal(t, cacheObj.taints[0].Value, taintValue1) - assert.Equal(t, cacheObj.taints[1].Effect, apiv1.TaintEffect(taintEffect2)) + assert.Equal(t, cacheObj.taints[1].Effect, taintEffectTranslated2) assert.Equal(t, cacheObj.taints[1].Key, taintKey2) assert.Equal(t, cacheObj.taints[1].Value, taintValue2) assert.Equal(t, len(cacheObj.labels), 7) @@ -249,11 +251,11 @@ func TestGetManagedNodegroupInfoObjectWithCachedNodegroup(t *testing.T) { clusterName := "clusterName" labelKey := "label key 1" labelValue := "label value 1" - taintEffect := "effect 1" + taintEffect := apiv1.TaintEffectNoSchedule taintKey := "key 1" taintValue := "value 1" taint := apiv1.Taint{ - Effect: apiv1.TaintEffect(taintEffect), + Effect: taintEffect, Key: taintKey, Value: taintValue, } @@ -345,11 +347,11 @@ func TestGetManagedNodegroupLabelsWithCachedNodegroup(t *testing.T) { clusterName := "clusterName" labelKey := "label key 1" labelValue := "label value 1" - taintEffect := "effect 1" + taintEffect := apiv1.TaintEffectNoSchedule taintKey := "key 1" taintValue := "value 1" taint := apiv1.Taint{ - Effect: apiv1.TaintEffect(taintEffect), + Effect: taintEffect, Key: taintKey, Value: taintValue, } @@ -568,7 +570,8 @@ func TestGetManagedNodegroupTaintsNoCachedNodegroup(t *testing.T) { k8sVersion := "1.19" diskSize := int64(100) - taintEffect1 := "effect 1" + taintEffect1 := eks.TaintEffectNoExecute + taintEffectTranslated1 := apiv1.TaintEffectNoExecute taintKey1 := "key 1" taintValue1 := "value 1" taint1 := eks.Taint{ @@ -577,7 +580,8 @@ func TestGetManagedNodegroupTaintsNoCachedNodegroup(t *testing.T) { Value: &taintValue1, } - taintEffect2 := "effect 2" + taintEffect2 := eks.TaintEffectPreferNoSchedule + taintEffectTranslated2 := apiv1.TaintEffectPreferNoSchedule taintKey2 := "key 2" taintValue2 := "value 2" taint2 := eks.Taint{ @@ -608,10 +612,10 @@ func TestGetManagedNodegroupTaintsNoCachedNodegroup(t *testing.T) { taintsList, err := c.getManagedNodegroupTaints(nodegroupName, clusterName) require.NoError(t, err) assert.Equal(t, len(taintsList), 2) - assert.Equal(t, taintsList[0].Effect, apiv1.TaintEffect(taintEffect1)) + assert.Equal(t, taintsList[0].Effect, taintEffectTranslated1) assert.Equal(t, taintsList[0].Key, taintKey1) assert.Equal(t, taintsList[0].Value, taintValue1) - assert.Equal(t, taintsList[1].Effect, apiv1.TaintEffect(taintEffect2)) + assert.Equal(t, taintsList[1].Effect, taintEffectTranslated2) assert.Equal(t, taintsList[1].Key, taintKey2) assert.Equal(t, taintsList[1].Value, taintValue2) k.AssertCalled(t, "DescribeNodegroup", &eks.DescribeNodegroupInput{ @@ -627,11 +631,11 @@ func TestGetManagedNodegroupTagsWithCachedNodegroup(t *testing.T) { clusterName := "clusterName" labelKey := "label key 1" labelValue := "label value 1" - taintEffect := "effect 1" + taintEffect := apiv1.TaintEffectNoSchedule taintKey := "key 1" taintValue := "value 1" taint := apiv1.Taint{ - Effect: apiv1.TaintEffect(taintEffect), + Effect: taintEffect, Key: taintKey, Value: taintValue, } @@ -667,7 +671,7 @@ func TestGetManagedNodegroupTagsNoCachedNodegroup(t *testing.T) { k8sVersion := "1.19" diskSize := int64(100) - taintEffect1 := "effect 1" + taintEffect1 := eks.TaintEffectNoSchedule taintKey1 := "key 1" taintValue1 := "value 1" taint1 := eks.Taint{ @@ -676,7 +680,7 @@ func TestGetManagedNodegroupTagsNoCachedNodegroup(t *testing.T) { Value: &taintValue1, } - taintEffect2 := "effect 2" + taintEffect2 := eks.TaintEffectPreferNoSchedule taintKey2 := "key 2" taintValue2 := "value 2" taint2 := eks.Taint{