diff --git a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml index c7dfeca4c..d36078ede 100644 --- a/apis/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/apis/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -11037,6 +11037,9 @@ spec: type: object openstackclient: properties: + enabled: + default: true + type: boolean template: properties: caBundleSecretName: diff --git a/apis/core/v1beta1/openstackcontrolplane_types.go b/apis/core/v1beta1/openstackcontrolplane_types.go index 9ec20b2b7..47a7813ed 100644 --- a/apis/core/v1beta1/openstackcontrolplane_types.go +++ b/apis/core/v1beta1/openstackcontrolplane_types.go @@ -128,10 +128,12 @@ type OpenStackControlPlaneSpec struct { // Memcached - Parameters related to the Memcached service Memcached MemcachedSection `json:"memcached,omitempty"` + // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Ovn - Overrides to use when creating the OVN Services Ovn OvnSection `json:"ovn,omitempty"` + // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Neutron - Overrides to use when creating the Neutron Service Neutron NeutronSection `json:"neutron,omitempty"` @@ -151,6 +153,8 @@ type OpenStackControlPlaneSpec struct { // Ironic - Parameters related to the Ironic services Ironic IronicSection `json:"ironic,omitempty"` + // +kubebuilder:validation:Optional + //+operator-sdk:csv:customresourcedefinitions:type=spec // Manila - Parameters related to the Manila service Manila ManilaSection `json:"manila,omitempty"` @@ -160,18 +164,27 @@ type OpenStackControlPlaneSpec struct { Horizon HorizonSection `json:"horizon,omitempty"` // +kubebuilder:validation:Optional + //+operator-sdk:csv:customresourcedefinitions:type=spec // Telemetry - Parameters related to the OpenStack Telemetry services Telemetry TelemetrySection `json:"telemetry,omitempty"` + // +kubebuilder:validation:Optional + //+operator-sdk:csv:customresourcedefinitions:type=spec // Swift - Parameters related to the Swift service Swift SwiftSection `json:"swift,omitempty"` + // +kubebuilder:validation:Optional + //+operator-sdk:csv:customresourcedefinitions:type=spec // Octavia - Parameters related to the Octavia service Octavia OctaviaSection `json:"octavia,omitempty"` + // +kubebuilder:validation:Optional + //+operator-sdk:csv:customresourcedefinitions:type=spec // Designate - Parameters related to the Designate service Designate DesignateSection `json:"designate,omitempty"` + // +kubebuilder:validation:Optional + //+operator-sdk:csv:customresourcedefinitions:type=spec // Barbican - Parameters related to the Barbican service Barbican BarbicanSection `json:"barbican,omitempty"` @@ -322,7 +335,7 @@ type DNSMasqSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the DNSMasq service - Template networkv1.DNSMasqSpec `json:"template,omitempty"` + Template *networkv1.DNSMasqSpec `json:"template,omitempty"` } // KeystoneSection defines the desired state of Keystone service @@ -336,7 +349,7 @@ type KeystoneSection struct { // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Keystone service - Template keystonev1.KeystoneAPISpecCore `json:"template,omitempty"` + Template *keystonev1.KeystoneAPISpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -376,7 +389,7 @@ type PlacementSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Placement API - Template placementv1.PlacementAPISpecCore `json:"template,omitempty"` + Template *placementv1.PlacementAPISpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -395,7 +408,7 @@ type GlanceSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Glance Service - Template glancev1.GlanceSpecCore `json:"template,omitempty"` + Template *glancev1.GlanceSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -414,7 +427,7 @@ type CinderSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating Cinder Resources - Template cinderv1.CinderSpecCore `json:"template,omitempty"` + Template *cinderv1.CinderSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -433,7 +446,7 @@ type GaleraSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Templates - Overrides to use when creating the Galera databases - Templates map[string]mariadbv1.GaleraSpecCore `json:"templates,omitempty"` + Templates *map[string]mariadbv1.GaleraSpecCore `json:"templates,omitempty"` } // RabbitmqSection defines the desired state of RabbitMQ service @@ -447,7 +460,7 @@ type RabbitmqSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Templates - Overrides to use when creating the Rabbitmq clusters - Templates map[string]RabbitmqTemplate `json:"templates"` + Templates *map[string]RabbitmqTemplate `json:"templates"` } // MemcachedSection defines the desired state of Memcached services @@ -461,7 +474,7 @@ type MemcachedSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Templates - Overrides to use when creating the Memcached databases - Templates map[string]memcachedv1.MemcachedSpecCore `json:"templates,omitempty"` + Templates *map[string]memcachedv1.MemcachedSpecCore `json:"templates,omitempty"` } // RabbitmqTemplate definition @@ -483,7 +496,7 @@ type OvnSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the OVN services - Template OvnResources `json:"template,omitempty"` + Template *OvnResources `json:"template,omitempty"` } // OvnResources defines the desired state of OVN services @@ -515,7 +528,7 @@ type NeutronSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Neutron Service - Template neutronv1.NeutronAPISpecCore `json:"template,omitempty"` + Template *neutronv1.NeutronAPISpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -534,7 +547,7 @@ type NovaSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Nova services - Template novav1.NovaSpec `json:"template,omitempty"` + Template *novav1.NovaSpec `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -566,7 +579,7 @@ type HeatSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Heat services - Template heatv1.HeatSpecCore `json:"template,omitempty"` + Template *heatv1.HeatSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -590,7 +603,7 @@ type IronicSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Ironic services - Template ironicv1.IronicSpecCore `json:"template,omitempty"` + Template *ironicv1.IronicSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -612,8 +625,9 @@ type ManilaSection struct { Enabled bool `json:"enabled"` // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating Manila Resources - Template manilav1.ManilaSpecCore `json:"template,omitempty"` + Template *manilav1.ManilaSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -629,8 +643,9 @@ type HorizonSection struct { Enabled bool `json:"enabled"` // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Horizon services - Template horizonv1.HorizonSpecCore `json:"template,omitempty"` + Template *horizonv1.HorizonSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -649,7 +664,7 @@ type TelemetrySection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the OpenStack Telemetry services - Template telemetryv1.TelemetrySpecCore `json:"template,omitempty"` + Template *telemetryv1.TelemetrySpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -678,7 +693,7 @@ type SwiftSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating Swift Resources - Template swiftv1.SwiftSpecCore `json:"template,omitempty"` + Template *swiftv1.SwiftSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -697,7 +712,7 @@ type OctaviaSection struct { // +kubebuilder:valdiation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating Octavia Resources - Template octaviav1.OctaviaSpecCore `json:"template,omitempty"` + Template *octaviav1.OctaviaSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -716,7 +731,7 @@ type DesignateSection struct { // +kubebuilder:valdiation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating Designate Resources - Template designatev1.DesignateSpecCore `json:"template,omitempty"` + Template *designatev1.DesignateSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -735,7 +750,7 @@ type BarbicanSection struct { // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the Barbican Service - Template barbicanv1.BarbicanSpecCore `json:"template,omitempty"` + Template *barbicanv1.BarbicanSpecCore `json:"template,omitempty"` // +kubebuilder:validation:Optional // +operator-sdk:csv:customresourcedefinitions:type=spec @@ -745,6 +760,12 @@ type BarbicanSection struct { // OpenStackClientSection defines the desired state of the OpenStackClient type OpenStackClientSection struct { + // +kubebuilder:validation:Optional + // Enabled - Whether the OpenStackClient pod should be deployed and managed + // +kubebuilder:default=true + // +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:booleanSwitch"} + Enabled bool `json:"enabled"` + // +kubebuilder:validation:Optional //+operator-sdk:csv:customresourcedefinitions:type=spec // Template - Overrides to use when creating the OpenStackClient Resource diff --git a/apis/core/v1beta1/openstackcontrolplane_webhook.go b/apis/core/v1beta1/openstackcontrolplane_webhook.go index 8b4edaf23..97f55c01e 100644 --- a/apis/core/v1beta1/openstackcontrolplane_webhook.go +++ b/apis/core/v1beta1/openstackcontrolplane_webhook.go @@ -20,15 +20,35 @@ import ( "fmt" "strings" + keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" "github.com/openstack-k8s-operators/lib-common/modules/common/route" + placementv1 "github.com/openstack-k8s-operators/placement-operator/api/v1beta1" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/validation/field" + "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/webhook" "sigs.k8s.io/controller-runtime/pkg/webhook/admission" + + barbicanv1 "github.com/openstack-k8s-operators/barbican-operator/api/v1beta1" + cinderv1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1" + glancev1 "github.com/openstack-k8s-operators/glance-operator/api/v1beta1" + heatv1 "github.com/openstack-k8s-operators/heat-operator/api/v1beta1" + horizonv1 "github.com/openstack-k8s-operators/horizon-operator/api/v1beta1" + memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" + networkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1" + ironicv1 "github.com/openstack-k8s-operators/ironic-operator/api/v1beta1" + manilav1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" + neutronv1 "github.com/openstack-k8s-operators/neutron-operator/api/v1beta1" + novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" + octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1" + swiftv1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" + telemetryv1 "github.com/openstack-k8s-operators/telemetry-operator/api/v1beta1" + //rabbitmqv2 "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" + //designatev1 "github.com/openstack-k8s-operators/designate-operator/api/v1beta1" ) // OpenStackControlPlaneDefaults - @@ -167,6 +187,10 @@ func (r *OpenStackControlPlane) checkDepsEnabled(name string) string { r.Spec.Ovn.Enabled) { reqs = "Galera, Memcached, RabbitMQ, Keystone, Glance, Neutron, Nova, OVN" } + case "OpenStackClient": + if !r.Spec.Keystone.Enabled { + reqs = "Keystone" + } } // If "reqs" is not the empty string, we have missing requirements @@ -184,55 +208,55 @@ func (r *OpenStackControlPlane) ValidateCreateServices(basePath *field.Path) fie errors = append(errors, r.ValidateServiceDependencies(basePath)...) // Call internal validation logic for individual service operators - if r.Spec.Keystone.Enabled { + if r.Spec.Keystone.Enabled && r.Spec.Keystone.Template != nil { errors = append(errors, r.Spec.Keystone.Template.ValidateCreate(basePath.Child("keystone").Child("template"))...) } - if r.Spec.Ironic.Enabled { + if r.Spec.Ironic.Enabled && r.Spec.Ironic.Template != nil { errors = append(errors, r.Spec.Ironic.Template.ValidateCreate(basePath.Child("ironic").Child("template"))...) } - if r.Spec.Nova.Enabled { + if r.Spec.Nova.Enabled && r.Spec.Nova.Template != nil { errors = append(errors, r.Spec.Nova.Template.ValidateCreate(basePath.Child("nova").Child("template"))...) } - if r.Spec.Placement.Enabled { + if r.Spec.Placement.Enabled && r.Spec.Placement.Template != nil { errors = append(errors, r.Spec.Placement.Template.ValidateCreate(basePath.Child("placement").Child("template"))...) } - if r.Spec.Barbican.Enabled { + if r.Spec.Barbican.Enabled && r.Spec.Barbican.Template != nil { errors = append(errors, r.Spec.Barbican.Template.ValidateCreate(basePath.Child("barbican").Child("template"))...) } - if r.Spec.Neutron.Enabled { + if r.Spec.Neutron.Enabled && r.Spec.Neutron.Template != nil { errors = append(errors, r.Spec.Neutron.Template.ValidateCreate(basePath.Child("neutron").Child("template"))...) } - if r.Spec.Glance.Enabled { + if r.Spec.Glance.Enabled && r.Spec.Glance.Template != nil { errors = append(errors, r.Spec.Glance.Template.ValidateCreate(basePath.Child("glance").Child("template"))...) } - if r.Spec.Cinder.Enabled { + if r.Spec.Cinder.Enabled && r.Spec.Cinder.Template != nil { errors = append(errors, r.Spec.Cinder.Template.ValidateCreate(basePath.Child("cinder").Child("template"))...) } - if r.Spec.Heat.Enabled { + if r.Spec.Heat.Enabled && r.Spec.Heat.Template != nil { errors = append(errors, r.Spec.Heat.Template.ValidateCreate(basePath.Child("heat").Child("template"))...) } - if r.Spec.Manila.Enabled { + if r.Spec.Manila.Enabled && r.Spec.Manila.Template != nil { errors = append(errors, r.Spec.Manila.Template.ValidateCreate(basePath.Child("manila").Child("template"))...) } - if r.Spec.Swift.Enabled { + if r.Spec.Swift.Enabled && r.Spec.Swift.Template != nil { errors = append(errors, r.Spec.Swift.Template.ValidateCreate(basePath.Child("swift").Child("template"))...) } - if r.Spec.Octavia.Enabled { + if r.Spec.Octavia.Enabled && r.Spec.Octavia.Template != nil { errors = append(errors, r.Spec.Octavia.Template.ValidateCreate(basePath.Child("octavia").Child("template"))...) } - if r.Spec.Designate.Enabled { + if r.Spec.Designate.Enabled && r.Spec.Designate.Template != nil { errors = append(errors, r.Spec.Designate.Template.ValidateCreate(basePath.Child("designate").Child("template"))...) } @@ -246,56 +270,56 @@ func (r *OpenStackControlPlane) ValidateUpdateServices(old OpenStackControlPlane errors = append(errors, r.ValidateServiceDependencies(basePath)...) // Call internal validation logic for individual service operators - if r.Spec.Keystone.Enabled { - errors = append(errors, r.Spec.Keystone.Template.ValidateUpdate(old.Keystone.Template, basePath.Child("keystone").Child("template"))...) + if r.Spec.Keystone.Enabled && r.Spec.Keystone.Template != nil && old.Keystone.Template != nil { + errors = append(errors, r.Spec.Keystone.Template.ValidateUpdate(*old.Keystone.Template, basePath.Child("keystone").Child("template"))...) } - if r.Spec.Ironic.Enabled { - errors = append(errors, r.Spec.Ironic.Template.ValidateUpdate(old.Ironic.Template, basePath.Child("ironic").Child("template"))...) + if r.Spec.Ironic.Enabled && r.Spec.Ironic.Template != nil && old.Ironic.Template != nil { + errors = append(errors, r.Spec.Ironic.Template.ValidateUpdate(*old.Ironic.Template, basePath.Child("ironic").Child("template"))...) } - if r.Spec.Nova.Enabled { - errors = append(errors, r.Spec.Nova.Template.ValidateUpdate(old.Nova.Template, basePath.Child("nova").Child("template"))...) + if r.Spec.Nova.Enabled && r.Spec.Nova.Template != nil && old.Nova.Template != nil { + errors = append(errors, r.Spec.Nova.Template.ValidateUpdate(*old.Nova.Template, basePath.Child("nova").Child("template"))...) } - if r.Spec.Placement.Enabled { - errors = append(errors, r.Spec.Placement.Template.ValidateUpdate(old.Placement.Template, basePath.Child("placement").Child("template"))...) + if r.Spec.Placement.Enabled && r.Spec.Placement.Template != nil && old.Placement.Template != nil { + errors = append(errors, r.Spec.Placement.Template.ValidateUpdate(*old.Placement.Template, basePath.Child("placement").Child("template"))...) } - if r.Spec.Barbican.Enabled { - errors = append(errors, r.Spec.Barbican.Template.ValidateUpdate(old.Barbican.Template, basePath.Child("barbican").Child("template"))...) + if r.Spec.Barbican.Enabled && r.Spec.Barbican.Template != nil && old.Barbican.Template != nil { + errors = append(errors, r.Spec.Barbican.Template.ValidateUpdate(*old.Barbican.Template, basePath.Child("barbican").Child("template"))...) } - if r.Spec.Neutron.Enabled { - errors = append(errors, r.Spec.Neutron.Template.ValidateUpdate(old.Neutron.Template, basePath.Child("neutron").Child("template"))...) + if r.Spec.Neutron.Enabled && r.Spec.Neutron.Template != nil && old.Neutron.Template != nil { + errors = append(errors, r.Spec.Neutron.Template.ValidateUpdate(*old.Neutron.Template, basePath.Child("neutron").Child("template"))...) } - if r.Spec.Glance.Enabled { - errors = append(errors, r.Spec.Glance.Template.ValidateUpdate(old.Glance.Template, basePath.Child("glance").Child("template"))...) + if r.Spec.Glance.Enabled && r.Spec.Glance.Template != nil && old.Glance.Template != nil { + errors = append(errors, r.Spec.Glance.Template.ValidateUpdate(*old.Glance.Template, basePath.Child("glance").Child("template"))...) } - if r.Spec.Cinder.Enabled { - errors = append(errors, r.Spec.Cinder.Template.ValidateUpdate(old.Cinder.Template, basePath.Child("cinder").Child("template"))...) + if r.Spec.Cinder.Enabled && r.Spec.Cinder.Template != nil && old.Cinder.Template != nil { + errors = append(errors, r.Spec.Cinder.Template.ValidateUpdate(*old.Cinder.Template, basePath.Child("cinder").Child("template"))...) } - if r.Spec.Heat.Enabled { - errors = append(errors, r.Spec.Heat.Template.ValidateUpdate(old.Heat.Template, basePath.Child("heat").Child("template"))...) + if r.Spec.Heat.Enabled && r.Spec.Heat.Template != nil && old.Heat.Template != nil { + errors = append(errors, r.Spec.Heat.Template.ValidateUpdate(*old.Heat.Template, basePath.Child("heat").Child("template"))...) } - if r.Spec.Manila.Enabled { - errors = append(errors, r.Spec.Manila.Template.ValidateUpdate(old.Manila.Template, basePath.Child("manila").Child("template"))...) + if r.Spec.Manila.Enabled && r.Spec.Manila.Template != nil && old.Manila.Template != nil { + errors = append(errors, r.Spec.Manila.Template.ValidateUpdate(*old.Manila.Template, basePath.Child("manila").Child("template"))...) } - if r.Spec.Swift.Enabled { - errors = append(errors, r.Spec.Swift.Template.ValidateUpdate(old.Swift.Template, basePath.Child("swift").Child("template"))...) + if r.Spec.Swift.Enabled && r.Spec.Swift.Template != nil && old.Swift.Template != nil { + errors = append(errors, r.Spec.Swift.Template.ValidateUpdate(*old.Swift.Template, basePath.Child("swift").Child("template"))...) } - if r.Spec.Octavia.Enabled { - errors = append(errors, r.Spec.Octavia.Template.ValidateUpdate(old.Octavia.Template, basePath.Child("octavia").Child("template"))...) + if r.Spec.Octavia.Enabled && r.Spec.Octavia.Template != nil && old.Octavia.Template != nil { + errors = append(errors, r.Spec.Octavia.Template.ValidateUpdate(*old.Octavia.Template, basePath.Child("octavia").Child("template"))...) } - if r.Spec.Designate.Enabled { - errors = append(errors, r.Spec.Designate.Template.ValidateUpdate(old.Designate.Template, basePath.Child("designate").Child("template"))...) + if r.Spec.Designate.Enabled && r.Spec.Designate.Template != nil && old.Designate.Template != nil { + errors = append(errors, r.Spec.Designate.Template.ValidateUpdate(*old.Designate.Template, basePath.Child("designate").Child("template"))...) } return errors @@ -423,116 +447,213 @@ func setOverrideSpec(override **route.OverrideSpec, anno map[string]string) { // DefaultServices - common function for calling individual services' defaulting functions func (r *OpenStackControlPlane) DefaultServices() { // Cinder - r.Spec.Cinder.Template.Default() - initializeOverrideSpec(&r.Spec.Cinder.APIOverride.Route, true) - r.Spec.Cinder.Template.SetDefaultRouteAnnotations(r.Spec.Cinder.APIOverride.Route.Annotations) + if r.Spec.Cinder.Enabled { + if r.Spec.Cinder.Template == nil { + r.Spec.Cinder.Template = &cinderv1.CinderSpecCore{} + } + r.Spec.Cinder.Template.Default() + initializeOverrideSpec(&r.Spec.Cinder.APIOverride.Route, true) + r.Spec.Cinder.Template.SetDefaultRouteAnnotations(r.Spec.Cinder.APIOverride.Route.Annotations) + } // Galera - for key, template := range r.Spec.Galera.Templates { - if template.StorageClass == "" { - template.StorageClass = r.Spec.StorageClass + if r.Spec.Galera.Enabled && r.Spec.Galera.Templates != nil { + //if r.Spec.Galera.Templates == nil { + // r.Spec.Galera.Templates = ptr.To(map[string]mariadbv1.GaleraSpecCore{}) + //} + + for key, template := range *r.Spec.Galera.Templates { + if template.StorageClass == "" { + template.StorageClass = r.Spec.StorageClass + } + if template.Secret == "" { + template.Secret = r.Spec.Secret + } + template.Default() + // By-value copy, need to update + (*r.Spec.Galera.Templates)[key] = template } - if template.Secret == "" { - template.Secret = r.Spec.Secret - } - template.Default() - // By-value copy, need to update - r.Spec.Galera.Templates[key] = template } // Glance - r.Spec.Glance.Template.Default() - - // initialize the main APIOverride struct - if r.Spec.Glance.APIOverride == nil { - r.Spec.Glance.APIOverride = map[string]Override{} - } - for name, glanceAPI := range r.Spec.Glance.Template.GlanceAPIs { - var override Override - var ok bool - - if override, ok = r.Spec.Glance.APIOverride[name]; !ok { - override = Override{} + if r.Spec.Glance.Enabled { + if r.Spec.Glance.Template == nil { + r.Spec.Glance.Template = &glancev1.GlanceSpecCore{} + } + r.Spec.Glance.Template.Default() + // initialize the main APIOverride struct + if r.Spec.Glance.APIOverride == nil { + r.Spec.Glance.APIOverride = map[string]Override{} + } + for name, glanceAPI := range r.Spec.Glance.Template.GlanceAPIs { + var override Override + var ok bool + + if override, ok = r.Spec.Glance.APIOverride[name]; !ok { + override = Override{} + } + initializeOverrideSpec(&override.Route, true) + glanceAPI.SetDefaultRouteAnnotations(override.Route.Annotations) + r.Spec.Glance.APIOverride[name] = override } - initializeOverrideSpec(&override.Route, true) - glanceAPI.SetDefaultRouteAnnotations(override.Route.Annotations) - r.Spec.Glance.APIOverride[name] = override } // Ironic - // Default Secret - if r.Spec.Ironic.Template.Secret == "" { - r.Spec.Ironic.Template.Secret = r.Spec.Secret - } - // Default DatabaseInstance - if r.Spec.Ironic.Template.DatabaseInstance == "" { - r.Spec.Ironic.Template.DatabaseInstance = "openstack" - } - // Default StorageClass - if r.Spec.Ironic.Template.StorageClass == "" { - r.Spec.Ironic.Template.StorageClass = r.Spec.StorageClass + if r.Spec.Ironic.Enabled { + if r.Spec.Ironic.Template == nil { + r.Spec.Ironic.Template = &ironicv1.IronicSpecCore{} + } + + // Default Secret + if r.Spec.Ironic.Template.Secret == "" { + r.Spec.Ironic.Template.Secret = r.Spec.Secret + } + // Default DatabaseInstance + if r.Spec.Ironic.Template.DatabaseInstance == "" { + r.Spec.Ironic.Template.DatabaseInstance = "openstack" + } + // Default StorageClass + if r.Spec.Ironic.Template.StorageClass == "" { + r.Spec.Ironic.Template.StorageClass = r.Spec.StorageClass + } + r.Spec.Ironic.Template.Default() } - r.Spec.Ironic.Template.Default() // Keystone - r.Spec.Keystone.Template.Default() + if r.Spec.Keystone.Enabled { + if r.Spec.Keystone.Template == nil { + r.Spec.Keystone.Template = &keystonev1.KeystoneAPISpecCore{} + } + r.Spec.Keystone.Template.Default() + } // Manila - r.Spec.Manila.Template.Default() - initializeOverrideSpec(&r.Spec.Manila.APIOverride.Route, true) - r.Spec.Manila.Template.SetDefaultRouteAnnotations(r.Spec.Manila.APIOverride.Route.Annotations) + if r.Spec.Manila.Enabled { + if r.Spec.Manila.Template == nil { + r.Spec.Manila.Template = &manilav1.ManilaSpecCore{} + } + r.Spec.Manila.Template.Default() + initializeOverrideSpec(&r.Spec.Manila.APIOverride.Route, true) + r.Spec.Manila.Template.SetDefaultRouteAnnotations(r.Spec.Manila.APIOverride.Route.Annotations) + } // Memcached - for key, template := range r.Spec.Memcached.Templates { - template.Default() - // By-value copy, need to update - r.Spec.Memcached.Templates[key] = template + if r.Spec.Memcached.Enabled { + if r.Spec.Memcached.Templates == nil { + r.Spec.Memcached.Templates = ptr.To(map[string]memcachedv1.MemcachedSpecCore{}) + } + + for key, template := range *r.Spec.Memcached.Templates { + template.Default() + // By-value copy, need to update + (*r.Spec.Memcached.Templates)[key] = template + } } // Neutron - r.Spec.Neutron.Template.Default() - setOverrideSpec(&r.Spec.Neutron.APIOverride.Route, r.Spec.Neutron.Template.GetDefaultRouteAnnotations()) + if r.Spec.Neutron.Enabled { + if r.Spec.Neutron.Template == nil { + r.Spec.Neutron.Template = &neutronv1.NeutronAPISpecCore{} + } + r.Spec.Neutron.Template.Default() + setOverrideSpec(&r.Spec.Neutron.APIOverride.Route, r.Spec.Neutron.Template.GetDefaultRouteAnnotations()) + } // Nova - r.Spec.Nova.Template.Default() + if r.Spec.Nova.Enabled { + if r.Spec.Nova.Template == nil { + r.Spec.Nova.Template = &novav1.NovaSpec{} + } + r.Spec.Nova.Template.Default() + } // OVN - for key, template := range r.Spec.Ovn.Template.OVNDBCluster { - template.Default() - // By-value copy, need to update - r.Spec.Ovn.Template.OVNDBCluster[key] = template - } + if r.Spec.Ovn.Enabled { + if r.Spec.Ovn.Template == nil { + r.Spec.Ovn.Template = &OvnResources{} + } - r.Spec.Ovn.Template.OVNNorthd.Default() - r.Spec.Ovn.Template.OVNController.Default() + for key, template := range r.Spec.Ovn.Template.OVNDBCluster { + template.Default() + // By-value copy, need to update + r.Spec.Ovn.Template.OVNDBCluster[key] = template + } + + r.Spec.Ovn.Template.OVNNorthd.Default() + r.Spec.Ovn.Template.OVNController.Default() + } // Placement - r.Spec.Placement.Template.Default() + if r.Spec.Placement.Enabled { + if r.Spec.Placement.Template == nil { + r.Spec.Placement.Template = &placementv1.PlacementAPISpecCore{} + } + r.Spec.Placement.Template.Default() + } // DNS - r.Spec.DNS.Template.Default() + if r.Spec.DNS.Enabled { + if r.Spec.DNS.Template == nil { + r.Spec.DNS.Template = &networkv1.DNSMasqSpec{} + } + + r.Spec.DNS.Template.Default() + } // Telemetry - r.Spec.Telemetry.Template.Default() + if r.Spec.Telemetry.Enabled { + if r.Spec.Telemetry.Template == nil { + r.Spec.Telemetry.Template = &telemetryv1.TelemetrySpecCore{} + } + r.Spec.Telemetry.Template.Default() + } // Heat - r.Spec.Heat.Template.Default() + if r.Spec.Heat.Enabled { + if r.Spec.Heat.Template == nil { + r.Spec.Heat.Template = &heatv1.HeatSpecCore{} + } + r.Spec.Heat.Template.Default() + } // Swift - if r.Spec.Swift.Template.SwiftStorage.StorageClass == "" { - r.Spec.Swift.Template.SwiftStorage.StorageClass = r.Spec.StorageClass - } + if r.Spec.Swift.Enabled { + if r.Spec.Swift.Template == nil { + r.Spec.Swift.Template = &swiftv1.SwiftSpecCore{} + } - r.Spec.Swift.Template.Default() + if r.Spec.Swift.Template.SwiftStorage.StorageClass == "" { + r.Spec.Swift.Template.SwiftStorage.StorageClass = r.Spec.StorageClass + } + + r.Spec.Swift.Template.Default() + } // Horizon - r.Spec.Horizon.Template.Default() + if r.Spec.Horizon.Enabled { + if r.Spec.Horizon.Template == nil { + r.Spec.Horizon.Template = &horizonv1.HorizonSpecCore{} + } + + r.Spec.Horizon.Template.Default() + } // Octavia - r.Spec.Octavia.Template.Default() + if r.Spec.Octavia.Enabled { + if r.Spec.Octavia.Template == nil { + r.Spec.Octavia.Template = &octaviav1.OctaviaSpecCore{} + } + + r.Spec.Octavia.Template.Default() + } // Barbican - r.Spec.Barbican.Template.Default() + if r.Spec.Barbican.Enabled { + if r.Spec.Barbican.Template == nil { + r.Spec.Barbican.Template = &barbicanv1.BarbicanSpecCore{} + } + r.Spec.Barbican.Template.Default() + } } // DefaultLabel - adding default label to the OpenStackControlPlane diff --git a/apis/core/v1beta1/zz_generated.deepcopy.go b/apis/core/v1beta1/zz_generated.deepcopy.go index 5e8d1a0a0..9e80fa89e 100644 --- a/apis/core/v1beta1/zz_generated.deepcopy.go +++ b/apis/core/v1beta1/zz_generated.deepcopy.go @@ -22,12 +22,28 @@ limitations under the License. package v1beta1 import ( + barbican_operatorapiv1beta1 "github.com/openstack-k8s-operators/barbican-operator/api/v1beta1" + cinder_operatorapiv1beta1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1" + designate_operatorapiv1beta1 "github.com/openstack-k8s-operators/designate-operator/api/v1beta1" + glance_operatorapiv1beta1 "github.com/openstack-k8s-operators/glance-operator/api/v1beta1" + heat_operatorapiv1beta1 "github.com/openstack-k8s-operators/heat-operator/api/v1beta1" + horizon_operatorapiv1beta1 "github.com/openstack-k8s-operators/horizon-operator/api/v1beta1" memcachedv1beta1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" + networkv1beta1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1" + ironic_operatorapiv1beta1 "github.com/openstack-k8s-operators/ironic-operator/api/v1beta1" + apiv1beta1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/route" "github.com/openstack-k8s-operators/lib-common/modules/storage" - apiv1beta1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" + manila_operatorapiv1beta1 "github.com/openstack-k8s-operators/manila-operator/api/v1beta1" + mariadb_operatorapiv1beta1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" + neutron_operatorapiv1beta1 "github.com/openstack-k8s-operators/neutron-operator/api/v1beta1" + nova_operatorapiv1beta1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1" + octavia_operatorapiv1beta1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1" ovn_operatorapiv1beta1 "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1" + placement_operatorapiv1beta1 "github.com/openstack-k8s-operators/placement-operator/api/v1beta1" + swift_operatorapiv1beta1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" + telemetry_operatorapiv1beta1 "github.com/openstack-k8s-operators/telemetry-operator/api/v1beta1" "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" ) @@ -35,7 +51,11 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BarbicanSection) DeepCopyInto(out *BarbicanSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(barbican_operatorapiv1beta1.BarbicanSpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) } @@ -124,7 +144,11 @@ func (in *CertSection) DeepCopy() *CertSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CinderSection) DeepCopyInto(out *CinderSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(cinder_operatorapiv1beta1.CinderSpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) } @@ -659,7 +683,11 @@ func (in *CustomContainerImages) DeepCopy() *CustomContainerImages { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DNSMasqSection) DeepCopyInto(out *DNSMasqSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(networkv1beta1.DNSMasqSpec) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSMasqSection. @@ -675,7 +703,11 @@ func (in *DNSMasqSection) DeepCopy() *DNSMasqSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DesignateSection) DeepCopyInto(out *DesignateSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(designate_operatorapiv1beta1.DesignateSpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) } @@ -694,9 +726,13 @@ func (in *GaleraSection) DeepCopyInto(out *GaleraSection) { *out = *in if in.Templates != nil { in, out := &in.Templates, &out.Templates - *out = make(map[string]apiv1beta1.GaleraSpecCore, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() + *out = new(map[string]mariadb_operatorapiv1beta1.GaleraSpecCore) + if **in != nil { + in, out := *in, *out + *out = make(map[string]mariadb_operatorapiv1beta1.GaleraSpecCore, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } } } } @@ -714,7 +750,11 @@ func (in *GaleraSection) DeepCopy() *GaleraSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GlanceSection) DeepCopyInto(out *GlanceSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(glance_operatorapiv1beta1.GlanceSpecCore) + (*in).DeepCopyInto(*out) + } if in.APIOverride != nil { in, out := &in.APIOverride, &out.APIOverride *out = make(map[string]Override, len(*in)) @@ -737,7 +777,11 @@ func (in *GlanceSection) DeepCopy() *GlanceSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HeatSection) DeepCopyInto(out *HeatSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(heat_operatorapiv1beta1.HeatSpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) in.CnfAPIOverride.DeepCopyInto(&out.CnfAPIOverride) } @@ -755,7 +799,11 @@ func (in *HeatSection) DeepCopy() *HeatSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *HorizonSection) DeepCopyInto(out *HorizonSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(horizon_operatorapiv1beta1.HorizonSpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) } @@ -772,7 +820,11 @@ func (in *HorizonSection) DeepCopy() *HorizonSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IronicSection) DeepCopyInto(out *IronicSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(ironic_operatorapiv1beta1.IronicSpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) in.InspectorOverride.DeepCopyInto(&out.InspectorOverride) } @@ -790,7 +842,11 @@ func (in *IronicSection) DeepCopy() *IronicSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KeystoneSection) DeepCopyInto(out *KeystoneSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(apiv1beta1.KeystoneAPISpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) } @@ -807,7 +863,11 @@ func (in *KeystoneSection) DeepCopy() *KeystoneSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ManilaSection) DeepCopyInto(out *ManilaSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(manila_operatorapiv1beta1.ManilaSpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) } @@ -826,9 +886,13 @@ func (in *MemcachedSection) DeepCopyInto(out *MemcachedSection) { *out = *in if in.Templates != nil { in, out := &in.Templates, &out.Templates - *out = make(map[string]memcachedv1beta1.MemcachedSpecCore, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() + *out = new(map[string]memcachedv1beta1.MemcachedSpecCore) + if **in != nil { + in, out := *in, *out + *out = make(map[string]memcachedv1beta1.MemcachedSpecCore, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } } } } @@ -846,7 +910,11 @@ func (in *MemcachedSection) DeepCopy() *MemcachedSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NeutronSection) DeepCopyInto(out *NeutronSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(neutron_operatorapiv1beta1.NeutronAPISpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) } @@ -879,7 +947,11 @@ func (in *NovaCellOverrideSpec) DeepCopy() *NovaCellOverrideSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *NovaSection) DeepCopyInto(out *NovaSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(nova_operatorapiv1beta1.NovaSpec) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) if in.CellOverride != nil { in, out := &in.CellOverride, &out.CellOverride @@ -903,7 +975,11 @@ func (in *NovaSection) DeepCopy() *NovaSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OctaviaSection) DeepCopyInto(out *OctaviaSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(octavia_operatorapiv1beta1.OctaviaSpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) } @@ -1304,7 +1380,11 @@ func (in *OvnResources) DeepCopy() *OvnResources { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OvnSection) DeepCopyInto(out *OvnSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(OvnResources) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OvnSection. @@ -1320,7 +1400,11 @@ func (in *OvnSection) DeepCopy() *OvnSection { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PlacementSection) DeepCopyInto(out *PlacementSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(placement_operatorapiv1beta1.PlacementAPISpecCore) + (*in).DeepCopyInto(*out) + } in.APIOverride.DeepCopyInto(&out.APIOverride) } @@ -1339,9 +1423,13 @@ func (in *RabbitmqSection) DeepCopyInto(out *RabbitmqSection) { *out = *in if in.Templates != nil { in, out := &in.Templates, &out.Templates - *out = make(map[string]RabbitmqTemplate, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() + *out = new(map[string]RabbitmqTemplate) + if **in != nil { + in, out := *in, *out + *out = make(map[string]RabbitmqTemplate, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } } } } @@ -1375,7 +1463,11 @@ func (in *RabbitmqTemplate) DeepCopy() *RabbitmqTemplate { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SwiftSection) DeepCopyInto(out *SwiftSection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(swift_operatorapiv1beta1.SwiftSpecCore) + (*in).DeepCopyInto(*out) + } in.ProxyOverride.DeepCopyInto(&out.ProxyOverride) } @@ -1495,7 +1587,11 @@ func (in *TLSStatus) DeepCopy() *TLSStatus { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TelemetrySection) DeepCopyInto(out *TelemetrySection) { *out = *in - in.Template.DeepCopyInto(&out.Template) + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(telemetry_operatorapiv1beta1.TelemetrySpecCore) + (*in).DeepCopyInto(*out) + } in.AodhAPIOverride.DeepCopyInto(&out.AodhAPIOverride) in.PrometheusOverride.DeepCopyInto(&out.PrometheusOverride) in.AlertmanagerOverride.DeepCopyInto(&out.AlertmanagerOverride) diff --git a/apis/go.mod b/apis/go.mod index 0da711217..ca6403d7d 100644 --- a/apis/go.mod +++ b/apis/go.mod @@ -38,6 +38,8 @@ require ( sigs.k8s.io/controller-runtime v0.16.6 ) +require k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 + require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -92,7 +94,6 @@ require ( k8s.io/component-base v0.28.10 // indirect k8s.io/klog/v2 v2.120.1 // indirect k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect - k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index c7dfeca4c..d36078ede 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -11037,6 +11037,9 @@ spec: type: object openstackclient: properties: + enabled: + default: true + type: boolean template: properties: caBundleSecretName: diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index 147ce3cd1..45c6fe52d 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -27,6 +27,9 @@ spec: kind: OpenStackControlPlane name: openstackcontrolplanes.core.openstack.org specDescriptors: + - description: Barbican - Parameters related to the Barbican service + displayName: Barbican + path: barbican - description: APIOverride, provides the ability to override the generated manifest of several child resources. displayName: APIOverride @@ -60,6 +63,9 @@ spec: - description: Template - Overrides to use when creating Cinder Resources displayName: Template path: cinder.template + - description: Designate - Parameters related to the Designate service + displayName: Designate + path: designate - description: APIOverride, provides the ability to override the generated manifest of several child resources. displayName: APIOverride @@ -157,6 +163,9 @@ spec: - description: TLS - overrides tls parameters for public endpoint displayName: TLS path: horizon.apiOverride.tls + - description: Template - Overrides to use when creating the Horizon services + displayName: Template + path: horizon.template - description: Ironic - Parameters related to the Ironic services displayName: Ironic path: ironic @@ -200,6 +209,9 @@ spec: - description: Template - Overrides to use when creating the Keystone service displayName: Template path: keystone.template + - description: Manila - Parameters related to the Manila service + displayName: Manila + path: manila - description: APIOverride, provides the ability to override the generated manifest of several child resources. displayName: APIOverride @@ -212,6 +224,9 @@ spec: path: manila.enabled x-descriptors: - urn:alm:descriptor:com.tectonic.ui:booleanSwitch + - description: Template - Overrides to use when creating Manila Resources + displayName: Template + path: manila.template - description: Memcached - Parameters related to the Memcached service displayName: Memcached path: memcached @@ -272,6 +287,9 @@ spec: - description: Template - Overrides to use when creating the Nova services displayName: Template path: nova.template + - description: Octavia - Parameters related to the Octavia service + displayName: Octavia + path: octavia - description: APIOverride, provides the ability to override the generated manifest of several child resources. displayName: APIOverride @@ -291,6 +309,12 @@ spec: - description: OpenStackClient - Parameters related to the OpenStackClient displayName: Open Stack Client path: openstackclient + - description: Enabled - Whether the OpenStackClient pod should be deployed + and managed + displayName: Enabled + path: openstackclient.enabled + x-descriptors: + - urn:alm:descriptor:com.tectonic.ui:booleanSwitch - description: Template - Overrides to use when creating the OpenStackClient Resource displayName: Template @@ -356,6 +380,9 @@ spec: path: storageClass x-descriptors: - urn:alm:descriptor:io.kubernetes:StorageClass + - description: Swift - Parameters related to the Swift service + displayName: Swift + path: swift - description: Enabled - Whether Swift service should be deployed and managed displayName: Enabled path: swift.enabled @@ -371,6 +398,9 @@ spec: - description: Template - Overrides to use when creating Swift Resources displayName: Template path: swift.template + - description: Telemetry - Parameters related to the OpenStack Telemetry services + displayName: Telemetry + path: telemetry - description: AlertmanagerOverride, provides the ability to override the generated manifest of several child resources. displayName: Alertmanager Override diff --git a/pkg/openstack/barbican.go b/pkg/openstack/barbican.go index b1fc1a204..c76d85141 100644 --- a/pkg/openstack/barbican.go +++ b/pkg/openstack/barbican.go @@ -36,6 +36,10 @@ func ReconcileBarbican(ctx context.Context, instance *corev1beta1.OpenStackContr return ctrl.Result{}, nil } + if instance.Spec.Barbican.Template == nil { + instance.Spec.Barbican.Template = &barbicanv1.BarbicanSpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Barbican.Template.BarbicanAPI.Override.Service == nil { diff --git a/pkg/openstack/cinder.go b/pkg/openstack/cinder.go index 9b3ea2142..501f212e2 100644 --- a/pkg/openstack/cinder.go +++ b/pkg/openstack/cinder.go @@ -38,6 +38,10 @@ func ReconcileCinder(ctx context.Context, instance *corev1beta1.OpenStackControl } Log := GetLogger(ctx) + if instance.Spec.Cinder.Template == nil { + instance.Spec.Cinder.Template = &cinderv1.CinderSpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Cinder.Template.CinderAPI.Override.Service == nil { diff --git a/pkg/openstack/designate.go b/pkg/openstack/designate.go index 3875b0de1..f7d62e120 100644 --- a/pkg/openstack/designate.go +++ b/pkg/openstack/designate.go @@ -37,6 +37,10 @@ func ReconcileDesignate(ctx context.Context, instance *corev1beta1.OpenStackCont return ctrl.Result{}, nil } + if instance.Spec.Designate.Template == nil { + instance.Spec.Designate.Template = &designatev1.DesignateSpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Designate.Template.DesignateAPI.Override.Service == nil { diff --git a/pkg/openstack/dnsmasq.go b/pkg/openstack/dnsmasq.go index 73bf578e9..2374d6758 100644 --- a/pkg/openstack/dnsmasq.go +++ b/pkg/openstack/dnsmasq.go @@ -35,6 +35,10 @@ func ReconcileDNSMasqs(ctx context.Context, instance *corev1beta1.OpenStackContr Log := GetLogger(ctx) + if instance.Spec.DNS.Template == nil { + instance.Spec.DNS.Template = &networkv1.DNSMasqSpec{} + } + Log.Info("Reconciling DNSMasq", "DNSMasq.Namespace", instance.Namespace, "DNSMasq.Name", "dnsmasq") op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), dnsmasq, func() error { instance.Spec.DNS.Template.DeepCopyInto(&dnsmasq.Spec) diff --git a/pkg/openstack/galera.go b/pkg/openstack/galera.go index 0c660583d..6c78d6620 100644 --- a/pkg/openstack/galera.go +++ b/pkg/openstack/galera.go @@ -41,7 +41,11 @@ func ReconcileGaleras( var failures = []string{} var inprogress = []string{} - for name, spec := range instance.Spec.Galera.Templates { + if instance.Spec.Galera.Templates == nil { + instance.Spec.Galera.Templates = ptr.To(map[string]mariadbv1.GaleraSpecCore{}) + } + + for name, spec := range *instance.Spec.Galera.Templates { hostname := fmt.Sprintf("%s.%s.svc", name, instance.Namespace) // Galera gets always configured to support TLS connections. @@ -59,7 +63,7 @@ func ReconcileGaleras( // at the initial deployment because there is no SST involved when the DB is bootstrapped // as there are no data to be transferred yet. Subject: &certmgrv1.X509Subject{ - Organizations: []string{fmt.Sprintf("%s.cluster.local", instance.Namespace)}, + Organizations: []string{fmt.Sprintf("%s.%s", instance.Namespace, ClusterInternalDomain)}, }, Usages: []certmgrv1.KeyUsage{ "key encipherment", diff --git a/pkg/openstack/glance.go b/pkg/openstack/glance.go index 7af739d34..428b87e26 100644 --- a/pkg/openstack/glance.go +++ b/pkg/openstack/glance.go @@ -46,6 +46,10 @@ func ReconcileGlance(ctx context.Context, instance *corev1beta1.OpenStackControl return ctrl.Result{}, nil } + if instance.Spec.Glance.Template == nil { + instance.Spec.Glance.Template = &glancev1.GlanceSpecCore{} + } + // When component services got created check if there is the need to create a route if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "glance", Namespace: instance.Namespace}, glance); err != nil { if !k8s_errors.IsNotFound(err) { diff --git a/pkg/openstack/heat.go b/pkg/openstack/heat.go index 5e7046bfc..d5ab7cb11 100644 --- a/pkg/openstack/heat.go +++ b/pkg/openstack/heat.go @@ -40,6 +40,10 @@ func ReconcileHeat(ctx context.Context, instance *corev1beta1.OpenStackControlPl return ctrl.Result{}, nil } + if instance.Spec.Heat.Template == nil { + instance.Spec.Heat.Template = &heatv1.HeatSpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Heat.Template.HeatAPI.Override.Service == nil { diff --git a/pkg/openstack/horizon.go b/pkg/openstack/horizon.go index c027c6f0e..1e876da2e 100644 --- a/pkg/openstack/horizon.go +++ b/pkg/openstack/horizon.go @@ -45,6 +45,10 @@ func ReconcileHorizon(ctx context.Context, instance *corev1beta1.OpenStackContro return ctrl.Result{}, nil } + if instance.Spec.Horizon.Template == nil { + instance.Spec.Horizon.Template = &horizonv1.HorizonSpecCore{} + } + // add selector to service overrides serviceOverrides := map[service.Endpoint]service.RoutedOverrideSpec{} if instance.Spec.Horizon.Template.Override.Service != nil { diff --git a/pkg/openstack/ironic.go b/pkg/openstack/ironic.go index 8c1dbcaee..93d4a3301 100644 --- a/pkg/openstack/ironic.go +++ b/pkg/openstack/ironic.go @@ -37,6 +37,10 @@ func ReconcileIronic(ctx context.Context, instance *corev1beta1.OpenStackControl return ctrl.Result{}, nil } + if instance.Spec.Ironic.Template == nil { + instance.Spec.Ironic.Template = &ironicv1.IronicSpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Ironic.Template.IronicAPI.Override.Service == nil { diff --git a/pkg/openstack/keystone.go b/pkg/openstack/keystone.go index f18db0288..a14aff6d9 100644 --- a/pkg/openstack/keystone.go +++ b/pkg/openstack/keystone.go @@ -38,6 +38,10 @@ func ReconcileKeystoneAPI(ctx context.Context, instance *corev1beta1.OpenStackCo return ctrl.Result{}, nil } + if instance.Spec.Keystone.Template == nil { + instance.Spec.Keystone.Template = &keystonev1.KeystoneAPISpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Keystone.Template.Override.Service == nil { diff --git a/pkg/openstack/manila.go b/pkg/openstack/manila.go index f63f64dcb..eb28a53ff 100644 --- a/pkg/openstack/manila.go +++ b/pkg/openstack/manila.go @@ -38,6 +38,10 @@ func ReconcileManila(ctx context.Context, instance *corev1beta1.OpenStackControl return ctrl.Result{}, nil } + if instance.Spec.Manila.Template == nil { + instance.Spec.Manila.Template = &manilav1.ManilaSpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Manila.Template.ManilaAPI.Override.Service == nil { diff --git a/pkg/openstack/memcached.go b/pkg/openstack/memcached.go index a494723b0..15b6c0e8d 100644 --- a/pkg/openstack/memcached.go +++ b/pkg/openstack/memcached.go @@ -53,6 +53,10 @@ func ReconcileMemcacheds( return ctrl.Result{}, err } + if instance.Spec.Memcached.Templates == nil { + instance.Spec.Memcached.Templates = ptr.To(map[string]memcachedv1.MemcachedSpecCore{}) + } + for _, memcached := range memcacheds.Items { for _, ref := range memcached.GetOwnerReferences() { // Check owner UID to ensure the memcached instance is owned by this OpenStackControlPlane instance @@ -60,10 +64,12 @@ func ReconcileMemcacheds( owned := false // Check whether the name appears in spec - for name := range instance.Spec.Memcached.Templates { - if name == memcached.GetName() { - owned = true - break + if instance.Spec.Memcached.Templates != nil { + for name := range *instance.Spec.Memcached.Templates { + if name == memcached.GetName() { + owned = true + break + } } } @@ -88,43 +94,45 @@ func ReconcileMemcacheds( var ctrlResult ctrl.Result var err error var status memcachedStatus - for name, spec := range instance.Spec.Memcached.Templates { - status, ctrlResult, err = reconcileMemcached(ctx, instance, version, helper, name, &spec) - - switch status { - case memcachedFailed: - failures = append(failures, fmt.Sprintf("%s(%v)", name, err.Error())) - case memcachedCreating: - inprogress = append(inprogress, name) - case memcachedReady: - default: - failures = append(failures, fmt.Sprintf("Invalid memcachedStatus from reconcileMemcached: %d for Memcached %s", status, name)) + if instance.Spec.Memcached.Templates != nil { + for name, spec := range *instance.Spec.Memcached.Templates { + status, ctrlResult, err = reconcileMemcached(ctx, instance, version, helper, name, &spec) + + switch status { + case memcachedFailed: + failures = append(failures, fmt.Sprintf("%s(%v)", name, err.Error())) + case memcachedCreating: + inprogress = append(inprogress, name) + case memcachedReady: + default: + failures = append(failures, fmt.Sprintf("Invalid memcachedStatus from reconcileMemcached: %d for Memcached %s", status, name)) + } } - } - - if len(failures) > 0 { - errors := strings.Join(failures, ",") - - instance.Status.Conditions.Set(condition.FalseCondition( - corev1beta1.OpenStackControlPlaneMemcachedReadyCondition, - condition.ErrorReason, - condition.SeverityWarning, - corev1beta1.OpenStackControlPlaneMemcachedReadyErrorMessage, - errors)) - - return ctrlResult, fmt.Errorf(errors) - } else if len(inprogress) > 0 { - instance.Status.Conditions.Set(condition.FalseCondition( - corev1beta1.OpenStackControlPlaneMemcachedReadyCondition, - condition.RequestedReason, - condition.SeverityInfo, - corev1beta1.OpenStackControlPlaneMemcachedReadyRunningMessage)) - } else { - instance.Status.Conditions.MarkTrue( - corev1beta1.OpenStackControlPlaneMemcachedReadyCondition, - corev1beta1.OpenStackControlPlaneMemcachedReadyMessage, - ) + if len(failures) > 0 { + errors := strings.Join(failures, ",") + + instance.Status.Conditions.Set(condition.FalseCondition( + corev1beta1.OpenStackControlPlaneMemcachedReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + corev1beta1.OpenStackControlPlaneMemcachedReadyErrorMessage, + errors)) + + return ctrlResult, fmt.Errorf(errors) + + } else if len(inprogress) > 0 { + instance.Status.Conditions.Set(condition.FalseCondition( + corev1beta1.OpenStackControlPlaneMemcachedReadyCondition, + condition.RequestedReason, + condition.SeverityInfo, + corev1beta1.OpenStackControlPlaneMemcachedReadyRunningMessage)) + } else { + instance.Status.Conditions.MarkTrue( + corev1beta1.OpenStackControlPlaneMemcachedReadyCondition, + corev1beta1.OpenStackControlPlaneMemcachedReadyMessage, + ) + } } return ctrlResult, nil diff --git a/pkg/openstack/neutron.go b/pkg/openstack/neutron.go index 392aaca93..ce8b76bf2 100644 --- a/pkg/openstack/neutron.go +++ b/pkg/openstack/neutron.go @@ -40,6 +40,10 @@ func ReconcileNeutron(ctx context.Context, instance *corev1beta1.OpenStackContro return ctrl.Result{}, nil } + if instance.Spec.Neutron.Template == nil { + instance.Spec.Neutron.Template = &neutronv1.NeutronAPISpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Neutron.Template.Override.Service == nil { diff --git a/pkg/openstack/nova.go b/pkg/openstack/nova.go index b9f7c9188..50df6e63c 100644 --- a/pkg/openstack/nova.go +++ b/pkg/openstack/nova.go @@ -58,6 +58,10 @@ func ReconcileNova(ctx context.Context, instance *corev1beta1.OpenStackControlPl return ctrl.Result{}, nil } + if instance.Spec.Nova.Template == nil { + instance.Spec.Nova.Template = &novav1.NovaSpec{} + } + // When component services got created check if there is the need to create routes and certificates if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "nova", Namespace: instance.Namespace}, nova); err != nil { if !k8s_errors.IsNotFound(err) { diff --git a/pkg/openstack/octavia.go b/pkg/openstack/octavia.go index 081093502..9e28e666b 100644 --- a/pkg/openstack/octavia.go +++ b/pkg/openstack/octavia.go @@ -55,6 +55,10 @@ func ReconcileOctavia(ctx context.Context, instance *corev1beta1.OpenStackContro return ctrl.Result{}, nil } + if instance.Spec.Octavia.Template == nil { + instance.Spec.Octavia.Template = &octaviav1.OctaviaSpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Octavia.Template.OctaviaAPI.Override.Service == nil { diff --git a/pkg/openstack/openstackclient.go b/pkg/openstack/openstackclient.go index 56f016022..5e350c489 100644 --- a/pkg/openstack/openstackclient.go +++ b/pkg/openstack/openstackclient.go @@ -43,6 +43,14 @@ func ReconcileOpenStackClient(ctx context.Context, instance *corev1.OpenStackCon } Log := GetLogger(ctx) + if !instance.Spec.OpenStackClient.Enabled { + if res, err := EnsureDeleted(ctx, helper, openstackclient); err != nil { + return res, err + } + instance.Status.Conditions.Remove(corev1.OpenStackControlPlaneClientReadyCondition) + return ctrl.Result{}, nil + } + Log.Info("Reconciling OpenStackClient", "OpenStackClient.Namespace", instance.Namespace, "OpenStackClient.Name", openstackclient.Name) op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), openstackclient, func() error { instance.Spec.OpenStackClient.Template.DeepCopyInto(&openstackclient.Spec) diff --git a/pkg/openstack/ovn.go b/pkg/openstack/ovn.go index d4441b4e4..858303af4 100644 --- a/pkg/openstack/ovn.go +++ b/pkg/openstack/ovn.go @@ -31,6 +31,10 @@ func ReconcileOVN(ctx context.Context, instance *corev1beta1.OpenStackControlPla err.Error())) } + if instance.Spec.Ovn.Template == nil { + instance.Spec.Ovn.Template = &corev1beta1.OvnResources{} + } + OVNDBClustersReady, err := ReconcileOVNDbClusters(ctx, instance, version, helper) if err != nil { Log.Error(err, "Failed to reconcile OVNDBClusters") diff --git a/pkg/openstack/placement.go b/pkg/openstack/placement.go index a1a0e991c..cd57d4257 100644 --- a/pkg/openstack/placement.go +++ b/pkg/openstack/placement.go @@ -37,6 +37,10 @@ func ReconcilePlacementAPI(ctx context.Context, instance *corev1beta1.OpenStackC return ctrl.Result{}, nil } + if instance.Spec.Placement.Template == nil { + instance.Spec.Placement.Template = &placementv1.PlacementAPISpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Placement.Template.Override.Service == nil { diff --git a/pkg/openstack/rabbitmq.go b/pkg/openstack/rabbitmq.go index c93d1556b..908afee94 100644 --- a/pkg/openstack/rabbitmq.go +++ b/pkg/openstack/rabbitmq.go @@ -22,6 +22,7 @@ import ( corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1" corev1 "k8s.io/api/core/v1" + "k8s.io/utils/ptr" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" @@ -48,7 +49,11 @@ func ReconcileRabbitMQs( var err error var status mqStatus - for name, spec := range instance.Spec.Rabbitmq.Templates { + if instance.Spec.Rabbitmq.Templates == nil { + instance.Spec.Rabbitmq.Templates = ptr.To(map[string]corev1beta1.RabbitmqTemplate{}) + } + + for name, spec := range *instance.Spec.Rabbitmq.Templates { status, ctrlResult, err = reconcileRabbitMQ(ctx, instance, version, helper, name, spec) switch status { diff --git a/pkg/openstack/swift.go b/pkg/openstack/swift.go index 4b1dcdc64..bf695a954 100644 --- a/pkg/openstack/swift.go +++ b/pkg/openstack/swift.go @@ -38,6 +38,10 @@ func ReconcileSwift(ctx context.Context, instance *corev1beta1.OpenStackControlP return ctrl.Result{}, nil } + if instance.Spec.Swift.Template == nil { + instance.Spec.Swift.Template = &swiftv1.SwiftSpecCore{} + } + // add selector to service overrides for _, endpointType := range []service.Endpoint{service.EndpointPublic, service.EndpointInternal} { if instance.Spec.Swift.Template.SwiftProxy.Override.Service == nil { diff --git a/pkg/openstack/telemetry.go b/pkg/openstack/telemetry.go index bde204daa..ec052e005 100644 --- a/pkg/openstack/telemetry.go +++ b/pkg/openstack/telemetry.go @@ -43,6 +43,10 @@ func ReconcileTelemetry(ctx context.Context, instance *corev1beta1.OpenStackCont return ctrl.Result{}, nil } + if instance.Spec.Telemetry.Template == nil { + instance.Spec.Telemetry.Template = &telemetryv1.TelemetrySpecCore{} + } + if err := helper.GetClient().Get(ctx, types.NamespacedName{Name: "telemetry", Namespace: instance.Namespace}, telemetry); err != nil { if !k8s_errors.IsNotFound(err) { return ctrl.Result{}, err diff --git a/tests/functional/base_test.go b/tests/functional/base_test.go index 388f9df4e..c042e3e22 100644 --- a/tests/functional/base_test.go +++ b/tests/functional/base_test.go @@ -66,6 +66,7 @@ type Names struct { OVNControllerCertName types.NamespacedName OVNDbServerNBName types.NamespacedName OVNDbServerSBName types.NamespacedName + NeutronOVNCertName types.NamespacedName } func CreateNames(openstackControlplaneName types.NamespacedName) Names { @@ -189,6 +190,10 @@ func CreateNames(openstackControlplaneName types.NamespacedName) Names { Namespace: openstackControlplaneName.Namespace, Name: "cert-ovncontroller-ovndbs", }, + NeutronOVNCertName: types.NamespacedName{ + Namespace: openstackControlplaneName.Namespace, + Name: "cert-neutron-ovndbs", + }, } } @@ -373,19 +378,19 @@ func GetDefaultOpenStackControlPlaneSpec() map[string]interface{} { "enabled": false, }, "glance": map[string]interface{}{ - "enabled": false, + "enabled": true, }, "horizon": map[string]interface{}{ "enabled": true, }, "cinder": map[string]interface{}{ - "enabled": false, + "enabled": true, }, "ovn": map[string]interface{}{ "enabled": false, }, "neutron": map[string]interface{}{ - "enabled": false, + "enabled": true, }, "swift": map[string]interface{}{ "enabled": false, @@ -403,6 +408,12 @@ func GetDefaultOpenStackControlPlaneSpec() map[string]interface{} { "barbican": map[string]interface{}{ "enabled": false, }, + "openstackclient": map[string]interface{}{ + "enabled": true, + }, + "manila": map[string]interface{}{ + "enabled": true, + }, } } diff --git a/tests/functional/openstackoperator_controller_test.go b/tests/functional/openstackoperator_controller_test.go index cc0c66535..9c1ec94ca 100644 --- a/tests/functional/openstackoperator_controller_test.go +++ b/tests/functional/openstackoperator_controller_test.go @@ -557,13 +557,18 @@ var _ = Describe("OpenStackOperator controller", func() { // Default route timeouts are set It("should have default timeout for the routes set", func() { OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane).Should(Not(BeNil())) + Expect(OSCtlplane.Spec.Neutron.APIOverride.Route).Should(Not(BeNil())) Expect(OSCtlplane.Spec.Neutron.APIOverride.Route.Annotations).Should(HaveKeyWithValue("haproxy.router.openshift.io/timeout", "120s")) + Expect(OSCtlplane.Spec.Cinder.APIOverride.Route).Should(Not(BeNil())) Expect(OSCtlplane.Spec.Cinder.APIOverride.Route.Annotations).Should(HaveKeyWithValue("haproxy.router.openshift.io/timeout", "60s")) Expect(OSCtlplane.Spec.Cinder.APIOverride.Route.Annotations).Should(HaveKeyWithValue("api.cinder.openstack.org/timeout", "60s")) + Expect(OSCtlplane.Spec.Glance.Template).Should(Not(BeNil())) for name := range OSCtlplane.Spec.Glance.Template.GlanceAPIs { Expect(OSCtlplane.Spec.Glance.APIOverride[name].Route.Annotations).Should(HaveKeyWithValue("haproxy.router.openshift.io/timeout", "60s")) Expect(OSCtlplane.Spec.Glance.APIOverride[name].Route.Annotations).Should(HaveKeyWithValue("api.glance.openstack.org/timeout", "60s")) } + Expect(OSCtlplane.Spec.Manila.APIOverride.Route).Should(Not(BeNil())) Expect(OSCtlplane.Spec.Manila.APIOverride.Route.Annotations).Should(HaveKeyWithValue("haproxy.router.openshift.io/timeout", "60s")) Expect(OSCtlplane.Spec.Manila.APIOverride.Route.Annotations).Should(HaveKeyWithValue("api.manila.openstack.org/timeout", "60s")) }) @@ -727,6 +732,7 @@ var _ = Describe("OpenStackOperator controller", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) DeferCleanup( th.DeleteInstance, CreateOpenStackControlPlane(names.OpenStackControlplaneName, GetDefaultOpenStackControlPlaneSpec()), @@ -770,6 +776,8 @@ var _ = Describe("OpenStackOperator controller", func() { // Default route timeouts are set It("should have default timeout for the routes set", func() { OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane).Should(Not(BeNil())) + Expect(OSCtlplane.Spec.Neutron.APIOverride.Route).Should(Not(BeNil())) Expect(OSCtlplane.Spec.Neutron.APIOverride.Route.Annotations).Should(HaveKeyWithValue("haproxy.router.openshift.io/timeout", "120s")) }) @@ -1015,6 +1023,7 @@ var _ = Describe("OpenStackOperator controller", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) spec := GetDefaultOpenStackControlPlaneSpec() spec["tls"] = GetTLSeCustomIssuerSpec() DeferCleanup( @@ -1141,6 +1150,7 @@ var _ = Describe("OpenStackOperator controller", func() { // create cert secrets for ovn instance DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNNorthdCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.OVNControllerCertName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(names.NeutronOVNCertName)) DeferCleanup(k8sClient.Delete, ctx, th.CreateSecret(types.NamespacedName{Name: "openstack-config-secret", Namespace: namespace}, map[string][]byte{"secure.yaml": []byte("foo")}))