Skip to content

Commit 449b95b

Browse files
JoelSpeedcloud-team-rebase-bot
authored and
cloud-team-rebase-bot
committed
UPSTREAM: <carry>: Fix unstructured taint parsing in Cluster API provider
This change corrects the behavior for parsing taints from the unstructured scalable resource. This is required on OpenShift as our implementation is slightly different from the upstream.
1 parent 68e58a9 commit 449b95b

File tree

3 files changed

+110
-4
lines changed

3 files changed

+110
-4
lines changed

cluster-autoscaler/cloudprovider/clusterapi/clusterapi_controller_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,17 @@ func createTestConfigs(specs ...testSpec) []*testConfig {
347347
"kind": machineTemplateKind,
348348
"name": "TestMachineTemplate",
349349
},
350+
"taints": []interface{}{
351+
map[string]interface{}{
352+
"key": "test",
353+
"value": "test",
354+
"effect": "NoSchedule",
355+
},
356+
map[string]interface{}{
357+
"key": "test-no-value",
358+
"effect": "NoSchedule",
359+
},
360+
},
350361
},
351362
},
352363
},
@@ -385,6 +396,17 @@ func createTestConfigs(specs ...testSpec) []*testConfig {
385396
"kind": machineTemplateKind,
386397
"name": "TestMachineTemplate",
387398
},
399+
"taints": []interface{}{
400+
map[string]interface{}{
401+
"key": "test",
402+
"value": "test",
403+
"effect": "NoSchedule",
404+
},
405+
map[string]interface{}{
406+
"key": "test-no-value",
407+
"effect": "NoSchedule",
408+
},
409+
},
388410
},
389411
},
390412
},

cluster-autoscaler/cloudprovider/clusterapi/clusterapi_unstructured.go

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,10 @@ func (r unstructuredScalableResource) Taints() []apiv1.Taint {
212212
}
213213
if found {
214214
for _, t := range newtaints {
215-
if v, ok := t.(apiv1.Taint); ok {
216-
taints = append(taints, v)
215+
if t := unstructuredToTaint(t); t != nil {
216+
taints = append(taints, *t)
217217
} else {
218-
klog.Warning("Unable to convert data to taint: %v", t)
218+
klog.Warningf("Unable to convert of type %T data to taint: %+v", t, t)
219219
continue
220220
}
221221
}
@@ -236,6 +236,22 @@ func (r unstructuredScalableResource) Taints() []apiv1.Taint {
236236
return taints
237237
}
238238

239+
func unstructuredToTaint(unstructuredTaintInterface interface{}) *corev1.Taint {
240+
unstructuredTaint := unstructuredTaintInterface.(map[string]interface{})
241+
if unstructuredTaint == nil {
242+
return nil
243+
}
244+
245+
taint := &corev1.Taint{}
246+
taint.Key = unstructuredTaint["key"].(string)
247+
// value is optional and could be nil if not present
248+
if unstructuredTaint["value"] != nil {
249+
taint.Value = unstructuredTaint["value"].(string)
250+
}
251+
taint.Effect = corev1.TaintEffect(unstructuredTaint["effect"].(string))
252+
return taint
253+
}
254+
239255
// A node group can scale from zero if it can inform about the CPU and memory
240256
// capacity of the nodes within the group.
241257
func (r unstructuredScalableResource) CanScaleFromZero() bool {

cluster-autoscaler/cloudprovider/clusterapi/clusterapi_unstructured_test.go

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package clusterapi
1919
import (
2020
"context"
2121
"fmt"
22+
"reflect"
2223
"testing"
2324
"time"
2425

@@ -222,6 +223,65 @@ func TestReplicas(t *testing.T) {
222223
})
223224
}
224225

226+
func TestTaints(t *testing.T) {
227+
initialReplicas := 1
228+
229+
expectedTaints := []v1.Taint{
230+
{Key: "test", Effect: v1.TaintEffectNoSchedule, Value: "test"},
231+
{Key: "test-no-value", Effect: v1.TaintEffectNoSchedule},
232+
}
233+
expectedTaintsWithAnnotations := []v1.Taint{
234+
{Key: "test", Effect: v1.TaintEffectNoSchedule, Value: "test"},
235+
{Key: "test-no-value", Effect: v1.TaintEffectNoSchedule},
236+
{Key: "key1", Effect: v1.TaintEffectNoSchedule, Value: "value1"},
237+
{Key: "key2", Effect: v1.TaintEffectNoExecute, Value: "value2"},
238+
}
239+
taintAnnotation := "key1=value1:NoSchedule,key2=value2:NoExecute"
240+
241+
test := func(t *testing.T, testConfig *testConfig) {
242+
controller, stop := mustCreateTestController(t, testConfig)
243+
defer stop()
244+
245+
testResource := testConfig.machineSet
246+
if testConfig.machineDeployment != nil {
247+
testResource = testConfig.machineDeployment
248+
}
249+
250+
sr, err := newUnstructuredScalableResource(controller, testResource)
251+
if err != nil {
252+
t.Fatal(err)
253+
}
254+
255+
taints := sr.Taints()
256+
257+
if !reflect.DeepEqual(taints, expectedTaints) {
258+
t.Errorf("expected %v, got: %v", expectedTaints, taints)
259+
}
260+
261+
srAnnotations := sr.unstructured.GetAnnotations()
262+
if srAnnotations == nil {
263+
srAnnotations = make(map[string]string)
264+
}
265+
266+
srAnnotations[taintsKey] = taintAnnotation
267+
sr.unstructured.SetAnnotations(srAnnotations)
268+
269+
taints = sr.Taints()
270+
271+
if !reflect.DeepEqual(taints, expectedTaintsWithAnnotations) {
272+
t.Errorf("expected %v, got: %v", expectedTaintsWithAnnotations, taints)
273+
}
274+
}
275+
276+
t.Run("MachineSet", func(t *testing.T) {
277+
test(t, createMachineSetTestConfig(RandomString(6), RandomString(6), RandomString(6), initialReplicas, nil, nil))
278+
})
279+
280+
t.Run("MachineDeployment", func(t *testing.T) {
281+
test(t, createMachineDeploymentTestConfig(RandomString(6), RandomString(6), RandomString(6), initialReplicas, nil, nil))
282+
})
283+
}
284+
225285
func TestSetSizeAndReplicas(t *testing.T) {
226286
initialReplicas := 1
227287
updatedReplicas := 5
@@ -297,7 +357,15 @@ func TestAnnotations(t *testing.T) {
297357
memQuantity := resource.MustParse("1024")
298358
gpuQuantity := resource.MustParse("1")
299359
maxPodsQuantity := resource.MustParse("42")
300-
expectedTaints := []v1.Taint{{Key: "key1", Effect: v1.TaintEffectNoSchedule, Value: "value1"}, {Key: "key2", Effect: v1.TaintEffectNoExecute, Value: "value2"}}
360+
361+
// Note, the first two taints comes from the spec of the machine template, the rest from the annotations.
362+
expectedTaints := []v1.Taint{
363+
{Key: "test", Effect: v1.TaintEffectNoSchedule, Value: "test"},
364+
{Key: "test-no-value", Effect: v1.TaintEffectNoSchedule},
365+
{Key: "key1", Effect: v1.TaintEffectNoSchedule, Value: "value1"},
366+
{Key: "key2", Effect: v1.TaintEffectNoExecute, Value: "value2"},
367+
}
368+
301369
annotations := map[string]string{
302370
cpuKey: cpuQuantity.String(),
303371
memoryKey: memQuantity.String(),

0 commit comments

Comments
 (0)