From 1563e9a66a5797566f190b0cfa2ae658a188faba Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Thu, 22 Mar 2018 17:31:13 +0100 Subject: [PATCH 1/8] Using refs in the spec as much as possible to detect unspecified fields --- .../deployment/v1alpha/authentication_spec.go | 30 ++++++-- .../v1alpha/authentication_spec_test.go | 49 ++++++------ .../deployment/v1alpha/deployment_spec.go | 29 +++++++ .../deployment/v1alpha/deployment_status.go | 3 + .../deployment/v1alpha/monitoring_spec.go | 20 ++++- .../v1alpha/monitoring_spec_test.go | 14 ++-- pkg/apis/deployment/v1alpha/rocksdb_spec.go | 30 +++++++- .../deployment/v1alpha/rocksdb_spec_test.go | 29 +++---- .../deployment/v1alpha/server_group_spec.go | 58 ++++++++++---- pkg/apis/deployment/v1alpha/sync_spec.go | 13 ++++ pkg/apis/deployment/v1alpha/sync_spec_test.go | 44 ++++++----- pkg/apis/deployment/v1alpha/tls_spec.go | 63 ++++++++++++--- pkg/apis/deployment/v1alpha/tls_spec_test.go | 32 ++++---- .../v1alpha/zz_generated.deepcopy.go | 29 +++++++ pkg/deployment/deployment.go | 19 ++++- pkg/deployment/members.go | 2 +- pkg/deployment/plan_builder.go | 10 +-- pkg/deployment/pod_creator.go | 8 +- pkg/deployment/pvcs.go | 2 +- pkg/deployment/secrets.go | 10 +-- pkg/deployment/tls.go | 12 +-- pkg/util/arangod/client.go | 2 +- pkg/util/refs.go | 77 +++++++++++++++++++ 23 files changed, 442 insertions(+), 143 deletions(-) create mode 100644 pkg/util/refs.go diff --git a/pkg/apis/deployment/v1alpha/authentication_spec.go b/pkg/apis/deployment/v1alpha/authentication_spec.go index 4ef4c664b..3848c3d2b 100644 --- a/pkg/apis/deployment/v1alpha/authentication_spec.go +++ b/pkg/apis/deployment/v1alpha/authentication_spec.go @@ -25,12 +25,13 @@ package v1alpha import ( "github.com/pkg/errors" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) // AuthenticationSpec holds authentication specific configuration settings type AuthenticationSpec struct { - JWTSecretName string `json:"jwtSecretName,omitempty"` + JWTSecretName *string `json:"jwtSecretName,omitempty"` } const ( @@ -38,10 +39,18 @@ const ( JWTSecretNameDisabled = "None" ) +// GetJWTSecretName returns the value of jwtSecretName. +func (s AuthenticationSpec) GetJWTSecretName() string { + if s.JWTSecretName == nil { + return "" + } + return *s.JWTSecretName +} + // IsAuthenticated returns true if authentication is enabled. // Returns false other (when JWTSecretName == "None"). func (s AuthenticationSpec) IsAuthenticated() bool { - return s.JWTSecretName != JWTSecretNameDisabled + return s.GetJWTSecretName() != JWTSecretNameDisabled } // Validate the given spec @@ -50,7 +59,7 @@ func (s AuthenticationSpec) Validate(required bool) error { return maskAny(errors.Wrap(ValidationError, "JWT secret is required")) } if s.IsAuthenticated() { - if err := k8sutil.ValidateResourceName(s.JWTSecretName); err != nil { + if err := k8sutil.ValidateResourceName(s.GetJWTSecretName()); err != nil { return maskAny(err) } } @@ -59,8 +68,17 @@ func (s AuthenticationSpec) Validate(required bool) error { // SetDefaults fills in missing defaults func (s *AuthenticationSpec) SetDefaults(defaultJWTSecretName string) { - if s.JWTSecretName == "" { - s.JWTSecretName = defaultJWTSecretName + if s.GetJWTSecretName() == "" { + // Note that we don't check for nil here, since even a specified, but empty + // string should result in the default value. + s.JWTSecretName = util.String(defaultJWTSecretName) + } +} + +// SetDefaultsFrom fills unspecified fields with a value from given source spec. +func (s *AuthenticationSpec) SetDefaultsFrom(source AuthenticationSpec) { + if s.JWTSecretName == nil { + s.JWTSecretName = util.String(source.GetJWTSecretName()) } } @@ -71,7 +89,7 @@ func (s AuthenticationSpec) ResetImmutableFields(fieldPrefix string, target *Aut var resetFields []string if s.IsAuthenticated() != target.IsAuthenticated() { // Note: You can change the name, but not from empty to non-empty (or reverse). - target.JWTSecretName = s.JWTSecretName + target.JWTSecretName = util.StringOrNil(s.JWTSecretName) resetFields = append(resetFields, fieldPrefix+".jwtSecretName") } return resetFields diff --git a/pkg/apis/deployment/v1alpha/authentication_spec_test.go b/pkg/apis/deployment/v1alpha/authentication_spec_test.go index 206312629..3f101782e 100644 --- a/pkg/apis/deployment/v1alpha/authentication_spec_test.go +++ b/pkg/apis/deployment/v1alpha/authentication_spec_test.go @@ -25,23 +25,24 @@ package v1alpha import ( "testing" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/stretchr/testify/assert" ) func TestAuthenticationSpecValidate(t *testing.T) { // Valid - assert.Nil(t, AuthenticationSpec{JWTSecretName: "None"}.Validate(false)) - assert.Nil(t, AuthenticationSpec{JWTSecretName: "foo"}.Validate(false)) - assert.Nil(t, AuthenticationSpec{JWTSecretName: "foo"}.Validate(true)) + assert.Nil(t, AuthenticationSpec{JWTSecretName: util.String("None")}.Validate(false)) + assert.Nil(t, AuthenticationSpec{JWTSecretName: util.String("foo")}.Validate(false)) + assert.Nil(t, AuthenticationSpec{JWTSecretName: util.String("foo")}.Validate(true)) // Not valid - assert.Error(t, AuthenticationSpec{JWTSecretName: "Foo"}.Validate(false)) + assert.Error(t, AuthenticationSpec{JWTSecretName: util.String("Foo")}.Validate(false)) } func TestAuthenticationSpecIsAuthenticated(t *testing.T) { - assert.False(t, AuthenticationSpec{JWTSecretName: "None"}.IsAuthenticated()) - assert.True(t, AuthenticationSpec{JWTSecretName: "foo"}.IsAuthenticated()) - assert.True(t, AuthenticationSpec{JWTSecretName: ""}.IsAuthenticated()) + assert.False(t, AuthenticationSpec{JWTSecretName: util.String("None")}.IsAuthenticated()) + assert.True(t, AuthenticationSpec{JWTSecretName: util.String("foo")}.IsAuthenticated()) + assert.True(t, AuthenticationSpec{JWTSecretName: util.String("")}.IsAuthenticated()) } func TestAuthenticationSpecSetDefaults(t *testing.T) { @@ -50,8 +51,8 @@ func TestAuthenticationSpecSetDefaults(t *testing.T) { return spec } - assert.Equal(t, "test-jwt", def(AuthenticationSpec{}).JWTSecretName) - assert.Equal(t, "foo", def(AuthenticationSpec{JWTSecretName: "foo"}).JWTSecretName) + assert.Equal(t, "test-jwt", def(AuthenticationSpec{}).GetJWTSecretName()) + assert.Equal(t, "foo", def(AuthenticationSpec{JWTSecretName: util.String("foo")}).GetJWTSecretName()) } func TestAuthenticationSpecResetImmutableFields(t *testing.T) { @@ -63,35 +64,35 @@ func TestAuthenticationSpecResetImmutableFields(t *testing.T) { }{ // Valid "changes" { - AuthenticationSpec{JWTSecretName: "None"}, - AuthenticationSpec{JWTSecretName: "None"}, - AuthenticationSpec{JWTSecretName: "None"}, + AuthenticationSpec{JWTSecretName: util.String("None")}, + AuthenticationSpec{JWTSecretName: util.String("None")}, + AuthenticationSpec{JWTSecretName: util.String("None")}, nil, }, { - AuthenticationSpec{JWTSecretName: "foo"}, - AuthenticationSpec{JWTSecretName: "foo"}, - AuthenticationSpec{JWTSecretName: "foo"}, + AuthenticationSpec{JWTSecretName: util.String("foo")}, + AuthenticationSpec{JWTSecretName: util.String("foo")}, + AuthenticationSpec{JWTSecretName: util.String("foo")}, nil, }, { - AuthenticationSpec{JWTSecretName: "foo"}, - AuthenticationSpec{JWTSecretName: "foo2"}, - AuthenticationSpec{JWTSecretName: "foo2"}, + AuthenticationSpec{JWTSecretName: util.String("foo")}, + AuthenticationSpec{JWTSecretName: util.String("foo2")}, + AuthenticationSpec{JWTSecretName: util.String("foo2")}, nil, }, // Invalid changes { - AuthenticationSpec{JWTSecretName: "foo"}, - AuthenticationSpec{JWTSecretName: "None"}, - AuthenticationSpec{JWTSecretName: "foo"}, + AuthenticationSpec{JWTSecretName: util.String("foo")}, + AuthenticationSpec{JWTSecretName: util.String("None")}, + AuthenticationSpec{JWTSecretName: util.String("foo")}, []string{"test.jwtSecretName"}, }, { - AuthenticationSpec{JWTSecretName: "None"}, - AuthenticationSpec{JWTSecretName: "foo"}, - AuthenticationSpec{JWTSecretName: "None"}, + AuthenticationSpec{JWTSecretName: util.String("None")}, + AuthenticationSpec{JWTSecretName: util.String("foo")}, + AuthenticationSpec{JWTSecretName: util.String("None")}, []string{"test.jwtSecretName"}, }, } diff --git a/pkg/apis/deployment/v1alpha/deployment_spec.go b/pkg/apis/deployment/v1alpha/deployment_spec.go index d112df828..cb88ce172 100644 --- a/pkg/apis/deployment/v1alpha/deployment_spec.go +++ b/pkg/apis/deployment/v1alpha/deployment_spec.go @@ -102,6 +102,35 @@ func (s *DeploymentSpec) SetDefaults(deploymentName string) { s.SyncWorkers.SetDefaults(ServerGroupSyncWorkers, s.Sync.Enabled, s.Mode) } +// SetDefaultsFrom fills unspecified fields with a value from given source spec. +func (s *DeploymentSpec) SetDefaultsFrom(source DeploymentSpec) { + if s.Mode == "" { + s.Mode = source.Mode + } + if s.Environment == "" { + s.Environment = source.Environment + } + if s.StorageEngine == "" { + s.StorageEngine = source.StorageEngine + } + if s.Image == "" { + s.Image = source.Image + } + if s.ImagePullPolicy == "" { + s.ImagePullPolicy = source.ImagePullPolicy + } + s.RocksDB.SetDefaultsFrom(source.RocksDB) + s.Authentication.SetDefaultsFrom(source.Authentication) + s.TLS.SetDefaultsFrom(source.TLS) + s.Sync.SetDefaultsFrom(source.Sync) + s.Single.SetDefaultsFrom(source.Single) + s.Agents.SetDefaultsFrom(source.Agents) + s.DBServers.SetDefaultsFrom(source.DBServers) + s.Coordinators.SetDefaultsFrom(source.Coordinators) + s.SyncMasters.SetDefaultsFrom(source.SyncMasters) + s.SyncWorkers.SetDefaultsFrom(source.SyncWorkers) +} + // Validate the specification. // Return errors when validation fails, nil on success. func (s *DeploymentSpec) Validate() error { diff --git a/pkg/apis/deployment/v1alpha/deployment_status.go b/pkg/apis/deployment/v1alpha/deployment_status.go index 645bf60ee..4c9660aa8 100644 --- a/pkg/apis/deployment/v1alpha/deployment_status.go +++ b/pkg/apis/deployment/v1alpha/deployment_status.go @@ -47,4 +47,7 @@ type DeploymentStatus struct { // Plan to update this deployment Plan Plan `json:"plan,omitempty"` + + // AcceptedSpec contains the last specification that was accepted by the operator. + AcceptedSpec *DeploymentSpec `json:"accepted-spec,omitempty"` } diff --git a/pkg/apis/deployment/v1alpha/monitoring_spec.go b/pkg/apis/deployment/v1alpha/monitoring_spec.go index 44c9917bc..d52579640 100644 --- a/pkg/apis/deployment/v1alpha/monitoring_spec.go +++ b/pkg/apis/deployment/v1alpha/monitoring_spec.go @@ -23,17 +23,26 @@ package v1alpha import ( + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) // MonitoringSpec holds monitoring specific configuration settings type MonitoringSpec struct { - TokenSecretName string `json:"tokenSecretName,omitempty"` + TokenSecretName *string `json:"tokenSecretName,omitempty"` +} + +// GetTokenSecretName returns the value of tokenSecretName. +func (s MonitoringSpec) GetTokenSecretName() string { + if s.TokenSecretName == nil { + return "" + } + return *s.TokenSecretName } // Validate the given spec func (s MonitoringSpec) Validate() error { - if err := k8sutil.ValidateOptionalResourceName(s.TokenSecretName); err != nil { + if err := k8sutil.ValidateOptionalResourceName(s.GetTokenSecretName()); err != nil { return maskAny(err) } return nil @@ -43,3 +52,10 @@ func (s MonitoringSpec) Validate() error { func (s *MonitoringSpec) SetDefaults() { // Nothing needed } + +// SetDefaultsFrom fills unspecified fields with a value from given source spec. +func (s *MonitoringSpec) SetDefaultsFrom(source MonitoringSpec) { + if s.TokenSecretName == nil { + s.TokenSecretName = util.StringOrNil(source.TokenSecretName) + } +} diff --git a/pkg/apis/deployment/v1alpha/monitoring_spec_test.go b/pkg/apis/deployment/v1alpha/monitoring_spec_test.go index 1aef3e71e..bdb242aa8 100644 --- a/pkg/apis/deployment/v1alpha/monitoring_spec_test.go +++ b/pkg/apis/deployment/v1alpha/monitoring_spec_test.go @@ -25,17 +25,19 @@ package v1alpha import ( "testing" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/stretchr/testify/assert" ) func TestMonitoringSpecValidate(t *testing.T) { // Valid - assert.Nil(t, MonitoringSpec{TokenSecretName: ""}.Validate()) - assert.Nil(t, MonitoringSpec{TokenSecretName: "foo"}.Validate()) - assert.Nil(t, MonitoringSpec{TokenSecretName: "foo"}.Validate()) + assert.Nil(t, MonitoringSpec{TokenSecretName: nil}.Validate()) + assert.Nil(t, MonitoringSpec{TokenSecretName: util.String("")}.Validate()) + assert.Nil(t, MonitoringSpec{TokenSecretName: util.String("foo")}.Validate()) + assert.Nil(t, MonitoringSpec{TokenSecretName: util.String("foo")}.Validate()) // Not valid - assert.Error(t, MonitoringSpec{TokenSecretName: "Foo"}.Validate()) + assert.Error(t, MonitoringSpec{TokenSecretName: util.String("Foo")}.Validate()) } func TestMonitoringSpecSetDefaults(t *testing.T) { @@ -44,6 +46,6 @@ func TestMonitoringSpecSetDefaults(t *testing.T) { return spec } - assert.Equal(t, "", def(MonitoringSpec{}).TokenSecretName) - assert.Equal(t, "foo", def(MonitoringSpec{TokenSecretName: "foo"}).TokenSecretName) + assert.Equal(t, "", def(MonitoringSpec{}).GetTokenSecretName()) + assert.Equal(t, "foo", def(MonitoringSpec{TokenSecretName: util.String("foo")}).GetTokenSecretName()) } diff --git a/pkg/apis/deployment/v1alpha/rocksdb_spec.go b/pkg/apis/deployment/v1alpha/rocksdb_spec.go index ad7e050bd..0f00439df 100644 --- a/pkg/apis/deployment/v1alpha/rocksdb_spec.go +++ b/pkg/apis/deployment/v1alpha/rocksdb_spec.go @@ -23,12 +23,27 @@ package v1alpha import ( + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) // RocksDBEncryptionSpec holds rocksdb encryption at rest specific configuration settings type RocksDBEncryptionSpec struct { - KeySecretName string `json:"keySecretName,omitempty"` + KeySecretName *string `json:"keySecretName,omitempty"` +} + +// GetKeySecretName returns the value of keySecretName. +func (s RocksDBEncryptionSpec) GetKeySecretName() string { + if s.KeySecretName == nil { + return "" + } + return *s.KeySecretName +} + +// IsEncrypted returns true when an encryption key secret name is provided, +// false otherwise. +func (s RocksDBEncryptionSpec) IsEncrypted() bool { + return s.GetKeySecretName() != "" } // RocksDBSpec holds rocksdb specific configuration settings @@ -39,12 +54,12 @@ type RocksDBSpec struct { // IsEncrypted returns true when an encryption key secret name is provided, // false otherwise. func (s RocksDBSpec) IsEncrypted() bool { - return s.Encryption.KeySecretName != "" + return s.Encryption.IsEncrypted() } // Validate the given spec func (s RocksDBSpec) Validate() error { - if err := k8sutil.ValidateOptionalResourceName(s.Encryption.KeySecretName); err != nil { + if err := k8sutil.ValidateOptionalResourceName(s.Encryption.GetKeySecretName()); err != nil { return maskAny(err) } return nil @@ -55,6 +70,13 @@ func (s *RocksDBSpec) SetDefaults() { // Nothing needed } +// SetDefaultsFrom fills unspecified fields with a value from given source spec. +func (s *RocksDBSpec) SetDefaultsFrom(source RocksDBSpec) { + if s.Encryption.KeySecretName == nil { + s.Encryption.KeySecretName = util.StringOrNil(source.Encryption.KeySecretName) + } +} + // ResetImmutableFields replaces all immutable fields in the given target with values from the source spec. // It returns a list of fields that have been reset. // Field names are relative to given field prefix. @@ -62,7 +84,7 @@ func (s RocksDBSpec) ResetImmutableFields(fieldPrefix string, target *RocksDBSpe var resetFields []string if s.IsEncrypted() != target.IsEncrypted() { // Note: You can change the name, but not from empty to non-empty (or reverse). - target.Encryption.KeySecretName = s.Encryption.KeySecretName + target.Encryption.KeySecretName = util.StringOrNil(s.Encryption.KeySecretName) resetFields = append(resetFields, fieldPrefix+".encryption.keySecretName") } return resetFields diff --git a/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go b/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go index a93b82fd1..720b5b7b3 100644 --- a/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go +++ b/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go @@ -25,22 +25,23 @@ package v1alpha import ( "testing" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/stretchr/testify/assert" ) func TestRocksDBSpecValidate(t *testing.T) { // Valid assert.Nil(t, RocksDBSpec{}.Validate()) - assert.Nil(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo"}}.Validate()) + assert.Nil(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}.Validate()) // Not valid - assert.Error(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "Foo"}}.Validate()) + assert.Error(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("Foo")}}.Validate()) } func TestRocksDBSpecIsEncrypted(t *testing.T) { assert.False(t, RocksDBSpec{}.IsEncrypted()) - assert.False(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: ""}}.IsEncrypted()) - assert.True(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo"}}.IsEncrypted()) + assert.False(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("")}}.IsEncrypted()) + assert.True(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}.IsEncrypted()) } func TestRocksDBSpecSetDefaults(t *testing.T) { @@ -49,7 +50,7 @@ func TestRocksDBSpecSetDefaults(t *testing.T) { return spec } - assert.Equal(t, "", def(RocksDBSpec{}).Encryption.KeySecretName) + assert.Equal(t, "", def(RocksDBSpec{}).Encryption.GetKeySecretName()) } func TestRocksDBSpecResetImmutableFields(t *testing.T) { @@ -67,23 +68,23 @@ func TestRocksDBSpecResetImmutableFields(t *testing.T) { nil, }, { - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo"}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo"}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo"}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, nil, }, { - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo"}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo2"}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo2"}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo2")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo2")}}, nil, }, // Invalid changes { - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo"}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: ""}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: "foo"}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, []string{"test.encryption.keySecretName"}, }, } diff --git a/pkg/apis/deployment/v1alpha/server_group_spec.go b/pkg/apis/deployment/v1alpha/server_group_spec.go index 0a8f7228d..8955a9064 100644 --- a/pkg/apis/deployment/v1alpha/server_group_spec.go +++ b/pkg/apis/deployment/v1alpha/server_group_spec.go @@ -26,20 +26,38 @@ import ( "github.com/pkg/errors" "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + + "github.com/arangodb/kube-arangodb/pkg/util" ) // ServerGroupSpec contains the specification for all servers in a specific group (e.g. all agents) type ServerGroupSpec struct { // Count holds the requested number of servers - Count int `json:"count,omitempty"` + Count *int `json:"count,omitempty"` // Args holds additional commandline arguments Args []string `json:"args,omitempty"` // StorageClassName specifies the classname for storage of the servers. - StorageClassName string `json:"storageClassName,omitempty"` + StorageClassName *string `json:"storageClassName,omitempty"` // Resources holds resource requests & limits Resources v1.ResourceRequirements `json:"resource,omitempty"` } +// GetCount returns the value of count. +func (s ServerGroupSpec) GetCount() int { + if s.Count == nil { + return 0 + } + return *s.Count +} + +// GetStorageClassName returns the value of count. +func (s ServerGroupSpec) GetStorageClassName() string { + if s.StorageClassName == nil { + return "" + } + return *s.StorageClassName +} + // Validate the given group spec func (s ServerGroupSpec) Validate(group ServerGroup, used bool, mode DeploymentMode, env Environment) error { if used { @@ -56,13 +74,13 @@ func (s ServerGroupSpec) Validate(group ServerGroup, used bool, mode DeploymentM minCount = 2 } } - if s.Count < minCount { + if s.GetCount() < minCount { return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected >= %d", s.Count, minCount)) } - if s.Count > 1 && group == ServerGroupSingle && mode == DeploymentModeSingle { + if s.GetCount() > 1 && group == ServerGroupSingle && mode == DeploymentModeSingle { return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected 1", s.Count)) } - } else if s.Count != 0 { + } else if s.GetCount() != 0 { return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d for un-used group. Expected 0", s.Count)) } return nil @@ -70,16 +88,16 @@ func (s ServerGroupSpec) Validate(group ServerGroup, used bool, mode DeploymentM // SetDefaults fills in missing defaults func (s *ServerGroupSpec) SetDefaults(group ServerGroup, used bool, mode DeploymentMode) { - if s.Count == 0 && used { + if s.GetCount() == 0 && used { switch group { case ServerGroupSingle: if mode == DeploymentModeSingle { - s.Count = 1 // Single server + s.Count = util.Int(1) // Single server } else { - s.Count = 2 // Resilient single + s.Count = util.Int(2) // Resilient single } default: - s.Count = 3 + s.Count = util.Int(3) } } if _, found := s.Resources.Requests[v1.ResourceStorage]; !found { @@ -93,18 +111,32 @@ func (s *ServerGroupSpec) SetDefaults(group ServerGroup, used bool, mode Deploym } } +// SetDefaultsFrom fills unspecified fields with a value from given source spec. +func (s *ServerGroupSpec) SetDefaultsFrom(source ServerGroupSpec) { + if s.Count == nil { + s.Count = util.IntOrNil(source.Count) + } + if s.Args == nil { + s.Args = source.Args + } + if s.StorageClassName == nil { + s.StorageClassName = util.StringOrNil(source.StorageClassName) + } + // TODO Resources +} + // ResetImmutableFields replaces all immutable fields in the given target with values from the source spec. // It returns a list of fields that have been reset. func (s ServerGroupSpec) ResetImmutableFields(group ServerGroup, fieldPrefix string, target *ServerGroupSpec) []string { var resetFields []string if group == ServerGroupAgents { - if s.Count != target.Count { - target.Count = s.Count + if s.GetCount() != target.GetCount() { + target.Count = util.IntOrNil(s.Count) resetFields = append(resetFields, fieldPrefix+".count") } } - if s.StorageClassName != target.StorageClassName { - target.StorageClassName = s.StorageClassName + if s.GetStorageClassName() != target.GetStorageClassName() { + target.StorageClassName = util.StringOrNil(s.StorageClassName) resetFields = append(resetFields, fieldPrefix+".storageClassName") } return resetFields diff --git a/pkg/apis/deployment/v1alpha/sync_spec.go b/pkg/apis/deployment/v1alpha/sync_spec.go index 07b83fc11..d7d26d8aa 100644 --- a/pkg/apis/deployment/v1alpha/sync_spec.go +++ b/pkg/apis/deployment/v1alpha/sync_spec.go @@ -73,6 +73,19 @@ func (s *SyncSpec) SetDefaults(defaultImage string, defaulPullPolicy v1.PullPoli s.Monitoring.SetDefaults() } +// SetDefaultsFrom fills unspecified fields with a value from given source spec. +func (s *SyncSpec) SetDefaultsFrom(source SyncSpec) { + if s.Image == "" { + s.Image = source.Image + } + if s.ImagePullPolicy == "" { + s.ImagePullPolicy = source.ImagePullPolicy + } + s.Authentication.SetDefaultsFrom(source.Authentication) + s.TLS.SetDefaultsFrom(source.TLS) + s.Monitoring.SetDefaultsFrom(source.Monitoring) +} + // ResetImmutableFields replaces all immutable fields in the given target with values from the source spec. // It returns a list of fields that have been reset. // Field names are relative to given field prefix. diff --git a/pkg/apis/deployment/v1alpha/sync_spec_test.go b/pkg/apis/deployment/v1alpha/sync_spec_test.go index 33a024908..dc2d84b44 100644 --- a/pkg/apis/deployment/v1alpha/sync_spec_test.go +++ b/pkg/apis/deployment/v1alpha/sync_spec_test.go @@ -25,24 +25,26 @@ package v1alpha import ( "testing" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/stretchr/testify/assert" "k8s.io/api/core/v1" ) func TestSyncSpecValidate(t *testing.T) { // Valid - auth := AuthenticationSpec{JWTSecretName: "foo"} + auth := AuthenticationSpec{JWTSecretName: util.String("foo")} + tls := TLSSpec{CASecretName: util.String("None")} assert.Nil(t, SyncSpec{Image: "foo", Authentication: auth}.Validate(DeploymentModeSingle)) assert.Nil(t, SyncSpec{Image: "foo", Authentication: auth}.Validate(DeploymentModeResilientSingle)) assert.Nil(t, SyncSpec{Image: "foo", Authentication: auth}.Validate(DeploymentModeCluster)) - assert.Nil(t, SyncSpec{Image: "foo", Authentication: auth, Enabled: true}.Validate(DeploymentModeCluster)) + assert.Nil(t, SyncSpec{Image: "foo", Authentication: auth, TLS: tls, Enabled: true}.Validate(DeploymentModeCluster)) // Not valid assert.Error(t, SyncSpec{Image: "", Authentication: auth}.Validate(DeploymentModeSingle)) assert.Error(t, SyncSpec{Image: "", Authentication: auth}.Validate(DeploymentModeResilientSingle)) assert.Error(t, SyncSpec{Image: "", Authentication: auth}.Validate(DeploymentModeCluster)) - assert.Error(t, SyncSpec{Image: "foo", Authentication: auth, Enabled: true}.Validate(DeploymentModeSingle)) - assert.Error(t, SyncSpec{Image: "foo", Authentication: auth, Enabled: true}.Validate(DeploymentModeResilientSingle)) + assert.Error(t, SyncSpec{Image: "foo", Authentication: auth, TLS: tls, Enabled: true}.Validate(DeploymentModeSingle)) + assert.Error(t, SyncSpec{Image: "foo", Authentication: auth, TLS: tls, Enabled: true}.Validate(DeploymentModeResilientSingle)) } func TestSyncSpecSetDefaults(t *testing.T) { @@ -58,8 +60,8 @@ func TestSyncSpecSetDefaults(t *testing.T) { assert.Equal(t, "foo", def(SyncSpec{Image: "foo"}).Image) assert.Equal(t, v1.PullAlways, def(SyncSpec{}).ImagePullPolicy) assert.Equal(t, v1.PullNever, def(SyncSpec{ImagePullPolicy: v1.PullNever}).ImagePullPolicy) - assert.Equal(t, "test-jwt", def(SyncSpec{}).Authentication.JWTSecretName) - assert.Equal(t, "foo", def(SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo"}}).Authentication.JWTSecretName) + assert.Equal(t, "test-jwt", def(SyncSpec{}).Authentication.GetJWTSecretName()) + assert.Equal(t, "foo", def(SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}).Authentication.GetJWTSecretName()) } func TestSyncSpecResetImmutableFields(t *testing.T) { @@ -95,35 +97,35 @@ func TestSyncSpecResetImmutableFields(t *testing.T) { nil, }, { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "None"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "None"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "None"}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, nil, }, { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo"}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, nil, }, { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo2"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo2"}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo2")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo2")}}, nil, }, // Invalid changes { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "None"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo"}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, []string{"test.auth.jwtSecretName"}, }, { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "None"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "foo"}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: "None"}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, []string{"test.auth.jwtSecretName"}, }, } diff --git a/pkg/apis/deployment/v1alpha/tls_spec.go b/pkg/apis/deployment/v1alpha/tls_spec.go index a197cc019..f2be5004d 100644 --- a/pkg/apis/deployment/v1alpha/tls_spec.go +++ b/pkg/apis/deployment/v1alpha/tls_spec.go @@ -27,6 +27,7 @@ import ( "net" "time" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" "github.com/arangodb/kube-arangodb/pkg/util/validation" ) @@ -37,9 +38,9 @@ const ( // TLSSpec holds TLS specific configuration settings type TLSSpec struct { - CASecretName string `json:"caSecretName,omitempty"` - AltNames []string `json:"altNames,omitempty"` - TTL time.Duration `json:"ttl,omitempty"` + CASecretName *string `json:"caSecretName,omitempty"` + AltNames []string `json:"altNames,omitempty"` + TTL *time.Duration `json:"ttl,omitempty"` } const ( @@ -47,14 +48,35 @@ const ( CASecretNameDisabled = "None" ) +// GetCASecretName returns the value of caSecretName. +func (s TLSSpec) GetCASecretName() string { + if s.CASecretName == nil { + return "" + } + return *s.CASecretName +} + +// GetAltNames returns the value of altNames. +func (s TLSSpec) GetAltNames() []string { + return s.AltNames +} + +// GetTTL returns the value of ttl. +func (s TLSSpec) GetTTL() time.Duration { + if s.TTL == nil { + return time.Duration(0) + } + return *s.TTL +} + // IsSecure returns true when a CA secret has been set, false otherwise. func (s TLSSpec) IsSecure() bool { - return s.CASecretName != CASecretNameDisabled + return s.GetCASecretName() != CASecretNameDisabled } -// GetAltNames splits the list of AltNames into DNS names, IP addresses & email addresses. +// GetParsedAltNames splits the list of AltNames into DNS names, IP addresses & email addresses. // When an entry is not valid for any of those categories, an error is returned. -func (s TLSSpec) GetAltNames() (dnsNames, ipAddresses, emailAddresses []string, err error) { +func (s TLSSpec) GetParsedAltNames() (dnsNames, ipAddresses, emailAddresses []string, err error) { for _, name := range s.AltNames { if net.ParseIP(name) != nil { ipAddresses = append(ipAddresses, name) @@ -72,10 +94,10 @@ func (s TLSSpec) GetAltNames() (dnsNames, ipAddresses, emailAddresses []string, // Validate the given spec func (s TLSSpec) Validate() error { if s.IsSecure() { - if err := k8sutil.ValidateOptionalResourceName(s.CASecretName); err != nil { + if err := k8sutil.ValidateResourceName(s.GetCASecretName()); err != nil { return maskAny(err) } - if _, _, _, err := s.GetAltNames(); err != nil { + if _, _, _, err := s.GetParsedAltNames(); err != nil { return maskAny(err) } } @@ -84,10 +106,27 @@ func (s TLSSpec) Validate() error { // SetDefaults fills in missing defaults func (s *TLSSpec) SetDefaults(defaultCASecretName string) { - if s.CASecretName == "" { - s.CASecretName = defaultCASecretName + if s.GetCASecretName() == "" { + // Note that we don't check for nil here, since even a specified, but empty + // string should result in the default value. + s.CASecretName = util.String(defaultCASecretName) + } + if s.GetTTL() == 0 { + // Note that we don't check for nil here, since even a specified, but zero + // should result in the default value. + s.TTL = util.Duration(defaultTLSTTL) + } +} + +// SetDefaultsFrom fills unspecified fields with a value from given source spec. +func (s *TLSSpec) SetDefaultsFrom(source TLSSpec) { + if s.CASecretName == nil { + s.CASecretName = util.String(source.GetCASecretName()) + } + if s.AltNames == nil { + s.AltNames = source.AltNames } - if s.TTL == 0 { - s.TTL = defaultTLSTTL + if s.TTL == nil { + s.TTL = util.Duration(source.GetTTL()) } } diff --git a/pkg/apis/deployment/v1alpha/tls_spec_test.go b/pkg/apis/deployment/v1alpha/tls_spec_test.go index e43c0fdca..42df9fe8e 100644 --- a/pkg/apis/deployment/v1alpha/tls_spec_test.go +++ b/pkg/apis/deployment/v1alpha/tls_spec_test.go @@ -26,27 +26,29 @@ import ( "testing" "time" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/stretchr/testify/assert" ) func TestTLSSpecValidate(t *testing.T) { // Valid - assert.Nil(t, TLSSpec{CASecretName: ""}.Validate()) - assert.Nil(t, TLSSpec{CASecretName: "foo"}.Validate()) - assert.Nil(t, TLSSpec{CASecretName: "None"}.Validate()) - assert.Nil(t, TLSSpec{AltNames: []string{}}.Validate()) - assert.Nil(t, TLSSpec{AltNames: []string{"foo"}}.Validate()) - assert.Nil(t, TLSSpec{AltNames: []string{"email@example.com", "127.0.0.1"}}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.String("foo")}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.String("None")}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.String("None"), AltNames: []string{}}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.String("None"), AltNames: []string{"foo"}}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.String("None"), AltNames: []string{"email@example.com", "127.0.0.1"}}.Validate()) // Not valid - assert.Error(t, TLSSpec{CASecretName: "Foo"}.Validate()) - assert.Error(t, TLSSpec{AltNames: []string{"@@"}}.Validate()) + assert.Error(t, TLSSpec{CASecretName: nil}.Validate()) + assert.Error(t, TLSSpec{CASecretName: util.String("")}.Validate()) + assert.Error(t, TLSSpec{CASecretName: util.String("Foo")}.Validate()) + assert.Error(t, TLSSpec{CASecretName: util.String("foo"), AltNames: []string{"@@"}}.Validate()) } func TestTLSSpecIsSecure(t *testing.T) { - assert.True(t, TLSSpec{CASecretName: ""}.IsSecure()) - assert.True(t, TLSSpec{CASecretName: "foo"}.IsSecure()) - assert.False(t, TLSSpec{CASecretName: "None"}.IsSecure()) + assert.True(t, TLSSpec{CASecretName: util.String("")}.IsSecure()) + assert.True(t, TLSSpec{CASecretName: util.String("foo")}.IsSecure()) + assert.False(t, TLSSpec{CASecretName: util.String("None")}.IsSecure()) } func TestTLSSpecSetDefaults(t *testing.T) { @@ -55,10 +57,10 @@ func TestTLSSpecSetDefaults(t *testing.T) { return spec } - assert.Equal(t, "", def(TLSSpec{}).CASecretName) - assert.Equal(t, "foo", def(TLSSpec{CASecretName: "foo"}).CASecretName) + assert.Equal(t, "", def(TLSSpec{}).GetCASecretName()) + assert.Equal(t, "foo", def(TLSSpec{CASecretName: util.String("foo")}).GetCASecretName()) assert.Len(t, def(TLSSpec{}).AltNames, 0) assert.Len(t, def(TLSSpec{AltNames: []string{"foo.local"}}).AltNames, 1) - assert.Equal(t, defaultTLSTTL, def(TLSSpec{}).TTL) - assert.Equal(t, time.Hour, def(TLSSpec{TTL: time.Hour}).TTL) + assert.Equal(t, defaultTLSTTL, def(TLSSpec{}).GetTTL()) + assert.Equal(t, time.Hour, def(TLSSpec{TTL: util.Duration(time.Hour)}).GetTTL()) } diff --git a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go index a4d97e29e..ec906bb51 100644 --- a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go @@ -25,6 +25,8 @@ package v1alpha import ( + time "time" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -198,6 +200,15 @@ func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.AcceptedSpec != nil { + in, out := &in.AcceptedSpec, &out.AcceptedSpec + if *in == nil { + *out = nil + } else { + *out = new(DeploymentSpec) + (*in).DeepCopyInto(*out) + } + } return } @@ -401,11 +412,29 @@ func (in *SyncSpec) DeepCopy() *SyncSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSSpec) DeepCopyInto(out *TLSSpec) { *out = *in + if in.CASecretName != nil { + in, out := &in.CASecretName, &out.CASecretName + if *in == nil { + *out = nil + } else { + *out = new(string) + **out = **in + } + } if in.AltNames != nil { in, out := &in.AltNames, &out.AltNames *out = make([]string, len(*in)) copy(*out, *in) } + if in.TTL != nil { + in, out := &in.TTL, &out.TTL + if *in == nil { + *out = nil + } else { + *out = new(time.Duration) + **out = **in + } + } return } diff --git a/pkg/deployment/deployment.go b/pkg/deployment/deployment.go index f815df6ed..bcf6dc511 100644 --- a/pkg/deployment/deployment.go +++ b/pkg/deployment/deployment.go @@ -72,7 +72,7 @@ type deploymentEvent struct { } const ( - deploymentEventQueueSize = 100 + deploymentEventQueueSize = 256 minInspectionInterval = time.Second // Ensure we inspect the generated resources no less than with this interval maxInspectionInterval = time.Minute // Ensure we inspect the generated resources no less than with this interval ) @@ -108,6 +108,10 @@ func New(config Config, deps Dependencies, apiObject *api.ArangoDeployment) (*De eventsCli: deps.KubeCli.Core().Events(apiObject.GetNamespace()), clientCache: newClientCache(deps.KubeCli, apiObject), } + if d.status.AcceptedSpec == nil { + // We've validated the spec, so let's use it from now. + d.status.AcceptedSpec = apiObject.Spec.DeepCopy() + } go d.run() go d.listenForPodEvents() @@ -284,10 +288,14 @@ func (d *Deployment) handleArangoDeploymentUpdatedEvent(event *deploymentEvent) return maskAny(err) } + specBefore := d.apiObject.Spec + if d.status.AcceptedSpec != nil { + specBefore = *d.status.AcceptedSpec + } newAPIObject := current.DeepCopy() - newAPIObject.Spec.SetDefaults(newAPIObject.GetName()) + newAPIObject.Spec.SetDefaultsFrom(specBefore) newAPIObject.Status = d.status - resetFields := d.apiObject.Spec.ResetImmutableFields(&newAPIObject.Spec) + resetFields := specBefore.ResetImmutableFields(&newAPIObject.Spec) if len(resetFields) > 0 { log.Debug().Strs("fields", resetFields).Msg("Found modified immutable fields") } @@ -311,6 +319,11 @@ func (d *Deployment) handleArangoDeploymentUpdatedEvent(event *deploymentEvent) if err := d.updateCRSpec(newAPIObject.Spec); err != nil { return maskAny(fmt.Errorf("failed to update ArangoDeployment spec: %v", err)) } + // Save updated accepted spec + d.status.AcceptedSpec = newAPIObject.Spec.DeepCopy() + if err := d.updateCRStatus(); err != nil { + return maskAny(fmt.Errorf("failed to update ArangoDeployment status: %v", err)) + } // Trigger inspect d.inspectTrigger.Trigger() diff --git a/pkg/deployment/members.go b/pkg/deployment/members.go index 6876e8797..13bcd29c4 100644 --- a/pkg/deployment/members.go +++ b/pkg/deployment/members.go @@ -40,7 +40,7 @@ func (d *Deployment) createInitialMembers(apiObject *api.ArangoDeployment) error // Go over all groups and create members if err := apiObject.ForeachServerGroup(func(group api.ServerGroup, spec api.ServerGroupSpec, status *api.MemberStatusList) error { - for len(*status) < spec.Count { + for len(*status) < spec.GetCount() { if err := d.createMember(group, apiObject); err != nil { return maskAny(err) } diff --git a/pkg/deployment/plan_builder.go b/pkg/deployment/plan_builder.go index de9cfcbb4..701f02309 100644 --- a/pkg/deployment/plan_builder.go +++ b/pkg/deployment/plan_builder.go @@ -69,13 +69,13 @@ func createPlan(log zerolog.Logger, currentPlan api.Plan, spec api.DeploymentSpe // Never scale down case api.DeploymentModeResilientSingle: // Only scale singles - plan = append(plan, createScalePlan(log, status.Members.Single, api.ServerGroupSingle, spec.Single.Count)...) + plan = append(plan, createScalePlan(log, status.Members.Single, api.ServerGroupSingle, spec.Single.GetCount())...) case api.DeploymentModeCluster: // Scale dbservers, coordinators, syncmasters & syncworkers - plan = append(plan, createScalePlan(log, status.Members.DBServers, api.ServerGroupDBServers, spec.DBServers.Count)...) - plan = append(plan, createScalePlan(log, status.Members.Coordinators, api.ServerGroupCoordinators, spec.Coordinators.Count)...) - plan = append(plan, createScalePlan(log, status.Members.SyncMasters, api.ServerGroupSyncMasters, spec.SyncMasters.Count)...) - plan = append(plan, createScalePlan(log, status.Members.SyncWorkers, api.ServerGroupSyncWorkers, spec.SyncWorkers.Count)...) + plan = append(plan, createScalePlan(log, status.Members.DBServers, api.ServerGroupDBServers, spec.DBServers.GetCount())...) + plan = append(plan, createScalePlan(log, status.Members.Coordinators, api.ServerGroupCoordinators, spec.Coordinators.GetCount())...) + plan = append(plan, createScalePlan(log, status.Members.SyncMasters, api.ServerGroupSyncMasters, spec.SyncMasters.GetCount())...) + plan = append(plan, createScalePlan(log, status.Members.SyncWorkers, api.ServerGroupSyncWorkers, spec.SyncWorkers.GetCount())...) } // Return plan diff --git a/pkg/deployment/pod_creator.go b/pkg/deployment/pod_creator.go index f9d594877..fb8c0001a 100644 --- a/pkg/deployment/pod_creator.go +++ b/pkg/deployment/pod_creator.go @@ -139,7 +139,7 @@ func createArangodArgs(apiObject metav1.Object, deplSpec api.DeploymentSpec, gro optionPair{"--cluster.my-id", id}, optionPair{"--agency.activate", "true"}, optionPair{"--agency.my-address", myTCPURL}, - optionPair{"--agency.size", strconv.Itoa(deplSpec.Agents.Count)}, + optionPair{"--agency.size", strconv.Itoa(deplSpec.Agents.GetCount())}, optionPair{"--agency.supervision", "true"}, optionPair{"--foxx.queues", "false"}, optionPair{"--server.statistics", "false"}, @@ -242,7 +242,7 @@ func (d *Deployment) createLivenessProbe(apiObject *api.ArangoDeployment, group return nil, nil case api.ServerGroupSyncMasters, api.ServerGroupSyncWorkers: authorization := "" - if apiObject.Spec.Sync.Monitoring.TokenSecretName != "" { + if apiObject.Spec.Sync.Monitoring.GetTokenSecretName() != "" { // Use monitoring token token, err := d.getSyncMonitoringToken(apiObject) if err != nil { @@ -344,14 +344,14 @@ func (d *Deployment) ensurePods(apiObject *api.ArangoDeployment) error { } rocksdbEncryptionSecretName := "" if apiObject.Spec.RocksDB.IsEncrypted() { - rocksdbEncryptionSecretName = apiObject.Spec.RocksDB.Encryption.KeySecretName + rocksdbEncryptionSecretName = apiObject.Spec.RocksDB.Encryption.GetKeySecretName() if err := k8sutil.ValidateEncryptionKeySecret(kubecli.CoreV1(), rocksdbEncryptionSecretName, ns); err != nil { return maskAny(errors.Wrapf(err, "RocksDB encryption key secret validation failed")) } } if apiObject.Spec.IsAuthenticated() { env[constants.EnvArangodJWTSecret] = k8sutil.EnvValue{ - SecretName: apiObject.Spec.Authentication.JWTSecretName, + SecretName: apiObject.Spec.Authentication.GetJWTSecretName(), SecretKey: constants.SecretKeyJWT, } } diff --git a/pkg/deployment/pvcs.go b/pkg/deployment/pvcs.go index a398992ed..b901a0aef 100644 --- a/pkg/deployment/pvcs.go +++ b/pkg/deployment/pvcs.go @@ -38,7 +38,7 @@ func (d *Deployment) ensurePVCs(apiObject *api.ArangoDeployment) error { if err := apiObject.ForeachServerGroup(func(group api.ServerGroup, spec api.ServerGroupSpec, status *api.MemberStatusList) error { for _, m := range *status { if m.PersistentVolumeClaimName != "" { - storageClassName := spec.StorageClassName + storageClassName := spec.GetStorageClassName() role := group.AsRole() resources := spec.Resources if err := k8sutil.CreatePersistentVolumeClaim(kubecli, m.PersistentVolumeClaimName, deploymentName, ns, storageClassName, role, resources, owner); err != nil { diff --git a/pkg/deployment/secrets.go b/pkg/deployment/secrets.go index 40566ded0..df38012b5 100644 --- a/pkg/deployment/secrets.go +++ b/pkg/deployment/secrets.go @@ -36,7 +36,7 @@ import ( // createSecrets creates all secrets needed to run the given deployment func (d *Deployment) createSecrets(apiObject *api.ArangoDeployment) error { if apiObject.Spec.IsAuthenticated() { - if err := d.ensureJWTSecret(apiObject.Spec.Authentication.JWTSecretName); err != nil { + if err := d.ensureJWTSecret(apiObject.Spec.Authentication.GetJWTSecretName()); err != nil { return maskAny(err) } } @@ -88,7 +88,7 @@ func (d *Deployment) ensureJWTSecret(secretName string) error { func (d *Deployment) ensureCACertificateSecret(spec api.TLSSpec) error { kubecli := d.deps.KubeCli ns := d.apiObject.GetNamespace() - if _, err := kubecli.CoreV1().Secrets(ns).Get(spec.CASecretName, metav1.GetOptions{}); k8sutil.IsNotFound(err) { + if _, err := kubecli.CoreV1().Secrets(ns).Get(spec.GetCASecretName(), metav1.GetOptions{}); k8sutil.IsNotFound(err) { // Secret not found, create it owner := d.apiObject.AsOwner() deploymentName := d.apiObject.GetName() @@ -112,7 +112,7 @@ func (d *Deployment) getJWTSecret(apiObject *api.ArangoDeployment) (string, erro return "", nil } kubecli := d.deps.KubeCli - secretName := apiObject.Spec.Authentication.JWTSecretName + secretName := apiObject.Spec.Authentication.GetJWTSecretName() s, err := k8sutil.GetJWTSecret(kubecli.CoreV1(), secretName, apiObject.GetNamespace()) if err != nil { d.deps.Log.Debug().Err(err).Str("secret-name", secretName).Msg("Failed to get JWT secret") @@ -124,7 +124,7 @@ func (d *Deployment) getJWTSecret(apiObject *api.ArangoDeployment) (string, erro // getSyncJWTSecret loads the JWT secret used for syncmasters from a Secret configured in apiObject.Spec.Sync.Authentication.JWTSecretName. func (d *Deployment) getSyncJWTSecret(apiObject *api.ArangoDeployment) (string, error) { kubecli := d.deps.KubeCli - secretName := apiObject.Spec.Sync.Authentication.JWTSecretName + secretName := apiObject.Spec.Sync.Authentication.GetJWTSecretName() s, err := k8sutil.GetJWTSecret(kubecli.CoreV1(), secretName, apiObject.GetNamespace()) if err != nil { d.deps.Log.Debug().Err(err).Str("secret-name", secretName).Msg("Failed to get sync JWT secret") @@ -136,7 +136,7 @@ func (d *Deployment) getSyncJWTSecret(apiObject *api.ArangoDeployment) (string, // getSyncMonitoringToken loads the token secret used for monitoring sync masters & workers. func (d *Deployment) getSyncMonitoringToken(apiObject *api.ArangoDeployment) (string, error) { kubecli := d.deps.KubeCli - secretName := apiObject.Spec.Sync.Monitoring.TokenSecretName + secretName := apiObject.Spec.Sync.Monitoring.GetTokenSecretName() s, err := kubecli.CoreV1().Secrets(apiObject.GetNamespace()).Get(secretName, metav1.GetOptions{}) if err != nil { d.deps.Log.Debug().Err(err).Str("secret-name", secretName).Msg("Failed to get monitoring token secret") diff --git a/pkg/deployment/tls.go b/pkg/deployment/tls.go index 24da23789..837b890e1 100644 --- a/pkg/deployment/tls.go +++ b/pkg/deployment/tls.go @@ -44,8 +44,8 @@ const ( // createCACertificate creates a CA certificate and stores it in a secret with name // specified in the given spec. func createCACertificate(log zerolog.Logger, cli v1.CoreV1Interface, spec api.TLSSpec, deploymentName, namespace string, ownerRef *metav1.OwnerReference) error { - log = log.With().Str("secret", spec.CASecretName).Logger() - dnsNames, ipAddresses, emailAddress, err := spec.GetAltNames() + log = log.With().Str("secret", spec.GetCASecretName()).Logger() + dnsNames, ipAddresses, emailAddress, err := spec.GetParsedAltNames() if err != nil { log.Debug().Err(err).Msg("Failed to get alternate names") return maskAny(err) @@ -65,7 +65,7 @@ func createCACertificate(log zerolog.Logger, cli v1.CoreV1Interface, spec api.TL log.Debug().Err(err).Msg("Failed to create CA certificate") return maskAny(err) } - if err := k8sutil.CreateCASecret(cli, spec.CASecretName, namespace, cert, priv, ownerRef); err != nil { + if err := k8sutil.CreateCASecret(cli, spec.GetCASecretName(), namespace, cert, priv, ownerRef); err != nil { if k8sutil.IsAlreadyExists(err) { log.Debug().Msg("CA Secret already exists") } else { @@ -82,14 +82,14 @@ func createCACertificate(log zerolog.Logger, cli v1.CoreV1Interface, spec api.TL func createServerCertificate(log zerolog.Logger, cli v1.CoreV1Interface, serverNames []string, spec api.TLSSpec, secretName, namespace string, ownerRef *metav1.OwnerReference) error { log = log.With().Str("secret", secretName).Logger() // Load alt names - dnsNames, ipAddresses, emailAddress, err := spec.GetAltNames() + dnsNames, ipAddresses, emailAddress, err := spec.GetParsedAltNames() if err != nil { log.Debug().Err(err).Msg("Failed to get alternate names") return maskAny(err) } // Load CA certificate - caCert, caKey, err := k8sutil.GetCASecret(cli, spec.CASecretName, namespace) + caCert, caKey, err := k8sutil.GetCASecret(cli, spec.GetCASecretName(), namespace) if err != nil { log.Debug().Err(err).Msg("Failed to load CA certificate") return maskAny(err) @@ -105,7 +105,7 @@ func createServerCertificate(log zerolog.Logger, cli v1.CoreV1Interface, serverN Hosts: append(append(serverNames, dnsNames...), ipAddresses...), EmailAddresses: emailAddress, ValidFrom: time.Now(), - ValidFor: spec.TTL, + ValidFor: spec.GetTTL(), IsCA: false, ECDSACurve: tlsECDSACurve, } diff --git a/pkg/util/arangod/client.go b/pkg/util/arangod/client.go index ce9cd7a53..acb8fb81f 100644 --- a/pkg/util/arangod/client.go +++ b/pkg/util/arangod/client.go @@ -146,7 +146,7 @@ func createArangodClientForDNSName(ctx context.Context, cli corev1.CoreV1Interfa // Authentication is enabled. // Should we skip using it? if ctx.Value(skipAuthenticationKey{}) == nil { - s, err := k8sutil.GetJWTSecret(cli, apiObject.Spec.Authentication.JWTSecretName, apiObject.GetNamespace()) + s, err := k8sutil.GetJWTSecret(cli, apiObject.Spec.Authentication.GetJWTSecretName(), apiObject.GetNamespace()) if err != nil { return nil, maskAny(err) } diff --git a/pkg/util/refs.go b/pkg/util/refs.go new file mode 100644 index 000000000..b838e8235 --- /dev/null +++ b/pkg/util/refs.go @@ -0,0 +1,77 @@ +// +// DISCLAIMER +// +// Copyright 2018 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// +// Author Ewout Prangsma +// + +package util + +import "time" + +// String returns a reference to a string with given value. +func String(input string) *string { + return &input +} + +// StringOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func StringOrNil(input *string) *string { + if input == nil { + return nil + } + return String(*input) +} + +// Int returns a reference to an int with given value. +func Int(input int) *int { + return &input +} + +// IntOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func IntOrNil(input *int) *int { + if input == nil { + return nil + } + return Int(*input) +} + +// Bool returns a reference to a bool with given value. +func Bool(input bool) *bool { + return &input +} + +// BoolOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func BoolOrNil(input *bool) *bool { + if input == nil { + return nil + } + return Bool(*input) +} + +// Duration returns a reference to a duration with given value. +func Duration(input time.Duration) *time.Duration { + return &input +} + +// DurationOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func DurationOrNil(input *time.Duration) *time.Duration { + if input == nil { + return nil + } + return Duration(*input) +} From 5211eafcd601b072b149e50d5b0e9544c6e53b71 Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Thu, 22 Mar 2018 17:31:36 +0100 Subject: [PATCH 2/8] Using refs in the spec as much as possible to detect unspecified fields --- .../v1alpha/zz_generated.deepcopy.go | 55 +++++++++++++++++-- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go index ec906bb51..8fd729118 100644 --- a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go @@ -120,6 +120,15 @@ func (in *ArangoDeploymentList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationSpec) DeepCopyInto(out *AuthenticationSpec) { *out = *in + if in.JWTSecretName != nil { + in, out := &in.JWTSecretName, &out.JWTSecretName + if *in == nil { + *out = nil + } else { + *out = new(string) + **out = **in + } + } return } @@ -154,8 +163,8 @@ func (in *Condition) DeepCopy() *Condition { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { *out = *in - out.RocksDB = in.RocksDB - out.Authentication = in.Authentication + in.RocksDB.DeepCopyInto(&out.RocksDB) + in.Authentication.DeepCopyInto(&out.Authentication) in.TLS.DeepCopyInto(&out.TLS) in.Sync.DeepCopyInto(&out.Sync) in.Single.DeepCopyInto(&out.Single) @@ -322,6 +331,15 @@ func (in *MemberStatus) DeepCopy() *MemberStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MonitoringSpec) DeepCopyInto(out *MonitoringSpec) { *out = *in + if in.TokenSecretName != nil { + in, out := &in.TokenSecretName, &out.TokenSecretName + if *in == nil { + *out = nil + } else { + *out = new(string) + **out = **in + } + } return } @@ -338,6 +356,15 @@ func (in *MonitoringSpec) DeepCopy() *MonitoringSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RocksDBEncryptionSpec) DeepCopyInto(out *RocksDBEncryptionSpec) { *out = *in + if in.KeySecretName != nil { + in, out := &in.KeySecretName, &out.KeySecretName + if *in == nil { + *out = nil + } else { + *out = new(string) + **out = **in + } + } return } @@ -354,7 +381,7 @@ func (in *RocksDBEncryptionSpec) DeepCopy() *RocksDBEncryptionSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RocksDBSpec) DeepCopyInto(out *RocksDBSpec) { *out = *in - out.Encryption = in.Encryption + in.Encryption.DeepCopyInto(&out.Encryption) return } @@ -371,11 +398,29 @@ func (in *RocksDBSpec) DeepCopy() *RocksDBSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) { *out = *in + if in.Count != nil { + in, out := &in.Count, &out.Count + if *in == nil { + *out = nil + } else { + *out = new(int) + **out = **in + } + } if in.Args != nil { in, out := &in.Args, &out.Args *out = make([]string, len(*in)) copy(*out, *in) } + if in.StorageClassName != nil { + in, out := &in.StorageClassName, &out.StorageClassName + if *in == nil { + *out = nil + } else { + *out = new(string) + **out = **in + } + } in.Resources.DeepCopyInto(&out.Resources) return } @@ -393,9 +438,9 @@ func (in *ServerGroupSpec) DeepCopy() *ServerGroupSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SyncSpec) DeepCopyInto(out *SyncSpec) { *out = *in - out.Authentication = in.Authentication + in.Authentication.DeepCopyInto(&out.Authentication) in.TLS.DeepCopyInto(&out.TLS) - out.Monitoring = in.Monitoring + in.Monitoring.DeepCopyInto(&out.Monitoring) return } From 4d322caa05954a40a25d249fffab0a394006931b Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Fri, 23 Mar 2018 09:27:07 +0100 Subject: [PATCH 3/8] Converted simple spec fields to references for improved default detection --- .../deployment/v1alpha/authentication_spec.go | 15 +-- .../v1alpha/authentication_spec_test.go | 46 +++---- .../deployment/v1alpha/deployment_mode.go | 24 ++++ .../deployment/v1alpha/deployment_spec.go | 124 +++++++++++------- .../v1alpha/deployment_spec_test.go | 21 +-- pkg/apis/deployment/v1alpha/environment.go | 24 ++++ .../deployment/v1alpha/monitoring_spec.go | 11 +- .../v1alpha/monitoring_spec_test.go | 12 +- pkg/apis/deployment/v1alpha/rocksdb_spec.go | 13 +- .../deployment/v1alpha/rocksdb_spec_test.go | 26 ++-- .../deployment/v1alpha/server_group_spec.go | 62 +++++---- .../v1alpha/server_group_spec_test.go | 113 ++++++++-------- pkg/apis/deployment/v1alpha/storage_engine.go | 24 ++++ pkg/apis/deployment/v1alpha/sync_spec.go | 54 +++++--- pkg/apis/deployment/v1alpha/sync_spec_test.go | 92 ++++++------- pkg/apis/deployment/v1alpha/tls_spec.go | 32 ++--- pkg/apis/deployment/v1alpha/tls_spec_test.go | 32 ++--- .../v1alpha/zz_generated.deepcopy.go | 101 ++++++++++++-- pkg/deployment/images.go | 6 +- pkg/deployment/plan_builder.go | 2 +- pkg/deployment/plan_builder_test.go | 13 +- pkg/deployment/pod_creator.go | 16 +-- pkg/deployment/pod_creator_agent_args_test.go | 15 ++- .../pod_creator_coordinator_args_test.go | 15 ++- .../pod_creator_dbserver_args_test.go | 15 ++- .../pod_creator_single_args_test.go | 19 +-- pkg/deployment/secrets.go | 2 +- pkg/deployment/services.go | 4 +- pkg/util/k8sutil/test/events_test.go | 2 +- pkg/util/refs.go | 114 +++++++++++++--- 30 files changed, 660 insertions(+), 389 deletions(-) diff --git a/pkg/apis/deployment/v1alpha/authentication_spec.go b/pkg/apis/deployment/v1alpha/authentication_spec.go index 3848c3d2b..8fc6727a8 100644 --- a/pkg/apis/deployment/v1alpha/authentication_spec.go +++ b/pkg/apis/deployment/v1alpha/authentication_spec.go @@ -31,7 +31,7 @@ import ( // AuthenticationSpec holds authentication specific configuration settings type AuthenticationSpec struct { - JWTSecretName *string `json:"jwtSecretName,omitempty"` + XJWTSecretName *string `json:"jwtSecretName,omitempty"` } const ( @@ -41,10 +41,7 @@ const ( // GetJWTSecretName returns the value of jwtSecretName. func (s AuthenticationSpec) GetJWTSecretName() string { - if s.JWTSecretName == nil { - return "" - } - return *s.JWTSecretName + return util.StringOrDefault(s.XJWTSecretName) } // IsAuthenticated returns true if authentication is enabled. @@ -71,14 +68,14 @@ func (s *AuthenticationSpec) SetDefaults(defaultJWTSecretName string) { if s.GetJWTSecretName() == "" { // Note that we don't check for nil here, since even a specified, but empty // string should result in the default value. - s.JWTSecretName = util.String(defaultJWTSecretName) + s.XJWTSecretName = util.NewString(defaultJWTSecretName) } } // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *AuthenticationSpec) SetDefaultsFrom(source AuthenticationSpec) { - if s.JWTSecretName == nil { - s.JWTSecretName = util.String(source.GetJWTSecretName()) + if s.XJWTSecretName == nil { + s.XJWTSecretName = util.NewString(source.GetJWTSecretName()) } } @@ -89,7 +86,7 @@ func (s AuthenticationSpec) ResetImmutableFields(fieldPrefix string, target *Aut var resetFields []string if s.IsAuthenticated() != target.IsAuthenticated() { // Note: You can change the name, but not from empty to non-empty (or reverse). - target.JWTSecretName = util.StringOrNil(s.JWTSecretName) + target.XJWTSecretName = util.NewStringOrNil(s.XJWTSecretName) resetFields = append(resetFields, fieldPrefix+".jwtSecretName") } return resetFields diff --git a/pkg/apis/deployment/v1alpha/authentication_spec_test.go b/pkg/apis/deployment/v1alpha/authentication_spec_test.go index 3f101782e..b8cdd810f 100644 --- a/pkg/apis/deployment/v1alpha/authentication_spec_test.go +++ b/pkg/apis/deployment/v1alpha/authentication_spec_test.go @@ -31,18 +31,18 @@ import ( func TestAuthenticationSpecValidate(t *testing.T) { // Valid - assert.Nil(t, AuthenticationSpec{JWTSecretName: util.String("None")}.Validate(false)) - assert.Nil(t, AuthenticationSpec{JWTSecretName: util.String("foo")}.Validate(false)) - assert.Nil(t, AuthenticationSpec{JWTSecretName: util.String("foo")}.Validate(true)) + assert.Nil(t, AuthenticationSpec{XJWTSecretName: util.NewString("None")}.Validate(false)) + assert.Nil(t, AuthenticationSpec{XJWTSecretName: util.NewString("foo")}.Validate(false)) + assert.Nil(t, AuthenticationSpec{XJWTSecretName: util.NewString("foo")}.Validate(true)) // Not valid - assert.Error(t, AuthenticationSpec{JWTSecretName: util.String("Foo")}.Validate(false)) + assert.Error(t, AuthenticationSpec{XJWTSecretName: util.NewString("Foo")}.Validate(false)) } func TestAuthenticationSpecIsAuthenticated(t *testing.T) { - assert.False(t, AuthenticationSpec{JWTSecretName: util.String("None")}.IsAuthenticated()) - assert.True(t, AuthenticationSpec{JWTSecretName: util.String("foo")}.IsAuthenticated()) - assert.True(t, AuthenticationSpec{JWTSecretName: util.String("")}.IsAuthenticated()) + assert.False(t, AuthenticationSpec{XJWTSecretName: util.NewString("None")}.IsAuthenticated()) + assert.True(t, AuthenticationSpec{XJWTSecretName: util.NewString("foo")}.IsAuthenticated()) + assert.True(t, AuthenticationSpec{XJWTSecretName: util.NewString("")}.IsAuthenticated()) } func TestAuthenticationSpecSetDefaults(t *testing.T) { @@ -52,7 +52,7 @@ func TestAuthenticationSpecSetDefaults(t *testing.T) { } assert.Equal(t, "test-jwt", def(AuthenticationSpec{}).GetJWTSecretName()) - assert.Equal(t, "foo", def(AuthenticationSpec{JWTSecretName: util.String("foo")}).GetJWTSecretName()) + assert.Equal(t, "foo", def(AuthenticationSpec{XJWTSecretName: util.NewString("foo")}).GetJWTSecretName()) } func TestAuthenticationSpecResetImmutableFields(t *testing.T) { @@ -64,35 +64,35 @@ func TestAuthenticationSpecResetImmutableFields(t *testing.T) { }{ // Valid "changes" { - AuthenticationSpec{JWTSecretName: util.String("None")}, - AuthenticationSpec{JWTSecretName: util.String("None")}, - AuthenticationSpec{JWTSecretName: util.String("None")}, + AuthenticationSpec{XJWTSecretName: util.NewString("None")}, + AuthenticationSpec{XJWTSecretName: util.NewString("None")}, + AuthenticationSpec{XJWTSecretName: util.NewString("None")}, nil, }, { - AuthenticationSpec{JWTSecretName: util.String("foo")}, - AuthenticationSpec{JWTSecretName: util.String("foo")}, - AuthenticationSpec{JWTSecretName: util.String("foo")}, + AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, + AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, + AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, nil, }, { - AuthenticationSpec{JWTSecretName: util.String("foo")}, - AuthenticationSpec{JWTSecretName: util.String("foo2")}, - AuthenticationSpec{JWTSecretName: util.String("foo2")}, + AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, + AuthenticationSpec{XJWTSecretName: util.NewString("foo2")}, + AuthenticationSpec{XJWTSecretName: util.NewString("foo2")}, nil, }, // Invalid changes { - AuthenticationSpec{JWTSecretName: util.String("foo")}, - AuthenticationSpec{JWTSecretName: util.String("None")}, - AuthenticationSpec{JWTSecretName: util.String("foo")}, + AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, + AuthenticationSpec{XJWTSecretName: util.NewString("None")}, + AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, []string{"test.jwtSecretName"}, }, { - AuthenticationSpec{JWTSecretName: util.String("None")}, - AuthenticationSpec{JWTSecretName: util.String("foo")}, - AuthenticationSpec{JWTSecretName: util.String("None")}, + AuthenticationSpec{XJWTSecretName: util.NewString("None")}, + AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, + AuthenticationSpec{XJWTSecretName: util.NewString("None")}, []string{"test.jwtSecretName"}, }, } diff --git a/pkg/apis/deployment/v1alpha/deployment_mode.go b/pkg/apis/deployment/v1alpha/deployment_mode.go index 33f9c1475..0be3a5382 100644 --- a/pkg/apis/deployment/v1alpha/deployment_mode.go +++ b/pkg/apis/deployment/v1alpha/deployment_mode.go @@ -73,3 +73,27 @@ func (m DeploymentMode) HasCoordinators() bool { func (m DeploymentMode) SupportsSync() bool { return m == DeploymentModeCluster } + +// NewMode returns a reference to a string with given value. +func NewMode(input DeploymentMode) *DeploymentMode { + return &input +} + +// NewModeOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func NewModeOrNil(input *DeploymentMode) *DeploymentMode { + if input == nil { + return nil + } + return NewMode(*input) +} + +// ModeOrDefault returns the default value (or empty string) if input is nil, otherwise returns the referenced value. +func ModeOrDefault(input *DeploymentMode, defaultValue ...DeploymentMode) DeploymentMode { + if input == nil { + if len(defaultValue) > 0 { + return defaultValue[0] + } + return "" + } + return *input +} diff --git a/pkg/apis/deployment/v1alpha/deployment_spec.go b/pkg/apis/deployment/v1alpha/deployment_spec.go index cb88ce172..d9bbf5fca 100644 --- a/pkg/apis/deployment/v1alpha/deployment_spec.go +++ b/pkg/apis/deployment/v1alpha/deployment_spec.go @@ -23,6 +23,7 @@ package v1alpha import ( + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/pkg/errors" "k8s.io/api/core/v1" ) @@ -44,11 +45,11 @@ func validatePullPolicy(v v1.PullPolicy) error { // DeploymentSpec contains the spec part of a ArangoDeployment resource. type DeploymentSpec struct { - Mode DeploymentMode `json:"mode,omitempty"` - Environment Environment `json:"environment,omitempty"` - StorageEngine StorageEngine `json:"storageEngine,omitempty"` - Image string `json:"image,omitempty"` - ImagePullPolicy v1.PullPolicy `json:"imagePullPolicy,omitempty"` + XMode *DeploymentMode `json:"mode,omitempty"` + XEnvironment *Environment `json:"environment,omitempty"` + XStorageEngine *StorageEngine `json:"storageEngine,omitempty"` + XImage *string `json:"image,omitempty"` + XImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"` RocksDB RocksDBSpec `json:"rocksdb"` Authentication AuthenticationSpec `json:"auth"` @@ -63,6 +64,31 @@ type DeploymentSpec struct { SyncWorkers ServerGroupSpec `json:"syncworkers"` } +// GetMode returns the value of mode. +func (s DeploymentSpec) GetMode() DeploymentMode { + return ModeOrDefault(s.XMode) +} + +// GetEnvironment returns the value of environment. +func (s DeploymentSpec) GetEnvironment() Environment { + return EnvironmentOrDefault(s.XEnvironment) +} + +// GetStorageEngine returns the value of storageEngine. +func (s DeploymentSpec) GetStorageEngine() StorageEngine { + return StorageEngineOrDefault(s.XStorageEngine) +} + +// GetImage returns the value of image. +func (s DeploymentSpec) GetImage() string { + return util.StringOrDefault(s.XImage) +} + +// GetImagePullPolicy returns the value of imagePullPolicy. +func (s DeploymentSpec) GetImagePullPolicy() v1.PullPolicy { + return util.PullPolicyOrDefault(s.XImagePullPolicy) +} + // IsAuthenticated returns true when authentication is enabled func (s DeploymentSpec) IsAuthenticated() bool { return s.Authentication.IsAuthenticated() @@ -75,49 +101,49 @@ func (s DeploymentSpec) IsSecure() bool { // SetDefaults fills in default values when a field is not specified. func (s *DeploymentSpec) SetDefaults(deploymentName string) { - if s.Mode == "" { - s.Mode = DeploymentModeCluster + if s.GetMode() == "" { + s.XMode = NewMode(DeploymentModeCluster) } - if s.Environment == "" { - s.Environment = EnvironmentDevelopment + if s.GetEnvironment() == "" { + s.XEnvironment = NewEnvironment(EnvironmentDevelopment) } - if s.StorageEngine == "" { - s.StorageEngine = StorageEngineRocksDB + if s.GetStorageEngine() == "" { + s.XStorageEngine = NewStorageEngine(StorageEngineRocksDB) } - if s.Image == "" && s.IsDevelopment() { - s.Image = defaultImage + if s.GetImage() == "" && s.IsDevelopment() { + s.XImage = util.NewString(defaultImage) } - if s.ImagePullPolicy == "" { - s.ImagePullPolicy = v1.PullIfNotPresent + if s.GetImagePullPolicy() == "" { + s.XImagePullPolicy = util.NewPullPolicy(v1.PullIfNotPresent) } s.RocksDB.SetDefaults() s.Authentication.SetDefaults(deploymentName + "-jwt") s.TLS.SetDefaults(deploymentName + "-ca") - s.Sync.SetDefaults(s.Image, s.ImagePullPolicy, deploymentName+"-sync-jwt", deploymentName+"-sync-ca") - s.Single.SetDefaults(ServerGroupSingle, s.Mode.HasSingleServers(), s.Mode) - s.Agents.SetDefaults(ServerGroupAgents, s.Mode.HasAgents(), s.Mode) - s.DBServers.SetDefaults(ServerGroupDBServers, s.Mode.HasDBServers(), s.Mode) - s.Coordinators.SetDefaults(ServerGroupCoordinators, s.Mode.HasCoordinators(), s.Mode) - s.SyncMasters.SetDefaults(ServerGroupSyncMasters, s.Sync.Enabled, s.Mode) - s.SyncWorkers.SetDefaults(ServerGroupSyncWorkers, s.Sync.Enabled, s.Mode) + s.Sync.SetDefaults(s.GetImage(), s.GetImagePullPolicy(), deploymentName+"-sync-jwt", deploymentName+"-sync-ca") + s.Single.SetDefaults(ServerGroupSingle, s.GetMode().HasSingleServers(), s.GetMode()) + s.Agents.SetDefaults(ServerGroupAgents, s.GetMode().HasAgents(), s.GetMode()) + s.DBServers.SetDefaults(ServerGroupDBServers, s.GetMode().HasDBServers(), s.GetMode()) + s.Coordinators.SetDefaults(ServerGroupCoordinators, s.GetMode().HasCoordinators(), s.GetMode()) + s.SyncMasters.SetDefaults(ServerGroupSyncMasters, s.Sync.IsEnabled(), s.GetMode()) + s.SyncWorkers.SetDefaults(ServerGroupSyncWorkers, s.Sync.IsEnabled(), s.GetMode()) } // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *DeploymentSpec) SetDefaultsFrom(source DeploymentSpec) { - if s.Mode == "" { - s.Mode = source.Mode + if s.XMode == nil { + s.XMode = NewModeOrNil(source.XMode) } - if s.Environment == "" { - s.Environment = source.Environment + if s.XEnvironment == nil { + s.XEnvironment = NewEnvironmentOrNil(source.XEnvironment) } - if s.StorageEngine == "" { - s.StorageEngine = source.StorageEngine + if s.XStorageEngine == nil { + s.XStorageEngine = NewStorageEngineOrNil(source.XStorageEngine) } - if s.Image == "" { - s.Image = source.Image + if s.XImage == nil { + s.XImage = util.NewStringOrNil(source.XImage) } - if s.ImagePullPolicy == "" { - s.ImagePullPolicy = source.ImagePullPolicy + if s.XImagePullPolicy == nil { + s.XImagePullPolicy = util.NewPullPolicyOrNil(source.XImagePullPolicy) } s.RocksDB.SetDefaultsFrom(source.RocksDB) s.Authentication.SetDefaultsFrom(source.Authentication) @@ -134,19 +160,19 @@ func (s *DeploymentSpec) SetDefaultsFrom(source DeploymentSpec) { // Validate the specification. // Return errors when validation fails, nil on success. func (s *DeploymentSpec) Validate() error { - if err := s.Mode.Validate(); err != nil { + if err := s.GetMode().Validate(); err != nil { return maskAny(errors.Wrap(err, "spec.mode")) } - if err := s.Environment.Validate(); err != nil { + if err := s.GetEnvironment().Validate(); err != nil { return maskAny(errors.Wrap(err, "spec.environment")) } - if err := s.StorageEngine.Validate(); err != nil { + if err := s.GetStorageEngine().Validate(); err != nil { return maskAny(errors.Wrap(err, "spec.storageEngine")) } - if err := validatePullPolicy(s.ImagePullPolicy); err != nil { + if err := validatePullPolicy(s.GetImagePullPolicy()); err != nil { return maskAny(errors.Wrap(err, "spec.imagePullPolicy")) } - if s.Image == "" { + if s.GetImage() == "" { return maskAny(errors.Wrapf(ValidationError, "spec.image must be set")) } if err := s.RocksDB.Validate(); err != nil { @@ -158,25 +184,25 @@ func (s *DeploymentSpec) Validate() error { if err := s.TLS.Validate(); err != nil { return maskAny(errors.Wrap(err, "spec.tls")) } - if err := s.Sync.Validate(s.Mode); err != nil { + if err := s.Sync.Validate(s.GetMode()); err != nil { return maskAny(errors.Wrap(err, "spec.sync")) } - if err := s.Single.Validate(ServerGroupSingle, s.Mode.HasSingleServers(), s.Mode, s.Environment); err != nil { + if err := s.Single.Validate(ServerGroupSingle, s.GetMode().HasSingleServers(), s.GetMode(), s.GetEnvironment()); err != nil { return maskAny(err) } - if err := s.Agents.Validate(ServerGroupAgents, s.Mode.HasAgents(), s.Mode, s.Environment); err != nil { + if err := s.Agents.Validate(ServerGroupAgents, s.GetMode().HasAgents(), s.GetMode(), s.GetEnvironment()); err != nil { return maskAny(err) } - if err := s.DBServers.Validate(ServerGroupDBServers, s.Mode.HasDBServers(), s.Mode, s.Environment); err != nil { + if err := s.DBServers.Validate(ServerGroupDBServers, s.GetMode().HasDBServers(), s.GetMode(), s.GetEnvironment()); err != nil { return maskAny(err) } - if err := s.Coordinators.Validate(ServerGroupCoordinators, s.Mode.HasCoordinators(), s.Mode, s.Environment); err != nil { + if err := s.Coordinators.Validate(ServerGroupCoordinators, s.GetMode().HasCoordinators(), s.GetMode(), s.GetEnvironment()); err != nil { return maskAny(err) } - if err := s.SyncMasters.Validate(ServerGroupSyncMasters, s.Sync.Enabled, s.Mode, s.Environment); err != nil { + if err := s.SyncMasters.Validate(ServerGroupSyncMasters, s.Sync.IsEnabled(), s.GetMode(), s.GetEnvironment()); err != nil { return maskAny(err) } - if err := s.SyncWorkers.Validate(ServerGroupSyncWorkers, s.Sync.Enabled, s.Mode, s.Environment); err != nil { + if err := s.SyncWorkers.Validate(ServerGroupSyncWorkers, s.Sync.IsEnabled(), s.GetMode(), s.GetEnvironment()); err != nil { return maskAny(err) } return nil @@ -184,7 +210,7 @@ func (s *DeploymentSpec) Validate() error { // IsDevelopment returns true when the spec contains a Development environment. func (s DeploymentSpec) IsDevelopment() bool { - return s.Environment == EnvironmentDevelopment + return s.GetEnvironment() == EnvironmentDevelopment } // ResetImmutableFields replaces all immutable fields in the given target with values from the source spec. @@ -192,12 +218,12 @@ func (s DeploymentSpec) IsDevelopment() bool { // Field names are relative to `spec.`. func (s DeploymentSpec) ResetImmutableFields(target *DeploymentSpec) []string { var resetFields []string - if s.Mode != target.Mode { - target.Mode = s.Mode + if s.GetMode() != target.GetMode() { + target.XMode = NewModeOrNil(s.XMode) resetFields = append(resetFields, "mode") } - if s.StorageEngine != target.StorageEngine { - target.StorageEngine = s.StorageEngine + if s.GetStorageEngine() != target.GetStorageEngine() { + target.XStorageEngine = NewStorageEngineOrNil(s.XStorageEngine) resetFields = append(resetFields, "storageEngine") } if l := s.RocksDB.ResetImmutableFields("rocksdb", &target.RocksDB); l != nil { diff --git a/pkg/apis/deployment/v1alpha/deployment_spec_test.go b/pkg/apis/deployment/v1alpha/deployment_spec_test.go index 822b49642..8e4c1010d 100644 --- a/pkg/apis/deployment/v1alpha/deployment_spec_test.go +++ b/pkg/apis/deployment/v1alpha/deployment_spec_test.go @@ -25,6 +25,7 @@ package v1alpha import ( "testing" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/stretchr/testify/assert" "k8s.io/api/core/v1" ) @@ -39,7 +40,7 @@ func TestDeploymentSpecSetDefaults(t *testing.T) { return spec } - assert.Equal(t, "arangodb/arangodb:latest", def(DeploymentSpec{}).Image) + assert.Equal(t, "arangodb/arangodb:latest", def(DeploymentSpec{}).GetImage()) } func TestDeploymentSpecResetImmutableFields(t *testing.T) { @@ -51,23 +52,23 @@ func TestDeploymentSpecResetImmutableFields(t *testing.T) { }{ // Valid "changes" { - DeploymentSpec{Image: "foo"}, - DeploymentSpec{Image: "foo2"}, - DeploymentSpec{Image: "foo2"}, + DeploymentSpec{XImage: util.NewString("foo")}, + DeploymentSpec{XImage: util.NewString("foo2")}, + DeploymentSpec{XImage: util.NewString("foo2")}, nil, }, { - DeploymentSpec{ImagePullPolicy: v1.PullAlways}, - DeploymentSpec{ImagePullPolicy: v1.PullNever}, - DeploymentSpec{ImagePullPolicy: v1.PullNever}, + DeploymentSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullAlways)}, + DeploymentSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, + DeploymentSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, nil, }, // Invalid changes { - DeploymentSpec{Mode: DeploymentModeSingle}, - DeploymentSpec{Mode: DeploymentModeCluster}, - DeploymentSpec{Mode: DeploymentModeSingle}, + DeploymentSpec{XMode: NewMode(DeploymentModeSingle)}, + DeploymentSpec{XMode: NewMode(DeploymentModeCluster)}, + DeploymentSpec{XMode: NewMode(DeploymentModeSingle)}, []string{"mode"}, }, } diff --git a/pkg/apis/deployment/v1alpha/environment.go b/pkg/apis/deployment/v1alpha/environment.go index ccf099bb4..62bbfb9d5 100644 --- a/pkg/apis/deployment/v1alpha/environment.go +++ b/pkg/apis/deployment/v1alpha/environment.go @@ -46,3 +46,27 @@ func (e Environment) Validate() error { return maskAny(errors.Wrapf(ValidationError, "Unknown environment: '%s'", string(e))) } } + +// NewEnvironment returns a reference to a string with given value. +func NewEnvironment(input Environment) *Environment { + return &input +} + +// NewEnvironmentOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func NewEnvironmentOrNil(input *Environment) *Environment { + if input == nil { + return nil + } + return NewEnvironment(*input) +} + +// EnvironmentOrDefault returns the default value (or empty string) if input is nil, otherwise returns the referenced value. +func EnvironmentOrDefault(input *Environment, defaultValue ...Environment) Environment { + if input == nil { + if len(defaultValue) > 0 { + return defaultValue[0] + } + return "" + } + return *input +} diff --git a/pkg/apis/deployment/v1alpha/monitoring_spec.go b/pkg/apis/deployment/v1alpha/monitoring_spec.go index d52579640..1e8bd8b5d 100644 --- a/pkg/apis/deployment/v1alpha/monitoring_spec.go +++ b/pkg/apis/deployment/v1alpha/monitoring_spec.go @@ -29,15 +29,12 @@ import ( // MonitoringSpec holds monitoring specific configuration settings type MonitoringSpec struct { - TokenSecretName *string `json:"tokenSecretName,omitempty"` + XTokenSecretName *string `json:"tokenSecretName,omitempty"` } // GetTokenSecretName returns the value of tokenSecretName. func (s MonitoringSpec) GetTokenSecretName() string { - if s.TokenSecretName == nil { - return "" - } - return *s.TokenSecretName + return util.StringOrDefault(s.XTokenSecretName) } // Validate the given spec @@ -55,7 +52,7 @@ func (s *MonitoringSpec) SetDefaults() { // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *MonitoringSpec) SetDefaultsFrom(source MonitoringSpec) { - if s.TokenSecretName == nil { - s.TokenSecretName = util.StringOrNil(source.TokenSecretName) + if s.XTokenSecretName == nil { + s.XTokenSecretName = util.NewStringOrNil(source.XTokenSecretName) } } diff --git a/pkg/apis/deployment/v1alpha/monitoring_spec_test.go b/pkg/apis/deployment/v1alpha/monitoring_spec_test.go index bdb242aa8..8ea215bc3 100644 --- a/pkg/apis/deployment/v1alpha/monitoring_spec_test.go +++ b/pkg/apis/deployment/v1alpha/monitoring_spec_test.go @@ -31,13 +31,13 @@ import ( func TestMonitoringSpecValidate(t *testing.T) { // Valid - assert.Nil(t, MonitoringSpec{TokenSecretName: nil}.Validate()) - assert.Nil(t, MonitoringSpec{TokenSecretName: util.String("")}.Validate()) - assert.Nil(t, MonitoringSpec{TokenSecretName: util.String("foo")}.Validate()) - assert.Nil(t, MonitoringSpec{TokenSecretName: util.String("foo")}.Validate()) + assert.Nil(t, MonitoringSpec{XTokenSecretName: nil}.Validate()) + assert.Nil(t, MonitoringSpec{XTokenSecretName: util.NewString("")}.Validate()) + assert.Nil(t, MonitoringSpec{XTokenSecretName: util.NewString("foo")}.Validate()) + assert.Nil(t, MonitoringSpec{XTokenSecretName: util.NewString("foo")}.Validate()) // Not valid - assert.Error(t, MonitoringSpec{TokenSecretName: util.String("Foo")}.Validate()) + assert.Error(t, MonitoringSpec{XTokenSecretName: util.NewString("Foo")}.Validate()) } func TestMonitoringSpecSetDefaults(t *testing.T) { @@ -47,5 +47,5 @@ func TestMonitoringSpecSetDefaults(t *testing.T) { } assert.Equal(t, "", def(MonitoringSpec{}).GetTokenSecretName()) - assert.Equal(t, "foo", def(MonitoringSpec{TokenSecretName: util.String("foo")}).GetTokenSecretName()) + assert.Equal(t, "foo", def(MonitoringSpec{XTokenSecretName: util.NewString("foo")}).GetTokenSecretName()) } diff --git a/pkg/apis/deployment/v1alpha/rocksdb_spec.go b/pkg/apis/deployment/v1alpha/rocksdb_spec.go index 0f00439df..711d2e44b 100644 --- a/pkg/apis/deployment/v1alpha/rocksdb_spec.go +++ b/pkg/apis/deployment/v1alpha/rocksdb_spec.go @@ -29,15 +29,12 @@ import ( // RocksDBEncryptionSpec holds rocksdb encryption at rest specific configuration settings type RocksDBEncryptionSpec struct { - KeySecretName *string `json:"keySecretName,omitempty"` + XKeySecretName *string `json:"keySecretName,omitempty"` } // GetKeySecretName returns the value of keySecretName. func (s RocksDBEncryptionSpec) GetKeySecretName() string { - if s.KeySecretName == nil { - return "" - } - return *s.KeySecretName + return util.StringOrDefault(s.XKeySecretName) } // IsEncrypted returns true when an encryption key secret name is provided, @@ -72,8 +69,8 @@ func (s *RocksDBSpec) SetDefaults() { // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *RocksDBSpec) SetDefaultsFrom(source RocksDBSpec) { - if s.Encryption.KeySecretName == nil { - s.Encryption.KeySecretName = util.StringOrNil(source.Encryption.KeySecretName) + if s.Encryption.XKeySecretName == nil { + s.Encryption.XKeySecretName = util.NewStringOrNil(source.Encryption.XKeySecretName) } } @@ -84,7 +81,7 @@ func (s RocksDBSpec) ResetImmutableFields(fieldPrefix string, target *RocksDBSpe var resetFields []string if s.IsEncrypted() != target.IsEncrypted() { // Note: You can change the name, but not from empty to non-empty (or reverse). - target.Encryption.KeySecretName = util.StringOrNil(s.Encryption.KeySecretName) + target.Encryption.XKeySecretName = util.NewStringOrNil(s.Encryption.XKeySecretName) resetFields = append(resetFields, fieldPrefix+".encryption.keySecretName") } return resetFields diff --git a/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go b/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go index 720b5b7b3..8b935ca01 100644 --- a/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go +++ b/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go @@ -32,16 +32,16 @@ import ( func TestRocksDBSpecValidate(t *testing.T) { // Valid assert.Nil(t, RocksDBSpec{}.Validate()) - assert.Nil(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}.Validate()) + assert.Nil(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}.Validate()) // Not valid - assert.Error(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("Foo")}}.Validate()) + assert.Error(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("Foo")}}.Validate()) } func TestRocksDBSpecIsEncrypted(t *testing.T) { assert.False(t, RocksDBSpec{}.IsEncrypted()) - assert.False(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("")}}.IsEncrypted()) - assert.True(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}.IsEncrypted()) + assert.False(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("")}}.IsEncrypted()) + assert.True(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}.IsEncrypted()) } func TestRocksDBSpecSetDefaults(t *testing.T) { @@ -68,23 +68,23 @@ func TestRocksDBSpecResetImmutableFields(t *testing.T) { nil, }, { - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, nil, }, { - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo2")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo2")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo2")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo2")}}, nil, }, // Invalid changes { - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.String("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, []string{"test.encryption.keySecretName"}, }, } diff --git a/pkg/apis/deployment/v1alpha/server_group_spec.go b/pkg/apis/deployment/v1alpha/server_group_spec.go index 8955a9064..0a8b712d2 100644 --- a/pkg/apis/deployment/v1alpha/server_group_spec.go +++ b/pkg/apis/deployment/v1alpha/server_group_spec.go @@ -33,29 +33,28 @@ import ( // ServerGroupSpec contains the specification for all servers in a specific group (e.g. all agents) type ServerGroupSpec struct { // Count holds the requested number of servers - Count *int `json:"count,omitempty"` + XCount *int `json:"count,omitempty"` // Args holds additional commandline arguments Args []string `json:"args,omitempty"` // StorageClassName specifies the classname for storage of the servers. - StorageClassName *string `json:"storageClassName,omitempty"` + XStorageClassName *string `json:"storageClassName,omitempty"` // Resources holds resource requests & limits - Resources v1.ResourceRequirements `json:"resource,omitempty"` + Resources v1.ResourceRequirements `json:"resources,omitempty"` } // GetCount returns the value of count. func (s ServerGroupSpec) GetCount() int { - if s.Count == nil { - return 0 - } - return *s.Count + return util.IntOrDefault(s.XCount) +} + +// GetArgs returns the value of args. +func (s ServerGroupSpec) GetArgs() []string { + return s.Args } -// GetStorageClassName returns the value of count. +// GetStorageClassName returns the value of storageClassName. func (s ServerGroupSpec) GetStorageClassName() string { - if s.StorageClassName == nil { - return "" - } - return *s.StorageClassName + return util.StringOrDefault(s.XStorageClassName) } // Validate the given group spec @@ -75,13 +74,13 @@ func (s ServerGroupSpec) Validate(group ServerGroup, used bool, mode DeploymentM } } if s.GetCount() < minCount { - return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected >= %d", s.Count, minCount)) + return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected >= %d", s.GetCount(), minCount)) } if s.GetCount() > 1 && group == ServerGroupSingle && mode == DeploymentModeSingle { - return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected 1", s.Count)) + return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d. Expected 1", s.GetCount())) } } else if s.GetCount() != 0 { - return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d for un-used group. Expected 0", s.Count)) + return maskAny(errors.Wrapf(ValidationError, "Invalid count value %d for un-used group. Expected 0", s.GetCount())) } return nil } @@ -92,12 +91,12 @@ func (s *ServerGroupSpec) SetDefaults(group ServerGroup, used bool, mode Deploym switch group { case ServerGroupSingle: if mode == DeploymentModeSingle { - s.Count = util.Int(1) // Single server + s.XCount = util.NewInt(1) // Single server } else { - s.Count = util.Int(2) // Resilient single + s.XCount = util.NewInt(2) // Resilient single } default: - s.Count = util.Int(3) + s.XCount = util.NewInt(3) } } if _, found := s.Resources.Requests[v1.ResourceStorage]; !found { @@ -111,18 +110,31 @@ func (s *ServerGroupSpec) SetDefaults(group ServerGroup, used bool, mode Deploym } } +// setDefaultsFromResourceList fills unspecified fields with a value from given source spec. +func setDefaultsFromResourceList(s *v1.ResourceList, source v1.ResourceList) { + for k, v := range source { + if *s == nil { + *s = make(v1.ResourceList) + } + if _, found := (*s)[k]; !found { + (*s)[k] = v + } + } +} + // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *ServerGroupSpec) SetDefaultsFrom(source ServerGroupSpec) { - if s.Count == nil { - s.Count = util.IntOrNil(source.Count) + if s.XCount == nil { + s.XCount = util.NewIntOrNil(source.XCount) } if s.Args == nil { s.Args = source.Args } - if s.StorageClassName == nil { - s.StorageClassName = util.StringOrNil(source.StorageClassName) + if s.XStorageClassName == nil { + s.XStorageClassName = util.NewStringOrNil(source.XStorageClassName) } - // TODO Resources + setDefaultsFromResourceList(&s.Resources.Limits, source.Resources.Limits) + setDefaultsFromResourceList(&s.Resources.Requests, source.Resources.Requests) } // ResetImmutableFields replaces all immutable fields in the given target with values from the source spec. @@ -131,12 +143,12 @@ func (s ServerGroupSpec) ResetImmutableFields(group ServerGroup, fieldPrefix str var resetFields []string if group == ServerGroupAgents { if s.GetCount() != target.GetCount() { - target.Count = util.IntOrNil(s.Count) + target.XCount = util.NewIntOrNil(s.XCount) resetFields = append(resetFields, fieldPrefix+".count") } } if s.GetStorageClassName() != target.GetStorageClassName() { - target.StorageClassName = util.StringOrNil(s.StorageClassName) + target.XStorageClassName = util.NewStringOrNil(s.XStorageClassName) resetFields = append(resetFields, fieldPrefix+".storageClassName") } return resetFields diff --git a/pkg/apis/deployment/v1alpha/server_group_spec_test.go b/pkg/apis/deployment/v1alpha/server_group_spec_test.go index 908affdd4..fcd173c9f 100644 --- a/pkg/apis/deployment/v1alpha/server_group_spec_test.go +++ b/pkg/apis/deployment/v1alpha/server_group_spec_test.go @@ -25,50 +25,51 @@ package v1alpha import ( "testing" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/stretchr/testify/assert" ) func TestServerGroupSpecValidateCount(t *testing.T) { // Valid - assert.Nil(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 0}.Validate(ServerGroupSingle, false, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 3}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 3}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 6}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 2}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{Count: 3}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{Count: 3}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{Count: 2}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{Count: 2}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{Count: 2}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{Count: 2}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupSingle, false, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(6)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) // Invalid - assert.Error(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupSingle, false, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: 2}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupSingle, true, DeploymentModeResilientSingle, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{Count: 0}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: 0}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: 0}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: 0}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: 0}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: 0}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: -1}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: -1}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: -1}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: -1}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: -1}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: -1}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{Count: 2}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{Count: 2}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{Count: 1}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSingle, false, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSingle, true, DeploymentModeResilientSingle, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) } func TestServerGroupSpecDefault(t *testing.T) { @@ -77,32 +78,32 @@ func TestServerGroupSpecDefault(t *testing.T) { return spec } - assert.Equal(t, 1, def(ServerGroupSpec{}, ServerGroupSingle, true, DeploymentModeSingle).Count) - assert.Equal(t, 2, def(ServerGroupSpec{}, ServerGroupSingle, true, DeploymentModeResilientSingle).Count) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSingle, false, DeploymentModeCluster).Count) + assert.Equal(t, 1, def(ServerGroupSpec{}, ServerGroupSingle, true, DeploymentModeSingle).GetCount()) + assert.Equal(t, 2, def(ServerGroupSpec{}, ServerGroupSingle, true, DeploymentModeResilientSingle).GetCount()) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSingle, false, DeploymentModeCluster).GetCount()) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupAgents, false, DeploymentModeSingle).Count) - assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupAgents, true, DeploymentModeResilientSingle).Count) - assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupAgents, true, DeploymentModeCluster).Count) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupAgents, false, DeploymentModeSingle).GetCount()) + assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupAgents, true, DeploymentModeResilientSingle).GetCount()) + assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupAgents, true, DeploymentModeCluster).GetCount()) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupDBServers, false, DeploymentModeSingle).Count) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupDBServers, false, DeploymentModeResilientSingle).Count) - assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupDBServers, true, DeploymentModeCluster).Count) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupDBServers, false, DeploymentModeSingle).GetCount()) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupDBServers, false, DeploymentModeResilientSingle).GetCount()) + assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupDBServers, true, DeploymentModeCluster).GetCount()) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupCoordinators, false, DeploymentModeSingle).Count) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupCoordinators, false, DeploymentModeResilientSingle).Count) - assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupCoordinators, true, DeploymentModeCluster).Count) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupCoordinators, false, DeploymentModeSingle).GetCount()) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupCoordinators, false, DeploymentModeResilientSingle).GetCount()) + assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupCoordinators, true, DeploymentModeCluster).GetCount()) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncMasters, false, DeploymentModeSingle).Count) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncMasters, false, DeploymentModeResilientSingle).Count) - assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupSyncMasters, true, DeploymentModeCluster).Count) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncMasters, false, DeploymentModeSingle).GetCount()) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncMasters, false, DeploymentModeResilientSingle).GetCount()) + assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupSyncMasters, true, DeploymentModeCluster).GetCount()) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncWorkers, false, DeploymentModeSingle).Count) - assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncWorkers, false, DeploymentModeResilientSingle).Count) - assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupSyncWorkers, true, DeploymentModeCluster).Count) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncWorkers, false, DeploymentModeSingle).GetCount()) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncWorkers, false, DeploymentModeResilientSingle).GetCount()) + assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupSyncWorkers, true, DeploymentModeCluster).GetCount()) for _, g := range AllServerGroups { assert.Equal(t, 0, len(def(ServerGroupSpec{}, g, true, DeploymentModeSingle).Args)) - assert.Equal(t, "", def(ServerGroupSpec{}, g, true, DeploymentModeSingle).StorageClassName) + assert.Equal(t, "", def(ServerGroupSpec{}, g, true, DeploymentModeSingle).GetStorageClassName()) } } diff --git a/pkg/apis/deployment/v1alpha/storage_engine.go b/pkg/apis/deployment/v1alpha/storage_engine.go index 5cee17ab4..354c1a3b5 100644 --- a/pkg/apis/deployment/v1alpha/storage_engine.go +++ b/pkg/apis/deployment/v1alpha/storage_engine.go @@ -46,3 +46,27 @@ func (se StorageEngine) Validate() error { return maskAny(errors.Wrapf(ValidationError, "Unknown storage engine: '%s'", string(se))) } } + +// NewStorageEngine returns a reference to a string with given value. +func NewStorageEngine(input StorageEngine) *StorageEngine { + return &input +} + +// NewStorageEngineOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func NewStorageEngineOrNil(input *StorageEngine) *StorageEngine { + if input == nil { + return nil + } + return NewStorageEngine(*input) +} + +// StorageEngineOrDefault returns the default value (or empty string) if input is nil, otherwise returns the referenced value. +func StorageEngineOrDefault(input *StorageEngine, defaultValue ...StorageEngine) StorageEngine { + if input == nil { + if len(defaultValue) > 0 { + return defaultValue[0] + } + return "" + } + return *input +} diff --git a/pkg/apis/deployment/v1alpha/sync_spec.go b/pkg/apis/deployment/v1alpha/sync_spec.go index d7d26d8aa..2f0b533d9 100644 --- a/pkg/apis/deployment/v1alpha/sync_spec.go +++ b/pkg/apis/deployment/v1alpha/sync_spec.go @@ -25,31 +25,51 @@ package v1alpha import ( "github.com/pkg/errors" "k8s.io/api/core/v1" + + "github.com/arangodb/kube-arangodb/pkg/util" ) // SyncSpec holds dc2dc replication specific configuration settings type SyncSpec struct { - Enabled bool `json:"enabled,omitempty"` - Image string `json:"image,omitempty"` - ImagePullPolicy v1.PullPolicy `json:"imagePullPolicy,omitempty"` + XEnabled *bool `json:"enabled,omitempty"` + XImage *string `json:"image,omitempty"` + XImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"` Authentication AuthenticationSpec `json:"auth"` TLS TLSSpec `json:"tls"` Monitoring MonitoringSpec `json:"monitoring"` } +// IsEnabled returns the value of enabled. +func (s SyncSpec) IsEnabled() bool { + return util.BoolOrDefault(s.XEnabled) +} + +// GetImage returns the value of image. +func (s SyncSpec) GetImage() string { + return util.StringOrDefault(s.XImage) +} + +// GetImagePullPolicy returns the value of imagePullPolicy. +func (s SyncSpec) GetImagePullPolicy() v1.PullPolicy { + if s.XImagePullPolicy == nil { + return "" + } + return *s.XImagePullPolicy +} + // Validate the given spec func (s SyncSpec) Validate(mode DeploymentMode) error { - if s.Enabled && !mode.SupportsSync() { + if s.IsEnabled() && !mode.SupportsSync() { return maskAny(errors.Wrapf(ValidationError, "Cannot enable sync with mode: '%s'", mode)) } - if s.Image == "" { + if s.GetImage() == "" { return maskAny(errors.Wrapf(ValidationError, "image must be set")) } - if err := s.Authentication.Validate(s.Enabled); err != nil { + if err := s.Authentication.Validate(s.IsEnabled()); err != nil { return maskAny(err) } - if s.Enabled { + if s.IsEnabled() { if err := s.TLS.Validate(); err != nil { return maskAny(err) } @@ -62,11 +82,12 @@ func (s SyncSpec) Validate(mode DeploymentMode) error { // SetDefaults fills in missing defaults func (s *SyncSpec) SetDefaults(defaultImage string, defaulPullPolicy v1.PullPolicy, defaultJWTSecretName, defaultCASecretName string) { - if s.Image == "" { - s.Image = defaultImage + if s.GetImage() == "" { + s.XImage = util.NewString(defaultImage) } - if s.ImagePullPolicy == "" { - s.ImagePullPolicy = defaulPullPolicy + if s.GetImagePullPolicy() == "" { + x := v1.PullPolicy(defaulPullPolicy) + s.XImagePullPolicy = &x } s.Authentication.SetDefaults(defaultJWTSecretName) s.TLS.SetDefaults(defaultCASecretName) @@ -75,11 +96,14 @@ func (s *SyncSpec) SetDefaults(defaultImage string, defaulPullPolicy v1.PullPoli // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *SyncSpec) SetDefaultsFrom(source SyncSpec) { - if s.Image == "" { - s.Image = source.Image + if s.XEnabled == nil { + s.XEnabled = util.NewBoolOrNil(source.XEnabled) + } + if s.XImage == nil { + s.XImage = util.NewStringOrNil(source.XImage) } - if s.ImagePullPolicy == "" { - s.ImagePullPolicy = source.ImagePullPolicy + if s.GetImagePullPolicy() == "" { + s.XImagePullPolicy = util.NewPullPolicyOrNil(source.XImagePullPolicy) } s.Authentication.SetDefaultsFrom(source.Authentication) s.TLS.SetDefaultsFrom(source.TLS) diff --git a/pkg/apis/deployment/v1alpha/sync_spec_test.go b/pkg/apis/deployment/v1alpha/sync_spec_test.go index dc2d84b44..0b64527fb 100644 --- a/pkg/apis/deployment/v1alpha/sync_spec_test.go +++ b/pkg/apis/deployment/v1alpha/sync_spec_test.go @@ -32,19 +32,19 @@ import ( func TestSyncSpecValidate(t *testing.T) { // Valid - auth := AuthenticationSpec{JWTSecretName: util.String("foo")} - tls := TLSSpec{CASecretName: util.String("None")} - assert.Nil(t, SyncSpec{Image: "foo", Authentication: auth}.Validate(DeploymentModeSingle)) - assert.Nil(t, SyncSpec{Image: "foo", Authentication: auth}.Validate(DeploymentModeResilientSingle)) - assert.Nil(t, SyncSpec{Image: "foo", Authentication: auth}.Validate(DeploymentModeCluster)) - assert.Nil(t, SyncSpec{Image: "foo", Authentication: auth, TLS: tls, Enabled: true}.Validate(DeploymentModeCluster)) + auth := AuthenticationSpec{XJWTSecretName: util.NewString("foo")} + tls := TLSSpec{XCASecretName: util.NewString("None")} + assert.Nil(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth}.Validate(DeploymentModeSingle)) + assert.Nil(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth}.Validate(DeploymentModeResilientSingle)) + assert.Nil(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth}.Validate(DeploymentModeCluster)) + assert.Nil(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth, TLS: tls, XEnabled: util.NewBool(true)}.Validate(DeploymentModeCluster)) // Not valid - assert.Error(t, SyncSpec{Image: "", Authentication: auth}.Validate(DeploymentModeSingle)) - assert.Error(t, SyncSpec{Image: "", Authentication: auth}.Validate(DeploymentModeResilientSingle)) - assert.Error(t, SyncSpec{Image: "", Authentication: auth}.Validate(DeploymentModeCluster)) - assert.Error(t, SyncSpec{Image: "foo", Authentication: auth, TLS: tls, Enabled: true}.Validate(DeploymentModeSingle)) - assert.Error(t, SyncSpec{Image: "foo", Authentication: auth, TLS: tls, Enabled: true}.Validate(DeploymentModeResilientSingle)) + assert.Error(t, SyncSpec{XImage: util.NewString(""), Authentication: auth}.Validate(DeploymentModeSingle)) + assert.Error(t, SyncSpec{XImage: util.NewString(""), Authentication: auth}.Validate(DeploymentModeResilientSingle)) + assert.Error(t, SyncSpec{XImage: util.NewString(""), Authentication: auth}.Validate(DeploymentModeCluster)) + assert.Error(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth, TLS: tls, XEnabled: util.NewBool(true)}.Validate(DeploymentModeSingle)) + assert.Error(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth, TLS: tls, XEnabled: util.NewBool(true)}.Validate(DeploymentModeResilientSingle)) } func TestSyncSpecSetDefaults(t *testing.T) { @@ -53,15 +53,15 @@ func TestSyncSpecSetDefaults(t *testing.T) { return spec } - assert.False(t, def(SyncSpec{}).Enabled) - assert.False(t, def(SyncSpec{Enabled: false}).Enabled) - assert.True(t, def(SyncSpec{Enabled: true}).Enabled) - assert.Equal(t, "test-image", def(SyncSpec{}).Image) - assert.Equal(t, "foo", def(SyncSpec{Image: "foo"}).Image) - assert.Equal(t, v1.PullAlways, def(SyncSpec{}).ImagePullPolicy) - assert.Equal(t, v1.PullNever, def(SyncSpec{ImagePullPolicy: v1.PullNever}).ImagePullPolicy) + assert.False(t, def(SyncSpec{}).IsEnabled()) + assert.False(t, def(SyncSpec{XEnabled: util.NewBool(false)}).IsEnabled()) + assert.True(t, def(SyncSpec{XEnabled: util.NewBool(true)}).IsEnabled()) + assert.Equal(t, "test-image", def(SyncSpec{}).GetImage()) + assert.Equal(t, "foo", def(SyncSpec{XImage: util.NewString("foo")}).GetImage()) + assert.Equal(t, v1.PullAlways, def(SyncSpec{}).GetImagePullPolicy()) + assert.Equal(t, v1.PullNever, def(SyncSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}).GetImagePullPolicy()) assert.Equal(t, "test-jwt", def(SyncSpec{}).Authentication.GetJWTSecretName()) - assert.Equal(t, "foo", def(SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}).Authentication.GetJWTSecretName()) + assert.Equal(t, "foo", def(SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}).Authentication.GetJWTSecretName()) } func TestSyncSpecResetImmutableFields(t *testing.T) { @@ -73,59 +73,59 @@ func TestSyncSpecResetImmutableFields(t *testing.T) { }{ // Valid "changes" { - SyncSpec{Enabled: false}, - SyncSpec{Enabled: true}, - SyncSpec{Enabled: true}, + SyncSpec{XEnabled: util.NewBool(false)}, + SyncSpec{XEnabled: util.NewBool(true)}, + SyncSpec{XEnabled: util.NewBool(true)}, nil, }, { - SyncSpec{Enabled: true}, - SyncSpec{Enabled: false}, - SyncSpec{Enabled: false}, + SyncSpec{XEnabled: util.NewBool(true)}, + SyncSpec{XEnabled: util.NewBool(false)}, + SyncSpec{XEnabled: util.NewBool(false)}, nil, }, { - SyncSpec{Image: "foo"}, - SyncSpec{Image: "foo2"}, - SyncSpec{Image: "foo2"}, + SyncSpec{XImage: util.NewString("foo")}, + SyncSpec{XImage: util.NewString("foo2")}, + SyncSpec{XImage: util.NewString("foo2")}, nil, }, { - SyncSpec{ImagePullPolicy: v1.PullAlways}, - SyncSpec{ImagePullPolicy: v1.PullNever}, - SyncSpec{ImagePullPolicy: v1.PullNever}, + SyncSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullAlways)}, + SyncSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, + SyncSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, nil, }, { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, nil, }, { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, nil, }, { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo2")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo2")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo2")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo2")}}, nil, }, // Invalid changes { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, []string{"test.auth.jwtSecretName"}, }, { - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.String("None")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, []string{"test.auth.jwtSecretName"}, }, } diff --git a/pkg/apis/deployment/v1alpha/tls_spec.go b/pkg/apis/deployment/v1alpha/tls_spec.go index f2be5004d..08ed6f358 100644 --- a/pkg/apis/deployment/v1alpha/tls_spec.go +++ b/pkg/apis/deployment/v1alpha/tls_spec.go @@ -38,9 +38,9 @@ const ( // TLSSpec holds TLS specific configuration settings type TLSSpec struct { - CASecretName *string `json:"caSecretName,omitempty"` - AltNames []string `json:"altNames,omitempty"` - TTL *time.Duration `json:"ttl,omitempty"` + XCASecretName *string `json:"caSecretName,omitempty"` + AltNames []string `json:"altNames,omitempty"` + XTTL *time.Duration `json:"ttl,omitempty"` } const ( @@ -50,10 +50,7 @@ const ( // GetCASecretName returns the value of caSecretName. func (s TLSSpec) GetCASecretName() string { - if s.CASecretName == nil { - return "" - } - return *s.CASecretName + return util.StringOrDefault(s.XCASecretName) } // GetAltNames returns the value of altNames. @@ -63,10 +60,7 @@ func (s TLSSpec) GetAltNames() []string { // GetTTL returns the value of ttl. func (s TLSSpec) GetTTL() time.Duration { - if s.TTL == nil { - return time.Duration(0) - } - return *s.TTL + return util.DurationOrDefault(s.XTTL) } // IsSecure returns true when a CA secret has been set, false otherwise. @@ -77,7 +71,7 @@ func (s TLSSpec) IsSecure() bool { // GetParsedAltNames splits the list of AltNames into DNS names, IP addresses & email addresses. // When an entry is not valid for any of those categories, an error is returned. func (s TLSSpec) GetParsedAltNames() (dnsNames, ipAddresses, emailAddresses []string, err error) { - for _, name := range s.AltNames { + for _, name := range s.GetAltNames() { if net.ParseIP(name) != nil { ipAddresses = append(ipAddresses, name) } else if validation.IsValidDNSName(name) { @@ -109,24 +103,24 @@ func (s *TLSSpec) SetDefaults(defaultCASecretName string) { if s.GetCASecretName() == "" { // Note that we don't check for nil here, since even a specified, but empty // string should result in the default value. - s.CASecretName = util.String(defaultCASecretName) + s.XCASecretName = util.NewString(defaultCASecretName) } if s.GetTTL() == 0 { // Note that we don't check for nil here, since even a specified, but zero // should result in the default value. - s.TTL = util.Duration(defaultTLSTTL) + s.XTTL = util.NewDuration(defaultTLSTTL) } } // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *TLSSpec) SetDefaultsFrom(source TLSSpec) { - if s.CASecretName == nil { - s.CASecretName = util.String(source.GetCASecretName()) + if s.XCASecretName == nil { + s.XCASecretName = util.NewString(source.GetCASecretName()) } if s.AltNames == nil { - s.AltNames = source.AltNames + s.AltNames = source.GetAltNames() } - if s.TTL == nil { - s.TTL = util.Duration(source.GetTTL()) + if s.XTTL == nil { + s.XTTL = util.NewDuration(source.GetTTL()) } } diff --git a/pkg/apis/deployment/v1alpha/tls_spec_test.go b/pkg/apis/deployment/v1alpha/tls_spec_test.go index 42df9fe8e..050d38bbd 100644 --- a/pkg/apis/deployment/v1alpha/tls_spec_test.go +++ b/pkg/apis/deployment/v1alpha/tls_spec_test.go @@ -32,23 +32,23 @@ import ( func TestTLSSpecValidate(t *testing.T) { // Valid - assert.Nil(t, TLSSpec{CASecretName: util.String("foo")}.Validate()) - assert.Nil(t, TLSSpec{CASecretName: util.String("None")}.Validate()) - assert.Nil(t, TLSSpec{CASecretName: util.String("None"), AltNames: []string{}}.Validate()) - assert.Nil(t, TLSSpec{CASecretName: util.String("None"), AltNames: []string{"foo"}}.Validate()) - assert.Nil(t, TLSSpec{CASecretName: util.String("None"), AltNames: []string{"email@example.com", "127.0.0.1"}}.Validate()) + assert.Nil(t, TLSSpec{XCASecretName: util.NewString("foo")}.Validate()) + assert.Nil(t, TLSSpec{XCASecretName: util.NewString("None")}.Validate()) + assert.Nil(t, TLSSpec{XCASecretName: util.NewString("None"), AltNames: []string{}}.Validate()) + assert.Nil(t, TLSSpec{XCASecretName: util.NewString("None"), AltNames: []string{"foo"}}.Validate()) + assert.Nil(t, TLSSpec{XCASecretName: util.NewString("None"), AltNames: []string{"email@example.com", "127.0.0.1"}}.Validate()) // Not valid - assert.Error(t, TLSSpec{CASecretName: nil}.Validate()) - assert.Error(t, TLSSpec{CASecretName: util.String("")}.Validate()) - assert.Error(t, TLSSpec{CASecretName: util.String("Foo")}.Validate()) - assert.Error(t, TLSSpec{CASecretName: util.String("foo"), AltNames: []string{"@@"}}.Validate()) + assert.Error(t, TLSSpec{XCASecretName: nil}.Validate()) + assert.Error(t, TLSSpec{XCASecretName: util.NewString("")}.Validate()) + assert.Error(t, TLSSpec{XCASecretName: util.NewString("Foo")}.Validate()) + assert.Error(t, TLSSpec{XCASecretName: util.NewString("foo"), AltNames: []string{"@@"}}.Validate()) } func TestTLSSpecIsSecure(t *testing.T) { - assert.True(t, TLSSpec{CASecretName: util.String("")}.IsSecure()) - assert.True(t, TLSSpec{CASecretName: util.String("foo")}.IsSecure()) - assert.False(t, TLSSpec{CASecretName: util.String("None")}.IsSecure()) + assert.True(t, TLSSpec{XCASecretName: util.NewString("")}.IsSecure()) + assert.True(t, TLSSpec{XCASecretName: util.NewString("foo")}.IsSecure()) + assert.False(t, TLSSpec{XCASecretName: util.NewString("None")}.IsSecure()) } func TestTLSSpecSetDefaults(t *testing.T) { @@ -58,9 +58,9 @@ func TestTLSSpecSetDefaults(t *testing.T) { } assert.Equal(t, "", def(TLSSpec{}).GetCASecretName()) - assert.Equal(t, "foo", def(TLSSpec{CASecretName: util.String("foo")}).GetCASecretName()) - assert.Len(t, def(TLSSpec{}).AltNames, 0) - assert.Len(t, def(TLSSpec{AltNames: []string{"foo.local"}}).AltNames, 1) + assert.Equal(t, "foo", def(TLSSpec{XCASecretName: util.NewString("foo")}).GetCASecretName()) + assert.Len(t, def(TLSSpec{}).GetAltNames(), 0) + assert.Len(t, def(TLSSpec{AltNames: []string{"foo.local"}}).GetAltNames(), 1) assert.Equal(t, defaultTLSTTL, def(TLSSpec{}).GetTTL()) - assert.Equal(t, time.Hour, def(TLSSpec{TTL: util.Duration(time.Hour)}).GetTTL()) + assert.Equal(t, time.Hour, def(TLSSpec{XTTL: util.NewDuration(time.Hour)}).GetTTL()) } diff --git a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go index 8fd729118..697427f4c 100644 --- a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go @@ -27,6 +27,7 @@ package v1alpha import ( time "time" + core_v1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -120,8 +121,8 @@ func (in *ArangoDeploymentList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationSpec) DeepCopyInto(out *AuthenticationSpec) { *out = *in - if in.JWTSecretName != nil { - in, out := &in.JWTSecretName, &out.JWTSecretName + if in.XJWTSecretName != nil { + in, out := &in.XJWTSecretName, &out.XJWTSecretName if *in == nil { *out = nil } else { @@ -163,6 +164,51 @@ func (in *Condition) DeepCopy() *Condition { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { *out = *in + if in.XMode != nil { + in, out := &in.XMode, &out.XMode + if *in == nil { + *out = nil + } else { + *out = new(DeploymentMode) + **out = **in + } + } + if in.XEnvironment != nil { + in, out := &in.XEnvironment, &out.XEnvironment + if *in == nil { + *out = nil + } else { + *out = new(Environment) + **out = **in + } + } + if in.XStorageEngine != nil { + in, out := &in.XStorageEngine, &out.XStorageEngine + if *in == nil { + *out = nil + } else { + *out = new(StorageEngine) + **out = **in + } + } + if in.XImage != nil { + in, out := &in.XImage, &out.XImage + if *in == nil { + *out = nil + } else { + *out = new(string) + **out = **in + } + } + if in.XImagePullPolicy != nil { + in, out := &in.XImagePullPolicy, &out.XImagePullPolicy + if *in == nil { + *out = nil + } else { + *out = new(core_v1.PullPolicy) + **out = **in + } + } in.RocksDB.DeepCopyInto(&out.RocksDB) in.Authentication.DeepCopyInto(&out.Authentication) in.TLS.DeepCopyInto(&out.TLS) @@ -331,8 +377,8 @@ func (in *MemberStatus) DeepCopy() *MemberStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MonitoringSpec) DeepCopyInto(out *MonitoringSpec) { *out = *in - if in.TokenSecretName != nil { - in, out := &in.TokenSecretName, &out.TokenSecretName + if in.XTokenSecretName != nil { + in, out := &in.XTokenSecretName, &out.XTokenSecretName if *in == nil { *out = nil } else { @@ -356,8 +402,8 @@ func (in *MonitoringSpec) DeepCopy() *MonitoringSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RocksDBEncryptionSpec) DeepCopyInto(out *RocksDBEncryptionSpec) { *out = *in - if in.KeySecretName != nil { - in, out := &in.KeySecretName, &out.KeySecretName + if in.XKeySecretName != nil { + in, out := &in.XKeySecretName, &out.XKeySecretName if *in == nil { *out = nil } else { @@ -398,8 +444,8 @@ func (in *RocksDBSpec) DeepCopy() *RocksDBSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) { *out = *in - if in.Count != nil { - in, out := &in.Count, &out.Count + if in.XCount != nil { + in, out := &in.XCount, &out.XCount if *in == nil { *out = nil } else { @@ -412,8 +458,8 @@ func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) { *out = make([]string, len(*in)) copy(*out, *in) } - if in.StorageClassName != nil { - in, out := &in.StorageClassName, &out.StorageClassName + if in.XStorageClassName != nil { + in, out := &in.XStorageClassName, &out.XStorageClassName if *in == nil { *out = nil } else { @@ -438,6 +484,33 @@ func (in *ServerGroupSpec) DeepCopy() *ServerGroupSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SyncSpec) DeepCopyInto(out *SyncSpec) { *out = *in + if in.XEnabled != nil { + in, out := &in.XEnabled, &out.XEnabled + if *in == nil { + *out = nil + } else { + *out = new(bool) + **out = **in + } + } + if in.XImage != nil { + in, out := &in.XImage, &out.XImage + if *in == nil { + *out = nil + } else { + *out = new(string) + **out = **in + } + } + if in.XImagePullPolicy != nil { + in, out := &in.XImagePullPolicy, &out.XImagePullPolicy + if *in == nil { + *out = nil + } else { + *out = new(core_v1.PullPolicy) + **out = **in + } + } in.Authentication.DeepCopyInto(&out.Authentication) in.TLS.DeepCopyInto(&out.TLS) in.Monitoring.DeepCopyInto(&out.Monitoring) @@ -457,8 +530,8 @@ func (in *SyncSpec) DeepCopy() *SyncSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSSpec) DeepCopyInto(out *TLSSpec) { *out = *in - if in.CASecretName != nil { - in, out := &in.CASecretName, &out.CASecretName + if in.XCASecretName != nil { + in, out := &in.XCASecretName, &out.XCASecretName if *in == nil { *out = nil } else { @@ -471,8 +544,8 @@ func (in *TLSSpec) DeepCopyInto(out *TLSSpec) { *out = make([]string, len(*in)) copy(*out, *in) } - if in.TTL != nil { - in, out := &in.TTL, &out.TTL + if in.XTTL != nil { + in, out := &in.XTTL, &out.XTTL if *in == nil { *out = nil } else { diff --git a/pkg/deployment/images.go b/pkg/deployment/images.go index 6fbaed52e..9ce2197fe 100644 --- a/pkg/deployment/images.go +++ b/pkg/deployment/images.go @@ -81,9 +81,9 @@ func (d *Deployment) ensureImages(apiObject *api.ArangoDeployment) (bool, error) func (ib *imagesBuilder) Run(ctx context.Context) (bool, error) { result := false // Check ArangoDB image - if _, found := ib.Status.Images.GetByImage(ib.Spec.Image); !found { + if _, found := ib.Status.Images.GetByImage(ib.Spec.GetImage()); !found { // We need to find the image ID for the ArangoDB image - retrySoon, err := ib.fetchArangoDBImageIDAndVersion(ctx, ib.Spec.Image) + retrySoon, err := ib.fetchArangoDBImageIDAndVersion(ctx, ib.Spec.GetImage()) if err != nil { return retrySoon, maskAny(err) } @@ -166,7 +166,7 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, ima "--server.authentication=false", fmt.Sprintf("--server.endpoint=tcp://[::]:%d", k8sutil.ArangoPort), } - if err := k8sutil.CreateArangodPod(ib.KubeCli, true, ib.APIObject, role, id, "", image, ib.Spec.ImagePullPolicy, args, nil, nil, nil, "", ""); err != nil { + if err := k8sutil.CreateArangodPod(ib.KubeCli, true, ib.APIObject, role, id, "", image, ib.Spec.GetImagePullPolicy(), args, nil, nil, nil, "", ""); err != nil { log.Debug().Err(err).Msg("Failed to create image ID pod") return true, maskAny(err) } diff --git a/pkg/deployment/plan_builder.go b/pkg/deployment/plan_builder.go index 701f02309..ce00a391e 100644 --- a/pkg/deployment/plan_builder.go +++ b/pkg/deployment/plan_builder.go @@ -64,7 +64,7 @@ func createPlan(log zerolog.Logger, currentPlan api.Plan, spec api.DeploymentSpe var plan api.Plan // Check for scale up/down - switch spec.Mode { + switch spec.GetMode() { case api.DeploymentModeSingle: // Never scale down case api.DeploymentModeResilientSingle: diff --git a/pkg/deployment/plan_builder_test.go b/pkg/deployment/plan_builder_test.go index 161f07b08..f16e295a7 100644 --- a/pkg/deployment/plan_builder_test.go +++ b/pkg/deployment/plan_builder_test.go @@ -30,13 +30,14 @@ import ( "github.com/stretchr/testify/require" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha" + "github.com/arangodb/kube-arangodb/pkg/util" ) // TestCreatePlanSingleScale creates a `single` deployment to test the creating of scaling plan. func TestCreatePlanSingleScale(t *testing.T) { log := zerolog.Nop() spec := api.DeploymentSpec{ - Mode: api.DeploymentModeSingle, + XMode: api.NewMode(api.DeploymentModeSingle), } spec.SetDefaults("test") @@ -77,10 +78,10 @@ func TestCreatePlanSingleScale(t *testing.T) { func TestCreatePlanResilientSingleScale(t *testing.T) { log := zerolog.Nop() spec := api.DeploymentSpec{ - Mode: api.DeploymentModeResilientSingle, + XMode: api.NewMode(api.DeploymentModeResilientSingle), } spec.SetDefaults("test") - spec.Single.Count = 2 + spec.Single.XCount = util.NewInt(2) // Test with empty status var status api.DeploymentStatus @@ -135,7 +136,7 @@ func TestCreatePlanResilientSingleScale(t *testing.T) { func TestCreatePlanClusterScale(t *testing.T) { log := zerolog.Nop() spec := api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), } spec.SetDefaults("test") @@ -209,8 +210,8 @@ func TestCreatePlanClusterScale(t *testing.T) { PodName: "coordinator2", }, } - spec.DBServers.Count = 1 - spec.Coordinators.Count = 1 + spec.DBServers.XCount = util.NewInt(1) + spec.Coordinators.XCount = util.NewInt(1) newPlan, changed = createPlan(log, nil, spec, status) assert.True(t, changed) require.Len(t, newPlan, 5) // Note: Downscaling is done 1 at a time diff --git a/pkg/deployment/pod_creator.go b/pkg/deployment/pod_creator.go index fb8c0001a..305c6a5b0 100644 --- a/pkg/deployment/pod_creator.go +++ b/pkg/deployment/pod_creator.go @@ -88,7 +88,7 @@ func createArangodArgs(apiObject metav1.Object, deplSpec api.DeploymentSpec, gro // Storage engine options = append(options, - optionPair{"--server.storage-engine", string(deplSpec.StorageEngine)}, + optionPair{"--server.storage-engine", string(deplSpec.GetStorageEngine())}, ) // Logging @@ -180,7 +180,7 @@ func createArangodArgs(apiObject metav1.Object, deplSpec api.DeploymentSpec, gro optionPair{"--foxx.queues", "true"}, optionPair{"--server.statistics", "true"}, ) - if deplSpec.Mode == api.DeploymentModeResilientSingle { + if deplSpec.GetMode() == api.DeploymentModeResilientSingle { addAgentEndpoints = true options = append(options, optionPair{"--replication.automatic-failover", "true"}, @@ -314,9 +314,9 @@ func (d *Deployment) ensurePods(apiObject *api.ArangoDeployment) error { role := group.AsRole() if group.IsArangod() { // Find image ID - info, found := apiObject.Status.Images.GetByImage(apiObject.Spec.Image) + info, found := apiObject.Status.Images.GetByImage(apiObject.Spec.GetImage()) if !found { - log.Debug().Str("image", apiObject.Spec.Image).Msg("Image ID is not known yet for image") + log.Debug().Str("image", apiObject.Spec.GetImage()).Msg("Image ID is not known yet for image") return nil } // Prepare arguments @@ -355,14 +355,14 @@ func (d *Deployment) ensurePods(apiObject *api.ArangoDeployment) error { SecretKey: constants.SecretKeyJWT, } } - if err := k8sutil.CreateArangodPod(kubecli, apiObject.Spec.IsDevelopment(), apiObject, role, m.ID, m.PersistentVolumeClaimName, info.ImageID, apiObject.Spec.ImagePullPolicy, args, env, livenessProbe, readinessProbe, tlsKeyfileSecretName, rocksdbEncryptionSecretName); err != nil { + if err := k8sutil.CreateArangodPod(kubecli, apiObject.Spec.IsDevelopment(), apiObject, role, m.ID, m.PersistentVolumeClaimName, info.ImageID, apiObject.Spec.GetImagePullPolicy(), args, env, livenessProbe, readinessProbe, tlsKeyfileSecretName, rocksdbEncryptionSecretName); err != nil { return maskAny(err) } } else if group.IsArangosync() { // Find image ID - info, found := apiObject.Status.Images.GetByImage(apiObject.Spec.Sync.Image) + info, found := apiObject.Status.Images.GetByImage(apiObject.Spec.Sync.GetImage()) if !found { - log.Debug().Str("image", apiObject.Spec.Sync.Image).Msg("Image ID is not known yet for image") + log.Debug().Str("image", apiObject.Spec.Sync.GetImage()).Msg("Image ID is not known yet for image") return nil } // Prepare arguments @@ -376,7 +376,7 @@ func (d *Deployment) ensurePods(apiObject *api.ArangoDeployment) error { if group == api.ServerGroupSyncWorkers { affinityWithRole = api.ServerGroupDBServers.AsRole() } - if err := k8sutil.CreateArangoSyncPod(kubecli, apiObject.Spec.IsDevelopment(), apiObject, role, m.ID, info.ImageID, apiObject.Spec.Sync.ImagePullPolicy, args, env, livenessProbe, affinityWithRole); err != nil { + if err := k8sutil.CreateArangoSyncPod(kubecli, apiObject.Spec.IsDevelopment(), apiObject, role, m.ID, info.ImageID, apiObject.Spec.Sync.GetImagePullPolicy(), args, env, livenessProbe, affinityWithRole); err != nil { return maskAny(err) } } diff --git a/pkg/deployment/pod_creator_agent_args_test.go b/pkg/deployment/pod_creator_agent_args_test.go index 540690d7f..97562121b 100644 --- a/pkg/deployment/pod_creator_agent_args_test.go +++ b/pkg/deployment/pod_creator_agent_args_test.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha" + "github.com/arangodb/kube-arangodb/pkg/util" ) // TestCreateArangodArgsAgent tests createArangodArgs for agent. @@ -41,7 +42,7 @@ func TestCreateArangodArgsAgent(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") @@ -84,9 +85,9 @@ func TestCreateArangodArgsAgent(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), TLS: api.TLSSpec{ - CASecretName: "None", + XCASecretName: util.NewString("None"), }, }, } @@ -128,12 +129,12 @@ func TestCreateArangodArgsAgent(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") - apiObject.Spec.Authentication.JWTSecretName = "None" - apiObject.Spec.StorageEngine = api.StorageEngineMMFiles + apiObject.Spec.Authentication.XJWTSecretName = util.NewString("None") + apiObject.Spec.XStorageEngine = api.NewStorageEngine(api.StorageEngineMMFiles) agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, api.MemberStatus{ID: "a2"}, @@ -172,7 +173,7 @@ func TestCreateArangodArgsAgent(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") diff --git a/pkg/deployment/pod_creator_coordinator_args_test.go b/pkg/deployment/pod_creator_coordinator_args_test.go index cdf3afdca..9995b95d7 100644 --- a/pkg/deployment/pod_creator_coordinator_args_test.go +++ b/pkg/deployment/pod_creator_coordinator_args_test.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha" + "github.com/arangodb/kube-arangodb/pkg/util" ) // TestCreateArangodArgsCoordinator tests createArangodArgs for coordinator. @@ -41,7 +42,7 @@ func TestCreateArangodArgsCoordinator(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") @@ -83,9 +84,9 @@ func TestCreateArangodArgsCoordinator(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), TLS: api.TLSSpec{ - CASecretName: "None", + XCASecretName: util.NewString("None"), }, }, } @@ -126,11 +127,11 @@ func TestCreateArangodArgsCoordinator(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") - apiObject.Spec.Authentication.JWTSecretName = "None" + apiObject.Spec.Authentication.XJWTSecretName = util.NewString("None") agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, api.MemberStatus{ID: "a2"}, @@ -168,12 +169,12 @@ func TestCreateArangodArgsCoordinator(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") apiObject.Spec.Coordinators.Args = []string{"--foo1", "--foo2"} - apiObject.Spec.StorageEngine = api.StorageEngineMMFiles + apiObject.Spec.XStorageEngine = api.NewStorageEngine(api.StorageEngineMMFiles) agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, api.MemberStatus{ID: "a2"}, diff --git a/pkg/deployment/pod_creator_dbserver_args_test.go b/pkg/deployment/pod_creator_dbserver_args_test.go index ac14f07a3..6b2c654f0 100644 --- a/pkg/deployment/pod_creator_dbserver_args_test.go +++ b/pkg/deployment/pod_creator_dbserver_args_test.go @@ -29,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha" + "github.com/arangodb/kube-arangodb/pkg/util" ) // TestCreateArangodArgsDBServer tests createArangodArgs for dbserver. @@ -41,7 +42,7 @@ func TestCreateArangodArgsDBServer(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") @@ -83,9 +84,9 @@ func TestCreateArangodArgsDBServer(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), TLS: api.TLSSpec{ - CASecretName: "None", + XCASecretName: util.NewString("None"), }, }, } @@ -126,11 +127,11 @@ func TestCreateArangodArgsDBServer(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") - apiObject.Spec.Authentication.JWTSecretName = "None" + apiObject.Spec.Authentication.XJWTSecretName = util.NewString("None") agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, api.MemberStatus{ID: "a2"}, @@ -168,11 +169,11 @@ func TestCreateArangodArgsDBServer(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") - apiObject.Spec.StorageEngine = api.StorageEngineMMFiles + apiObject.Spec.XStorageEngine = api.NewStorageEngine(api.StorageEngineMMFiles) apiObject.Spec.DBServers.Args = []string{"--foo1", "--foo2"} agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, diff --git a/pkg/deployment/pod_creator_single_args_test.go b/pkg/deployment/pod_creator_single_args_test.go index be3f8674c..481226fb7 100644 --- a/pkg/deployment/pod_creator_single_args_test.go +++ b/pkg/deployment/pod_creator_single_args_test.go @@ -28,6 +28,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/stretchr/testify/assert" ) @@ -37,7 +38,7 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeSingle, + XMode: api.NewMode(api.DeploymentModeSingle), }, } apiObject.Spec.SetDefaults("test") @@ -64,9 +65,9 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeSingle, + XMode: api.NewMode(api.DeploymentModeSingle), TLS: api.TLSSpec{ - CASecretName: "None", + XCASecretName: util.NewString("None"), }, }, } @@ -92,8 +93,8 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeSingle, - StorageEngine: api.StorageEngineMMFiles, + XMode: api.NewMode(api.DeploymentModeSingle), + XStorageEngine: api.NewStorageEngine(api.StorageEngineMMFiles), }, } apiObject.Spec.SetDefaults("test") @@ -120,10 +121,10 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeSingle, + XMode: api.NewMode(api.DeploymentModeSingle), }, } - apiObject.Spec.Authentication.JWTSecretName = "None" + apiObject.Spec.Authentication.XJWTSecretName = util.NewString("None") apiObject.Spec.SetDefaults("test") cmdline := createArangodArgs(apiObject, apiObject.Spec, api.ServerGroupSingle, apiObject.Spec.Single, nil, "id1") assert.Equal(t, @@ -147,7 +148,7 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeSingle, + XMode: api.NewMode(api.DeploymentModeSingle), }, } apiObject.Spec.Single.Args = []string{"--foo1", "--foo2"} @@ -181,7 +182,7 @@ func TestCreateArangodArgsSingle(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeResilientSingle, + XMode: api.NewMode(api.DeploymentModeResilientSingle), }, } apiObject.Spec.SetDefaults("test") diff --git a/pkg/deployment/secrets.go b/pkg/deployment/secrets.go index df38012b5..83407571c 100644 --- a/pkg/deployment/secrets.go +++ b/pkg/deployment/secrets.go @@ -45,7 +45,7 @@ func (d *Deployment) createSecrets(apiObject *api.ArangoDeployment) error { return maskAny(err) } } - if apiObject.Spec.Sync.Enabled { + if apiObject.Spec.Sync.IsEnabled() { if err := d.ensureCACertificateSecret(apiObject.Spec.Sync.TLS); err != nil { return maskAny(err) } diff --git a/pkg/deployment/services.go b/pkg/deployment/services.go index 7ea58c87a..6063dcb6d 100644 --- a/pkg/deployment/services.go +++ b/pkg/deployment/services.go @@ -39,7 +39,7 @@ func (d *Deployment) createServices(apiObject *api.ArangoDeployment) error { log.Debug().Err(err).Msg("Failed to create headless service") return maskAny(err) } - single := apiObject.Spec.Mode.HasSingleServers() + single := apiObject.Spec.GetMode().HasSingleServers() if svcName, err := k8sutil.CreateDatabaseClientService(kubecli, apiObject, single, owner); err != nil { log.Debug().Err(err).Msg("Failed to create database client service") return maskAny(err) @@ -49,7 +49,7 @@ func (d *Deployment) createServices(apiObject *api.ArangoDeployment) error { return maskAny(err) } } - if apiObject.Spec.Sync.Enabled { + if apiObject.Spec.Sync.IsEnabled() { if svcName, err := k8sutil.CreateSyncMasterClientService(kubecli, apiObject, owner); err != nil { log.Debug().Err(err).Msg("Failed to create syncmaster client service") return maskAny(err) diff --git a/pkg/util/k8sutil/test/events_test.go b/pkg/util/k8sutil/test/events_test.go index 813161013..c05563ca5 100644 --- a/pkg/util/k8sutil/test/events_test.go +++ b/pkg/util/k8sutil/test/events_test.go @@ -41,7 +41,7 @@ var apiObjectForTest = api.ArangoDeployment{ Namespace: "Wonka", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + XMode: api.NewMode(api.DeploymentModeCluster), }, } diff --git a/pkg/util/refs.go b/pkg/util/refs.go index b838e8235..e0ab792fa 100644 --- a/pkg/util/refs.go +++ b/pkg/util/refs.go @@ -22,56 +22,128 @@ package util -import "time" +import ( + "time" -// String returns a reference to a string with given value. -func String(input string) *string { + "k8s.io/api/core/v1" +) + +// NewString returns a reference to a string with given value. +func NewString(input string) *string { return &input } -// StringOrNil returns nil if input is nil, otherwise returns a clone of the given value. -func StringOrNil(input *string) *string { +// NewStringOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func NewStringOrNil(input *string) *string { if input == nil { return nil } - return String(*input) + return NewString(*input) +} + +// StringOrDefault returns the default value (or empty string) if input is nil, otherwise returns the referenced value. +func StringOrDefault(input *string, defaultValue ...string) string { + if input == nil { + if len(defaultValue) > 0 { + return defaultValue[0] + } + return "" + } + return *input } -// Int returns a reference to an int with given value. -func Int(input int) *int { +// NewInt returns a reference to an int with given value. +func NewInt(input int) *int { return &input } -// IntOrNil returns nil if input is nil, otherwise returns a clone of the given value. -func IntOrNil(input *int) *int { +// NewIntOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func NewIntOrNil(input *int) *int { if input == nil { return nil } - return Int(*input) + return NewInt(*input) } -// Bool returns a reference to a bool with given value. -func Bool(input bool) *bool { +// IntOrDefault returns the default value (or 0) if input is nil, otherwise returns the referenced value. +func IntOrDefault(input *int, defaultValue ...int) int { + if input == nil { + if len(defaultValue) > 0 { + return defaultValue[0] + } + return 0 + } + return *input +} + +// NewBool returns a reference to a bool with given value. +func NewBool(input bool) *bool { return &input } -// BoolOrNil returns nil if input is nil, otherwise returns a clone of the given value. -func BoolOrNil(input *bool) *bool { +// NewBoolOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func NewBoolOrNil(input *bool) *bool { if input == nil { return nil } - return Bool(*input) + return NewBool(*input) } -// Duration returns a reference to a duration with given value. -func Duration(input time.Duration) *time.Duration { +// BoolOrDefault returns the default value (or false) if input is nil, otherwise returns the referenced value. +func BoolOrDefault(input *bool, defaultValue ...bool) bool { + if input == nil { + if len(defaultValue) > 0 { + return defaultValue[0] + } + return false + } + return *input +} + +// NewDuration returns a reference to a duration with given value. +func NewDuration(input time.Duration) *time.Duration { return &input } -// DurationOrNil returns nil if input is nil, otherwise returns a clone of the given value. -func DurationOrNil(input *time.Duration) *time.Duration { +// NewDurationOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func NewDurationOrNil(input *time.Duration) *time.Duration { if input == nil { return nil } - return Duration(*input) + return NewDuration(*input) +} + +// DurationOrDefault returns the default value (or 0) if input is nil, otherwise returns the referenced value. +func DurationOrDefault(input *time.Duration, defaultValue ...time.Duration) time.Duration { + if input == nil { + if len(defaultValue) > 0 { + return defaultValue[0] + } + return 0 + } + return *input +} + +// NewPullPolicy returns a reference to a pull policy with given value. +func NewPullPolicy(input v1.PullPolicy) *v1.PullPolicy { + return &input +} + +// NewPullPolicyOrNil returns nil if input is nil, otherwise returns a clone of the given value. +func NewPullPolicyOrNil(input *v1.PullPolicy) *v1.PullPolicy { + if input == nil { + return nil + } + return NewPullPolicy(*input) +} + +// PullPolicyOrDefault returns the default value (or 0) if input is nil, otherwise returns the referenced value. +func PullPolicyOrDefault(input *v1.PullPolicy, defaultValue ...v1.PullPolicy) v1.PullPolicy { + if input == nil { + if len(defaultValue) > 0 { + return defaultValue[0] + } + return "" + } + return *input } From 15e3f7518f5482aed706fee12c03ab9fda266705 Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Fri, 23 Mar 2018 09:53:42 +0100 Subject: [PATCH 4/8] Merged in master --- .../deployment/v1alpha/authentication_spec.go | 12 +-- .../v1alpha/authentication_spec_test.go | 46 +++++----- .../deployment/v1alpha/deployment_spec.go | 54 ++++++------ .../v1alpha/deployment_spec_test.go | 18 ++-- .../deployment/v1alpha/monitoring_spec.go | 8 +- .../v1alpha/monitoring_spec_test.go | 12 +-- .../deployment/v1alpha/server_group_spec.go | 26 +++--- .../v1alpha/server_group_spec_test.go | 74 ++++++++-------- pkg/apis/deployment/v1alpha/sync_spec.go | 32 +++---- pkg/apis/deployment/v1alpha/sync_spec_test.go | 86 +++++++++---------- pkg/apis/deployment/v1alpha/tls_spec.go | 24 +++--- pkg/apis/deployment/v1alpha/tls_spec_test.go | 28 +++--- .../v1alpha/zz_generated.deepcopy.go | 56 ++++++------ pkg/deployment/plan_builder_test.go | 14 +-- pkg/deployment/pod_creator_agent_args_test.go | 16 ++-- .../pod_creator_coordinator_args_test.go | 16 ++-- .../pod_creator_dbserver_args_test.go | 16 ++-- .../pod_creator_single_args_test.go | 20 ++--- 18 files changed, 277 insertions(+), 281 deletions(-) diff --git a/pkg/apis/deployment/v1alpha/authentication_spec.go b/pkg/apis/deployment/v1alpha/authentication_spec.go index 8fc6727a8..c6e5bcbac 100644 --- a/pkg/apis/deployment/v1alpha/authentication_spec.go +++ b/pkg/apis/deployment/v1alpha/authentication_spec.go @@ -31,7 +31,7 @@ import ( // AuthenticationSpec holds authentication specific configuration settings type AuthenticationSpec struct { - XJWTSecretName *string `json:"jwtSecretName,omitempty"` + JWTSecretName *string `json:"jwtSecretName,omitempty"` } const ( @@ -41,7 +41,7 @@ const ( // GetJWTSecretName returns the value of jwtSecretName. func (s AuthenticationSpec) GetJWTSecretName() string { - return util.StringOrDefault(s.XJWTSecretName) + return util.StringOrDefault(s.JWTSecretName) } // IsAuthenticated returns true if authentication is enabled. @@ -68,14 +68,14 @@ func (s *AuthenticationSpec) SetDefaults(defaultJWTSecretName string) { if s.GetJWTSecretName() == "" { // Note that we don't check for nil here, since even a specified, but empty // string should result in the default value. - s.XJWTSecretName = util.NewString(defaultJWTSecretName) + s.JWTSecretName = util.NewString(defaultJWTSecretName) } } // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *AuthenticationSpec) SetDefaultsFrom(source AuthenticationSpec) { - if s.XJWTSecretName == nil { - s.XJWTSecretName = util.NewString(source.GetJWTSecretName()) + if s.JWTSecretName == nil { + s.JWTSecretName = util.NewStringOrNil(source.JWTSecretName) } } @@ -86,7 +86,7 @@ func (s AuthenticationSpec) ResetImmutableFields(fieldPrefix string, target *Aut var resetFields []string if s.IsAuthenticated() != target.IsAuthenticated() { // Note: You can change the name, but not from empty to non-empty (or reverse). - target.XJWTSecretName = util.NewStringOrNil(s.XJWTSecretName) + target.JWTSecretName = util.NewStringOrNil(s.JWTSecretName) resetFields = append(resetFields, fieldPrefix+".jwtSecretName") } return resetFields diff --git a/pkg/apis/deployment/v1alpha/authentication_spec_test.go b/pkg/apis/deployment/v1alpha/authentication_spec_test.go index b8cdd810f..0c00354db 100644 --- a/pkg/apis/deployment/v1alpha/authentication_spec_test.go +++ b/pkg/apis/deployment/v1alpha/authentication_spec_test.go @@ -31,18 +31,18 @@ import ( func TestAuthenticationSpecValidate(t *testing.T) { // Valid - assert.Nil(t, AuthenticationSpec{XJWTSecretName: util.NewString("None")}.Validate(false)) - assert.Nil(t, AuthenticationSpec{XJWTSecretName: util.NewString("foo")}.Validate(false)) - assert.Nil(t, AuthenticationSpec{XJWTSecretName: util.NewString("foo")}.Validate(true)) + assert.Nil(t, AuthenticationSpec{JWTSecretName: util.NewString("None")}.Validate(false)) + assert.Nil(t, AuthenticationSpec{JWTSecretName: util.NewString("foo")}.Validate(false)) + assert.Nil(t, AuthenticationSpec{JWTSecretName: util.NewString("foo")}.Validate(true)) // Not valid - assert.Error(t, AuthenticationSpec{XJWTSecretName: util.NewString("Foo")}.Validate(false)) + assert.Error(t, AuthenticationSpec{JWTSecretName: util.NewString("Foo")}.Validate(false)) } func TestAuthenticationSpecIsAuthenticated(t *testing.T) { - assert.False(t, AuthenticationSpec{XJWTSecretName: util.NewString("None")}.IsAuthenticated()) - assert.True(t, AuthenticationSpec{XJWTSecretName: util.NewString("foo")}.IsAuthenticated()) - assert.True(t, AuthenticationSpec{XJWTSecretName: util.NewString("")}.IsAuthenticated()) + assert.False(t, AuthenticationSpec{JWTSecretName: util.NewString("None")}.IsAuthenticated()) + assert.True(t, AuthenticationSpec{JWTSecretName: util.NewString("foo")}.IsAuthenticated()) + assert.True(t, AuthenticationSpec{JWTSecretName: util.NewString("")}.IsAuthenticated()) } func TestAuthenticationSpecSetDefaults(t *testing.T) { @@ -52,7 +52,7 @@ func TestAuthenticationSpecSetDefaults(t *testing.T) { } assert.Equal(t, "test-jwt", def(AuthenticationSpec{}).GetJWTSecretName()) - assert.Equal(t, "foo", def(AuthenticationSpec{XJWTSecretName: util.NewString("foo")}).GetJWTSecretName()) + assert.Equal(t, "foo", def(AuthenticationSpec{JWTSecretName: util.NewString("foo")}).GetJWTSecretName()) } func TestAuthenticationSpecResetImmutableFields(t *testing.T) { @@ -64,35 +64,35 @@ func TestAuthenticationSpecResetImmutableFields(t *testing.T) { }{ // Valid "changes" { - AuthenticationSpec{XJWTSecretName: util.NewString("None")}, - AuthenticationSpec{XJWTSecretName: util.NewString("None")}, - AuthenticationSpec{XJWTSecretName: util.NewString("None")}, + AuthenticationSpec{JWTSecretName: util.NewString("None")}, + AuthenticationSpec{JWTSecretName: util.NewString("None")}, + AuthenticationSpec{JWTSecretName: util.NewString("None")}, nil, }, { - AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, - AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, - AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, + AuthenticationSpec{JWTSecretName: util.NewString("foo")}, + AuthenticationSpec{JWTSecretName: util.NewString("foo")}, + AuthenticationSpec{JWTSecretName: util.NewString("foo")}, nil, }, { - AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, - AuthenticationSpec{XJWTSecretName: util.NewString("foo2")}, - AuthenticationSpec{XJWTSecretName: util.NewString("foo2")}, + AuthenticationSpec{JWTSecretName: util.NewString("foo")}, + AuthenticationSpec{JWTSecretName: util.NewString("foo2")}, + AuthenticationSpec{JWTSecretName: util.NewString("foo2")}, nil, }, // Invalid changes { - AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, - AuthenticationSpec{XJWTSecretName: util.NewString("None")}, - AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, + AuthenticationSpec{JWTSecretName: util.NewString("foo")}, + AuthenticationSpec{JWTSecretName: util.NewString("None")}, + AuthenticationSpec{JWTSecretName: util.NewString("foo")}, []string{"test.jwtSecretName"}, }, { - AuthenticationSpec{XJWTSecretName: util.NewString("None")}, - AuthenticationSpec{XJWTSecretName: util.NewString("foo")}, - AuthenticationSpec{XJWTSecretName: util.NewString("None")}, + AuthenticationSpec{JWTSecretName: util.NewString("None")}, + AuthenticationSpec{JWTSecretName: util.NewString("foo")}, + AuthenticationSpec{JWTSecretName: util.NewString("None")}, []string{"test.jwtSecretName"}, }, } diff --git a/pkg/apis/deployment/v1alpha/deployment_spec.go b/pkg/apis/deployment/v1alpha/deployment_spec.go index 59c4f9e5c..5954719bc 100644 --- a/pkg/apis/deployment/v1alpha/deployment_spec.go +++ b/pkg/apis/deployment/v1alpha/deployment_spec.go @@ -45,11 +45,11 @@ func validatePullPolicy(v v1.PullPolicy) error { // DeploymentSpec contains the spec part of a ArangoDeployment resource. type DeploymentSpec struct { - XMode *DeploymentMode `json:"mode,omitempty"` - XEnvironment *Environment `json:"environment,omitempty"` - XStorageEngine *StorageEngine `json:"storageEngine,omitempty"` - XImage *string `json:"image,omitempty"` - XImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"` + Mode *DeploymentMode `json:"mode,omitempty"` + Environment *Environment `json:"environment,omitempty"` + StorageEngine *StorageEngine `json:"storageEngine,omitempty"` + Image *string `json:"image,omitempty"` + ImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"` RocksDB RocksDBSpec `json:"rocksdb"` Authentication AuthenticationSpec `json:"auth"` @@ -66,27 +66,27 @@ type DeploymentSpec struct { // GetMode returns the value of mode. func (s DeploymentSpec) GetMode() DeploymentMode { - return ModeOrDefault(s.XMode) + return ModeOrDefault(s.Mode) } // GetEnvironment returns the value of environment. func (s DeploymentSpec) GetEnvironment() Environment { - return EnvironmentOrDefault(s.XEnvironment) + return EnvironmentOrDefault(s.Environment) } // GetStorageEngine returns the value of storageEngine. func (s DeploymentSpec) GetStorageEngine() StorageEngine { - return StorageEngineOrDefault(s.XStorageEngine) + return StorageEngineOrDefault(s.StorageEngine) } // GetImage returns the value of image. func (s DeploymentSpec) GetImage() string { - return util.StringOrDefault(s.XImage) + return util.StringOrDefault(s.Image) } // GetImagePullPolicy returns the value of imagePullPolicy. func (s DeploymentSpec) GetImagePullPolicy() v1.PullPolicy { - return util.PullPolicyOrDefault(s.XImagePullPolicy) + return util.PullPolicyOrDefault(s.ImagePullPolicy) } // IsAuthenticated returns true when authentication is enabled @@ -123,19 +123,19 @@ func (s DeploymentSpec) GetServerGroupSpec(group ServerGroup) ServerGroupSpec { // SetDefaults fills in default values when a field is not specified. func (s *DeploymentSpec) SetDefaults(deploymentName string) { if s.GetMode() == "" { - s.XMode = NewMode(DeploymentModeCluster) + s.Mode = NewMode(DeploymentModeCluster) } if s.GetEnvironment() == "" { - s.XEnvironment = NewEnvironment(EnvironmentDevelopment) + s.Environment = NewEnvironment(EnvironmentDevelopment) } if s.GetStorageEngine() == "" { - s.XStorageEngine = NewStorageEngine(StorageEngineRocksDB) + s.StorageEngine = NewStorageEngine(StorageEngineRocksDB) } if s.GetImage() == "" && s.IsDevelopment() { - s.XImage = util.NewString(defaultImage) + s.Image = util.NewString(defaultImage) } if s.GetImagePullPolicy() == "" { - s.XImagePullPolicy = util.NewPullPolicy(v1.PullIfNotPresent) + s.ImagePullPolicy = util.NewPullPolicy(v1.PullIfNotPresent) } s.RocksDB.SetDefaults() s.Authentication.SetDefaults(deploymentName + "-jwt") @@ -151,20 +151,20 @@ func (s *DeploymentSpec) SetDefaults(deploymentName string) { // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *DeploymentSpec) SetDefaultsFrom(source DeploymentSpec) { - if s.XMode == nil { - s.XMode = NewModeOrNil(source.XMode) + if s.Mode == nil { + s.Mode = NewModeOrNil(source.Mode) } - if s.XEnvironment == nil { - s.XEnvironment = NewEnvironmentOrNil(source.XEnvironment) + if s.Environment == nil { + s.Environment = NewEnvironmentOrNil(source.Environment) } - if s.XStorageEngine == nil { - s.XStorageEngine = NewStorageEngineOrNil(source.XStorageEngine) + if s.StorageEngine == nil { + s.StorageEngine = NewStorageEngineOrNil(source.StorageEngine) } - if s.XImage == nil { - s.XImage = util.NewStringOrNil(source.XImage) + if s.Image == nil { + s.Image = util.NewStringOrNil(source.Image) } - if s.XImagePullPolicy == nil { - s.XImagePullPolicy = util.NewPullPolicyOrNil(source.XImagePullPolicy) + if s.ImagePullPolicy == nil { + s.ImagePullPolicy = util.NewPullPolicyOrNil(source.ImagePullPolicy) } s.RocksDB.SetDefaultsFrom(source.RocksDB) s.Authentication.SetDefaultsFrom(source.Authentication) @@ -240,11 +240,11 @@ func (s DeploymentSpec) IsDevelopment() bool { func (s DeploymentSpec) ResetImmutableFields(target *DeploymentSpec) []string { var resetFields []string if s.GetMode() != target.GetMode() { - target.XMode = NewModeOrNil(s.XMode) + target.Mode = NewModeOrNil(s.Mode) resetFields = append(resetFields, "mode") } if s.GetStorageEngine() != target.GetStorageEngine() { - target.XStorageEngine = NewStorageEngineOrNil(s.XStorageEngine) + target.StorageEngine = NewStorageEngineOrNil(s.StorageEngine) resetFields = append(resetFields, "storageEngine") } if l := s.RocksDB.ResetImmutableFields("rocksdb", &target.RocksDB); l != nil { diff --git a/pkg/apis/deployment/v1alpha/deployment_spec_test.go b/pkg/apis/deployment/v1alpha/deployment_spec_test.go index 8e4c1010d..430e48c65 100644 --- a/pkg/apis/deployment/v1alpha/deployment_spec_test.go +++ b/pkg/apis/deployment/v1alpha/deployment_spec_test.go @@ -52,23 +52,23 @@ func TestDeploymentSpecResetImmutableFields(t *testing.T) { }{ // Valid "changes" { - DeploymentSpec{XImage: util.NewString("foo")}, - DeploymentSpec{XImage: util.NewString("foo2")}, - DeploymentSpec{XImage: util.NewString("foo2")}, + DeploymentSpec{Image: util.NewString("foo")}, + DeploymentSpec{Image: util.NewString("foo2")}, + DeploymentSpec{Image: util.NewString("foo2")}, nil, }, { - DeploymentSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullAlways)}, - DeploymentSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, - DeploymentSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, + DeploymentSpec{ImagePullPolicy: util.NewPullPolicy(v1.PullAlways)}, + DeploymentSpec{ImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, + DeploymentSpec{ImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, nil, }, // Invalid changes { - DeploymentSpec{XMode: NewMode(DeploymentModeSingle)}, - DeploymentSpec{XMode: NewMode(DeploymentModeCluster)}, - DeploymentSpec{XMode: NewMode(DeploymentModeSingle)}, + DeploymentSpec{Mode: NewMode(DeploymentModeSingle)}, + DeploymentSpec{Mode: NewMode(DeploymentModeCluster)}, + DeploymentSpec{Mode: NewMode(DeploymentModeSingle)}, []string{"mode"}, }, } diff --git a/pkg/apis/deployment/v1alpha/monitoring_spec.go b/pkg/apis/deployment/v1alpha/monitoring_spec.go index 1e8bd8b5d..719468cd7 100644 --- a/pkg/apis/deployment/v1alpha/monitoring_spec.go +++ b/pkg/apis/deployment/v1alpha/monitoring_spec.go @@ -29,12 +29,12 @@ import ( // MonitoringSpec holds monitoring specific configuration settings type MonitoringSpec struct { - XTokenSecretName *string `json:"tokenSecretName,omitempty"` + TokenSecretName *string `json:"tokenSecretName,omitempty"` } // GetTokenSecretName returns the value of tokenSecretName. func (s MonitoringSpec) GetTokenSecretName() string { - return util.StringOrDefault(s.XTokenSecretName) + return util.StringOrDefault(s.TokenSecretName) } // Validate the given spec @@ -52,7 +52,7 @@ func (s *MonitoringSpec) SetDefaults() { // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *MonitoringSpec) SetDefaultsFrom(source MonitoringSpec) { - if s.XTokenSecretName == nil { - s.XTokenSecretName = util.NewStringOrNil(source.XTokenSecretName) + if s.TokenSecretName == nil { + s.TokenSecretName = util.NewStringOrNil(source.TokenSecretName) } } diff --git a/pkg/apis/deployment/v1alpha/monitoring_spec_test.go b/pkg/apis/deployment/v1alpha/monitoring_spec_test.go index 8ea215bc3..8ece949d0 100644 --- a/pkg/apis/deployment/v1alpha/monitoring_spec_test.go +++ b/pkg/apis/deployment/v1alpha/monitoring_spec_test.go @@ -31,13 +31,13 @@ import ( func TestMonitoringSpecValidate(t *testing.T) { // Valid - assert.Nil(t, MonitoringSpec{XTokenSecretName: nil}.Validate()) - assert.Nil(t, MonitoringSpec{XTokenSecretName: util.NewString("")}.Validate()) - assert.Nil(t, MonitoringSpec{XTokenSecretName: util.NewString("foo")}.Validate()) - assert.Nil(t, MonitoringSpec{XTokenSecretName: util.NewString("foo")}.Validate()) + assert.Nil(t, MonitoringSpec{TokenSecretName: nil}.Validate()) + assert.Nil(t, MonitoringSpec{TokenSecretName: util.NewString("")}.Validate()) + assert.Nil(t, MonitoringSpec{TokenSecretName: util.NewString("foo")}.Validate()) + assert.Nil(t, MonitoringSpec{TokenSecretName: util.NewString("foo")}.Validate()) // Not valid - assert.Error(t, MonitoringSpec{XTokenSecretName: util.NewString("Foo")}.Validate()) + assert.Error(t, MonitoringSpec{TokenSecretName: util.NewString("Foo")}.Validate()) } func TestMonitoringSpecSetDefaults(t *testing.T) { @@ -47,5 +47,5 @@ func TestMonitoringSpecSetDefaults(t *testing.T) { } assert.Equal(t, "", def(MonitoringSpec{}).GetTokenSecretName()) - assert.Equal(t, "foo", def(MonitoringSpec{XTokenSecretName: util.NewString("foo")}).GetTokenSecretName()) + assert.Equal(t, "foo", def(MonitoringSpec{TokenSecretName: util.NewString("foo")}).GetTokenSecretName()) } diff --git a/pkg/apis/deployment/v1alpha/server_group_spec.go b/pkg/apis/deployment/v1alpha/server_group_spec.go index 0a8b712d2..f73bc3788 100644 --- a/pkg/apis/deployment/v1alpha/server_group_spec.go +++ b/pkg/apis/deployment/v1alpha/server_group_spec.go @@ -33,18 +33,18 @@ import ( // ServerGroupSpec contains the specification for all servers in a specific group (e.g. all agents) type ServerGroupSpec struct { // Count holds the requested number of servers - XCount *int `json:"count,omitempty"` + Count *int `json:"count,omitempty"` // Args holds additional commandline arguments Args []string `json:"args,omitempty"` // StorageClassName specifies the classname for storage of the servers. - XStorageClassName *string `json:"storageClassName,omitempty"` + StorageClassName *string `json:"storageClassName,omitempty"` // Resources holds resource requests & limits Resources v1.ResourceRequirements `json:"resources,omitempty"` } // GetCount returns the value of count. func (s ServerGroupSpec) GetCount() int { - return util.IntOrDefault(s.XCount) + return util.IntOrDefault(s.Count) } // GetArgs returns the value of args. @@ -54,7 +54,7 @@ func (s ServerGroupSpec) GetArgs() []string { // GetStorageClassName returns the value of storageClassName. func (s ServerGroupSpec) GetStorageClassName() string { - return util.StringOrDefault(s.XStorageClassName) + return util.StringOrDefault(s.StorageClassName) } // Validate the given group spec @@ -91,12 +91,12 @@ func (s *ServerGroupSpec) SetDefaults(group ServerGroup, used bool, mode Deploym switch group { case ServerGroupSingle: if mode == DeploymentModeSingle { - s.XCount = util.NewInt(1) // Single server + s.Count = util.NewInt(1) // Single server } else { - s.XCount = util.NewInt(2) // Resilient single + s.Count = util.NewInt(2) // Resilient single } default: - s.XCount = util.NewInt(3) + s.Count = util.NewInt(3) } } if _, found := s.Resources.Requests[v1.ResourceStorage]; !found { @@ -124,14 +124,14 @@ func setDefaultsFromResourceList(s *v1.ResourceList, source v1.ResourceList) { // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *ServerGroupSpec) SetDefaultsFrom(source ServerGroupSpec) { - if s.XCount == nil { - s.XCount = util.NewIntOrNil(source.XCount) + if s.Count == nil { + s.Count = util.NewIntOrNil(source.Count) } if s.Args == nil { s.Args = source.Args } - if s.XStorageClassName == nil { - s.XStorageClassName = util.NewStringOrNil(source.XStorageClassName) + if s.StorageClassName == nil { + s.StorageClassName = util.NewStringOrNil(source.StorageClassName) } setDefaultsFromResourceList(&s.Resources.Limits, source.Resources.Limits) setDefaultsFromResourceList(&s.Resources.Requests, source.Resources.Requests) @@ -143,12 +143,12 @@ func (s ServerGroupSpec) ResetImmutableFields(group ServerGroup, fieldPrefix str var resetFields []string if group == ServerGroupAgents { if s.GetCount() != target.GetCount() { - target.XCount = util.NewIntOrNil(s.XCount) + target.Count = util.NewIntOrNil(s.Count) resetFields = append(resetFields, fieldPrefix+".count") } } if s.GetStorageClassName() != target.GetStorageClassName() { - target.XStorageClassName = util.NewStringOrNil(s.XStorageClassName) + target.StorageClassName = util.NewStringOrNil(s.StorageClassName) resetFields = append(resetFields, fieldPrefix+".storageClassName") } return resetFields diff --git a/pkg/apis/deployment/v1alpha/server_group_spec_test.go b/pkg/apis/deployment/v1alpha/server_group_spec_test.go index fcd173c9f..53134094e 100644 --- a/pkg/apis/deployment/v1alpha/server_group_spec_test.go +++ b/pkg/apis/deployment/v1alpha/server_group_spec_test.go @@ -31,45 +31,45 @@ import ( func TestServerGroupSpecValidateCount(t *testing.T) { // Valid - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupSingle, false, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(6)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Nil(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(0)}.Validate(ServerGroupSingle, false, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(6)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(3)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) // Invalid - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSingle, false, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSingle, true, DeploymentModeResilientSingle, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(0)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(-1)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentDevelopment)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(2)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) - assert.Error(t, ServerGroupSpec{XCount: util.NewInt(1)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupSingle, false, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupSingle, true, DeploymentModeSingle, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupSingle, true, DeploymentModeResilientSingle, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(0)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(0)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(0)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(0)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(0)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(0)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(-1)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(-1)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(-1)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(-1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(-1)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(-1)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentDevelopment)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupAgents, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(2)}.Validate(ServerGroupAgents, true, DeploymentModeResilientSingle, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupDBServers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Error(t, ServerGroupSpec{Count: util.NewInt(1)}.Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) } func TestServerGroupSpecDefault(t *testing.T) { diff --git a/pkg/apis/deployment/v1alpha/sync_spec.go b/pkg/apis/deployment/v1alpha/sync_spec.go index 2f0b533d9..56aad0f64 100644 --- a/pkg/apis/deployment/v1alpha/sync_spec.go +++ b/pkg/apis/deployment/v1alpha/sync_spec.go @@ -31,9 +31,9 @@ import ( // SyncSpec holds dc2dc replication specific configuration settings type SyncSpec struct { - XEnabled *bool `json:"enabled,omitempty"` - XImage *string `json:"image,omitempty"` - XImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Image *string `json:"image,omitempty"` + ImagePullPolicy *v1.PullPolicy `json:"imagePullPolicy,omitempty"` Authentication AuthenticationSpec `json:"auth"` TLS TLSSpec `json:"tls"` @@ -42,20 +42,17 @@ type SyncSpec struct { // IsEnabled returns the value of enabled. func (s SyncSpec) IsEnabled() bool { - return util.BoolOrDefault(s.XEnabled) + return util.BoolOrDefault(s.Enabled) } // GetImage returns the value of image. func (s SyncSpec) GetImage() string { - return util.StringOrDefault(s.XImage) + return util.StringOrDefault(s.Image) } // GetImagePullPolicy returns the value of imagePullPolicy. func (s SyncSpec) GetImagePullPolicy() v1.PullPolicy { - if s.XImagePullPolicy == nil { - return "" - } - return *s.XImagePullPolicy + return util.PullPolicyOrDefault(s.ImagePullPolicy) } // Validate the given spec @@ -83,11 +80,10 @@ func (s SyncSpec) Validate(mode DeploymentMode) error { // SetDefaults fills in missing defaults func (s *SyncSpec) SetDefaults(defaultImage string, defaulPullPolicy v1.PullPolicy, defaultJWTSecretName, defaultCASecretName string) { if s.GetImage() == "" { - s.XImage = util.NewString(defaultImage) + s.Image = util.NewString(defaultImage) } if s.GetImagePullPolicy() == "" { - x := v1.PullPolicy(defaulPullPolicy) - s.XImagePullPolicy = &x + s.ImagePullPolicy = util.NewPullPolicy(defaulPullPolicy) } s.Authentication.SetDefaults(defaultJWTSecretName) s.TLS.SetDefaults(defaultCASecretName) @@ -96,14 +92,14 @@ func (s *SyncSpec) SetDefaults(defaultImage string, defaulPullPolicy v1.PullPoli // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *SyncSpec) SetDefaultsFrom(source SyncSpec) { - if s.XEnabled == nil { - s.XEnabled = util.NewBoolOrNil(source.XEnabled) + if s.Enabled == nil { + s.Enabled = util.NewBoolOrNil(source.Enabled) } - if s.XImage == nil { - s.XImage = util.NewStringOrNil(source.XImage) + if s.Image == nil { + s.Image = util.NewStringOrNil(source.Image) } - if s.GetImagePullPolicy() == "" { - s.XImagePullPolicy = util.NewPullPolicyOrNil(source.XImagePullPolicy) + if s.ImagePullPolicy == nil { + s.ImagePullPolicy = util.NewPullPolicyOrNil(source.ImagePullPolicy) } s.Authentication.SetDefaultsFrom(source.Authentication) s.TLS.SetDefaultsFrom(source.TLS) diff --git a/pkg/apis/deployment/v1alpha/sync_spec_test.go b/pkg/apis/deployment/v1alpha/sync_spec_test.go index 0b64527fb..567edf19c 100644 --- a/pkg/apis/deployment/v1alpha/sync_spec_test.go +++ b/pkg/apis/deployment/v1alpha/sync_spec_test.go @@ -32,19 +32,19 @@ import ( func TestSyncSpecValidate(t *testing.T) { // Valid - auth := AuthenticationSpec{XJWTSecretName: util.NewString("foo")} - tls := TLSSpec{XCASecretName: util.NewString("None")} - assert.Nil(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth}.Validate(DeploymentModeSingle)) - assert.Nil(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth}.Validate(DeploymentModeResilientSingle)) - assert.Nil(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth}.Validate(DeploymentModeCluster)) - assert.Nil(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth, TLS: tls, XEnabled: util.NewBool(true)}.Validate(DeploymentModeCluster)) + auth := AuthenticationSpec{JWTSecretName: util.NewString("foo")} + tls := TLSSpec{CASecretName: util.NewString("None")} + assert.Nil(t, SyncSpec{Image: util.NewString("foo"), Authentication: auth}.Validate(DeploymentModeSingle)) + assert.Nil(t, SyncSpec{Image: util.NewString("foo"), Authentication: auth}.Validate(DeploymentModeResilientSingle)) + assert.Nil(t, SyncSpec{Image: util.NewString("foo"), Authentication: auth}.Validate(DeploymentModeCluster)) + assert.Nil(t, SyncSpec{Image: util.NewString("foo"), Authentication: auth, TLS: tls, Enabled: util.NewBool(true)}.Validate(DeploymentModeCluster)) // Not valid - assert.Error(t, SyncSpec{XImage: util.NewString(""), Authentication: auth}.Validate(DeploymentModeSingle)) - assert.Error(t, SyncSpec{XImage: util.NewString(""), Authentication: auth}.Validate(DeploymentModeResilientSingle)) - assert.Error(t, SyncSpec{XImage: util.NewString(""), Authentication: auth}.Validate(DeploymentModeCluster)) - assert.Error(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth, TLS: tls, XEnabled: util.NewBool(true)}.Validate(DeploymentModeSingle)) - assert.Error(t, SyncSpec{XImage: util.NewString("foo"), Authentication: auth, TLS: tls, XEnabled: util.NewBool(true)}.Validate(DeploymentModeResilientSingle)) + assert.Error(t, SyncSpec{Image: util.NewString(""), Authentication: auth}.Validate(DeploymentModeSingle)) + assert.Error(t, SyncSpec{Image: util.NewString(""), Authentication: auth}.Validate(DeploymentModeResilientSingle)) + assert.Error(t, SyncSpec{Image: util.NewString(""), Authentication: auth}.Validate(DeploymentModeCluster)) + assert.Error(t, SyncSpec{Image: util.NewString("foo"), Authentication: auth, TLS: tls, Enabled: util.NewBool(true)}.Validate(DeploymentModeSingle)) + assert.Error(t, SyncSpec{Image: util.NewString("foo"), Authentication: auth, TLS: tls, Enabled: util.NewBool(true)}.Validate(DeploymentModeResilientSingle)) } func TestSyncSpecSetDefaults(t *testing.T) { @@ -54,14 +54,14 @@ func TestSyncSpecSetDefaults(t *testing.T) { } assert.False(t, def(SyncSpec{}).IsEnabled()) - assert.False(t, def(SyncSpec{XEnabled: util.NewBool(false)}).IsEnabled()) - assert.True(t, def(SyncSpec{XEnabled: util.NewBool(true)}).IsEnabled()) + assert.False(t, def(SyncSpec{Enabled: util.NewBool(false)}).IsEnabled()) + assert.True(t, def(SyncSpec{Enabled: util.NewBool(true)}).IsEnabled()) assert.Equal(t, "test-image", def(SyncSpec{}).GetImage()) - assert.Equal(t, "foo", def(SyncSpec{XImage: util.NewString("foo")}).GetImage()) + assert.Equal(t, "foo", def(SyncSpec{Image: util.NewString("foo")}).GetImage()) assert.Equal(t, v1.PullAlways, def(SyncSpec{}).GetImagePullPolicy()) - assert.Equal(t, v1.PullNever, def(SyncSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}).GetImagePullPolicy()) + assert.Equal(t, v1.PullNever, def(SyncSpec{ImagePullPolicy: util.NewPullPolicy(v1.PullNever)}).GetImagePullPolicy()) assert.Equal(t, "test-jwt", def(SyncSpec{}).Authentication.GetJWTSecretName()) - assert.Equal(t, "foo", def(SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}).Authentication.GetJWTSecretName()) + assert.Equal(t, "foo", def(SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo")}}).Authentication.GetJWTSecretName()) } func TestSyncSpecResetImmutableFields(t *testing.T) { @@ -73,59 +73,59 @@ func TestSyncSpecResetImmutableFields(t *testing.T) { }{ // Valid "changes" { - SyncSpec{XEnabled: util.NewBool(false)}, - SyncSpec{XEnabled: util.NewBool(true)}, - SyncSpec{XEnabled: util.NewBool(true)}, + SyncSpec{Enabled: util.NewBool(false)}, + SyncSpec{Enabled: util.NewBool(true)}, + SyncSpec{Enabled: util.NewBool(true)}, nil, }, { - SyncSpec{XEnabled: util.NewBool(true)}, - SyncSpec{XEnabled: util.NewBool(false)}, - SyncSpec{XEnabled: util.NewBool(false)}, + SyncSpec{Enabled: util.NewBool(true)}, + SyncSpec{Enabled: util.NewBool(false)}, + SyncSpec{Enabled: util.NewBool(false)}, nil, }, { - SyncSpec{XImage: util.NewString("foo")}, - SyncSpec{XImage: util.NewString("foo2")}, - SyncSpec{XImage: util.NewString("foo2")}, + SyncSpec{Image: util.NewString("foo")}, + SyncSpec{Image: util.NewString("foo2")}, + SyncSpec{Image: util.NewString("foo2")}, nil, }, { - SyncSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullAlways)}, - SyncSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, - SyncSpec{XImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, + SyncSpec{ImagePullPolicy: util.NewPullPolicy(v1.PullAlways)}, + SyncSpec{ImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, + SyncSpec{ImagePullPolicy: util.NewPullPolicy(v1.PullNever)}, nil, }, { - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("None")}}, nil, }, { - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo")}}, nil, }, { - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo2")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo2")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo2")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo2")}}, nil, }, // Invalid changes { - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo")}}, []string{"test.auth.jwtSecretName"}, }, { - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("foo")}}, - SyncSpec{Authentication: AuthenticationSpec{XJWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("None")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("foo")}}, + SyncSpec{Authentication: AuthenticationSpec{JWTSecretName: util.NewString("None")}}, []string{"test.auth.jwtSecretName"}, }, } diff --git a/pkg/apis/deployment/v1alpha/tls_spec.go b/pkg/apis/deployment/v1alpha/tls_spec.go index 08ed6f358..4298f4c60 100644 --- a/pkg/apis/deployment/v1alpha/tls_spec.go +++ b/pkg/apis/deployment/v1alpha/tls_spec.go @@ -38,9 +38,9 @@ const ( // TLSSpec holds TLS specific configuration settings type TLSSpec struct { - XCASecretName *string `json:"caSecretName,omitempty"` - AltNames []string `json:"altNames,omitempty"` - XTTL *time.Duration `json:"ttl,omitempty"` + CASecretName *string `json:"caSecretName,omitempty"` + AltNames []string `json:"altNames,omitempty"` + TTL *time.Duration `json:"ttl,omitempty"` } const ( @@ -50,7 +50,7 @@ const ( // GetCASecretName returns the value of caSecretName. func (s TLSSpec) GetCASecretName() string { - return util.StringOrDefault(s.XCASecretName) + return util.StringOrDefault(s.CASecretName) } // GetAltNames returns the value of altNames. @@ -60,7 +60,7 @@ func (s TLSSpec) GetAltNames() []string { // GetTTL returns the value of ttl. func (s TLSSpec) GetTTL() time.Duration { - return util.DurationOrDefault(s.XTTL) + return util.DurationOrDefault(s.TTL) } // IsSecure returns true when a CA secret has been set, false otherwise. @@ -103,24 +103,24 @@ func (s *TLSSpec) SetDefaults(defaultCASecretName string) { if s.GetCASecretName() == "" { // Note that we don't check for nil here, since even a specified, but empty // string should result in the default value. - s.XCASecretName = util.NewString(defaultCASecretName) + s.CASecretName = util.NewString(defaultCASecretName) } if s.GetTTL() == 0 { // Note that we don't check for nil here, since even a specified, but zero // should result in the default value. - s.XTTL = util.NewDuration(defaultTLSTTL) + s.TTL = util.NewDuration(defaultTLSTTL) } } // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *TLSSpec) SetDefaultsFrom(source TLSSpec) { - if s.XCASecretName == nil { - s.XCASecretName = util.NewString(source.GetCASecretName()) + if s.CASecretName == nil { + s.CASecretName = util.NewStringOrNil(source.CASecretName) } if s.AltNames == nil { - s.AltNames = source.GetAltNames() + s.AltNames = source.AltNames } - if s.XTTL == nil { - s.XTTL = util.NewDuration(source.GetTTL()) + if s.TTL == nil { + s.TTL = util.NewDurationOrNil(source.TTL) } } diff --git a/pkg/apis/deployment/v1alpha/tls_spec_test.go b/pkg/apis/deployment/v1alpha/tls_spec_test.go index 050d38bbd..15d006ab8 100644 --- a/pkg/apis/deployment/v1alpha/tls_spec_test.go +++ b/pkg/apis/deployment/v1alpha/tls_spec_test.go @@ -32,23 +32,23 @@ import ( func TestTLSSpecValidate(t *testing.T) { // Valid - assert.Nil(t, TLSSpec{XCASecretName: util.NewString("foo")}.Validate()) - assert.Nil(t, TLSSpec{XCASecretName: util.NewString("None")}.Validate()) - assert.Nil(t, TLSSpec{XCASecretName: util.NewString("None"), AltNames: []string{}}.Validate()) - assert.Nil(t, TLSSpec{XCASecretName: util.NewString("None"), AltNames: []string{"foo"}}.Validate()) - assert.Nil(t, TLSSpec{XCASecretName: util.NewString("None"), AltNames: []string{"email@example.com", "127.0.0.1"}}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.NewString("foo")}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.NewString("None")}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.NewString("None"), AltNames: []string{}}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.NewString("None"), AltNames: []string{"foo"}}.Validate()) + assert.Nil(t, TLSSpec{CASecretName: util.NewString("None"), AltNames: []string{"email@example.com", "127.0.0.1"}}.Validate()) // Not valid - assert.Error(t, TLSSpec{XCASecretName: nil}.Validate()) - assert.Error(t, TLSSpec{XCASecretName: util.NewString("")}.Validate()) - assert.Error(t, TLSSpec{XCASecretName: util.NewString("Foo")}.Validate()) - assert.Error(t, TLSSpec{XCASecretName: util.NewString("foo"), AltNames: []string{"@@"}}.Validate()) + assert.Error(t, TLSSpec{CASecretName: nil}.Validate()) + assert.Error(t, TLSSpec{CASecretName: util.NewString("")}.Validate()) + assert.Error(t, TLSSpec{CASecretName: util.NewString("Foo")}.Validate()) + assert.Error(t, TLSSpec{CASecretName: util.NewString("foo"), AltNames: []string{"@@"}}.Validate()) } func TestTLSSpecIsSecure(t *testing.T) { - assert.True(t, TLSSpec{XCASecretName: util.NewString("")}.IsSecure()) - assert.True(t, TLSSpec{XCASecretName: util.NewString("foo")}.IsSecure()) - assert.False(t, TLSSpec{XCASecretName: util.NewString("None")}.IsSecure()) + assert.True(t, TLSSpec{CASecretName: util.NewString("")}.IsSecure()) + assert.True(t, TLSSpec{CASecretName: util.NewString("foo")}.IsSecure()) + assert.False(t, TLSSpec{CASecretName: util.NewString("None")}.IsSecure()) } func TestTLSSpecSetDefaults(t *testing.T) { @@ -58,9 +58,9 @@ func TestTLSSpecSetDefaults(t *testing.T) { } assert.Equal(t, "", def(TLSSpec{}).GetCASecretName()) - assert.Equal(t, "foo", def(TLSSpec{XCASecretName: util.NewString("foo")}).GetCASecretName()) + assert.Equal(t, "foo", def(TLSSpec{CASecretName: util.NewString("foo")}).GetCASecretName()) assert.Len(t, def(TLSSpec{}).GetAltNames(), 0) assert.Len(t, def(TLSSpec{AltNames: []string{"foo.local"}}).GetAltNames(), 1) assert.Equal(t, defaultTLSTTL, def(TLSSpec{}).GetTTL()) - assert.Equal(t, time.Hour, def(TLSSpec{XTTL: util.NewDuration(time.Hour)}).GetTTL()) + assert.Equal(t, time.Hour, def(TLSSpec{TTL: util.NewDuration(time.Hour)}).GetTTL()) } diff --git a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go index 328832e72..b89714d67 100644 --- a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go @@ -122,8 +122,8 @@ func (in *ArangoDeploymentList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *AuthenticationSpec) DeepCopyInto(out *AuthenticationSpec) { *out = *in - if in.XJWTSecretName != nil { - in, out := &in.XJWTSecretName, &out.XJWTSecretName + if in.JWTSecretName != nil { + in, out := &in.JWTSecretName, &out.JWTSecretName if *in == nil { *out = nil } else { @@ -165,8 +165,8 @@ func (in *Condition) DeepCopy() *Condition { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { *out = *in - if in.XMode != nil { - in, out := &in.XMode, &out.XMode + if in.Mode != nil { + in, out := &in.Mode, &out.Mode if *in == nil { *out = nil } else { @@ -174,8 +174,8 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { **out = **in } } - if in.XEnvironment != nil { - in, out := &in.XEnvironment, &out.XEnvironment + if in.Environment != nil { + in, out := &in.Environment, &out.Environment if *in == nil { *out = nil } else { @@ -183,8 +183,8 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { **out = **in } } - if in.XStorageEngine != nil { - in, out := &in.XStorageEngine, &out.XStorageEngine + if in.StorageEngine != nil { + in, out := &in.StorageEngine, &out.StorageEngine if *in == nil { *out = nil } else { @@ -192,8 +192,8 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { **out = **in } } - if in.XImage != nil { - in, out := &in.XImage, &out.XImage + if in.Image != nil { + in, out := &in.Image, &out.Image if *in == nil { *out = nil } else { @@ -201,8 +201,8 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { **out = **in } } - if in.XImagePullPolicy != nil { - in, out := &in.XImagePullPolicy, &out.XImagePullPolicy + if in.ImagePullPolicy != nil { + in, out := &in.ImagePullPolicy, &out.ImagePullPolicy if *in == nil { *out = nil } else { @@ -378,8 +378,8 @@ func (in *MemberStatus) DeepCopy() *MemberStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MonitoringSpec) DeepCopyInto(out *MonitoringSpec) { *out = *in - if in.XTokenSecretName != nil { - in, out := &in.XTokenSecretName, &out.XTokenSecretName + if in.TokenSecretName != nil { + in, out := &in.TokenSecretName, &out.TokenSecretName if *in == nil { *out = nil } else { @@ -445,8 +445,8 @@ func (in *RocksDBSpec) DeepCopy() *RocksDBSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) { *out = *in - if in.XCount != nil { - in, out := &in.XCount, &out.XCount + if in.Count != nil { + in, out := &in.Count, &out.Count if *in == nil { *out = nil } else { @@ -459,8 +459,8 @@ func (in *ServerGroupSpec) DeepCopyInto(out *ServerGroupSpec) { *out = make([]string, len(*in)) copy(*out, *in) } - if in.XStorageClassName != nil { - in, out := &in.XStorageClassName, &out.XStorageClassName + if in.StorageClassName != nil { + in, out := &in.StorageClassName, &out.StorageClassName if *in == nil { *out = nil } else { @@ -485,8 +485,8 @@ func (in *ServerGroupSpec) DeepCopy() *ServerGroupSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SyncSpec) DeepCopyInto(out *SyncSpec) { *out = *in - if in.XEnabled != nil { - in, out := &in.XEnabled, &out.XEnabled + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled if *in == nil { *out = nil } else { @@ -494,8 +494,8 @@ func (in *SyncSpec) DeepCopyInto(out *SyncSpec) { **out = **in } } - if in.XImage != nil { - in, out := &in.XImage, &out.XImage + if in.Image != nil { + in, out := &in.Image, &out.Image if *in == nil { *out = nil } else { @@ -503,8 +503,8 @@ func (in *SyncSpec) DeepCopyInto(out *SyncSpec) { **out = **in } } - if in.XImagePullPolicy != nil { - in, out := &in.XImagePullPolicy, &out.XImagePullPolicy + if in.ImagePullPolicy != nil { + in, out := &in.ImagePullPolicy, &out.ImagePullPolicy if *in == nil { *out = nil } else { @@ -531,8 +531,8 @@ func (in *SyncSpec) DeepCopy() *SyncSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSSpec) DeepCopyInto(out *TLSSpec) { *out = *in - if in.XCASecretName != nil { - in, out := &in.XCASecretName, &out.XCASecretName + if in.CASecretName != nil { + in, out := &in.CASecretName, &out.CASecretName if *in == nil { *out = nil } else { @@ -545,8 +545,8 @@ func (in *TLSSpec) DeepCopyInto(out *TLSSpec) { *out = make([]string, len(*in)) copy(*out, *in) } - if in.XTTL != nil { - in, out := &in.XTTL, &out.XTTL + if in.TTL != nil { + in, out := &in.TTL, &out.TTL if *in == nil { *out = nil } else { diff --git a/pkg/deployment/plan_builder_test.go b/pkg/deployment/plan_builder_test.go index 4a2e89146..9810fffd2 100644 --- a/pkg/deployment/plan_builder_test.go +++ b/pkg/deployment/plan_builder_test.go @@ -38,7 +38,7 @@ import ( func TestCreatePlanSingleScale(t *testing.T) { log := zerolog.Nop() spec := api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeSingle), + Mode: api.NewMode(api.DeploymentModeSingle), } spec.SetDefaults("test") depl := &api.ArangoDeployment{ @@ -86,10 +86,10 @@ func TestCreatePlanSingleScale(t *testing.T) { func TestCreatePlanResilientSingleScale(t *testing.T) { log := zerolog.Nop() spec := api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeResilientSingle), + Mode: api.NewMode(api.DeploymentModeResilientSingle), } spec.SetDefaults("test") - spec.Single.XCount = util.NewInt(2) + spec.Single.Count = util.NewInt(2) depl := &api.ArangoDeployment{ ObjectMeta: metav1.ObjectMeta{ Name: "test_depl", @@ -151,7 +151,7 @@ func TestCreatePlanResilientSingleScale(t *testing.T) { func TestCreatePlanClusterScale(t *testing.T) { log := zerolog.Nop() spec := api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), } spec.SetDefaults("test") depl := &api.ArangoDeployment{ @@ -232,9 +232,9 @@ func TestCreatePlanClusterScale(t *testing.T) { PodName: "coordinator2", }, } - spec.DBServers.XCount = util.NewInt(1) - spec.Coordinators.XCount = util.NewInt(1) - newPlan, changed = createPlan(log, nil, spec, status, nil) + spec.DBServers.Count = util.NewInt(1) + spec.Coordinators.Count = util.NewInt(1) + newPlan, changed = createPlan(log, depl, nil, spec, status, nil) assert.True(t, changed) require.Len(t, newPlan, 5) // Note: Downscaling is done 1 at a time assert.Equal(t, api.ActionTypeCleanOutMember, newPlan[0].Type) diff --git a/pkg/deployment/pod_creator_agent_args_test.go b/pkg/deployment/pod_creator_agent_args_test.go index 2e1204199..c7b89240c 100644 --- a/pkg/deployment/pod_creator_agent_args_test.go +++ b/pkg/deployment/pod_creator_agent_args_test.go @@ -42,7 +42,7 @@ func TestCreateArangodArgsAgent(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") @@ -85,7 +85,7 @@ func TestCreateArangodArgsAgent(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") @@ -129,9 +129,9 @@ func TestCreateArangodArgsAgent(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), TLS: api.TLSSpec{ - XCASecretName: util.NewString("None"), + CASecretName: util.NewString("None"), }, }, } @@ -173,12 +173,12 @@ func TestCreateArangodArgsAgent(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") - apiObject.Spec.Authentication.XJWTSecretName = util.NewString("None") - apiObject.Spec.XStorageEngine = api.NewStorageEngine(api.StorageEngineMMFiles) + apiObject.Spec.Authentication.JWTSecretName = util.NewString("None") + apiObject.Spec.StorageEngine = api.NewStorageEngine(api.StorageEngineMMFiles) agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, api.MemberStatus{ID: "a2"}, @@ -217,7 +217,7 @@ func TestCreateArangodArgsAgent(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") diff --git a/pkg/deployment/pod_creator_coordinator_args_test.go b/pkg/deployment/pod_creator_coordinator_args_test.go index 6c1b3e451..becf97967 100644 --- a/pkg/deployment/pod_creator_coordinator_args_test.go +++ b/pkg/deployment/pod_creator_coordinator_args_test.go @@ -42,7 +42,7 @@ func TestCreateArangodArgsCoordinator(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") @@ -83,7 +83,7 @@ func TestCreateArangodArgsCoordinator(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") @@ -125,9 +125,9 @@ func TestCreateArangodArgsCoordinator(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), TLS: api.TLSSpec{ - XCASecretName: util.NewString("None"), + CASecretName: util.NewString("None"), }, }, } @@ -167,11 +167,11 @@ func TestCreateArangodArgsCoordinator(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") - apiObject.Spec.Authentication.XJWTSecretName = util.NewString("None") + apiObject.Spec.Authentication.JWTSecretName = util.NewString("None") agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, api.MemberStatus{ID: "a2"}, @@ -208,12 +208,12 @@ func TestCreateArangodArgsCoordinator(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") apiObject.Spec.Coordinators.Args = []string{"--foo1", "--foo2"} - apiObject.Spec.XStorageEngine = api.NewStorageEngine(api.StorageEngineMMFiles) + apiObject.Spec.StorageEngine = api.NewStorageEngine(api.StorageEngineMMFiles) agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, api.MemberStatus{ID: "a2"}, diff --git a/pkg/deployment/pod_creator_dbserver_args_test.go b/pkg/deployment/pod_creator_dbserver_args_test.go index e4bf2ba98..e211f2792 100644 --- a/pkg/deployment/pod_creator_dbserver_args_test.go +++ b/pkg/deployment/pod_creator_dbserver_args_test.go @@ -42,7 +42,7 @@ func TestCreateArangodArgsDBServer(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") @@ -83,7 +83,7 @@ func TestCreateArangodArgsDBServer(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeCluster, + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") @@ -125,9 +125,9 @@ func TestCreateArangodArgsDBServer(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), TLS: api.TLSSpec{ - XCASecretName: util.NewString("None"), + CASecretName: util.NewString("None"), }, }, } @@ -167,11 +167,11 @@ func TestCreateArangodArgsDBServer(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") - apiObject.Spec.Authentication.XJWTSecretName = util.NewString("None") + apiObject.Spec.Authentication.JWTSecretName = util.NewString("None") agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, api.MemberStatus{ID: "a2"}, @@ -208,11 +208,11 @@ func TestCreateArangodArgsDBServer(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } apiObject.Spec.SetDefaults("test") - apiObject.Spec.XStorageEngine = api.NewStorageEngine(api.StorageEngineMMFiles) + apiObject.Spec.StorageEngine = api.NewStorageEngine(api.StorageEngineMMFiles) apiObject.Spec.DBServers.Args = []string{"--foo1", "--foo2"} agents := api.MemberStatusList{ api.MemberStatus{ID: "a1"}, diff --git a/pkg/deployment/pod_creator_single_args_test.go b/pkg/deployment/pod_creator_single_args_test.go index 7d7a56127..b8166b0fa 100644 --- a/pkg/deployment/pod_creator_single_args_test.go +++ b/pkg/deployment/pod_creator_single_args_test.go @@ -38,7 +38,7 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeSingle), + Mode: api.NewMode(api.DeploymentModeSingle), }, } apiObject.Spec.SetDefaults("test") @@ -65,7 +65,7 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - Mode: api.DeploymentModeSingle, + Mode: api.NewMode(api.DeploymentModeSingle), }, } apiObject.Spec.SetDefaults("test") @@ -93,9 +93,9 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeSingle), + Mode: api.NewMode(api.DeploymentModeSingle), TLS: api.TLSSpec{ - XCASecretName: util.NewString("None"), + CASecretName: util.NewString("None"), }, }, } @@ -121,8 +121,8 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeSingle), - XStorageEngine: api.NewStorageEngine(api.StorageEngineMMFiles), + Mode: api.NewMode(api.DeploymentModeSingle), + StorageEngine: api.NewStorageEngine(api.StorageEngineMMFiles), }, } apiObject.Spec.SetDefaults("test") @@ -149,10 +149,10 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeSingle), + Mode: api.NewMode(api.DeploymentModeSingle), }, } - apiObject.Spec.Authentication.XJWTSecretName = util.NewString("None") + apiObject.Spec.Authentication.JWTSecretName = util.NewString("None") apiObject.Spec.SetDefaults("test") cmdline := createArangodArgs(apiObject, apiObject.Spec, api.ServerGroupSingle, nil, "id1", false) assert.Equal(t, @@ -176,7 +176,7 @@ func TestCreateArangodArgsSingle(t *testing.T) { { apiObject := &api.ArangoDeployment{ Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeSingle), + Mode: api.NewMode(api.DeploymentModeSingle), }, } apiObject.Spec.Single.Args = []string{"--foo1", "--foo2"} @@ -210,7 +210,7 @@ func TestCreateArangodArgsSingle(t *testing.T) { Namespace: "ns", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeResilientSingle), + Mode: api.NewMode(api.DeploymentModeResilientSingle), }, } apiObject.Spec.SetDefaults("test") From 61aaf55e31493f6e8dd0dc735e8d1eb30c1a1cad Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Fri, 23 Mar 2018 10:03:39 +0100 Subject: [PATCH 5/8] Fixed int-test code --- pkg/apis/deployment/v1alpha/rocksdb_spec.go | 10 ++--- .../v1alpha/zz_generated.deepcopy.go | 4 +- tests/auth_test.go | 41 ++++++++++--------- tests/rocksdb_encryption_test.go | 13 +++--- tests/scale_test.go | 6 ++- tests/simple_test.go | 6 +-- 6 files changed, 42 insertions(+), 38 deletions(-) diff --git a/pkg/apis/deployment/v1alpha/rocksdb_spec.go b/pkg/apis/deployment/v1alpha/rocksdb_spec.go index 711d2e44b..2f0c40249 100644 --- a/pkg/apis/deployment/v1alpha/rocksdb_spec.go +++ b/pkg/apis/deployment/v1alpha/rocksdb_spec.go @@ -29,12 +29,12 @@ import ( // RocksDBEncryptionSpec holds rocksdb encryption at rest specific configuration settings type RocksDBEncryptionSpec struct { - XKeySecretName *string `json:"keySecretName,omitempty"` + KeySecretName *string `json:"keySecretName,omitempty"` } // GetKeySecretName returns the value of keySecretName. func (s RocksDBEncryptionSpec) GetKeySecretName() string { - return util.StringOrDefault(s.XKeySecretName) + return util.StringOrDefault(s.KeySecretName) } // IsEncrypted returns true when an encryption key secret name is provided, @@ -69,8 +69,8 @@ func (s *RocksDBSpec) SetDefaults() { // SetDefaultsFrom fills unspecified fields with a value from given source spec. func (s *RocksDBSpec) SetDefaultsFrom(source RocksDBSpec) { - if s.Encryption.XKeySecretName == nil { - s.Encryption.XKeySecretName = util.NewStringOrNil(source.Encryption.XKeySecretName) + if s.Encryption.KeySecretName == nil { + s.Encryption.KeySecretName = util.NewStringOrNil(source.Encryption.KeySecretName) } } @@ -81,7 +81,7 @@ func (s RocksDBSpec) ResetImmutableFields(fieldPrefix string, target *RocksDBSpe var resetFields []string if s.IsEncrypted() != target.IsEncrypted() { // Note: You can change the name, but not from empty to non-empty (or reverse). - target.Encryption.XKeySecretName = util.NewStringOrNil(s.Encryption.XKeySecretName) + target.Encryption.KeySecretName = util.NewStringOrNil(s.Encryption.KeySecretName) resetFields = append(resetFields, fieldPrefix+".encryption.keySecretName") } return resetFields diff --git a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go index b89714d67..b843241da 100644 --- a/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v1alpha/zz_generated.deepcopy.go @@ -403,8 +403,8 @@ func (in *MonitoringSpec) DeepCopy() *MonitoringSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RocksDBEncryptionSpec) DeepCopyInto(out *RocksDBEncryptionSpec) { *out = *in - if in.XKeySecretName != nil { - in, out := &in.XKeySecretName, &out.XKeySecretName + if in.KeySecretName != nil { + in, out := &in.KeySecretName, &out.KeySecretName if *in == nil { *out = nil } else { diff --git a/tests/auth_test.go b/tests/auth_test.go index ac201810f..63bc9e16f 100644 --- a/tests/auth_test.go +++ b/tests/auth_test.go @@ -10,6 +10,7 @@ import ( api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha" "github.com/arangodb/kube-arangodb/pkg/client" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/arangod" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) @@ -24,7 +25,7 @@ func TestAuthenticationSingleDefaultSecret(t *testing.T) { // Prepare deployment config depl := newDeployment("test-auth-sng-def-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeSingle + depl.Spec.Mode = api.NewMode(api.DeploymentModeSingle) depl.Spec.SetDefaults(depl.GetName()) // Create deployment @@ -39,7 +40,7 @@ func TestAuthenticationSingleDefaultSecret(t *testing.T) { } // Secret must now exist - if _, err := waitUntilSecret(kubecli, depl.Spec.Authentication.JWTSecretName, ns, nil, time.Second); err != nil { + if _, err := waitUntilSecret(kubecli, depl.Spec.Authentication.GetJWTSecretName(), ns, nil, time.Second); err != nil { t.Fatalf("JWT secret '%s' not found: %v", depl.Spec.Authentication.JWTSecretName, err) } @@ -56,7 +57,7 @@ func TestAuthenticationSingleDefaultSecret(t *testing.T) { removeDeployment(c, depl.GetName(), ns) // Secret must no longer exist - if err := waitUntilSecretNotFound(kubecli, depl.Spec.Authentication.JWTSecretName, ns, time.Minute); err != nil { + if err := waitUntilSecretNotFound(kubecli, depl.Spec.Authentication.GetJWTSecretName(), ns, time.Minute); err != nil { t.Fatalf("JWT secret '%s' still found: %v", depl.Spec.Authentication.JWTSecretName, err) } } @@ -71,12 +72,12 @@ func TestAuthenticationSingleCustomSecret(t *testing.T) { // Prepare deployment config depl := newDeployment("test-auth-sng-cst-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeSingle - depl.Spec.Authentication.JWTSecretName = strings.ToLower(uniuri.New()) + depl.Spec.Mode = api.NewMode(api.DeploymentModeSingle) + depl.Spec.Authentication.JWTSecretName = util.NewString(strings.ToLower(uniuri.New())) depl.Spec.SetDefaults(depl.GetName()) // Create secret - if err := k8sutil.CreateJWTSecret(kubecli.CoreV1(), depl.Spec.Authentication.JWTSecretName, ns, "foo", nil); err != nil { + if err := k8sutil.CreateJWTSecret(kubecli.CoreV1(), depl.Spec.Authentication.GetJWTSecretName(), ns, "foo", nil); err != nil { t.Fatalf("Create JWT secret failed: %v", err) } @@ -104,12 +105,12 @@ func TestAuthenticationSingleCustomSecret(t *testing.T) { removeDeployment(c, depl.GetName(), ns) // Secret must still exist - if _, err := waitUntilSecret(kubecli, depl.Spec.Authentication.JWTSecretName, ns, nil, time.Second); err != nil { + if _, err := waitUntilSecret(kubecli, depl.Spec.Authentication.GetJWTSecretName(), ns, nil, time.Second); err != nil { t.Fatalf("JWT secret '%s' not found: %v", depl.Spec.Authentication.JWTSecretName, err) } // Cleanup secret - removeSecret(kubecli, depl.Spec.Authentication.JWTSecretName, ns) + removeSecret(kubecli, depl.Spec.Authentication.GetJWTSecretName(), ns) } // TestAuthenticationNoneSingle creating a single server @@ -122,8 +123,8 @@ func TestAuthenticationNoneSingle(t *testing.T) { // Prepare deployment config depl := newDeployment("test-auth-none-sng-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeSingle - depl.Spec.Authentication.JWTSecretName = api.JWTSecretNameDisabled + depl.Spec.Mode = api.NewMode(api.DeploymentModeSingle) + depl.Spec.Authentication.JWTSecretName = util.NewString(api.JWTSecretNameDisabled) depl.Spec.SetDefaults(depl.GetName()) // Create deployment @@ -160,7 +161,7 @@ func TestAuthenticationClusterDefaultSecret(t *testing.T) { // Prepare deployment config depl := newDeployment("test-auth-cls-def-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeCluster + depl.Spec.Mode = api.NewMode(api.DeploymentModeCluster) depl.Spec.SetDefaults(depl.GetName()) // Create deployment @@ -175,7 +176,7 @@ func TestAuthenticationClusterDefaultSecret(t *testing.T) { } // Secret must now exist - if _, err := waitUntilSecret(kubecli, depl.Spec.Authentication.JWTSecretName, ns, nil, time.Second); err != nil { + if _, err := waitUntilSecret(kubecli, depl.Spec.Authentication.GetJWTSecretName(), ns, nil, time.Second); err != nil { t.Fatalf("JWT secret '%s' not found: %v", depl.Spec.Authentication.JWTSecretName, err) } @@ -192,7 +193,7 @@ func TestAuthenticationClusterDefaultSecret(t *testing.T) { removeDeployment(c, depl.GetName(), ns) // Secret must no longer exist - if err := waitUntilSecretNotFound(kubecli, depl.Spec.Authentication.JWTSecretName, ns, time.Minute); err != nil { + if err := waitUntilSecretNotFound(kubecli, depl.Spec.Authentication.GetJWTSecretName(), ns, time.Minute); err != nil { t.Fatalf("JWT secret '%s' still found: %v", depl.Spec.Authentication.JWTSecretName, err) } } @@ -207,12 +208,12 @@ func TestAuthenticationClusterCustomSecret(t *testing.T) { // Prepare deployment config depl := newDeployment("test-auth-cls-cst-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeCluster - depl.Spec.Authentication.JWTSecretName = strings.ToLower(uniuri.New()) + depl.Spec.Mode = api.NewMode(api.DeploymentModeCluster) + depl.Spec.Authentication.JWTSecretName = util.NewString(strings.ToLower(uniuri.New())) depl.Spec.SetDefaults(depl.GetName()) // Create secret - if err := k8sutil.CreateJWTSecret(kubecli.CoreV1(), depl.Spec.Authentication.JWTSecretName, ns, "foo", nil); err != nil { + if err := k8sutil.CreateJWTSecret(kubecli.CoreV1(), depl.Spec.Authentication.GetJWTSecretName(), ns, "foo", nil); err != nil { t.Fatalf("Create JWT secret failed: %v", err) } @@ -240,12 +241,12 @@ func TestAuthenticationClusterCustomSecret(t *testing.T) { removeDeployment(c, depl.GetName(), ns) // Secret must still exist - if _, err := waitUntilSecret(kubecli, depl.Spec.Authentication.JWTSecretName, ns, nil, time.Second); err != nil { + if _, err := waitUntilSecret(kubecli, depl.Spec.Authentication.GetJWTSecretName(), ns, nil, time.Second); err != nil { t.Fatalf("JWT secret '%s' not found: %v", depl.Spec.Authentication.JWTSecretName, err) } // Cleanup secret - removeSecret(kubecli, depl.Spec.Authentication.JWTSecretName, ns) + removeSecret(kubecli, depl.Spec.Authentication.GetJWTSecretName(), ns) } // TestAuthenticationNoneCluster creating a cluster @@ -258,8 +259,8 @@ func TestAuthenticationNoneCluster(t *testing.T) { // Prepare deployment config depl := newDeployment("test-auth-none-cls-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeCluster - depl.Spec.Authentication.JWTSecretName = api.JWTSecretNameDisabled + depl.Spec.Mode = api.NewMode(api.DeploymentModeCluster) + depl.Spec.Authentication.JWTSecretName = util.NewString(api.JWTSecretNameDisabled) depl.Spec.SetDefaults(depl.GetName()) // Create deployment diff --git a/tests/rocksdb_encryption_test.go b/tests/rocksdb_encryption_test.go index 50c40d2e6..425aa7952 100644 --- a/tests/rocksdb_encryption_test.go +++ b/tests/rocksdb_encryption_test.go @@ -10,6 +10,7 @@ import ( api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha" "github.com/arangodb/kube-arangodb/pkg/client" + "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) @@ -24,15 +25,15 @@ func TestRocksDBEncryptionSingle(t *testing.T) { // Prepare deployment config depl := newDeployment("test-rocksdb-enc-sng-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeSingle - depl.Spec.Image = image - depl.Spec.StorageEngine = api.StorageEngineRocksDB - depl.Spec.RocksDB.Encryption.KeySecretName = strings.ToLower(uniuri.New()) + depl.Spec.Mode = api.NewMode(api.DeploymentModeSingle) + depl.Spec.Image = util.NewString(image) + depl.Spec.StorageEngine = api.NewStorageEngine(api.StorageEngineRocksDB) + depl.Spec.RocksDB.Encryption.KeySecretName = util.NewString(strings.ToLower(uniuri.New())) // Create encryption key secret key := make([]byte, 32) rand.Read(key) - if err := k8sutil.CreateEncryptionKeySecret(kubecli.CoreV1(), depl.Spec.RocksDB.Encryption.KeySecretName, ns, key); err != nil { + if err := k8sutil.CreateEncryptionKeySecret(kubecli.CoreV1(), depl.Spec.RocksDB.Encryption.GetKeySecretName(), ns, key); err != nil { t.Fatalf("Create encryption key secret failed: %v", err) } @@ -59,5 +60,5 @@ func TestRocksDBEncryptionSingle(t *testing.T) { // Cleanup removeDeployment(c, depl.GetName(), ns) - removeSecret(kubecli, depl.Spec.RocksDB.Encryption.KeySecretName, ns) + removeSecret(kubecli, depl.Spec.RocksDB.Encryption.GetKeySecretName(), ns) } diff --git a/tests/scale_test.go b/tests/scale_test.go index f96178188..c31ed97f0 100644 --- a/tests/scale_test.go +++ b/tests/scale_test.go @@ -3,12 +3,14 @@ package tests import ( "context" "testing" + "time" "github.com/dchest/uniuri" driver "github.com/arangodb/go-driver" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1alpha" "github.com/arangodb/kube-arangodb/pkg/client" + "github.com/arangodb/kube-arangodb/pkg/util" ) // TestScaleCluster tests scaling up/down the number of DBServers & coordinators @@ -21,8 +23,8 @@ func TestScaleClusterNonTLS(t *testing.T) { // Prepare deployment config depl := newDeployment("test-scale-non-tls" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeCluster - depl.Spec.TLS = api.TLSSpec{"None", nil, 50} + depl.Spec.Mode = api.NewMode(api.DeploymentModeCluster) + depl.Spec.TLS = api.TLSSpec{util.NewString("None"), nil, util.NewDuration(time.Second * 50)} depl.Spec.SetDefaults(depl.GetName()) // this must be last // Create deployment diff --git a/tests/simple_test.go b/tests/simple_test.go index 99f68004c..da378e2a9 100644 --- a/tests/simple_test.go +++ b/tests/simple_test.go @@ -21,7 +21,7 @@ func TestSimpleSingle(t *testing.T) { // Prepare deployment config depl := newDeployment("test-sng-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeSingle + depl.Spec.Mode = api.NewMode(api.DeploymentModeSingle) // Create deployment _, err := c.DatabaseV1alpha().ArangoDeployments(ns).Create(depl) @@ -62,7 +62,7 @@ func TestSimpleResilientSingle(t *testing.T) { // Prepare deployment config depl := newDeployment("test-rs-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeResilientSingle + depl.Spec.Mode = api.NewMode(api.DeploymentModeResilientSingle) // Create deployment _, err := c.DatabaseV1alpha().ArangoDeployments(ns).Create(depl) @@ -103,7 +103,7 @@ func TestSimpleCluster(t *testing.T) { // Prepare deployment config depl := newDeployment("test-cls-" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeCluster + depl.Spec.Mode = api.NewMode(api.DeploymentModeCluster) // Create deployment _, err := c.DatabaseV1alpha().ArangoDeployments(ns).Create(depl) From e22ddcc27b7ce022e03a8778a1909d77f8643d39 Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Fri, 23 Mar 2018 10:08:03 +0100 Subject: [PATCH 6/8] Merged in master --- pkg/deployment/cluster_informer.go | 8 +++++--- pkg/deployment/cluster_updater.go | 4 ++-- pkg/deployment/deployment.go | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pkg/deployment/cluster_informer.go b/pkg/deployment/cluster_informer.go index e0f4c95a5..0a232d811 100644 --- a/pkg/deployment/cluster_informer.go +++ b/pkg/deployment/cluster_informer.go @@ -26,8 +26,10 @@ import ( "context" "time" - "github.com/arangodb/kube-arangodb/pkg/util/arangod" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/arangod" ) // listenForClusterEvents keep listening for changes entered in the UI of the cluster. @@ -91,10 +93,10 @@ func (d *Deployment) inspectCluster(ctx context.Context) error { return maskAny(err) } if coordinatorsChanged { - current.Spec.Coordinators.Count = req.GetCoordinators() + current.Spec.Coordinators.Count = util.NewInt(req.GetCoordinators()) } if dbserversChanged { - current.Spec.DBServers.Count = req.GetDBServers() + current.Spec.DBServers.Count = util.NewInt(req.GetDBServers()) } if err := d.updateCRSpec(current.Spec); err != nil { log.Warn().Err(err).Msg("Failed to update current deployment") diff --git a/pkg/deployment/cluster_updater.go b/pkg/deployment/cluster_updater.go index bf6d1a599..41151f926 100644 --- a/pkg/deployment/cluster_updater.go +++ b/pkg/deployment/cluster_updater.go @@ -36,8 +36,8 @@ func (d *Deployment) updateClusterServerCount(ctx context.Context) error { return maskAny(err) } spec := d.apiObject.Spec - coordinatorCount := spec.Coordinators.Count - dbserverCount := spec.DBServers.Count + coordinatorCount := spec.Coordinators.GetCount() + dbserverCount := spec.DBServers.GetCount() if err := arangod.SetNumberOfServers(ctx, c.Connection(), coordinatorCount, dbserverCount); err != nil { log.Debug().Err(err).Msg("Failed to set number of servers") return maskAny(err) diff --git a/pkg/deployment/deployment.go b/pkg/deployment/deployment.go index 8ec8d968e..28a369b76 100644 --- a/pkg/deployment/deployment.go +++ b/pkg/deployment/deployment.go @@ -122,7 +122,7 @@ func New(config Config, deps Dependencies, apiObject *api.ArangoDeployment) (*De go d.run() go d.listenForPodEvents() - if apiObject.Spec.Mode == api.DeploymentModeCluster { + if apiObject.Spec.GetMode() == api.DeploymentModeCluster { go d.listenForClusterEvents(d.stopCh) } @@ -293,7 +293,7 @@ func (d *Deployment) handleArangoDeploymentUpdatedEvent(event *deploymentEvent) } // Notify cluster of desired server count - if d.apiObject.Spec.Mode == api.DeploymentModeCluster { + if d.apiObject.Spec.GetMode() == api.DeploymentModeCluster { ctx := context.Background() if err := d.updateClusterServerCount(ctx); err != nil { log.Error().Err(err).Msg("Failed to update desired server count in cluster") From b3dc7a8f9443fd5e70707201655945432c06cc89 Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Fri, 23 Mar 2018 10:12:06 +0100 Subject: [PATCH 7/8] Fixed unit-tests --- .../deployment/v1alpha/rocksdb_spec_test.go | 26 +++++++++---------- pkg/util/k8sutil/test/events_test.go | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go b/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go index 8b935ca01..068199f51 100644 --- a/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go +++ b/pkg/apis/deployment/v1alpha/rocksdb_spec_test.go @@ -32,16 +32,16 @@ import ( func TestRocksDBSpecValidate(t *testing.T) { // Valid assert.Nil(t, RocksDBSpec{}.Validate()) - assert.Nil(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}.Validate()) + assert.Nil(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo")}}.Validate()) // Not valid - assert.Error(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("Foo")}}.Validate()) + assert.Error(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("Foo")}}.Validate()) } func TestRocksDBSpecIsEncrypted(t *testing.T) { assert.False(t, RocksDBSpec{}.IsEncrypted()) - assert.False(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("")}}.IsEncrypted()) - assert.True(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}.IsEncrypted()) + assert.False(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("")}}.IsEncrypted()) + assert.True(t, RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo")}}.IsEncrypted()) } func TestRocksDBSpecSetDefaults(t *testing.T) { @@ -68,23 +68,23 @@ func TestRocksDBSpecResetImmutableFields(t *testing.T) { nil, }, { - RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo")}}, nil, }, { - RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo2")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo2")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo2")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo2")}}, nil, }, // Invalid changes { - RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("")}}, - RocksDBSpec{Encryption: RocksDBEncryptionSpec{XKeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("")}}, + RocksDBSpec{Encryption: RocksDBEncryptionSpec{KeySecretName: util.NewString("foo")}}, []string{"test.encryption.keySecretName"}, }, } diff --git a/pkg/util/k8sutil/test/events_test.go b/pkg/util/k8sutil/test/events_test.go index c05563ca5..fe983bd6e 100644 --- a/pkg/util/k8sutil/test/events_test.go +++ b/pkg/util/k8sutil/test/events_test.go @@ -41,7 +41,7 @@ var apiObjectForTest = api.ArangoDeployment{ Namespace: "Wonka", }, Spec: api.DeploymentSpec{ - XMode: api.NewMode(api.DeploymentModeCluster), + Mode: api.NewMode(api.DeploymentModeCluster), }, } From 3ed5c7749b5dc810ca96ceea83823b468f03c32c Mon Sep 17 00:00:00 2001 From: Ewout Prangsma Date: Fri, 23 Mar 2018 10:25:16 +0100 Subject: [PATCH 8/8] Fixed int-tests --- tests/scale_test.go | 18 +++++++++--------- tests/test_util.go | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/scale_test.go b/tests/scale_test.go index c31ed97f0..99c278305 100644 --- a/tests/scale_test.go +++ b/tests/scale_test.go @@ -51,8 +51,8 @@ func TestScaleClusterNonTLS(t *testing.T) { // Add 2 DBServers, 1 coordinator updated, err := updateDeployment(c, depl.GetName(), ns, func(spec *api.DeploymentSpec) { - spec.DBServers.Count = 5 - spec.Coordinators.Count = 4 + spec.DBServers.Count = util.NewInt(5) + spec.Coordinators.Count = util.NewInt(4) }) if err != nil { t.Fatalf("Failed to update deployment: %v", err) @@ -67,8 +67,8 @@ func TestScaleClusterNonTLS(t *testing.T) { // Remove 3 DBServers, 2 coordinator updated, err = updateDeployment(c, depl.GetName(), ns, func(spec *api.DeploymentSpec) { - spec.DBServers.Count = 3 - spec.Coordinators.Count = 2 + spec.DBServers.Count = util.NewInt(3) + spec.Coordinators.Count = util.NewInt(2) }) if err != nil { t.Fatalf("Failed to update deployment: %v", err) @@ -93,7 +93,7 @@ func TestScaleCluster(t *testing.T) { // Prepare deployment config depl := newDeployment("test-scale" + uniuri.NewLen(4)) - depl.Spec.Mode = api.DeploymentModeCluster + depl.Spec.Mode = api.NewMode(api.DeploymentModeCluster) depl.Spec.TLS = api.TLSSpec{} // should auto-generate cert depl.Spec.SetDefaults(depl.GetName()) // this must be last @@ -121,8 +121,8 @@ func TestScaleCluster(t *testing.T) { // Add 2 DBServers, 1 coordinator updated, err := updateDeployment(c, depl.GetName(), ns, func(spec *api.DeploymentSpec) { - spec.DBServers.Count = 5 - spec.Coordinators.Count = 4 + spec.DBServers.Count = util.NewInt(5) + spec.Coordinators.Count = util.NewInt(4) }) if err != nil { t.Fatalf("Failed to update deployment: %v", err) @@ -137,8 +137,8 @@ func TestScaleCluster(t *testing.T) { // Remove 3 DBServers, 2 coordinator updated, err = updateDeployment(c, depl.GetName(), ns, func(spec *api.DeploymentSpec) { - spec.DBServers.Count = 3 - spec.Coordinators.Count = 2 + spec.DBServers.Count = util.NewInt(3) + spec.Coordinators.Count = util.NewInt(2) }) if err != nil { t.Fatalf("Failed to update deployment: %v", err) diff --git a/tests/test_util.go b/tests/test_util.go index 9f78e276b..eaac48f02 100644 --- a/tests/test_util.go +++ b/tests/test_util.go @@ -239,13 +239,13 @@ func clusterHealthEqualsSpec(h driver.ClusterHealth, spec api.DeploymentSpec) er } } } - if spec.Agents.Count == agents && - spec.DBServers.Count == goodDBServers && - spec.Coordinators.Count == goodCoordinators { + if spec.Agents.GetCount() == agents && + spec.DBServers.GetCount() == goodDBServers && + spec.Coordinators.GetCount() == goodCoordinators { return nil } return fmt.Errorf("Expected %d,%d,%d got %d,%d,%d", - spec.Agents.Count, spec.DBServers.Count, spec.Coordinators.Count, + spec.Agents.GetCount(), spec.DBServers.GetCount(), spec.Coordinators.GetCount(), agents, goodDBServers, goodCoordinators, ) }