From 9beb738de5341851e2df71cf2a70a86ff74339a8 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Wed, 21 Feb 2024 12:27:12 -0500 Subject: [PATCH] add DatabaseAccount and migrate to MariaDBAccount --- .../ironic.openstack.org_ironicapis.yaml | 13 ++- ...ironic.openstack.org_ironicconductors.yaml | 17 ++-- ...ironic.openstack.org_ironicinspectors.yaml | 17 ++-- ...nic.openstack.org_ironicneutronagents.yaml | 5 - api/bases/ironic.openstack.org_ironics.yaml | 20 ++-- api/v1beta1/common_types.go | 7 +- api/v1beta1/ironic_types.go | 9 +- api/v1beta1/ironicapi_types.go | 9 +- api/v1beta1/ironicconductor_types.go | 11 ++- api/v1beta1/ironicinspector_types.go | 19 ++-- .../ironic.openstack.org_ironicapis.yaml | 13 ++- ...ironic.openstack.org_ironicconductors.yaml | 17 ++-- ...ironic.openstack.org_ironicinspectors.yaml | 17 ++-- ...nic.openstack.org_ironicneutronagents.yaml | 5 - .../bases/ironic.openstack.org_ironics.yaml | 20 ++-- controllers/ironic_controller.go | 62 ++++++++++-- controllers/ironicapi_controller.go | 16 +++- controllers/ironicconductor_controller.go | 17 +++- controllers/ironicinspector_controller.go | 66 ++++++++++--- controllers/ironicneutronagent_controller.go | 3 +- go.mod | 2 + go.sum | 4 +- pkg/ironic/dbsync.go | 1 - pkg/ironic/initcontainer.go | 12 --- pkg/ironic/volumes.go | 12 +-- pkg/ironicapi/deployment.go | 1 - pkg/ironicapi/volumes.go | 6 +- pkg/ironicconductor/statefulset.go | 1 - pkg/ironicconductor/volumes.go | 6 +- pkg/ironicinspector/dbsync.go | 1 - pkg/ironicinspector/initcontainer.go | 12 --- pkg/ironicinspector/statefulset.go | 1 - pkg/ironicinspector/volumes.go | 12 +-- pkg/ironicneutronagent/volumes.go | 12 +-- templates/common/bin/common.sh | 5 - templates/common/config/ironic.conf | 1 + templates/ironicinspector/bin/init.sh | 5 - .../ironicinspector/config/inspector.conf | 3 + tests/functional/base_test.go | 18 +++- tests/functional/ironic_controller_test.go | 95 ++++++++++++++++++- tests/functional/ironicapi_controller_test.go | 17 ++-- .../ironicconductor_controller_test.go | 11 ++- .../ironicinspector_controller_test.go | 94 ++++++++++++++++-- .../tests/deploy/10-assert-deploy-ironic.yaml | 12 +-- .../10-assert-deploy-ironic-standalone.yaml | 10 +- 45 files changed, 471 insertions(+), 246 deletions(-) diff --git a/api/bases/ironic.openstack.org_ironicapis.yaml b/api/bases/ironic.openstack.org_ironicapis.yaml index 8afbeafa..db40c32d 100644 --- a/api/bases/ironic.openstack.org_ironicapis.yaml +++ b/api/bases/ironic.openstack.org_ironicapis.yaml @@ -59,6 +59,11 @@ spec: added to to /etc//.conf.d directory as custom.conf file. type: string + databaseAccount: + default: ironic + description: DatabaseAccount - optional MariaDBAccount used for ironic + DB, defaults to ironic. + type: string databaseHostname: description: DatabaseHostname - Ironic Database Hostname type: string @@ -269,16 +274,10 @@ spec: type: object passwordSelectors: default: - database: IronicDatabasePassword service: IronicPassword description: PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret properties: - database: - default: IronicDatabasePassword - description: 'Database - Selector to get the ironic Database user - password from the Secret TODO: not used, need change in mariadb-operator' - type: string service: default: IronicPassword description: Service - Selector to get the ironic service password @@ -353,7 +352,7 @@ spec: type: string secret: description: Secret containing OpenStack password information for - IronicDatabasePassword, AdminPassword + AdminPassword type: string serviceUser: default: ironic diff --git a/api/bases/ironic.openstack.org_ironicconductors.yaml b/api/bases/ironic.openstack.org_ironicconductors.yaml index 659a2c0c..2d70c025 100644 --- a/api/bases/ironic.openstack.org_ironicconductors.yaml +++ b/api/bases/ironic.openstack.org_ironicconductors.yaml @@ -62,6 +62,11 @@ spec: added to to /etc//.conf.d directory as custom.conf file. type: string + databaseAccount: + default: ironic + description: DatabaseAccount - optional MariaDBAccount used for ironic + DB, defaults to ironic. + type: string databaseHostname: description: DatabaseHostname - Ironic Database Hostname type: string @@ -137,16 +142,10 @@ spec: type: object passwordSelectors: default: - database: IronicDatabasePassword service: IronicPassword - description: PasswordSelectors - Selectors to identify the DB and - ServiceUser password from the Secret + description: PasswordSelectors - Selectors to identify the ServiceUser + password from the Secret properties: - database: - default: IronicDatabasePassword - description: 'Database - Selector to get the ironic Database user - password from the Secret TODO: not used, need change in mariadb-operator' - type: string service: default: IronicPassword description: Service - Selector to get the ironic service password @@ -228,7 +227,7 @@ spec: type: string secret: description: Secret containing OpenStack password information for - IronicDatabasePassword, AdminPassword + AdminPassword type: string serviceUser: default: ironic diff --git a/api/bases/ironic.openstack.org_ironicinspectors.yaml b/api/bases/ironic.openstack.org_ironicinspectors.yaml index 85795b38..35737895 100644 --- a/api/bases/ironic.openstack.org_ironicinspectors.yaml +++ b/api/bases/ironic.openstack.org_ironicinspectors.yaml @@ -59,6 +59,14 @@ spec: added to to /etc//.conf.d directory as custom.conf file. type: string + databaseAccount: + default: ironic-inspector + description: DatabaseAccount - optional MariaDBAccount used for ironic + DB, defaults to ironic-inspector. this is separate from the account + used for ironic, as a MariaDBAccount can only refer to a single + MariaDBDatabase and it appears that ironic inspector uses its own + MariaDBDatabase. + type: string databaseInstance: description: MariaDB instance name. Right now required by the maridb-operator to get the credentials from the instance to create the DB. Might @@ -304,17 +312,10 @@ spec: type: object passwordSelectors: default: - database: IronicInspectorDatabasePassword service: IronicInspectorPassword description: PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret properties: - database: - default: IronicInspectorDatabasePassword - description: 'Database - Selector to get the ironic-inspector - Database user password from the Secret TODO: not used, need - change in mariadb-operator' - type: string service: default: IronicInspectorPassword description: Service - Selector to get the ironic-inspector service @@ -403,7 +404,7 @@ spec: type: string secret: description: Secret containing OpenStack password information for - IronicInspectorDatabasePassword, AdminPassword + AdminPassword type: string serviceUser: default: ironic-inspector diff --git a/api/bases/ironic.openstack.org_ironicneutronagents.yaml b/api/bases/ironic.openstack.org_ironicneutronagents.yaml index 861e54f6..87c2af79 100644 --- a/api/bases/ironic.openstack.org_ironicneutronagents.yaml +++ b/api/bases/ironic.openstack.org_ironicneutronagents.yaml @@ -83,11 +83,6 @@ spec: description: PasswordSelectors - Selectors to identify the ServiceUser password from the Secret properties: - database: - default: IronicDatabasePassword - description: 'Database - Selector to get the ironic Database user - password from the Secret TODO: not used, need change in mariadb-operator' - type: string service: default: IronicPassword description: Service - Selector to get the ironic service password diff --git a/api/bases/ironic.openstack.org_ironics.yaml b/api/bases/ironic.openstack.org_ironics.yaml index 1eee6a6b..e1aa2934 100644 --- a/api/bases/ironic.openstack.org_ironics.yaml +++ b/api/bases/ironic.openstack.org_ironics.yaml @@ -43,6 +43,11 @@ spec: added to to /etc//.conf.d directory as custom.conf file. type: string + databaseAccount: + default: ironic + description: DatabaseAccount - optional MariaDBAccount used for ironic + DB, defaults to ironic. + type: string databaseInstance: description: MariaDB instance name. Right now required by the maridb-operator to get the credentials from the instance to create the DB. Might @@ -790,17 +795,10 @@ spec: type: object passwordSelectors: default: - database: IronicInspectorDatabasePassword service: IronicInspectorPassword description: PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret properties: - database: - default: IronicInspectorDatabasePassword - description: 'Database - Selector to get the ironic-inspector - Database user password from the Secret TODO: not used, need - change in mariadb-operator' - type: string service: default: IronicInspectorPassword description: Service - Selector to get the ironic-inspector @@ -1007,16 +1005,10 @@ spec: type: object passwordSelectors: default: - database: IronicDatabasePassword service: IronicPassword description: PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret properties: - database: - default: IronicDatabasePassword - description: 'Database - Selector to get the ironic Database user - password from the Secret TODO: not used, need change in mariadb-operator' - type: string service: default: IronicPassword description: Service - Selector to get the ironic service password @@ -1046,7 +1038,7 @@ spec: type: string secret: description: Secret containing OpenStack password information for - ironic IronicDatabasePassword, IronicPassword + ironic IronicPassword type: string serviceUser: default: ironic diff --git a/api/v1beta1/common_types.go b/api/v1beta1/common_types.go index 291f08dd..45aa1d78 100644 --- a/api/v1beta1/common_types.go +++ b/api/v1beta1/common_types.go @@ -53,13 +53,8 @@ type IronicServiceTemplate struct { DefaultConfigOverwrite map[string]string `json:"defaultConfigOverwrite,omitempty"` } -// PasswordSelector to identify the DB and AdminUser password from the Secret +// PasswordSelector to identify the AdminUser password from the Secret type PasswordSelector struct { - // +kubebuilder:validation:Optional - // +kubebuilder:default="IronicDatabasePassword" - // Database - Selector to get the ironic Database user password from the Secret - // TODO: not used, need change in mariadb-operator - Database string `json:"database"` // +kubebuilder:validation:Optional // +kubebuilder:default="IronicPassword" // Service - Selector to get the ironic service password from the Secret diff --git a/api/v1beta1/ironic_types.go b/api/v1beta1/ironic_types.go index 89d9e048..b39901d6 100644 --- a/api/v1beta1/ironic_types.go +++ b/api/v1beta1/ironic_types.go @@ -71,12 +71,17 @@ type IronicSpec struct { // Might not be required in future. DatabaseInstance string `json:"databaseInstance"` + // +kubebuilder:validation:Optional + // +kubebuilder:default=ironic + // DatabaseAccount - optional MariaDBAccount used for ironic DB, defaults to ironic. + DatabaseAccount string `json:"databaseAccount"` + // +kubebuilder:validation:Required - // Secret containing OpenStack password information for ironic IronicDatabasePassword, IronicPassword + // Secret containing OpenStack password information for ironic IronicPassword Secret string `json:"secret"` // +kubebuilder:validation:Optional - // +kubebuilder:default={database: IronicDatabasePassword, service: IronicPassword} + // +kubebuilder:default={service: IronicPassword} // PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret PasswordSelectors PasswordSelector `json:"passwordSelectors"` diff --git a/api/v1beta1/ironicapi_types.go b/api/v1beta1/ironicapi_types.go index c5a22e89..62a7cbed 100644 --- a/api/v1beta1/ironicapi_types.go +++ b/api/v1beta1/ironicapi_types.go @@ -72,11 +72,11 @@ type IronicAPISpec struct { ServiceUser string `json:"serviceUser"` // +kubebuilder:validation:Optional - // Secret containing OpenStack password information for IronicDatabasePassword, AdminPassword + // Secret containing OpenStack password information for AdminPassword Secret string `json:"secret,omitempty"` // +kubebuilder:validation:Optional - // +kubebuilder:default={database: IronicDatabasePassword, service: IronicPassword} + // +kubebuilder:default={service: IronicPassword} // PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret PasswordSelectors PasswordSelector `json:"passwordSelectors"` @@ -84,6 +84,11 @@ type IronicAPISpec struct { // DatabaseHostname - Ironic Database Hostname DatabaseHostname string `json:"databaseHostname"` + // +kubebuilder:validation:Optional + // +kubebuilder:default=ironic + // DatabaseAccount - optional MariaDBAccount used for ironic DB, defaults to ironic. + DatabaseAccount string `json:"databaseAccount"` + // +kubebuilder:validation:Optional // Secret containing RabbitMq transport URL TransportURLSecret string `json:"transportURLSecret,omitempty"` diff --git a/api/v1beta1/ironicconductor_types.go b/api/v1beta1/ironicconductor_types.go index ec07f055..f1623bf8 100644 --- a/api/v1beta1/ironicconductor_types.go +++ b/api/v1beta1/ironicconductor_types.go @@ -81,18 +81,23 @@ type IronicConductorSpec struct { ServiceUser string `json:"serviceUser"` // +kubebuilder:validation:Optional - // Secret containing OpenStack password information for IronicDatabasePassword, AdminPassword + // Secret containing OpenStack password information for AdminPassword Secret string `json:"secret,omitempty"` // +kubebuilder:validation:Optional - // +kubebuilder:default={database: IronicDatabasePassword, service: IronicPassword} - // PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret + // +kubebuilder:default={service: IronicPassword} + // PasswordSelectors - Selectors to identify the ServiceUser password from the Secret PasswordSelectors PasswordSelector `json:"passwordSelectors"` // +kubebuilder:validation:Required // DatabaseHostname - Ironic Database Hostname DatabaseHostname string `json:"databaseHostname"` + // +kubebuilder:validation:Optional + // +kubebuilder:default=ironic + // DatabaseAccount - optional MariaDBAccount used for ironic DB, defaults to ironic. + DatabaseAccount string `json:"databaseAccount"` + // +kubebuilder:validation:Optional // TransportURLSecret - Secret containing RabbitMQ transportURL TransportURLSecret string `json:"transportURLSecret,omitempty"` diff --git a/api/v1beta1/ironicinspector_types.go b/api/v1beta1/ironicinspector_types.go index 0fde7138..c42d24c5 100644 --- a/api/v1beta1/ironicinspector_types.go +++ b/api/v1beta1/ironicinspector_types.go @@ -24,13 +24,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// IronicInspectorPasswordSelector to identify the DB and AdminUser password from the Secret +// IronicInspectorPasswordSelector to identify the AdminUser password from the Secret type IronicInspectorPasswordSelector struct { - // +kubebuilder:validation:Optional - // +kubebuilder:default="IronicInspectorDatabasePassword" - // Database - Selector to get the ironic-inspector Database user password from the Secret - // TODO: not used, need change in mariadb-operator - Database string `json:"database"` // +kubebuilder:validation:Optional // +kubebuilder:default="IronicInspectorPassword" // Service - Selector to get the ironic-inspector service password from the Secret @@ -52,7 +47,7 @@ type IronicInspectorTemplate struct { Replicas *int32 `json:"replicas"` // +kubebuilder:validation:Optional - // +kubebuilder:default={database: IronicInspectorDatabasePassword, service: IronicInspectorPassword} + // +kubebuilder:default={service: IronicInspectorPassword} // PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret PasswordSelectors IronicInspectorPasswordSelector `json:"passwordSelectors"` @@ -146,7 +141,15 @@ type IronicInspectorSpec struct { DatabaseInstance string `json:"databaseInstance"` // +kubebuilder:validation:Optional - // Secret containing OpenStack password information for IronicInspectorDatabasePassword, AdminPassword + // +kubebuilder:default=ironic-inspector + // DatabaseAccount - optional MariaDBAccount used for ironic DB, defaults to ironic-inspector. + // this is separate from the account used for ironic, as a MariaDBAccount can only + // refer to a single MariaDBDatabase and it appears that ironic inspector uses its + // own MariaDBDatabase. + DatabaseAccount string `json:"databaseAccount"` + + // +kubebuilder:validation:Optional + // Secret containing OpenStack password information for AdminPassword Secret string `json:"secret,omitempty"` // +kubebuilder:validation:Optional diff --git a/config/crd/bases/ironic.openstack.org_ironicapis.yaml b/config/crd/bases/ironic.openstack.org_ironicapis.yaml index 8afbeafa..db40c32d 100644 --- a/config/crd/bases/ironic.openstack.org_ironicapis.yaml +++ b/config/crd/bases/ironic.openstack.org_ironicapis.yaml @@ -59,6 +59,11 @@ spec: added to to /etc//.conf.d directory as custom.conf file. type: string + databaseAccount: + default: ironic + description: DatabaseAccount - optional MariaDBAccount used for ironic + DB, defaults to ironic. + type: string databaseHostname: description: DatabaseHostname - Ironic Database Hostname type: string @@ -269,16 +274,10 @@ spec: type: object passwordSelectors: default: - database: IronicDatabasePassword service: IronicPassword description: PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret properties: - database: - default: IronicDatabasePassword - description: 'Database - Selector to get the ironic Database user - password from the Secret TODO: not used, need change in mariadb-operator' - type: string service: default: IronicPassword description: Service - Selector to get the ironic service password @@ -353,7 +352,7 @@ spec: type: string secret: description: Secret containing OpenStack password information for - IronicDatabasePassword, AdminPassword + AdminPassword type: string serviceUser: default: ironic diff --git a/config/crd/bases/ironic.openstack.org_ironicconductors.yaml b/config/crd/bases/ironic.openstack.org_ironicconductors.yaml index 659a2c0c..2d70c025 100644 --- a/config/crd/bases/ironic.openstack.org_ironicconductors.yaml +++ b/config/crd/bases/ironic.openstack.org_ironicconductors.yaml @@ -62,6 +62,11 @@ spec: added to to /etc//.conf.d directory as custom.conf file. type: string + databaseAccount: + default: ironic + description: DatabaseAccount - optional MariaDBAccount used for ironic + DB, defaults to ironic. + type: string databaseHostname: description: DatabaseHostname - Ironic Database Hostname type: string @@ -137,16 +142,10 @@ spec: type: object passwordSelectors: default: - database: IronicDatabasePassword service: IronicPassword - description: PasswordSelectors - Selectors to identify the DB and - ServiceUser password from the Secret + description: PasswordSelectors - Selectors to identify the ServiceUser + password from the Secret properties: - database: - default: IronicDatabasePassword - description: 'Database - Selector to get the ironic Database user - password from the Secret TODO: not used, need change in mariadb-operator' - type: string service: default: IronicPassword description: Service - Selector to get the ironic service password @@ -228,7 +227,7 @@ spec: type: string secret: description: Secret containing OpenStack password information for - IronicDatabasePassword, AdminPassword + AdminPassword type: string serviceUser: default: ironic diff --git a/config/crd/bases/ironic.openstack.org_ironicinspectors.yaml b/config/crd/bases/ironic.openstack.org_ironicinspectors.yaml index 85795b38..35737895 100644 --- a/config/crd/bases/ironic.openstack.org_ironicinspectors.yaml +++ b/config/crd/bases/ironic.openstack.org_ironicinspectors.yaml @@ -59,6 +59,14 @@ spec: added to to /etc//.conf.d directory as custom.conf file. type: string + databaseAccount: + default: ironic-inspector + description: DatabaseAccount - optional MariaDBAccount used for ironic + DB, defaults to ironic-inspector. this is separate from the account + used for ironic, as a MariaDBAccount can only refer to a single + MariaDBDatabase and it appears that ironic inspector uses its own + MariaDBDatabase. + type: string databaseInstance: description: MariaDB instance name. Right now required by the maridb-operator to get the credentials from the instance to create the DB. Might @@ -304,17 +312,10 @@ spec: type: object passwordSelectors: default: - database: IronicInspectorDatabasePassword service: IronicInspectorPassword description: PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret properties: - database: - default: IronicInspectorDatabasePassword - description: 'Database - Selector to get the ironic-inspector - Database user password from the Secret TODO: not used, need - change in mariadb-operator' - type: string service: default: IronicInspectorPassword description: Service - Selector to get the ironic-inspector service @@ -403,7 +404,7 @@ spec: type: string secret: description: Secret containing OpenStack password information for - IronicInspectorDatabasePassword, AdminPassword + AdminPassword type: string serviceUser: default: ironic-inspector diff --git a/config/crd/bases/ironic.openstack.org_ironicneutronagents.yaml b/config/crd/bases/ironic.openstack.org_ironicneutronagents.yaml index 861e54f6..87c2af79 100644 --- a/config/crd/bases/ironic.openstack.org_ironicneutronagents.yaml +++ b/config/crd/bases/ironic.openstack.org_ironicneutronagents.yaml @@ -83,11 +83,6 @@ spec: description: PasswordSelectors - Selectors to identify the ServiceUser password from the Secret properties: - database: - default: IronicDatabasePassword - description: 'Database - Selector to get the ironic Database user - password from the Secret TODO: not used, need change in mariadb-operator' - type: string service: default: IronicPassword description: Service - Selector to get the ironic service password diff --git a/config/crd/bases/ironic.openstack.org_ironics.yaml b/config/crd/bases/ironic.openstack.org_ironics.yaml index 1eee6a6b..e1aa2934 100644 --- a/config/crd/bases/ironic.openstack.org_ironics.yaml +++ b/config/crd/bases/ironic.openstack.org_ironics.yaml @@ -43,6 +43,11 @@ spec: added to to /etc//.conf.d directory as custom.conf file. type: string + databaseAccount: + default: ironic + description: DatabaseAccount - optional MariaDBAccount used for ironic + DB, defaults to ironic. + type: string databaseInstance: description: MariaDB instance name. Right now required by the maridb-operator to get the credentials from the instance to create the DB. Might @@ -790,17 +795,10 @@ spec: type: object passwordSelectors: default: - database: IronicInspectorDatabasePassword service: IronicInspectorPassword description: PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret properties: - database: - default: IronicInspectorDatabasePassword - description: 'Database - Selector to get the ironic-inspector - Database user password from the Secret TODO: not used, need - change in mariadb-operator' - type: string service: default: IronicInspectorPassword description: Service - Selector to get the ironic-inspector @@ -1007,16 +1005,10 @@ spec: type: object passwordSelectors: default: - database: IronicDatabasePassword service: IronicPassword description: PasswordSelectors - Selectors to identify the DB and ServiceUser password from the Secret properties: - database: - default: IronicDatabasePassword - description: 'Database - Selector to get the ironic Database user - password from the Secret TODO: not used, need change in mariadb-operator' - type: string service: default: IronicPassword description: Service - Selector to get the ironic service password @@ -1046,7 +1038,7 @@ spec: type: string secret: description: Secret containing OpenStack password information for - ironic IronicDatabasePassword, IronicPassword + ironic IronicPassword type: string serviceUser: default: ironic diff --git a/controllers/ironic_controller.go b/controllers/ironic_controller.go index 8be12dfe..6f3d7bca 100644 --- a/controllers/ironic_controller.go +++ b/controllers/ironic_controller.go @@ -27,13 +27,13 @@ import ( common "github.com/openstack-k8s-operators/lib-common/modules/common" condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" - configmap "github.com/openstack-k8s-operators/lib-common/modules/common/configmap" endpoint "github.com/openstack-k8s-operators/lib-common/modules/common/endpoint" env "github.com/openstack-k8s-operators/lib-common/modules/common/env" helper "github.com/openstack-k8s-operators/lib-common/modules/common/helper" job "github.com/openstack-k8s-operators/lib-common/modules/common/job" labels "github.com/openstack-k8s-operators/lib-common/modules/common/labels" common_rbac "github.com/openstack-k8s-operators/lib-common/modules/common/rbac" + "github.com/openstack-k8s-operators/lib-common/modules/common/secret" oko_secret "github.com/openstack-k8s-operators/lib-common/modules/common/secret" util "github.com/openstack-k8s-operators/lib-common/modules/common/util" @@ -230,7 +230,7 @@ func (r *IronicReconciler) reconcileDelete(ctx context.Context, instance *ironic Log.Info("Reconciling Ironic delete") // remove db finalizer first - db, err := mariadbv1.GetDatabaseByName(ctx, helper, instance.Name) + db, err := mariadbv1.GetDatabaseByNameAndAccount(ctx, helper, ironic.DatabaseName, instance.Spec.DatabaseAccount, instance.Namespace) if err != nil && !k8s_errors.IsNotFound(err) { return ctrl.Result{}, err } @@ -355,6 +355,28 @@ func (r *IronicReconciler) reconcileNormal(ctx context.Context, instance *ironic } } + // ensure MariaDBAccount exists. This account record may be created by + // openstack-operator or the cloud operator up front without a specific + // MariaDBDatabase configured yet. Otherwise, a MariaDBAccount CR is + // created here with a generated username as well as a secret with + // generated password. The MariaDBAccount is created without being + // yet associated with any MariaDBDatabase. + _, _, err = mariadbv1.EnsureMariaDBAccount( + ctx, helper, instance.Spec.DatabaseAccount, + instance.Namespace, false, + ) + + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + mariadbv1.MariaDBAccountReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + mariadbv1.MariaDBAccountNotReadyMessage, + err.Error())) + + return ctrl.Result{}, err + } + // // Create ConfigMaps and Secrets required as input for the Service and calculate an overall hash of hashes // @@ -579,6 +601,11 @@ func (r *IronicReconciler) reconcileNormal(ctx context.Context, instance *ironic instance.Status.Conditions.MarkTrue(ironicv1.IronicNeutronAgentReadyCondition, "") } + err = mariadbv1.DeleteUnusedMariaDBAccountFinalizers(ctx, helper, ironic.DatabaseName, instance.Spec.DatabaseAccount, instance.Namespace) + if err != nil { + return ctrl.Result{}, err + } + Log.Info("Reconciled Ironic successfully") return ctrl.Result{}, nil } @@ -596,14 +623,14 @@ func (r *IronicReconciler) reconcileInit( // // create service DB instance // - db := mariadbv1.NewDatabase( - instance.Name, - instance.Name, - instance.Spec.Secret, - map[string]string{ - "dbName": instance.Spec.DatabaseInstance, - }, + db := mariadbv1.NewDatabaseForAccount( + instance.Spec.DatabaseInstance, // mariadb/galera service to target + ironic.DatabaseName, // name used in CREATE DATABASE in mariadb + instance.Name, // CR name for MariaDBDatabase + instance.Spec.DatabaseAccount, // CR name for MariaDBAccount + instance.Namespace, // namespace ) + // create or patch the DB ctrlResult, err := db.CreateOrPatchDB( ctx, @@ -738,6 +765,7 @@ func (r *IronicReconciler) conductorDeploymentCreateOrUpdate( Secret: instance.Spec.Secret, PasswordSelectors: instance.Spec.PasswordSelectors, ServiceUser: instance.Spec.ServiceUser, + DatabaseAccount: instance.Spec.DatabaseAccount, DatabaseHostname: instance.Status.DatabaseHostname, TransportURLSecret: instance.Status.TransportURLSecret, KeystoneEndpoints: *keystoneEndpoints, @@ -781,6 +809,7 @@ func (r *IronicReconciler) apiDeploymentCreateOrUpdate( Secret: instance.Spec.Secret, PasswordSelectors: instance.Spec.PasswordSelectors, ServiceUser: instance.Spec.ServiceUser, + DatabaseAccount: instance.Spec.DatabaseAccount, DatabaseHostname: instance.Status.DatabaseHostname, TransportURLSecret: instance.Status.TransportURLSecret, KeystoneEndpoints: *keystoneEndpoints, @@ -850,6 +879,18 @@ func (r *IronicReconciler) generateServiceConfigMaps( templateParameters["Standalone"] = instance.Spec.Standalone templateParameters["LogPath"] = ironic.LogPath + databaseAccount, dbSecret, err := mariadbv1.GetAccountAndSecret(ctx, h, instance.Spec.DatabaseAccount, instance.Namespace) + if err != nil { + return err + } + + templateParameters["DatabaseConnection"] = fmt.Sprintf("mysql+pymysql://%s:%s@%s/%s", + databaseAccount.Spec.UserName, + string(dbSecret.Data[mariadbv1.DatabasePasswordSelector]), + instance.Status.DatabaseHostname, + ironic.DatabaseName, + ) + cms := []util.Template{ // Scripts ConfigMap { @@ -878,7 +919,7 @@ func (r *IronicReconciler) generateServiceConfigMaps( }, } - return configmap.EnsureConfigMaps(ctx, h, instance, cms, envVars) + return secret.EnsureSecrets(ctx, h, instance, cms, envVars) } // createHashOfInputHashes - creates a hash of hashes which gets added to the resources which requires a restart @@ -917,6 +958,7 @@ func (r *IronicReconciler) inspectorDeploymentCreateOrUpdate( IronicPythonAgentImage: instance.Spec.Images.IronicPythonAgent, Standalone: instance.Spec.Standalone, RPCTransport: instance.Spec.RPCTransport, + DatabaseAccount: fmt.Sprintf("%s-inspector", instance.Spec.DatabaseAccount), DatabaseInstance: instance.Spec.DatabaseInstance, RabbitMqClusterName: instance.Spec.RabbitMqClusterName, Secret: instance.Spec.Secret, diff --git a/controllers/ironicapi_controller.go b/controllers/ironicapi_controller.go index 2eeee310..c55b7386 100644 --- a/controllers/ironicapi_controller.go +++ b/controllers/ironicapi_controller.go @@ -46,7 +46,6 @@ import ( keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" "github.com/openstack-k8s-operators/lib-common/modules/common" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" - "github.com/openstack-k8s-operators/lib-common/modules/common/configmap" "github.com/openstack-k8s-operators/lib-common/modules/common/deployment" "github.com/openstack-k8s-operators/lib-common/modules/common/endpoint" "github.com/openstack-k8s-operators/lib-common/modules/common/env" @@ -58,6 +57,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/service" "github.com/openstack-k8s-operators/lib-common/modules/common/tls" "github.com/openstack-k8s-operators/lib-common/modules/common/util" + mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" ) // IronicAPIReconciler reconciles a IronicAPI object @@ -944,6 +944,18 @@ func (r *IronicAPIReconciler) generateServiceConfigMaps( templateParameters["Standalone"] = instance.Spec.Standalone templateParameters["LogPath"] = ironic.LogPath + databaseAccount, dbSecret, err := mariadbv1.GetAccountAndSecret(ctx, h, instance.Spec.DatabaseAccount, instance.Namespace) + if err != nil { + return err + } + + templateParameters["DatabaseConnection"] = fmt.Sprintf("mysql+pymysql://%s:%s@%s/%s", + databaseAccount.Spec.UserName, + string(dbSecret.Data[mariadbv1.DatabasePasswordSelector]), + instance.Spec.DatabaseHostname, + ironic.DatabaseName, + ) + // create httpd vhost template parameters httpdVhostConfig := map[string]interface{}{} for _, endpt := range []service.Endpoint{service.EndpointInternal, service.EndpointPublic} { @@ -987,7 +999,7 @@ func (r *IronicAPIReconciler) generateServiceConfigMaps( }, } - return configmap.EnsureConfigMaps(ctx, h, instance, cms, envVars) + return secret.EnsureSecrets(ctx, h, instance, cms, envVars) } // createHashOfInputHashes - creates a hash of hashes which gets added to the resources which requires a restart diff --git a/controllers/ironicconductor_controller.go b/controllers/ironicconductor_controller.go index baad7227..229b18f0 100644 --- a/controllers/ironicconductor_controller.go +++ b/controllers/ironicconductor_controller.go @@ -48,7 +48,6 @@ import ( ironicconductor "github.com/openstack-k8s-operators/ironic-operator/pkg/ironicconductor" "github.com/openstack-k8s-operators/lib-common/modules/common" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" - "github.com/openstack-k8s-operators/lib-common/modules/common/configmap" "github.com/openstack-k8s-operators/lib-common/modules/common/endpoint" "github.com/openstack-k8s-operators/lib-common/modules/common/env" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" @@ -60,6 +59,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/statefulset" "github.com/openstack-k8s-operators/lib-common/modules/common/tls" "github.com/openstack-k8s-operators/lib-common/modules/common/util" + mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" ) // IronicConductorReconciler reconciles a IronicConductor object @@ -786,6 +786,7 @@ func (r *IronicConductorReconciler) generateServiceConfigMaps( } templateParameters["IronicPublicURL"] = ironicPublicURL } + dhcpRanges, err := ironic.PrefixOrNetmaskFromCIDR(instance.Spec.DHCPRanges) if err != nil { Log.Error(err, "Failed to get Prefix or Netmask from IP network Prefix (CIDR)") @@ -795,6 +796,18 @@ func (r *IronicConductorReconciler) generateServiceConfigMaps( templateParameters["ConductorGroup"] = instance.Spec.ConductorGroup templateParameters["LogPath"] = ironicconductor.LogPath + databaseAccount, dbSecret, err := mariadbv1.GetAccountAndSecret(ctx, h, instance.Spec.DatabaseAccount, instance.Namespace) + if err != nil { + return err + } + + templateParameters["DatabaseConnection"] = fmt.Sprintf("mysql+pymysql://%s:%s@%s/%s", + databaseAccount.Spec.UserName, + string(dbSecret.Data[mariadbv1.DatabasePasswordSelector]), + instance.Spec.DatabaseHostname, + ironic.DatabaseName, + ) + cms := []util.Template{ // Scripts ConfigMap { @@ -824,7 +837,7 @@ func (r *IronicConductorReconciler) generateServiceConfigMaps( }, } - return configmap.EnsureConfigMaps(ctx, h, instance, cms, envVars) + return secret.EnsureSecrets(ctx, h, instance, cms, envVars) } // createHashOfInputHashes - creates a hash of hashes which gets added to the resources which requires a restart diff --git a/controllers/ironicinspector_controller.go b/controllers/ironicinspector_controller.go index dbe5df1f..97e5d28f 100644 --- a/controllers/ironicinspector_controller.go +++ b/controllers/ironicinspector_controller.go @@ -19,7 +19,6 @@ package controllers import ( "context" "fmt" - "strings" "time" "github.com/go-logr/logr" @@ -28,12 +27,12 @@ import ( mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1" common "github.com/openstack-k8s-operators/lib-common/modules/common" - configmap "github.com/openstack-k8s-operators/lib-common/modules/common/configmap" endpoint "github.com/openstack-k8s-operators/lib-common/modules/common/endpoint" env "github.com/openstack-k8s-operators/lib-common/modules/common/env" job "github.com/openstack-k8s-operators/lib-common/modules/common/job" nad "github.com/openstack-k8s-operators/lib-common/modules/common/networkattachment" common_rbac "github.com/openstack-k8s-operators/lib-common/modules/common/rbac" + "github.com/openstack-k8s-operators/lib-common/modules/common/secret" oko_secret "github.com/openstack-k8s-operators/lib-common/modules/common/secret" "github.com/openstack-k8s-operators/lib-common/modules/common/service" "github.com/openstack-k8s-operators/lib-common/modules/common/statefulset" @@ -725,6 +724,28 @@ func (r *IronicInspectorReconciler) reconcileNormal( return ctrlResult, nil } + // ensure MariaDBAccount exists. This account record may be created by + // openstack-operator or the cloud operator up front without a specific + // MariaDBDatabase configured yet. Otherwise, a MariaDBAccount CR is + // created here with a generated username as well as a secret with + // generated password. The MariaDBAccount is created without being + // yet associated with any MariaDBDatabase. + _, _, err = mariadbv1.EnsureMariaDBAccount( + ctx, helper, instance.Spec.DatabaseAccount, + instance.Namespace, false, + ) + + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + mariadbv1.MariaDBAccountReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + mariadbv1.MariaDBAccountNotReadyMessage, + err.Error())) + + return ctrl.Result{}, err + } + ctrlResult, inputHash, err := r.reconcileConfigMapsAndSecrets(ctx, instance, helper) if err != nil { return ctrlResult, err @@ -803,6 +824,7 @@ func (r *IronicInspectorReconciler) reconcileNormal( } else if (ctrlResult != ctrl.Result{}) { return ctrlResult, nil } + // Handle service init ctrlResult, err = r.reconcileServices(ctx, instance, helper, serviceLabels) if err != nil { @@ -811,6 +833,11 @@ func (r *IronicInspectorReconciler) reconcileNormal( return ctrlResult, nil } + err = mariadbv1.DeleteUnusedMariaDBAccountFinalizers(ctx, helper, instance.Name, instance.Spec.DatabaseAccount, instance.Namespace) + if err != nil { + return ctrl.Result{}, err + } + Log.Info("Reconciled Ironic Inspector successfully") return ctrl.Result{}, nil } @@ -862,7 +889,7 @@ func (r *IronicInspectorReconciler) reconcileDeleteDatabase( helper *helper.Helper, ) (ctrl.Result, error) { // remove db finalizer first - db, err := mariadbv1.GetDatabaseByName(ctx, helper, instance.Name) + db, err := mariadbv1.GetDatabaseByNameAndAccount(ctx, helper, instance.Name, instance.Spec.DatabaseAccount, instance.Namespace) if err != nil && !k8s_errors.IsNotFound(err) { return ctrl.Result{}, err } @@ -911,14 +938,13 @@ func (r *IronicInspectorReconciler) reconcileServiceDBinstance( helper *helper.Helper, serviceLabels map[string]string, ) (ctrl.Result, error) { - databaseName := strings.Replace(instance.Name, "-", "_", -1) - db := mariadbv1.NewDatabase( - databaseName, - databaseName, - instance.Spec.Secret, - map[string]string{ - "dbName": instance.Spec.DatabaseInstance, - }, + + db := mariadbv1.NewDatabaseForAccount( + instance.Spec.DatabaseInstance, // mariadb/galera service to target + ironicinspector.DatabaseName, // name used in CREATE DATABASE in mariadb + instance.Name, // CR name for MariaDBDatabase + instance.Spec.DatabaseAccount, // CR name for MariaDBAccount + instance.Namespace, // namespace ) // create or patch the DB @@ -964,7 +990,9 @@ func (r *IronicInspectorReconciler) reconcileServiceDBinstance( condition.DBReadyRunningMessage)) return ctrlResult, nil } - // update Status.DatabaseHostname, used to bootstrap/config the service + + // update Status.DatabaseName and Status.DatabaseHostname, used to + // bootstrap/config the service instance.Status.DatabaseHostname = db.GetDatabaseHostname() instance.Status.Conditions.MarkTrue( condition.DBReadyCondition, @@ -1369,6 +1397,18 @@ func (r *IronicInspectorReconciler) generateServiceConfigMaps( templateParameters["DHCPRanges"] = dhcpRanges templateParameters["Standalone"] = instance.Spec.Standalone + databaseAccount, dbSecret, err := mariadbv1.GetAccountAndSecret(ctx, h, instance.Spec.DatabaseAccount, instance.Namespace) + if err != nil { + return err + } + + templateParameters["DatabaseConnection"] = fmt.Sprintf("mysql+pymysql://%s:%s@%s/%s", + databaseAccount.Spec.UserName, + string(dbSecret.Data[mariadbv1.DatabasePasswordSelector]), + instance.Status.DatabaseHostname, + ironicinspector.DatabaseName, + ) + // create httpd vhost template parameters httpdVhostConfig := map[string]interface{}{} for _, endpt := range []service.Endpoint{service.EndpointInternal, service.EndpointPublic} { @@ -1408,7 +1448,7 @@ func (r *IronicInspectorReconciler) generateServiceConfigMaps( Labels: cmLabels, }, } - return configmap.EnsureConfigMaps(ctx, h, instance, cms, envVars) + return secret.EnsureSecrets(ctx, h, instance, cms, envVars) } // createHashOfInputHashes - creates a hash of hashes which gets added to the diff --git a/controllers/ironicneutronagent_controller.go b/controllers/ironicneutronagent_controller.go index e524fd3b..ea4b408e 100644 --- a/controllers/ironicneutronagent_controller.go +++ b/controllers/ironicneutronagent_controller.go @@ -50,7 +50,6 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" - "github.com/openstack-k8s-operators/lib-common/modules/common/configmap" "github.com/openstack-k8s-operators/lib-common/modules/common/deployment" "github.com/openstack-k8s-operators/lib-common/modules/common/env" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" @@ -695,7 +694,7 @@ func (r *IronicNeutronAgentReconciler) generateServiceConfigMaps( }, } - return configmap.EnsureConfigMaps(ctx, h, instance, cms, envVars) + return secret.EnsureSecrets(ctx, h, instance, cms, envVars) } // createHashOfInputHashes - creates a hash of hashes which gets added to the resources which requires a restart diff --git a/go.mod b/go.mod index 4f9c63ee..b591b429 100644 --- a/go.mod +++ b/go.mod @@ -90,3 +90,5 @@ replace github.com/openstack-k8s-operators/ironic-operator/api => ./api // mschuppert: map to latest commit from release-4.13 tag // must consistent within modules and service operators replace github.com/openshift/api => github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 //allow-merging + +replace github.com/openstack-k8s-operators/mariadb-operator/api => github.com/zzzeek/mariadb-operator/api v0.3.1-0.20240220154131-35c205caf022 //allow-merging diff --git a/go.sum b/go.sum index 71ce43af..1961b25c 100644 --- a/go.sum +++ b/go.sum @@ -88,8 +88,6 @@ github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.2024021 github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240214144842-5dcac51e5b36/go.mod h1:8QsCFttAm+X6A8I8EQThGjNjeMAYt2hK7ivbvnR3434= github.com/openstack-k8s-operators/lib-common/modules/test v0.3.1-0.20240214144842-5dcac51e5b36 h1:GXdro9f/BoLdkW1PxPlRs3e/47ml56UiJunjIO6uu3Q= github.com/openstack-k8s-operators/lib-common/modules/test v0.3.1-0.20240214144842-5dcac51e5b36/go.mod h1:82nzS+DbBe1tzaMvNHH8FctmZzQ14ZAJysFGsMJiivo= -github.com/openstack-k8s-operators/mariadb-operator/api v0.3.1-0.20240214153937-3b28b9d3d09b h1:3A0CmqlHswSLJYwddVTfQ/ndB5DfP7W2GKFv6C3jOec= -github.com/openstack-k8s-operators/mariadb-operator/api v0.3.1-0.20240214153937-3b28b9d3d09b/go.mod h1:52Ja/B4RrrytMmKh+Kf+/BPe7Fq40Pi77vcFH4yJeoU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -112,6 +110,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zzzeek/mariadb-operator/api v0.3.1-0.20240220154131-35c205caf022 h1:GYSerUlfrs77MTb9NKFdc4c+/W39HlbHCScCkVz3IJQ= +github.com/zzzeek/mariadb-operator/api v0.3.1-0.20240220154131-35c205caf022/go.mod h1:PDqfLbP4ZWqQHAu1OtbjfpOGQUKSzLqRJChvE/9pcyQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= diff --git a/pkg/ironic/dbsync.go b/pkg/ironic/dbsync.go index ce16a7be..c8f286e1 100644 --- a/pkg/ironic/dbsync.go +++ b/pkg/ironic/dbsync.go @@ -90,7 +90,6 @@ func DbSyncJob( DatabaseHost: instance.Status.DatabaseHostname, DatabaseName: DatabaseName, OSPSecret: instance.Spec.Secret, - DBPasswordSelector: instance.Spec.PasswordSelectors.Database, UserPasswordSelector: instance.Spec.PasswordSelectors.Service, VolumeMounts: initVolumeMounts, } diff --git a/pkg/ironic/initcontainer.go b/pkg/ironic/initcontainer.go index 6bf245e6..3e6be6a1 100644 --- a/pkg/ironic/initcontainer.go +++ b/pkg/ironic/initcontainer.go @@ -30,7 +30,6 @@ type APIDetails struct { DatabaseName string TransportURLSecret string OSPSecret string - DBPasswordSelector string UserPasswordSelector string VolumeMounts []corev1.VolumeMount Privileged bool @@ -61,17 +60,6 @@ func InitContainer(init APIDetails) []corev1.Container { envVars["IngressDomain"] = env.SetValue(init.IngressDomain) envs := []corev1.EnvVar{ - { - Name: "DatabasePassword", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: init.OSPSecret, - }, - Key: init.DBPasswordSelector, - }, - }, - }, { Name: "IronicPassword", ValueFrom: &corev1.EnvVarSource{ diff --git a/pkg/ironic/volumes.go b/pkg/ironic/volumes.go index c16ed7f9..3809100d 100644 --- a/pkg/ironic/volumes.go +++ b/pkg/ironic/volumes.go @@ -13,22 +13,18 @@ func GetVolumes(name string) []corev1.Volume { { Name: "scripts", VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ + Secret: &corev1.SecretVolumeSource{ DefaultMode: &scriptsVolumeDefaultMode, - LocalObjectReference: corev1.LocalObjectReference{ - Name: name + "-scripts", - }, + SecretName: name + "-scripts", }, }, }, { Name: "config-data", VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ + Secret: &corev1.SecretVolumeSource{ DefaultMode: &config0640AccessMode, - LocalObjectReference: corev1.LocalObjectReference{ - Name: name + "-config-data", - }, + SecretName: name + "-config-data", }, }, }, diff --git a/pkg/ironicapi/deployment.go b/pkg/ironicapi/deployment.go index a934d104..48a432b0 100644 --- a/pkg/ironicapi/deployment.go +++ b/pkg/ironicapi/deployment.go @@ -190,7 +190,6 @@ func Deployment( DatabaseName: ironic.DatabaseName, OSPSecret: instance.Spec.Secret, TransportURLSecret: instance.Spec.TransportURLSecret, - DBPasswordSelector: instance.Spec.PasswordSelectors.Database, UserPasswordSelector: instance.Spec.PasswordSelectors.Service, VolumeMounts: initVolumeMounts, PxeInit: false, diff --git a/pkg/ironicapi/volumes.go b/pkg/ironicapi/volumes.go index 7a41b3c8..60059ba6 100644 --- a/pkg/ironicapi/volumes.go +++ b/pkg/ironicapi/volumes.go @@ -13,11 +13,9 @@ func GetVolumes(name string) []corev1.Volume { { Name: "config-data-custom", VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ + Secret: &corev1.SecretVolumeSource{ DefaultMode: &config0640AccessMode, - LocalObjectReference: corev1.LocalObjectReference{ - Name: name + "-config-data", - }, + SecretName: name + "-config-data", }, }, }, diff --git a/pkg/ironicconductor/statefulset.go b/pkg/ironicconductor/statefulset.go index 8f31fb73..760e8a85 100644 --- a/pkg/ironicconductor/statefulset.go +++ b/pkg/ironicconductor/statefulset.go @@ -280,7 +280,6 @@ func StatefulSet( DatabaseName: ironic.DatabaseName, OSPSecret: instance.Spec.Secret, TransportURLSecret: instance.Spec.TransportURLSecret, - DBPasswordSelector: instance.Spec.PasswordSelectors.Database, UserPasswordSelector: instance.Spec.PasswordSelectors.Service, VolumeMounts: initVolumeMounts, PxeInit: true, diff --git a/pkg/ironicconductor/volumes.go b/pkg/ironicconductor/volumes.go index e2db42d4..a7fedd82 100644 --- a/pkg/ironicconductor/volumes.go +++ b/pkg/ironicconductor/volumes.go @@ -20,11 +20,9 @@ func GetVolumes(instance *ironicv1.IronicConductor) []corev1.Volume { { Name: "config-data-custom", VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ + Secret: &corev1.SecretVolumeSource{ DefaultMode: &config0640AccessMode, - LocalObjectReference: corev1.LocalObjectReference{ - Name: fmt.Sprintf("%s-config-data", instance.Name), - }, + SecretName: fmt.Sprintf("%s-config-data", instance.Name), }, }, }, diff --git a/pkg/ironicinspector/dbsync.go b/pkg/ironicinspector/dbsync.go index 73d4b1a5..8cc55ab8 100644 --- a/pkg/ironicinspector/dbsync.go +++ b/pkg/ironicinspector/dbsync.go @@ -81,7 +81,6 @@ func DbSyncJob( DatabaseHost: instance.Status.DatabaseHostname, DatabaseName: DatabaseName, OSPSecret: instance.Spec.Secret, - DBPasswordSelector: instance.Spec.PasswordSelectors.Database, UserPasswordSelector: instance.Spec.PasswordSelectors.Service, VolumeMounts: GetInitVolumeMounts(), } diff --git a/pkg/ironicinspector/initcontainer.go b/pkg/ironicinspector/initcontainer.go index 810ab7c4..5a9e9ece 100644 --- a/pkg/ironicinspector/initcontainer.go +++ b/pkg/ironicinspector/initcontainer.go @@ -32,7 +32,6 @@ type APIDetails struct { DatabaseName string TransportURLSecret string OSPSecret string - DBPasswordSelector string UserPasswordSelector string VolumeMounts []corev1.VolumeMount Privileged bool @@ -62,17 +61,6 @@ func InitContainer(init APIDetails) []corev1.Container { envVars["InspectionNetwork"] = env.SetValue(init.InspectionNetwork) envs := []corev1.EnvVar{ - { - Name: "DatabasePassword", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: init.OSPSecret, - }, - Key: init.DBPasswordSelector, - }, - }, - }, { Name: "IronicInspectorPassword", ValueFrom: &corev1.EnvVarSource{ diff --git a/pkg/ironicinspector/statefulset.go b/pkg/ironicinspector/statefulset.go index b5cf9a21..0c2112c6 100644 --- a/pkg/ironicinspector/statefulset.go +++ b/pkg/ironicinspector/statefulset.go @@ -311,7 +311,6 @@ func StatefulSet( DatabaseName: DatabaseName, OSPSecret: instance.Spec.Secret, TransportURLSecret: instance.Status.TransportURLSecret, - DBPasswordSelector: instance.Spec.PasswordSelectors.Database, UserPasswordSelector: instance.Spec.PasswordSelectors.Service, VolumeMounts: initVolumeMounts, PxeInit: true, diff --git a/pkg/ironicinspector/volumes.go b/pkg/ironicinspector/volumes.go index 57ec5407..55ddd09e 100644 --- a/pkg/ironicinspector/volumes.go +++ b/pkg/ironicinspector/volumes.go @@ -13,22 +13,18 @@ func GetVolumes(name string) []corev1.Volume { { Name: "scripts", VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ + Secret: &corev1.SecretVolumeSource{ DefaultMode: &scriptsVolumeDefaultMode, - LocalObjectReference: corev1.LocalObjectReference{ - Name: name + "-scripts", - }, + SecretName: name + "-scripts", }, }, }, { Name: "config-data", VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ + Secret: &corev1.SecretVolumeSource{ DefaultMode: &config0640AccessMode, - LocalObjectReference: corev1.LocalObjectReference{ - Name: name + "-config-data", - }, + SecretName: name + "-config-data", }, }, }, diff --git a/pkg/ironicneutronagent/volumes.go b/pkg/ironicneutronagent/volumes.go index 8ada63a7..ab9babf7 100644 --- a/pkg/ironicneutronagent/volumes.go +++ b/pkg/ironicneutronagent/volumes.go @@ -29,22 +29,18 @@ func GetVolumes(name string) []corev1.Volume { { Name: "scripts", VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ + Secret: &corev1.SecretVolumeSource{ DefaultMode: &scriptsVolumeDefaultMode, - LocalObjectReference: corev1.LocalObjectReference{ - Name: name + "-scripts", - }, + SecretName: name + "-scripts", }, }, }, { Name: "config-data", VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ + Secret: &corev1.SecretVolumeSource{ DefaultMode: &config0640AccessMode, - LocalObjectReference: corev1.LocalObjectReference{ - Name: name + "-config-data", - }, + SecretName: name + "-config-data", }, }, }, diff --git a/templates/common/bin/common.sh b/templates/common/bin/common.sh index 3dd039f9..fd352b93 100755 --- a/templates/common/bin/common.sh +++ b/templates/common/bin/common.sh @@ -36,10 +36,6 @@ function merge_config_dir { function common_ironic_config { # Secrets are obtained from ENV variables. - export DB=${DatabaseName:-"ironic"} - export DBHOST=${DatabaseHost:?"Please specify a DatabaseHost variable."} - export DBUSER=${DatabaseName:-"ironic"} - export DBPASSWORD=${DatabasePassword:?"Please specify a DatabasePassword variable."} export IRONICPASSWORD=${IronicPassword:?"Please specify a IronicPassword variable."} export TRANSPORTURL=${TransportURL:-""} # TODO: nova password @@ -86,7 +82,6 @@ function common_ironic_config { crudini --set ${SVC_CFG_MERGED} DEFAULT transport_url $TRANSPORTURL crudini --set ${SVC_CFG_MERGED} DEFAULT rpc_transport oslo fi - crudini --set ${SVC_CFG_MERGED} database connection mysql+pymysql://${DBUSER}:${DBPASSWORD}@${DBHOST}/${DB} crudini --set ${SVC_CFG_MERGED} keystone_authtoken password $IRONICPASSWORD crudini --set ${SVC_CFG_MERGED} service_catalog password $IRONICPASSWORD crudini --set ${SVC_CFG_MERGED} cinder password $IRONICPASSWORD diff --git a/templates/common/config/ironic.conf b/templates/common/config/ironic.conf index 331c4793..ea441e62 100644 --- a/templates/common/config/ironic.conf +++ b/templates/common/config/ironic.conf @@ -127,6 +127,7 @@ allow_methods=GET,POST,PUT,DELETE,OPTIONS,PATCH allow_headers=Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma,X-Auth-Token [database] +connection={{ .DatabaseConnection }} max_retries=-1 db_max_retries=-1 diff --git a/templates/ironicinspector/bin/init.sh b/templates/ironicinspector/bin/init.sh index e5e19c02..60c7c51f 100755 --- a/templates/ironicinspector/bin/init.sh +++ b/templates/ironicinspector/bin/init.sh @@ -15,10 +15,6 @@ # under the License. # Secrets are obtained from ENV variables. -export DB=${DatabaseName:-"ironic_inspector"} -export DBHOST=${DatabaseHost:?"Please specify a DatabaseHost variable."} -export DBUSER=${DatabaseName:-"ironic_inspector"} -export DBPASSWORD=${DatabasePassword:?"Please specify a DatabasePassword variable."} export INSPECTORPASSWORD=${IronicInspectorPassword:?"Please specify a IronicInspectorPassword variable."} export TRANSPORTURL=${TransportURL:-""} @@ -66,7 +62,6 @@ fi if [ -n "$TRANSPORTURL" ]; then crudini --set ${SVC_CFG_MERGED} DEFAULT transport_url $TRANSPORTURL fi -crudini --set ${SVC_CFG_MERGED} database connection mysql+pymysql://${DBUSER}:${DBPASSWORD}@${DBHOST}/${DB} crudini --set ${SVC_CFG_MERGED} keystone_authtoken password $INSPECTORPASSWORD crudini --set ${SVC_CFG_MERGED} service_catalog password $INSPECTORPASSWORD crudini --set ${SVC_CFG_MERGED} ironic password $INSPECTORPASSWORD diff --git a/templates/ironicinspector/config/inspector.conf b/templates/ironicinspector/config/inspector.conf index c15a4bdd..739cfe95 100644 --- a/templates/ironicinspector/config/inspector.conf +++ b/templates/ironicinspector/config/inspector.conf @@ -16,6 +16,9 @@ allow_headers=Content-Type,Cache-Control,Content-Language,Expires,Last-Modified, dhcp_hostsdir=/var/lib/ironic-inspector/dhcp-hostsdir purge_dhcp_hostsdir=False +[database] +connection={{ .DatabaseConnection }} + {{if .Standalone}} [ironic] auth_type=none diff --git a/tests/functional/base_test.go b/tests/functional/base_test.go index a4b65ba8..e1e60625 100644 --- a/tests/functional/base_test.go +++ b/tests/functional/base_test.go @@ -53,13 +53,14 @@ type IronicNames struct { IronicServiceAccount types.NamespacedName IronicTransportURLName types.NamespacedName IronicDatabaseName types.NamespacedName + IronicDatabaseAccount types.NamespacedName IronicDBSyncJobName types.NamespacedName ServiceAccountName types.NamespacedName APIName types.NamespacedName APIServiceAccount types.NamespacedName APIRole types.NamespacedName APIRoleBinding types.NamespacedName - APIConfigDataName types.NamespacedName + APIConfigSecretName types.NamespacedName ConductorName types.NamespacedName ConductorServiceAccount types.NamespacedName ConductorRole types.NamespacedName @@ -70,8 +71,9 @@ type IronicNames struct { InspectorRole types.NamespacedName InspectorRoleBinding types.NamespacedName InspectorDatabaseName types.NamespacedName + InspectorDatabaseAccount types.NamespacedName InspectorDBSyncJobName types.NamespacedName - InspectorConfigDataName types.NamespacedName + InspectorConfigSecretName types.NamespacedName INAName types.NamespacedName INATransportURLName types.NamespacedName KeystoneServiceName types.NamespacedName @@ -118,6 +120,10 @@ func GetIronicNames( Namespace: ironic.Namespace, Name: ironic.Name, }, + IronicDatabaseAccount: types.NamespacedName{ + Namespace: ironic.Namespace, + Name: ironic.Name, + }, IronicDBSyncJobName: types.NamespacedName{ Namespace: ironic.Namespace, Name: ironic_pkg.ServiceName + "-db-sync", @@ -150,7 +156,7 @@ func GetIronicNames( Namespace: ironicAPI.Namespace, Name: "ironicapi-" + ironicAPI.Name + "-rolebinding", }, - APIConfigDataName: types.NamespacedName{ + APIConfigSecretName: types.NamespacedName{ Namespace: ironicAPI.Namespace, Name: "ironic-api-config-data", }, @@ -194,11 +200,15 @@ func GetIronicNames( Namespace: ironicInspector.Namespace, Name: ironicInspector.Name, }, + InspectorDatabaseAccount: types.NamespacedName{ + Namespace: ironicInspector.Namespace, + Name: ironicInspector.Name, + }, InspectorDBSyncJobName: types.NamespacedName{ Namespace: ironicInspector.Namespace, Name: ironic_pkg.ServiceName + "-" + ironic_pkg.InspectorComponent + "-db-sync", }, - InspectorConfigDataName: types.NamespacedName{ + InspectorConfigSecretName: types.NamespacedName{ Namespace: ironicAPI.Namespace, Name: "ironic-inspector-config-data", }, diff --git a/tests/functional/ironic_controller_test.go b/tests/functional/ironic_controller_test.go index c050d42a..14f184b3 100644 --- a/tests/functional/ironic_controller_test.go +++ b/tests/functional/ironic_controller_test.go @@ -23,6 +23,7 @@ import ( ironicv1 "github.com/openstack-k8s-operators/ironic-operator/api/v1beta1" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" . "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers" + mariadb_test "github.com/openstack-k8s-operators/mariadb-operator/api/test/helpers" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" ) @@ -67,8 +68,7 @@ var _ = Describe("Ironic controller", func() { Expect(instance.Spec.Standalone).Should(BeFalse()) Expect(instance.Spec.PasswordSelectors).Should(Equal( ironicv1.PasswordSelector{ - Database: "IronicDatabasePassword", - Service: "IronicPassword", + Service: "IronicPassword", })) Expect(instance.Spec.CustomServiceConfig).Should(Equal("# add your customization here")) Expect(instance.Spec.StorageClass).Should(Equal("")) @@ -154,7 +154,7 @@ var _ = Describe("Ironic controller", func() { infra.GetTransportURL(ironicNames.IronicTransportURLName) infra.SimulateTransportURLReady(ironicNames.IronicTransportURLName) mariadb.GetMariaDBDatabase(ironicNames.IronicDatabaseName) - mariadb.SimulateMariaDBAccountCompleted(ironicNames.IronicDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(ironicNames.IronicDatabaseAccount) mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.IronicDatabaseName) th.ExpectCondition( ironicNames.IronicName, @@ -167,7 +167,7 @@ var _ = Describe("Ironic controller", func() { infra.GetTransportURL(ironicNames.IronicTransportURLName) infra.SimulateTransportURLReady(ironicNames.IronicTransportURLName) mariadb.GetMariaDBDatabase(ironicNames.IronicDatabaseName) - mariadb.SimulateMariaDBAccountCompleted(ironicNames.IronicDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(ironicNames.IronicDatabaseAccount) mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.IronicDatabaseName) th.SimulateJobSuccess(ironicNames.IronicDBSyncJobName) th.ExpectCondition( @@ -181,7 +181,7 @@ var _ = Describe("Ironic controller", func() { infra.GetTransportURL(ironicNames.IronicTransportURLName) infra.SimulateTransportURLReady(ironicNames.IronicTransportURLName) mariadb.GetMariaDBDatabase(ironicNames.IronicDatabaseName) - mariadb.SimulateMariaDBAccountCompleted(ironicNames.IronicDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(ironicNames.IronicDatabaseAccount) mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.IronicDatabaseName) th.SimulateJobSuccess(ironicNames.IronicDBSyncJobName) Eventually(func(g Gomega) { @@ -210,4 +210,89 @@ var _ = Describe("Ironic controller", func() { }, th.Timeout, th.Interval).Should(Succeed()) }) }) + + // Run MariaDBAccount suite tests. these are pre-packaged ginkgo tests + // that exercise standard account create / update patterns that should be + // common to all controllers that ensure MariaDBAccount CRs. + mariadb_test.MariaDBAccountSuiteTests( + "Ironic", + // Populate test variables which will run inside of BeforeEach + func(harness *mariadb_test.MariaDBTestHarness) { + harness.PopulateHarness( + ironicNames.Namespace, + ironicNames.IronicDatabaseName.Name, + "Ironic", + mariadb, + timeout, + interval, + ) + }, + // Generate a fully running Ironic service given an accountName + // needs to make it all the way to the end where the mariadb finalizers + // are removed from unused accounts since that's part of what we are testing + func(accountName types.NamespacedName) { + spec := GetDefaultIronicSpec() + + spec["databaseAccount"] = accountName.Name + + DeferCleanup( + k8sClient.Delete, + ctx, + CreateIronicSecret(ironicNames.Namespace, SecretName), + ) + DeferCleanup( + k8sClient.Delete, + ctx, + CreateMessageBusSecret(ironicNames.Namespace, MessageBusSecretName), + ) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + ironicNames.Namespace, + "openstack", + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + DeferCleanup( + keystone.DeleteKeystoneAPI, + keystone.CreateKeystoneAPI(ironicNames.Namespace)) + + spec["rpcTransport"] = "oslo" + spec["transportURLSecret"] = MessageBusSecretName + DeferCleanup( + th.DeleteInstance, + CreateIronic(ironicNames.IronicName, spec), + ) + infra.GetTransportURL(ironicNames.IronicTransportURLName) + infra.SimulateTransportURLReady(ironicNames.IronicTransportURLName) + mariadb.GetMariaDBDatabase(ironicNames.IronicDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(accountName) + mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.IronicDatabaseName) + th.SimulateJobSuccess(ironicNames.IronicDBSyncJobName) + th.ExpectCondition( + ironicNames.IronicName, + ConditionGetterFunc(IronicConditionGetter), + condition.DBSyncReadyCondition, + corev1.ConditionTrue, + ) + + }, + // Change the account name in the service to a new name + func(newAccountName types.NamespacedName) { + + Eventually(func(g Gomega) { + ironic := GetIronic(ironicNames.IronicName) + ironic.Spec.DatabaseAccount = newAccountName.Name + g.Expect(th.K8sClient.Update(ctx, ironic)).Should(Succeed()) + }, timeout, interval).Should(Succeed()) + + }, + // delete the keystone instance to exercise finalizer removal + func() { + th.DeleteInstance(GetIronic(ironicNames.IronicName)) + }, + ) + }) diff --git a/tests/functional/ironicapi_controller_test.go b/tests/functional/ironicapi_controller_test.go index 47b915ec..ac1dfba7 100644 --- a/tests/functional/ironicapi_controller_test.go +++ b/tests/functional/ironicapi_controller_test.go @@ -28,6 +28,12 @@ import ( ) var _ = Describe("IronicAPI controller", func() { + BeforeEach(func() { + apiMariaDBAccount, apiMariaDBSecret := mariadb.CreateMariaDBAccount(ironicNames.IronicDatabaseAccount) + DeferCleanup(k8sClient.Delete, ctx, apiMariaDBAccount) + DeferCleanup(k8sClient.Delete, ctx, apiMariaDBSecret) + }) + When("IronicAPI is created with rpcTransport == oslo", func() { BeforeEach(func() { DeferCleanup( @@ -66,8 +72,7 @@ var _ = Describe("IronicAPI controller", func() { Expect(instance.Spec.Standalone).Should(BeFalse()) Expect(instance.Spec.PasswordSelectors).Should(Equal( ironicv1.PasswordSelector{ - Database: "IronicDatabasePassword", - Service: "IronicPassword", + Service: "IronicPassword", })) Expect(instance.Spec.CustomServiceConfig).Should(Equal("# add your customization here")) }) @@ -111,7 +116,7 @@ var _ = Describe("IronicAPI controller", func() { Expect(binding.Subjects).To(HaveLen(1)) Expect(binding.Subjects[0].Name).To(Equal(sa.Name)) }) - It("Creates ConfigMaps and gets Secrets (input) and set Hash of inputs", func() { + It("Creates config Secrets and gets Secrets (input) and set Hash of inputs", func() { th.ExpectCondition( ironicNames.APIName, ConditionGetterFunc(IronicAPIConditionGetter), @@ -137,11 +142,11 @@ var _ = Describe("IronicAPI controller", func() { corev1.ConditionTrue, ) instance := GetIronicAPI(ironicNames.APIName) - apiConfigMapName := types.NamespacedName{ + apiSecretName := types.NamespacedName{ Namespace: instance.Namespace, Name: fmt.Sprintf("%s-config-data", instance.Name), } - configDataMap := th.GetConfigMap(apiConfigMapName) + configDataMap := th.GetSecret(apiSecretName) Expect(configDataMap).ShouldNot(BeNil()) Expect(configDataMap.Data).Should(HaveKey("ironic.conf")) configData := string(configDataMap.Data["ironic.conf"]) @@ -341,7 +346,7 @@ var _ = Describe("IronicAPI controller", func() { Expect(apiContainer.ReadinessProbe.HTTPGet.Scheme).To(Equal(corev1.URISchemeHTTPS)) Expect(apiContainer.LivenessProbe.HTTPGet.Scheme).To(Equal(corev1.URISchemeHTTPS)) - configDataMap := th.GetConfigMap(ironicNames.APIConfigDataName) + configDataMap := th.GetSecret(ironicNames.APIConfigSecretName) Expect(configDataMap).ShouldNot(BeNil()) Expect(configDataMap.Data).Should(HaveKey("ironic-api-httpd.conf")) Expect(configDataMap.Data).Should(HaveKey("ssl.conf")) diff --git a/tests/functional/ironicconductor_controller_test.go b/tests/functional/ironicconductor_controller_test.go index a9b72f22..729aae53 100644 --- a/tests/functional/ironicconductor_controller_test.go +++ b/tests/functional/ironicconductor_controller_test.go @@ -29,6 +29,12 @@ import ( ) var _ = Describe("IronicConductor controller", func() { + BeforeEach(func() { + apiMariaDBAccount, apiMariaDBSecret := mariadb.CreateMariaDBAccount(ironicNames.IronicDatabaseAccount) + DeferCleanup(k8sClient.Delete, ctx, apiMariaDBAccount) + DeferCleanup(k8sClient.Delete, ctx, apiMariaDBSecret) + }) + When("IronicConductor is created with rpcTransport == oslo", func() { BeforeEach(func() { DeferCleanup( @@ -67,8 +73,7 @@ var _ = Describe("IronicConductor controller", func() { Expect(instance.Spec.Standalone).Should(BeFalse()) Expect(instance.Spec.PasswordSelectors).Should(Equal( ironicv1.PasswordSelector{ - Database: "IronicDatabasePassword", - Service: "IronicPassword", + Service: "IronicPassword", })) Expect(instance.Spec.CustomServiceConfig).Should(Equal("# add your customization here")) Expect(instance.Spec.StorageClass).Should(Equal("")) @@ -113,7 +118,7 @@ var _ = Describe("IronicConductor controller", func() { Expect(binding.Subjects).To(HaveLen(1)) Expect(binding.Subjects[0].Name).To(Equal(sa.Name)) }) - It("Creates ConfigMaps and gets Secrets (input) and set Hash of inputs", func() { + It("Creates config Secrets and gets Secrets (input) and set Hash of inputs", func() { th.ExpectCondition( ironicNames.ConductorName, ConditionGetterFunc(IronicConductorConditionGetter), diff --git a/tests/functional/ironicinspector_controller_test.go b/tests/functional/ironicinspector_controller_test.go index 0d584afc..856b04f4 100644 --- a/tests/functional/ironicinspector_controller_test.go +++ b/tests/functional/ironicinspector_controller_test.go @@ -23,7 +23,9 @@ import ( . "github.com/onsi/gomega" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" . "github.com/openstack-k8s-operators/lib-common/modules/common/test/helpers" + mariadb_test "github.com/openstack-k8s-operators/mariadb-operator/api/test/helpers" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" ) var _ = Describe("IronicInspector controller", func() { @@ -114,7 +116,7 @@ var _ = Describe("IronicInspector controller", func() { instance := GetIronicInspector(ironicNames.InspectorName) Expect(instance.Status.TransportURLSecret).To(Equal("rabbitmq-secret")) }) - It("Creates ConfigMaps and gets Secrets (input)", func() { + It("Creates Config Secrets and gets Secrets (input)", func() { infra.GetTransportURL(ironicNames.InspectorTransportURLName) infra.SimulateTransportURLReady(ironicNames.InspectorTransportURLName) th.ExpectCondition( @@ -134,7 +136,7 @@ var _ = Describe("IronicInspector controller", func() { infra.GetTransportURL(ironicNames.InspectorTransportURLName) infra.SimulateTransportURLReady(ironicNames.InspectorTransportURLName) mariadb.GetMariaDBDatabase(ironicNames.InspectorDatabaseName) - mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseAccount) mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.InspectorDatabaseName) th.ExpectCondition( ironicNames.InspectorName, @@ -147,7 +149,7 @@ var _ = Describe("IronicInspector controller", func() { infra.GetTransportURL(ironicNames.InspectorTransportURLName) infra.SimulateTransportURLReady(ironicNames.InspectorTransportURLName) mariadb.GetMariaDBDatabase(ironicNames.InspectorDatabaseName) - mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseAccount) mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.InspectorDatabaseName) th.SimulateJobSuccess(ironicNames.InspectorDBSyncJobName) th.ExpectCondition( @@ -161,7 +163,7 @@ var _ = Describe("IronicInspector controller", func() { infra.GetTransportURL(ironicNames.InspectorTransportURLName) infra.SimulateTransportURLReady(ironicNames.InspectorTransportURLName) mariadb.GetMariaDBDatabase(ironicNames.InspectorDatabaseName) - mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseAccount) mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.InspectorDatabaseName) th.SimulateJobSuccess(ironicNames.InspectorDBSyncJobName) th.ExpectCondition( @@ -175,7 +177,7 @@ var _ = Describe("IronicInspector controller", func() { infra.GetTransportURL(ironicNames.InspectorTransportURLName) infra.SimulateTransportURLReady(ironicNames.InspectorTransportURLName) mariadb.GetMariaDBDatabase(ironicNames.InspectorDatabaseName) - mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseAccount) mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.InspectorDatabaseName) th.SimulateJobSuccess(ironicNames.InspectorDBSyncJobName) th.SimulateStatefulSetReplicaReady(ironicNames.InspectorName) @@ -216,7 +218,7 @@ var _ = Describe("IronicInspector controller", func() { infra.GetTransportURL(ironicNames.InspectorTransportURLName) infra.SimulateTransportURLReady(ironicNames.InspectorTransportURLName) mariadb.GetMariaDBDatabase(ironicNames.InspectorDatabaseName) - mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseAccount) mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.InspectorDatabaseName) th.SimulateJobSuccess(ironicNames.InspectorDBSyncJobName) th.SimulateStatefulSetReplicaReady(ironicNames.InspectorName) @@ -239,7 +241,7 @@ var _ = Describe("IronicInspector controller", func() { infra.GetTransportURL(ironicNames.InspectorTransportURLName) infra.SimulateTransportURLReady(ironicNames.InspectorTransportURLName) mariadb.GetMariaDBDatabase(ironicNames.InspectorDatabaseName) - mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(ironicNames.InspectorDatabaseAccount) mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.InspectorDatabaseName) th.SimulateJobSuccess(ironicNames.InspectorDBSyncJobName) th.SimulateStatefulSetReplicaReady(ironicNames.InspectorName) @@ -389,7 +391,7 @@ var _ = Describe("IronicInspector controller", func() { Expect(container.ReadinessProbe.HTTPGet.Scheme).To(Equal(corev1.URISchemeHTTPS)) Expect(container.LivenessProbe.HTTPGet.Scheme).To(Equal(corev1.URISchemeHTTPS)) - configDataMap := th.GetConfigMap(ironicNames.InspectorConfigDataName) + configDataMap := th.GetSecret(ironicNames.InspectorConfigSecretName) Expect(configDataMap).ShouldNot(BeNil()) Expect(configDataMap.Data).Should(HaveKey("httpd.conf")) Expect(configDataMap.Data).Should(HaveKey("ssl.conf")) @@ -465,4 +467,80 @@ var _ = Describe("IronicInspector controller", func() { }, timeout, interval).Should(Succeed()) }) }) + + // Run MariaDBAccount suite tests. these are pre-packaged ginkgo tests + // that exercise standard account create / update patterns that should be + // common to all controllers that ensure MariaDBAccount CRs. + mariadb_test.MariaDBAccountSuiteTests( + "IronicInspector", + // Populate test variables which will run inside of BeforeEach + func(harness *mariadb_test.MariaDBTestHarness) { + harness.PopulateHarness( + ironicNames.Namespace, + ironicNames.InspectorDatabaseName.Name, + "IronicInspector", + mariadb, + timeout, + interval, + ) + }, + // Generate a fully running Ironic Inspector service given an accountName + // needs to make it all the way to the end where the mariadb finalizers + // are removed from unused accounts since that's part of what we are testing + func(accountName types.NamespacedName) { + spec := GetDefaultIronicInspectorSpec() + + spec["databaseAccount"] = accountName.Name + + DeferCleanup( + k8sClient.Delete, + ctx, + CreateIronicSecret(ironicNames.Namespace, SecretName), + ) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + ironicNames.Namespace, + "openstack", + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + DeferCleanup( + keystone.DeleteKeystoneAPI, + keystone.CreateKeystoneAPI(ironicNames.Namespace)) + + spec["rpcTransport"] = "oslo" + DeferCleanup( + th.DeleteInstance, + CreateIronicInspector(ironicNames.InspectorName, spec)) + + infra.GetTransportURL(ironicNames.InspectorTransportURLName) + infra.SimulateTransportURLReady(ironicNames.InspectorTransportURLName) + mariadb.GetMariaDBDatabase(ironicNames.InspectorDatabaseName) + mariadb.SimulateMariaDBAccountCompleted(accountName) + mariadb.SimulateMariaDBDatabaseCompleted(ironicNames.InspectorDatabaseName) + th.SimulateJobSuccess(ironicNames.InspectorDBSyncJobName) + th.SimulateStatefulSetReplicaReady(ironicNames.InspectorName) + keystone.SimulateKeystoneServiceReady(ironicNames.InspectorName) + keystone.SimulateKeystoneEndpointReady(ironicNames.InspectorName) + + }, + // Change the account name in the service to a new name + func(newAccountName types.NamespacedName) { + + Eventually(func(g Gomega) { + inspector := GetIronicInspector(ironicNames.InspectorName) + inspector.Spec.DatabaseAccount = newAccountName.Name + g.Expect(th.K8sClient.Update(ctx, inspector)).Should(Succeed()) + }, timeout, interval).Should(Succeed()) + + }, + // delete the keystone instance to exercise finalizer removal + func() { + th.DeleteInstance(GetIronicInspector(ironicNames.InspectorName)) + }, + ) + }) diff --git a/tests/kuttl/tests/deploy/10-assert-deploy-ironic.yaml b/tests/kuttl/tests/deploy/10-assert-deploy-ironic.yaml index 1d2fb2de..cf423bb5 100644 --- a/tests/kuttl/tests/deploy/10-assert-deploy-ironic.yaml +++ b/tests/kuttl/tests/deploy/10-assert-deploy-ironic.yaml @@ -26,8 +26,8 @@ spec: storageRequest: 10G ironicInspector: customServiceConfig: '# add your customization here' + databaseAccount: ironic passwordSelectors: - database: IronicInspectorDatabasePassword service: IronicInspectorPassword preserveJobs: true replicas: 1 @@ -35,8 +35,8 @@ spec: ironicNeutronAgent: customServiceConfig: "# add your customization here" replicas: 1 + databaseAccount: ironic passwordSelectors: - database: IronicDatabasePassword service: IronicPassword preserveJobs: true rabbitMqClusterName: rabbitmq @@ -66,8 +66,8 @@ metadata: spec: customServiceConfig: '# add your customization here' databaseHostname: openstack.ironic-kuttl-tests.svc + databaseAccount: ironic passwordSelectors: - database: IronicDatabasePassword service: IronicPassword replicas: 1 resources: {} @@ -94,8 +94,8 @@ spec: conductorGroup: "" customServiceConfig: '# add your customization here' databaseHostname: openstack.ironic-kuttl-tests.svc + databaseAccount: ironic passwordSelectors: - database: IronicDatabasePassword service: IronicPassword replicas: 1 resources: {} @@ -122,8 +122,8 @@ metadata: spec: customServiceConfig: '# add your customization here' databaseInstance: openstack + databaseAccount: ironic passwordSelectors: - database: IronicInspectorDatabasePassword service: IronicInspectorPassword preserveJobs: true rabbitMqClusterName: rabbitmq @@ -151,8 +151,8 @@ metadata: name: ironic spec: customServiceConfig: "# add your customization here" + databaseAccount: ironic passwordSelectors: - database: IronicDatabasePassword service: IronicPassword rabbitMqClusterName: rabbitmq replicas: 1 diff --git a/tests/kuttl/tests/standalone/10-assert-deploy-ironic-standalone.yaml b/tests/kuttl/tests/standalone/10-assert-deploy-ironic-standalone.yaml index 44019424..16d1448f 100644 --- a/tests/kuttl/tests/standalone/10-assert-deploy-ironic-standalone.yaml +++ b/tests/kuttl/tests/standalone/10-assert-deploy-ironic-standalone.yaml @@ -18,6 +18,7 @@ spec: [DEFAULT] debug = true databaseInstance: openstack + databaseAccount: ironic ironicAPI: replicas: 1 ironicConductors: @@ -25,14 +26,13 @@ spec: storageRequest: 10G ironicInspector: customServiceConfig: '# add your customization here' + databaseAccount: ironic passwordSelectors: - database: IronicInspectorDatabasePassword service: IronicInspectorPassword preserveJobs: true replicas: 1 serviceUser: ironic-inspector passwordSelectors: - database: IronicDatabasePassword service: IronicPassword preserveJobs: true rabbitMqClusterName: rabbitmq @@ -61,8 +61,8 @@ metadata: spec: customServiceConfig: '# add your customization here' databaseHostname: openstack.ironic-kuttl-tests.svc + databaseAccount: ironic passwordSelectors: - database: IronicDatabasePassword service: IronicPassword replicas: 1 resources: {} @@ -89,8 +89,8 @@ spec: conductorGroup: "" customServiceConfig: '# add your customization here' databaseHostname: openstack.ironic-kuttl-tests.svc + databaseAccount: ironic passwordSelectors: - database: IronicDatabasePassword service: IronicPassword replicas: 1 resources: {} @@ -117,8 +117,8 @@ metadata: spec: customServiceConfig: '# add your customization here' databaseInstance: openstack + databaseAccount: ironic passwordSelectors: - database: IronicInspectorDatabasePassword service: IronicInspectorPassword preserveJobs: true rabbitMqClusterName: rabbitmq