From b701dd48e6aec738d94e12ea893a3c89c7120bbe Mon Sep 17 00:00:00 2001 From: Dan Prince Date: Tue, 13 Feb 2024 10:26:48 -0500 Subject: [PATCH] Add CinderSpecCore struct This version of the struct (called "core") is meant to be used via the OpenStackControlplane. It is the same as CinderSpec only it is missing the containerImages from the nested API, Backup, Scheduler, and Volume specs. The Default() function for webhooks has been split accordingly. Jira: OSPRH-4835 --- api/v1beta1/cinder_types.go | 56 ++++++--- api/v1beta1/cinder_webhook.go | 26 ++-- api/v1beta1/cinderapi_types.go | 28 +++++ api/v1beta1/cinderbackup_types.go | 18 +++ api/v1beta1/cinderscheduler_types.go | 17 +++ api/v1beta1/cindervolume_types.go | 19 +++ api/v1beta1/common_types.go | 3 - api/v1beta1/zz_generated.deepcopy.go | 138 +++++++++++++++++++++- test/functional/cinder_controller_test.go | 4 +- 9 files changed, 270 insertions(+), 39 deletions(-) diff --git a/api/v1beta1/cinder_types.go b/api/v1beta1/cinder_types.go index 6aeeebb5d..519572c62 100644 --- a/api/v1beta1/cinder_types.go +++ b/api/v1beta1/cinder_types.go @@ -52,8 +52,7 @@ const ( DBPurgeDefaultSchedule = "1 0 * * *" ) -// CinderSpec defines the desired state of Cinder -type CinderSpec struct { +type CinderSpecBase struct { CinderTemplate `json:",inline"` // +kubebuilder:validation:Required @@ -89,35 +88,60 @@ type CinderSpec struct { // to /etc//.conf.d directory as a custom config file. CustomServiceConfig string `json:"customServiceConfig,omitempty"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional + // ExtraMounts containing conf files and credentials + ExtraMounts []CinderExtraVolMounts `json:"extraMounts,omitempty"` + + // +kubebuilder:validation:Optional + // NodeSelector to target subset of worker nodes running this service. Setting + // NodeSelector here acts as a default value and can be overridden by service + // specific NodeSelector Settings. + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + + // +kubebuilder:validation:Optional + // DBPurge parameters - + DBPurge DBPurge `json:"dbPurge,omitempty"` +} + +// CinderSpecCore the same as CinderSpec without ContainerImage references +type CinderSpecCore struct { + CinderSpecBase `json:",inline"` + // CinderAPI - Spec definition for the API service of this Cinder deployment - CinderAPI CinderAPITemplate `json:"cinderAPI"` + CinderAPI CinderAPITemplateCore `json:"cinderAPI"` // +kubebuilder:validation:Required // CinderScheduler - Spec definition for the Scheduler service of this Cinder deployment - CinderScheduler CinderSchedulerTemplate `json:"cinderScheduler"` + CinderScheduler CinderSchedulerTemplateCore `json:"cinderScheduler"` // +kubebuilder:validation:Optional // CinderBackup - Spec definition for the Backup service of this Cinder deployment - CinderBackup CinderBackupTemplate `json:"cinderBackup"` + CinderBackup CinderBackupTemplateCore `json:"cinderBackup"` // +kubebuilder:validation:Optional // CinderVolumes - Map of chosen names to spec definitions for the Volume(s) service(s) of this Cinder deployment - CinderVolumes map[string]CinderVolumeTemplate `json:"cinderVolumes,omitempty"` + CinderVolumes map[string]CinderVolumeTemplateCore `json:"cinderVolumes,omitempty"` +} - // +kubebuilder:validation:Optional - // ExtraMounts containing conf files and credentials - ExtraMounts []CinderExtraVolMounts `json:"extraMounts,omitempty"` +// CinderSpec defines the desired state of Cinder +type CinderSpec struct { + CinderSpecBase `json:",inline"` + + // +kubebuilder:validation:Required + // CinderAPI - Spec definition for the API service of this Cinder deployment + CinderAPI CinderAPITemplate `json:"cinderAPI"` + + // +kubebuilder:validation:Required + // CinderScheduler - Spec definition for the Scheduler service of this Cinder deployment + CinderScheduler CinderSchedulerTemplate `json:"cinderScheduler"` // +kubebuilder:validation:Optional - // NodeSelector to target subset of worker nodes running this service. Setting - // NodeSelector here acts as a default value and can be overridden by service - // specific NodeSelector Settings. - NodeSelector map[string]string `json:"nodeSelector,omitempty"` + // CinderBackup - Spec definition for the Backup service of this Cinder deployment + CinderBackup CinderBackupTemplate `json:"cinderBackup"` // +kubebuilder:validation:Optional - // DBPurge parameters - - DBPurge DBPurge `json:"dbPurge,omitempty"` + // CinderVolumes - Map of chosen names to spec definitions for the Volume(s) service(s) of this Cinder deployment + CinderVolumes map[string]CinderVolumeTemplate `json:"cinderVolumes,omitempty"` } // CinderStatus defines the observed state of Cinder diff --git a/api/v1beta1/cinder_webhook.go b/api/v1beta1/cinder_webhook.go index d30c80a29..2edbb91db 100644 --- a/api/v1beta1/cinder_webhook.go +++ b/api/v1beta1/cinder_webhook.go @@ -74,30 +74,30 @@ var _ webhook.Defaulter = &Cinder{} func (r *Cinder) Default() { cinderlog.Info("default", "name", r.Name) - r.Spec.Default() -} - -// Default - set defaults for this Cinder spec -func (spec *CinderSpec) Default() { - if spec.CinderAPI.ContainerImage == "" { - spec.CinderAPI.ContainerImage = cinderDefaults.APIContainerImageURL + if r.Spec.CinderAPI.ContainerImage == "" { + r.Spec.CinderAPI.ContainerImage = cinderDefaults.APIContainerImageURL } - if spec.CinderBackup.ContainerImage == "" { - spec.CinderBackup.ContainerImage = cinderDefaults.BackupContainerImageURL + if r.Spec.CinderBackup.ContainerImage == "" { + r.Spec.CinderBackup.ContainerImage = cinderDefaults.BackupContainerImageURL } - if spec.CinderScheduler.ContainerImage == "" { - spec.CinderScheduler.ContainerImage = cinderDefaults.SchedulerContainerImageURL + if r.Spec.CinderScheduler.ContainerImage == "" { + r.Spec.CinderScheduler.ContainerImage = cinderDefaults.SchedulerContainerImageURL } - for index, cinderVolume := range spec.CinderVolumes { + for index, cinderVolume := range r.Spec.CinderVolumes { if cinderVolume.ContainerImage == "" { cinderVolume.ContainerImage = cinderDefaults.VolumeContainerImageURL } // This is required, as the loop variable is a by-value copy - spec.CinderVolumes[index] = cinderVolume + r.Spec.CinderVolumes[index] = cinderVolume } + r.Spec.Default() +} + +// Default - set defaults for this Cinder spec +func (spec *CinderSpecBase) Default() { if spec.DBPurge.Age == 0 { spec.DBPurge.Age = cinderDefaults.DBPurgeAge diff --git a/api/v1beta1/cinderapi_types.go b/api/v1beta1/cinderapi_types.go index bc145e739..cf772a801 100644 --- a/api/v1beta1/cinderapi_types.go +++ b/api/v1beta1/cinderapi_types.go @@ -23,8 +23,36 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) + +// CinderAPITemplate defines the input parameters for the Cinder API service +type CinderAPITemplateCore struct { + // Common input parameters for the Cinder API service + CinderServiceTemplate `json:",inline"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=0 + // Replicas - Cinder API Replicas + Replicas *int32 `json:"replicas"` + + // +kubebuilder:validation:Optional + // Override, provides the ability to override the generated manifest of several child resources. + Override APIOverrideSpec `json:"override,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // TLS - Parameters related to the TLS + TLS tls.API `json:"tls,omitempty"` +} + + // CinderAPITemplate defines the input parameters for the Cinder API service type CinderAPITemplate struct { + + // +kubebuilder:validation:Required + // ContainerImage - Cinder Container Image URL (will be set to environmental default if empty) + ContainerImage string `json:"containerImage"` + // Common input parameters for the Cinder API service CinderServiceTemplate `json:",inline"` diff --git a/api/v1beta1/cinderbackup_types.go b/api/v1beta1/cinderbackup_types.go index 00e9fd87f..60be729b8 100644 --- a/api/v1beta1/cinderbackup_types.go +++ b/api/v1beta1/cinderbackup_types.go @@ -22,8 +22,26 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// CinderBackupTemplate defines the input parameters for the Cinder Backup service +type CinderBackupTemplateCore struct { + // Common input parameters for the Cinder Backup service + CinderServiceTemplate `json:",inline"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=0 + // Replicas - Cinder Backup Replicas + Replicas *int32 `json:"replicas"` +} + + // CinderBackupTemplate defines the input parameters for the Cinder Backup service type CinderBackupTemplate struct { + + // +kubebuilder:validation:Required + // ContainerImage - Cinder Container Image URL (will be set to environmental default if empty) + ContainerImage string `json:"containerImage"` + // Common input parameters for the Cinder Backup service CinderServiceTemplate `json:",inline"` diff --git a/api/v1beta1/cinderscheduler_types.go b/api/v1beta1/cinderscheduler_types.go index 063471c92..62065739c 100644 --- a/api/v1beta1/cinderscheduler_types.go +++ b/api/v1beta1/cinderscheduler_types.go @@ -22,8 +22,25 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// CinderSchedulerTemplate defines the input parameters for the Cinder Scheduler service +type CinderSchedulerTemplateCore struct { + // Common input parameters for the Cinder Scheduler service + CinderServiceTemplate `json:",inline"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=0 + // Replicas - Cinder Scheduler Replicas + Replicas *int32 `json:"replicas"` +} + // CinderSchedulerTemplate defines the input parameters for the Cinder Scheduler service type CinderSchedulerTemplate struct { + + // +kubebuilder:validation:Required + // ContainerImage - Cinder Container Image URL (will be set to environmental default if empty) + ContainerImage string `json:"containerImage"` + // Common input parameters for the Cinder Scheduler service CinderServiceTemplate `json:",inline"` diff --git a/api/v1beta1/cindervolume_types.go b/api/v1beta1/cindervolume_types.go index 00fe376eb..2dd291335 100644 --- a/api/v1beta1/cindervolume_types.go +++ b/api/v1beta1/cindervolume_types.go @@ -22,8 +22,27 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// CinderVolumeTemplate defines the input parameters for the Cinder Volume service +type CinderVolumeTemplateCore struct { + // Common input parameters for the Cinder Volume service + CinderServiceTemplate `json:",inline"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default=1 + // +kubebuilder:validation:Minimum=0 + // +kubebuilder:validation:Maximum=1 + // Replicas - Cinder Volume Replicas + Replicas *int32 `json:"replicas"` +} + + // CinderVolumeTemplate defines the input parameters for the Cinder Volume service type CinderVolumeTemplate struct { + + // +kubebuilder:validation:Required + // ContainerImage - Cinder Container Image URL (will be set to environmental default if empty) + ContainerImage string `json:"containerImage"` + // Common input parameters for the Cinder Volume service CinderServiceTemplate `json:",inline"` diff --git a/api/v1beta1/common_types.go b/api/v1beta1/common_types.go index e2f6358ad..6eec263e8 100644 --- a/api/v1beta1/common_types.go +++ b/api/v1beta1/common_types.go @@ -46,9 +46,6 @@ type CinderTemplate struct { // CinderServiceTemplate defines the input parameters that can be defined for a given // Cinder service type CinderServiceTemplate struct { - // +kubebuilder:validation:Required - // ContainerImage - Cinder Container Image URL (will be set to environmental default if empty) - ContainerImage string `json:"containerImage"` // +kubebuilder:validation:Optional // NodeSelector to target subset of worker nodes running this service. Setting here overrides diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 0e0b056d8..1e553e22c 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -251,6 +251,29 @@ func (in *CinderAPITemplate) DeepCopy() *CinderAPITemplate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CinderAPITemplateCore) DeepCopyInto(out *CinderAPITemplateCore) { + *out = *in + in.CinderServiceTemplate.DeepCopyInto(&out.CinderServiceTemplate) + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + in.Override.DeepCopyInto(&out.Override) + in.TLS.DeepCopyInto(&out.TLS) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderAPITemplateCore. +func (in *CinderAPITemplateCore) DeepCopy() *CinderAPITemplateCore { + if in == nil { + return nil + } + out := new(CinderAPITemplateCore) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CinderBackup) DeepCopyInto(out *CinderBackup) { *out = *in @@ -400,6 +423,27 @@ func (in *CinderBackupTemplate) DeepCopy() *CinderBackupTemplate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CinderBackupTemplateCore) DeepCopyInto(out *CinderBackupTemplateCore) { + *out = *in + in.CinderServiceTemplate.DeepCopyInto(&out.CinderServiceTemplate) + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderBackupTemplateCore. +func (in *CinderBackupTemplateCore) DeepCopy() *CinderBackupTemplateCore { + if in == nil { + return nil + } + out := new(CinderBackupTemplateCore) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CinderDebug) DeepCopyInto(out *CinderDebug) { *out = *in @@ -633,6 +677,27 @@ func (in *CinderSchedulerTemplate) DeepCopy() *CinderSchedulerTemplate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CinderSchedulerTemplateCore) DeepCopyInto(out *CinderSchedulerTemplateCore) { + *out = *in + in.CinderServiceTemplate.DeepCopyInto(&out.CinderServiceTemplate) + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderSchedulerTemplateCore. +func (in *CinderSchedulerTemplateCore) DeepCopy() *CinderSchedulerTemplateCore { + if in == nil { + return nil + } + out := new(CinderSchedulerTemplateCore) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CinderServiceDebug) DeepCopyInto(out *CinderServiceDebug) { *out = *in @@ -685,8 +750,7 @@ func (in *CinderServiceTemplate) DeepCopy() *CinderServiceTemplate { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CinderSpec) DeepCopyInto(out *CinderSpec) { *out = *in - out.CinderTemplate = in.CinderTemplate - out.Debug = in.Debug + in.CinderSpecBase.DeepCopyInto(&out.CinderSpecBase) in.CinderAPI.DeepCopyInto(&out.CinderAPI) in.CinderScheduler.DeepCopyInto(&out.CinderScheduler) in.CinderBackup.DeepCopyInto(&out.CinderBackup) @@ -697,6 +761,23 @@ func (in *CinderSpec) DeepCopyInto(out *CinderSpec) { (*out)[key] = *val.DeepCopy() } } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderSpec. +func (in *CinderSpec) DeepCopy() *CinderSpec { + if in == nil { + return nil + } + out := new(CinderSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CinderSpecBase) DeepCopyInto(out *CinderSpecBase) { + *out = *in + out.CinderTemplate = in.CinderTemplate + out.Debug = in.Debug if in.ExtraMounts != nil { in, out := &in.ExtraMounts, &out.ExtraMounts *out = make([]CinderExtraVolMounts, len(*in)) @@ -714,12 +795,38 @@ func (in *CinderSpec) DeepCopyInto(out *CinderSpec) { out.DBPurge = in.DBPurge } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderSpec. -func (in *CinderSpec) DeepCopy() *CinderSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderSpecBase. +func (in *CinderSpecBase) DeepCopy() *CinderSpecBase { if in == nil { return nil } - out := new(CinderSpec) + out := new(CinderSpecBase) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CinderSpecCore) DeepCopyInto(out *CinderSpecCore) { + *out = *in + in.CinderSpecBase.DeepCopyInto(&out.CinderSpecBase) + in.CinderAPI.DeepCopyInto(&out.CinderAPI) + in.CinderScheduler.DeepCopyInto(&out.CinderScheduler) + in.CinderBackup.DeepCopyInto(&out.CinderBackup) + if in.CinderVolumes != nil { + in, out := &in.CinderVolumes, &out.CinderVolumes + *out = make(map[string]CinderVolumeTemplateCore, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderSpecCore. +func (in *CinderSpecCore) DeepCopy() *CinderSpecCore { + if in == nil { + return nil + } + out := new(CinderSpecCore) in.DeepCopyInto(out) return out } @@ -949,6 +1056,27 @@ func (in *CinderVolumeTemplate) DeepCopy() *CinderVolumeTemplate { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CinderVolumeTemplateCore) DeepCopyInto(out *CinderVolumeTemplateCore) { + *out = *in + in.CinderServiceTemplate.DeepCopyInto(&out.CinderServiceTemplate) + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderVolumeTemplateCore. +func (in *CinderVolumeTemplateCore) DeepCopy() *CinderVolumeTemplateCore { + if in == nil { + return nil + } + out := new(CinderVolumeTemplateCore) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DBPurge) DeepCopyInto(out *DBPurge) { *out = *in diff --git a/test/functional/cinder_controller_test.go b/test/functional/cinder_controller_test.go index bba5adeb1..73ae909bd 100644 --- a/test/functional/cinder_controller_test.go +++ b/test/functional/cinder_controller_test.go @@ -238,8 +238,8 @@ var _ = Describe("Cinder controller", func() { }) It("has the expected container image defaults", func() { cinderDefault := GetCinder(cinderTest.Instance) - Expect(cinderDefault.Spec.CinderAPI.CinderServiceTemplate.ContainerImage).To(Equal(util.GetEnvVar("RELATED_IMAGE_CINDER_API_IMAGE_URL_DEFAULT", cinderv1.CinderAPIContainerImage))) - Expect(cinderDefault.Spec.CinderScheduler.CinderServiceTemplate.ContainerImage).To(Equal(util.GetEnvVar("RELATED_IMAGE_CINDER_SCHEDULER_IMAGE_URL_DEFAULT", cinderv1.CinderSchedulerContainerImage))) + Expect(cinderDefault.Spec.CinderAPI.ContainerImage).To(Equal(util.GetEnvVar("RELATED_IMAGE_CINDER_API_IMAGE_URL_DEFAULT", cinderv1.CinderAPIContainerImage))) + Expect(cinderDefault.Spec.CinderScheduler.ContainerImage).To(Equal(util.GetEnvVar("RELATED_IMAGE_CINDER_SCHEDULER_IMAGE_URL_DEFAULT", cinderv1.CinderSchedulerContainerImage))) for _, volume := range cinderDefault.Spec.CinderVolumes { Expect(volume.ContainerImage).To(Equal(util.GetEnvVar("RELATED_IMAGE_CINDER_VOLUME_IMAGE_URL_DEFAULT", cinderv1.CinderVolumeContainerImage))) }