diff --git a/pkg/validation/validate_cluster.go b/pkg/validation/validate_cluster.go index 0f2c957dbb..4becb3730c 100644 --- a/pkg/validation/validate_cluster.go +++ b/pkg/validation/validate_cluster.go @@ -235,13 +235,20 @@ func (v *ValidationCluster) validateNodes(cloudGroups map[string]*cloudinstances var allMembers []*cloudinstances.CloudInstanceGroupMember allMembers = append(allMembers, cloudGroup.Ready...) allMembers = append(allMembers, cloudGroup.NeedUpdate...) - if len(allMembers) < cloudGroup.MinSize { + + numNodes := 0 + for _, m := range allMembers { + if !m.Detached { + numNodes++ + } + } + if numNodes < cloudGroup.MinSize { v.addError(&ValidationError{ Kind: "InstanceGroup", Name: cloudGroup.InstanceGroup.Name, Message: fmt.Sprintf("InstanceGroup %q did not have enough nodes %d vs %d", cloudGroup.InstanceGroup.Name, - len(allMembers), + numNodes, cloudGroup.MinSize), }) } diff --git a/pkg/validation/validate_cluster_test.go b/pkg/validation/validate_cluster_test.go index a61fe8a725..92f0e1e234 100644 --- a/pkg/validation/validate_cluster_test.go +++ b/pkg/validation/validate_cluster_test.go @@ -164,6 +164,59 @@ func Test_ValidateNodesNotEnough(t *testing.T) { } } +func Test_ValidateDetachedNodesDontCount(t *testing.T) { + groups := make(map[string]*cloudinstances.CloudInstanceGroup) + groups["node-1"] = &cloudinstances.CloudInstanceGroup{ + InstanceGroup: &kopsapi.InstanceGroup{ + ObjectMeta: metav1.ObjectMeta{ + Name: "node-1", + }, + Spec: kopsapi.InstanceGroupSpec{ + Role: kopsapi.InstanceGroupRoleNode, + }, + }, + MinSize: 2, + Ready: []*cloudinstances.CloudInstanceGroupMember{ + { + ID: "i-00001", + Node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "node-1a"}, + Status: v1.NodeStatus{ + Conditions: []v1.NodeCondition{ + {Type: "Ready", Status: v1.ConditionTrue}, + }, + }, + }, + }, + }, + NeedUpdate: []*cloudinstances.CloudInstanceGroupMember{ + { + ID: "i-00002", + Node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{Name: "node-1b"}, + Status: v1.NodeStatus{ + Conditions: []v1.NodeCondition{ + {Type: "Ready", Status: v1.ConditionTrue}, + }, + }, + }, + Detached: true, + }, + }, + } + + v, err := testValidate(t, groups, nil) + require.NoError(t, err) + if !assert.Len(t, v.Failures, 1) || + !assert.Equal(t, &ValidationError{ + Kind: "InstanceGroup", + Name: "node-1", + Message: "InstanceGroup \"node-1\" did not have enough nodes 1 vs 2", + }, v.Failures[0]) { + printDebug(t, v) + } +} + func Test_ValidateNodeNotReady(t *testing.T) { groups := make(map[string]*cloudinstances.CloudInstanceGroup) groups["node-1"] = &cloudinstances.CloudInstanceGroup{