Skip to content

Commit d8a4a30

Browse files
Merge pull request #42 from frobware/fix-bz-1656334
UPSTREAM: <carry>: openshift: return no nodegroup when scaling size is zero
2 parents 1e8e192 + d64b32a commit d8a4a30

File tree

3 files changed

+225
-232
lines changed

3 files changed

+225
-232
lines changed

cluster-autoscaler/cloudprovider/openshiftmachineapi/machineapi_controller.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,12 @@ func (c *machineController) nodeGroupForNode(node *apiv1.Node) (cloudprovider.No
406406
if err != nil {
407407
return nil, fmt.Errorf("failed to build nodegroup for node %q: %v", node.Name, err)
408408
}
409+
// We don't scale from 0 so nodes must belong
410+
// to a nodegroup that has a scale size of at
411+
// least 1.
412+
if nodegroup.MaxSize()-nodegroup.MinSize() < 1 {
413+
return nil, nil
414+
}
409415
return nodegroup, nil
410416
}
411417
}
@@ -415,6 +421,12 @@ func (c *machineController) nodeGroupForNode(node *apiv1.Node) (cloudprovider.No
415421
return nil, fmt.Errorf("failed to build nodegroup for node %q: %v", node.Name, err)
416422
}
417423

424+
// We don't scale from 0 so nodes must belong to a nodegroup
425+
// that has a scale size of at least 1.
426+
if nodegroup.MaxSize()-nodegroup.MinSize() < 1 {
427+
return nil, nil
428+
}
429+
418430
glog.V(4).Infof("node %q is in nodegroup %q", node.Name, machineSet.Name)
419431
return nodegroup, nil
420432
}

cluster-autoscaler/cloudprovider/openshiftmachineapi/machineapi_controller_test.go

Lines changed: 130 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"k8s.io/apimachinery/pkg/apis/meta/v1"
3030
"k8s.io/apimachinery/pkg/labels"
3131
"k8s.io/apimachinery/pkg/runtime"
32+
"k8s.io/apimachinery/pkg/types"
3233
fakekube "k8s.io/client-go/kubernetes/fake"
3334
)
3435

@@ -61,6 +62,50 @@ func mustCreateTestController(t *testing.T, config testControllerConfig) (*machi
6162
}
6263
}
6364

65+
func makeMachineOwner(i int, replicaCount int, annotations map[string]string, ownedByMachineDeployment bool) (*v1beta1.MachineSet, *v1beta1.MachineDeployment) {
66+
machineSet := v1beta1.MachineSet{
67+
TypeMeta: v1.TypeMeta{
68+
Kind: "MachineSet",
69+
},
70+
ObjectMeta: v1.ObjectMeta{
71+
Name: fmt.Sprintf("machineset-%d", i),
72+
Namespace: "test-namespace",
73+
UID: types.UID(fmt.Sprintf("machineset-%d", i)),
74+
},
75+
Spec: v1beta1.MachineSetSpec{
76+
Replicas: int32ptr(int32(replicaCount)),
77+
},
78+
}
79+
80+
if !ownedByMachineDeployment {
81+
machineSet.ObjectMeta.Annotations = annotations
82+
return &machineSet, nil
83+
}
84+
85+
machineDeployment := v1beta1.MachineDeployment{
86+
TypeMeta: v1.TypeMeta{
87+
Kind: "MachineDeployment",
88+
},
89+
ObjectMeta: v1.ObjectMeta{
90+
Name: fmt.Sprintf("machinedeployment-%d", i),
91+
Namespace: "test-namespace",
92+
UID: types.UID(fmt.Sprintf("machinedeployment-%d", i)),
93+
Annotations: annotations,
94+
},
95+
Spec: v1beta1.MachineDeploymentSpec{
96+
Replicas: int32ptr(int32(replicaCount)),
97+
},
98+
}
99+
100+
machineSet.OwnerReferences = append(machineSet.OwnerReferences, v1.OwnerReference{
101+
Name: machineDeployment.Name,
102+
Kind: machineDeployment.Kind,
103+
UID: machineDeployment.UID,
104+
})
105+
106+
return &machineSet, &machineDeployment
107+
}
108+
64109
func TestControllerFindMachineByID(t *testing.T) {
65110
controller, stop := mustCreateTestController(t, testControllerConfig{})
66111
defer stop()
@@ -591,178 +636,6 @@ func TestControllerNodeGroupForNodeWithMissingMachineOwner(t *testing.T) {
591636
}
592637
}
593638

594-
func TestControllerNodeGroupForNodeSuccessFromMachineSet(t *testing.T) {
595-
node := &apiv1.Node{
596-
TypeMeta: v1.TypeMeta{
597-
Kind: "Node",
598-
},
599-
ObjectMeta: v1.ObjectMeta{
600-
Name: "node",
601-
Annotations: map[string]string{
602-
machineAnnotationKey: "test-namespace/machine",
603-
},
604-
},
605-
Spec: apiv1.NodeSpec{
606-
ProviderID: "provider-id",
607-
},
608-
}
609-
610-
machineSet := &v1beta1.MachineSet{
611-
TypeMeta: v1.TypeMeta{
612-
Kind: "MachineSet",
613-
},
614-
ObjectMeta: v1.ObjectMeta{
615-
Name: "machineset",
616-
Namespace: "test-namespace",
617-
UID: uuid1,
618-
},
619-
}
620-
621-
machine := &v1beta1.Machine{
622-
TypeMeta: v1.TypeMeta{
623-
Kind: "Machine",
624-
},
625-
ObjectMeta: v1.ObjectMeta{
626-
Name: "machine",
627-
Namespace: "test-namespace",
628-
OwnerReferences: []v1.OwnerReference{{
629-
Name: machineSet.Name,
630-
Kind: machineSet.Kind,
631-
UID: machineSet.UID,
632-
}},
633-
},
634-
}
635-
636-
controller, stop := mustCreateTestController(t, testControllerConfig{
637-
nodeObjects: []runtime.Object{
638-
node,
639-
},
640-
machineObjects: []runtime.Object{
641-
machine,
642-
machineSet,
643-
},
644-
})
645-
defer stop()
646-
647-
ng, err := controller.nodeGroupForNode(&apiv1.Node{
648-
TypeMeta: v1.TypeMeta{
649-
Kind: "Node",
650-
},
651-
ObjectMeta: v1.ObjectMeta{
652-
Name: "node",
653-
},
654-
Spec: apiv1.NodeSpec{
655-
ProviderID: "provider-id",
656-
},
657-
})
658-
659-
if err != nil {
660-
t.Fatal("expected no error")
661-
}
662-
663-
if ng == nil {
664-
t.Fatal("expected a nodegroup")
665-
}
666-
667-
expected := path.Join(machineSet.Namespace, machineSet.Name)
668-
if actual := ng.Id(); actual != expected {
669-
t.Errorf("expected %q, got %q", expected, actual)
670-
}
671-
}
672-
673-
func TestControllerNodeGroupForNodeSuccessFromMachineDeployment(t *testing.T) {
674-
node := &apiv1.Node{
675-
TypeMeta: v1.TypeMeta{
676-
Kind: "Node",
677-
},
678-
ObjectMeta: v1.ObjectMeta{
679-
Name: "node",
680-
Annotations: map[string]string{
681-
machineAnnotationKey: "test-namespace/machine",
682-
},
683-
},
684-
Spec: apiv1.NodeSpec{
685-
ProviderID: "provider-id",
686-
},
687-
}
688-
689-
machineDeployment := &v1beta1.MachineDeployment{
690-
TypeMeta: v1.TypeMeta{
691-
Kind: "MachineDeployment",
692-
},
693-
ObjectMeta: v1.ObjectMeta{
694-
Name: "machinedeployment",
695-
Namespace: "test-namespace",
696-
},
697-
}
698-
699-
machineSet := &v1beta1.MachineSet{
700-
TypeMeta: v1.TypeMeta{
701-
Kind: "MachineSet",
702-
},
703-
ObjectMeta: v1.ObjectMeta{
704-
Name: "machineset",
705-
Namespace: "test-namespace",
706-
OwnerReferences: []v1.OwnerReference{{
707-
Kind: "MachineDeployment",
708-
Name: machineDeployment.Name,
709-
}},
710-
},
711-
}
712-
713-
machine := &v1beta1.Machine{
714-
TypeMeta: v1.TypeMeta{
715-
Kind: "Machine",
716-
},
717-
ObjectMeta: v1.ObjectMeta{
718-
Name: "machine",
719-
Namespace: "test-namespace",
720-
OwnerReferences: []v1.OwnerReference{{
721-
Name: machineSet.Name,
722-
Kind: machineSet.Kind,
723-
UID: machineSet.UID,
724-
}},
725-
},
726-
}
727-
728-
controller, stop := mustCreateTestController(t, testControllerConfig{
729-
nodeObjects: []runtime.Object{
730-
node,
731-
},
732-
machineObjects: []runtime.Object{
733-
machine,
734-
machineSet,
735-
machineDeployment,
736-
},
737-
})
738-
defer stop()
739-
740-
ng, err := controller.nodeGroupForNode(&apiv1.Node{
741-
TypeMeta: v1.TypeMeta{
742-
Kind: "Node",
743-
},
744-
ObjectMeta: v1.ObjectMeta{
745-
Name: "node",
746-
},
747-
Spec: apiv1.NodeSpec{
748-
ProviderID: "provider-id",
749-
},
750-
})
751-
752-
if err != nil {
753-
t.Fatal("expected no error")
754-
}
755-
756-
if ng == nil {
757-
t.Fatal("expected a nodegroup")
758-
}
759-
760-
expected := path.Join(machineDeployment.Namespace, machineDeployment.Name)
761-
if actual := ng.Id(); actual != expected {
762-
t.Errorf("expected %q, got %q", expected, actual)
763-
}
764-
}
765-
766639
func TestControllerNodeGroupsWithMachineDeployments(t *testing.T) {
767640
machineDeploymentTemplate := &v1beta1.MachineDeployment{
768641
TypeMeta: v1.TypeMeta{
@@ -928,3 +801,88 @@ func TestControllerNodeGroupsWithMachineSets(t *testing.T) {
928801
}
929802
}
930803
}
804+
805+
func TestControllerNodeGroupForNodeLookup(t *testing.T) {
806+
for i, tc := range []struct {
807+
description string
808+
annotations map[string]string
809+
lookupSucceeds bool
810+
}{{
811+
description: "lookup is nil because no annotations",
812+
annotations: map[string]string{},
813+
lookupSucceeds: false,
814+
}, {
815+
description: "lookup is nil because scaling range == 0",
816+
annotations: map[string]string{
817+
nodeGroupMinSizeAnnotationKey: "1",
818+
nodeGroupMaxSizeAnnotationKey: "1",
819+
},
820+
lookupSucceeds: false,
821+
}, {
822+
description: "lookup is successful because scaling range >= 1",
823+
annotations: map[string]string{
824+
nodeGroupMinSizeAnnotationKey: "1",
825+
nodeGroupMaxSizeAnnotationKey: "2",
826+
},
827+
lookupSucceeds: true,
828+
}} {
829+
test := func(t *testing.T, i int, annotations map[string]string, useMachineDeployment bool) {
830+
t.Helper()
831+
832+
machineSet, machineDeployment := makeMachineOwner(i, 1, annotations, useMachineDeployment)
833+
834+
node, machine := makeLinkedNodeAndMachine(i, v1.OwnerReference{
835+
Name: machineSet.Name,
836+
Kind: machineSet.Kind,
837+
UID: machineSet.UID,
838+
})
839+
840+
machineObjects := []runtime.Object{
841+
machine,
842+
machineSet,
843+
}
844+
845+
if machineDeployment != nil {
846+
machineObjects = append(machineObjects, machineDeployment)
847+
}
848+
849+
controller, stop := mustCreateTestController(t, testControllerConfig{
850+
nodeObjects: []runtime.Object{node},
851+
machineObjects: machineObjects,
852+
})
853+
defer stop()
854+
855+
ng, err := controller.nodeGroupForNode(node)
856+
if err != nil {
857+
t.Fatalf("unexpected error: %v", err)
858+
}
859+
860+
if ng == nil && tc.lookupSucceeds {
861+
t.Fatalf("expected nil from lookup")
862+
}
863+
864+
if ng != nil && !tc.lookupSucceeds {
865+
t.Fatalf("expected non-nil from lookup")
866+
}
867+
868+
if tc.lookupSucceeds {
869+
var expected string
870+
871+
if useMachineDeployment {
872+
expected = path.Join(machineDeployment.Namespace, machineDeployment.Name)
873+
} else {
874+
expected = path.Join(machineSet.Namespace, machineSet.Name)
875+
}
876+
877+
if actual := ng.Id(); actual != expected {
878+
t.Errorf("expected %q, got %q", expected, actual)
879+
}
880+
}
881+
}
882+
883+
t.Run(tc.description, func(t *testing.T) {
884+
test(t, i, tc.annotations, true) // with MachineDeployment
885+
test(t, i, tc.annotations, false)
886+
})
887+
}
888+
}

0 commit comments

Comments
 (0)