From bbd724fdc7c48d698ac849faa14083f10b0b0105 Mon Sep 17 00:00:00 2001 From: Eric Wolinetz Date: Wed, 12 Aug 2020 12:11:08 -0500 Subject: [PATCH] adding back redundancy validation based on number of data nodes --- pkg/k8shandler/util.go | 28 +++++++++ pkg/k8shandler/util_test.go | 122 +++++++++++++++++++++++++++++++++++- 2 files changed, 149 insertions(+), 1 deletion(-) diff --git a/pkg/k8shandler/util.go b/pkg/k8shandler/util.go index a7db3902b..9f342d861 100644 --- a/pkg/k8shandler/util.go +++ b/pkg/k8shandler/util.go @@ -198,6 +198,23 @@ func isValidDataCount(dpl *api.Elasticsearch) bool { return dataCount > 0 } +func isValidRedundancyPolicy(dpl *api.Elasticsearch) bool { + dataCount := int(getDataCount(dpl)) + + switch dpl.Spec.RedundancyPolicy { + case api.ZeroRedundancy: + return true + case api.SingleRedundancy: + fallthrough + case api.MultipleRedundancy: + fallthrough + case api.FullRedundancy: + return dataCount > 1 + default: + return false + } +} + func (elasticsearchRequest *ElasticsearchRequest) isValidConf() error { dpl := elasticsearchRequest.cluster @@ -225,6 +242,17 @@ func (elasticsearchRequest *ElasticsearchRequest) isValidConf() error { } } + if !isValidRedundancyPolicy(dpl) { + if err := updateConditionWithRetry(dpl, v1.ConditionTrue, updateInvalidReplicationCondition, client); err != nil { + return err + } + return fmt.Errorf("Wrong RedundancyPolicy selected '%s'. Choose different RedundancyPolicy or add more nodes with data roles", dpl.Spec.RedundancyPolicy) + } else { + if err := updateConditionWithRetry(dpl, v1.ConditionFalse, updateInvalidReplicationCondition, client); err != nil { + return err + } + } + // TODO: replace this with a validating web hook to ensure field is immutable if ok, msg := hasValidUUIDs(dpl); !ok { if err := updateInvalidUUIDChangeCondition(dpl, v1.ConditionTrue, msg, client); err != nil { diff --git a/pkg/k8shandler/util_test.go b/pkg/k8shandler/util_test.go index 95c39f53c..f6efc626d 100644 --- a/pkg/k8shandler/util_test.go +++ b/pkg/k8shandler/util_test.go @@ -134,11 +134,125 @@ func TestSelectorsCommonOverwritten(t *testing.T) { } } +func TestInvalidRedundancyPolicySpecified(t *testing.T) { + + esNode := api.ElasticsearchNode{ + Roles: []api.ElasticsearchNodeRole{"data"}, + NodeCount: int32(1), + } + + esCR := &api.Elasticsearch{ + Spec: api.ElasticsearchSpec{ + RedundancyPolicy: api.SingleRedundancy, + Nodes: []api.ElasticsearchNode{esNode}, + }, + } + + //replicaCount := calculateReplicaCount(esCR) + isValid := isValidRedundancyPolicy(esCR) + + if isValid { + t.Error("Expected SingleRedundancy with one data node to be invalid, flagged as valid") + } + + esCR = &api.Elasticsearch{ + Spec: api.ElasticsearchSpec{ + RedundancyPolicy: api.MultipleRedundancy, + Nodes: []api.ElasticsearchNode{esNode}, + }, + } + + isValid = isValidRedundancyPolicy(esCR) + + if isValid { + t.Error("Expected MultipleRedundancy with two data nodes to be invalid, flagged as valid") + } + + esCR = &api.Elasticsearch{ + Spec: api.ElasticsearchSpec{ + RedundancyPolicy: api.FullRedundancy, + Nodes: []api.ElasticsearchNode{esNode}, + }, + } + + isValid = isValidRedundancyPolicy(esCR) + + if isValid { + t.Error("Expected FullRedundancy with two data nodes to be invalid, flagged as valid") + } +} + +func TestValidRedundancyPolicySpecified(t *testing.T) { + + esNode := api.ElasticsearchNode{ + Roles: []api.ElasticsearchNodeRole{"data"}, + NodeCount: int32(1), + } + + esCR := &api.Elasticsearch{ + Spec: api.ElasticsearchSpec{ + RedundancyPolicy: api.ZeroRedundancy, + Nodes: []api.ElasticsearchNode{esNode}, + }, + } + + isValid := isValidRedundancyPolicy(esCR) + + if !isValid { + t.Error("Expected ZeroRedundancy with one data node to be valid, flagged as invalid") + } + + esNode = api.ElasticsearchNode{ + Roles: []api.ElasticsearchNodeRole{"data"}, + NodeCount: int32(2), + } + + esCR = &api.Elasticsearch{ + Spec: api.ElasticsearchSpec{ + RedundancyPolicy: api.SingleRedundancy, + Nodes: []api.ElasticsearchNode{esNode}, + }, + } + + isValid = isValidRedundancyPolicy(esCR) + + if !isValid { + t.Error("Expected SingleRedundancy with two data nodes to be valid, flagged as invalid") + } + + esCR = &api.Elasticsearch{ + Spec: api.ElasticsearchSpec{ + RedundancyPolicy: api.MultipleRedundancy, + Nodes: []api.ElasticsearchNode{esNode}, + }, + } + + isValid = isValidRedundancyPolicy(esCR) + + if !isValid { + t.Error("Expected MultipleRedundancy with two data nodes to be valid, flagged as invalid") + } + + esCR = &api.Elasticsearch{ + Spec: api.ElasticsearchSpec{ + RedundancyPolicy: api.FullRedundancy, + Nodes: []api.ElasticsearchNode{esNode}, + }, + } + + isValid = isValidRedundancyPolicy(esCR) + + if !isValid { + t.Error("Expected FullRedundancy with two data nodes to be valid, flagged as invalid") + } +} + func TestValidNoNodesSpecified(t *testing.T) { esCR := &api.Elasticsearch{ Spec: api.ElasticsearchSpec{ - Nodes: []api.ElasticsearchNode{}, + Nodes: []api.ElasticsearchNode{}, + RedundancyPolicy: api.ZeroRedundancy, }, } @@ -154,6 +268,12 @@ func TestValidNoNodesSpecified(t *testing.T) { t.Error("Expected no nodes defined to be flagged as valid, was found to be invalid data count") } + isValid = isValidRedundancyPolicy(esCR) + + if !isValid { + t.Error("Expected no nodes defined to be flagged as valid, was found to be invalid redundancy policy") + } + if ok, msg := hasValidUUIDs(esCR); !ok { t.Errorf("Expected no nodes defined to be flagged as valid, was found to be invalid UUIDs: %v", msg) }