diff --git a/api/bases/core.openstack.org_openstackcontrolplanes.yaml b/api/bases/core.openstack.org_openstackcontrolplanes.yaml index 31e6663d8..18a18e12b 100644 --- a/api/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/api/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -40,6 +40,52 @@ spec: type: object spec: properties: + applicationCredential: + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + default: 365 + minimum: 2 + type: integer + gracePeriodDays: + default: 182 + minimum: 1 + type: integer + roles: + default: + - service + items: + type: string + minItems: 1 + type: array + unrestricted: + default: false + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: self.gracePeriodDays < self.expirationDays barbican: properties: apiOverride: @@ -166,6 +212,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -179,6 +269,11 @@ spec: properties: apiTimeout: type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string customServiceConfigSecrets: @@ -674,6 +769,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -685,6 +824,11 @@ spec: type: integer cinderAPI: properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string customServiceConfigSecrets: @@ -1767,6 +1911,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -1797,6 +1985,11 @@ spec: properties: apiTimeout: type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object backendMdnsServerProtocol: type: string backendType: @@ -3646,6 +3839,50 @@ spec: type: object type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -4191,6 +4428,11 @@ spec: apiTimeout: minimum: 1 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object containerImage: type: string customServiceConfig: @@ -4574,6 +4816,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' cnfAPIOverride: properties: route: @@ -6509,6 +6795,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -6642,6 +6972,11 @@ spec: default: 60 minimum: 10 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -6903,6 +7238,11 @@ spec: type: array ironicInspector: properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -8166,6 +8506,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -8710,6 +9094,11 @@ spec: type: array manilaAPI: properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -9233,6 +9622,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -9242,6 +9675,11 @@ spec: default: 120 minimum: 1 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object corePlugin: default: ml2 type: string @@ -10063,6 +10501,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' cellOverride: additionalProperties: properties: @@ -10346,6 +10828,11 @@ spec: default: 60 minimum: 10 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object cellTemplates: additionalProperties: properties: @@ -11131,6 +11618,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -11166,6 +11697,11 @@ spec: apiTimeout: default: 120 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11208,6 +11744,11 @@ spec: properties: apiTimeout: type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11416,6 +11957,11 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11568,6 +12114,11 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11826,6 +12377,11 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -12613,6 +13169,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -12622,6 +13222,11 @@ spec: default: 60 minimum: 10 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string databaseAccount: @@ -13688,6 +14293,50 @@ spec: type: string swift: properties: + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -13844,6 +14493,11 @@ spec: default: 60 minimum: 1 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object ceilometerEnabled: default: false type: boolean @@ -14335,6 +14989,138 @@ spec: type: string type: object type: object + applicationCredentialAodh: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' + applicationCredentialCeilometer: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' + applicationCredentialCloudKitty: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' cloudKittyApiOverride: properties: route: @@ -14604,6 +15390,11 @@ spec: apiTimeout: default: 60 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -14770,6 +15561,11 @@ spec: apiTimeout: default: 60 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -14856,6 +15652,11 @@ spec: apiTimeout: default: 60 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object cloudKittyAPI: properties: customServiceConfig: @@ -16235,6 +17036,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -16244,6 +17089,11 @@ spec: default: replicas: 1 properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string nodeSelector: @@ -16428,6 +17278,11 @@ spec: type: string type: object type: object + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string databaseAccount: diff --git a/api/core/v1beta1/openstackcontrolplane_types.go b/api/core/v1beta1/openstackcontrolplane_types.go index e74e8d50a..0455412f9 100644 --- a/api/core/v1beta1/openstackcontrolplane_types.go +++ b/api/core/v1beta1/openstackcontrolplane_types.go @@ -225,6 +225,14 @@ type OpenStackControlPlaneSpec struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // Watcher - Parameters related to the Watcher service Watcher WatcherSection `json:"watcher,omitempty"` + + // +kubebuilder:validation:Optional + // +operator-sdk:csv:customresourcedefinitions:type=spec + // ApplicationCredential - Global configuration for ApplicationCredentials. + // Both this global section AND the per-service applicationCredential section + // must be enabled for a service to use ApplicationCredentials. + // If omitted, defaults to enabled=false with standard expiration/grace periods. + ApplicationCredential ApplicationCredentialSection `json:"applicationCredential,omitempty"` } // TLSSection defines the desired state of TLS configuration @@ -419,6 +427,13 @@ type PlacementSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // APIOverride, provides the ability to override the generated manifest of several child resources. APIOverride Override `json:"apiOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // GlanceSection defines the desired state of Glance service @@ -445,6 +460,13 @@ type GlanceSection struct { // Convenient to avoid podname (and thus hostname) collision between different deployments. // Useful for CI jobs as well as preproduction and production environments that use the same storage backend, etc. UniquePodNames bool `json:"uniquePodNames"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // CinderSection defines the desired state of Cinder service @@ -471,6 +493,13 @@ type CinderSection struct { // Convenient to avoid podname (and thus hostname) collision between different deployments. // Useful for CI jobs as well as preproduction and production environments that use the same storage backend, etc. UniquePodNames bool `json:"uniquePodNames"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // GaleraSection defines the desired state of Galera services @@ -564,6 +593,13 @@ type NeutronSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // APIOverride, provides the ability to override the generated manifest of several child resources. APIOverride Override `json:"apiOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // NovaSection defines the desired state of Nova services @@ -590,6 +626,13 @@ type NovaSection struct { // for a nova cell. cell0 never have compute nodes and therefore it won't have a noVNCProxy deployed. // Providing an override for cell0 noVNCProxy does not have an effect. CellOverride map[string]NovaCellOverrideSpec `json:"cellOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // NovaCellOverrideSpec to override the generated manifest of several child resources. @@ -620,6 +663,13 @@ type HeatSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // CnfAPIOverride, provides the ability to override the generated manifest of several child resources. CnfAPIOverride Override `json:"cnfAPIOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // IronicSection defines the desired state of Ironic services @@ -644,6 +694,13 @@ type IronicSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // InspectorOverride, provides the ability to override the generated manifest of several child resources. InspectorOverride Override `json:"inspectorOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // ManilaSection defines the desired state of Manila service @@ -663,6 +720,13 @@ type ManilaSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // APIOverride, provides the ability to override the generated manifest of several child resources. APIOverride Override `json:"apiOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // HorizonSection defines the desired state of Horizon services @@ -716,6 +780,27 @@ type TelemetrySection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // AlertmanagerOverride, provides the ability to override the generated manifest of several child resources. AlertmanagerOverride Override `json:"alertmanagerOverride,omitempty"` + + // ApplicationCredentialCeilometer allows service-specific overrides of the global AC configuration for Ceilometer. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredentialCeilometer *ServiceAppCredSection `json:"applicationCredentialCeilometer"` + + // ApplicationCredentialAodh allows service-specific overrides of the global AC configuration for Aodh. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredentialAodh *ServiceAppCredSection `json:"applicationCredentialAodh"` + + // ApplicationCredentialCloudKitty allows service-specific overrides of the global AC configuration for CloudKitty. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredentialCloudKitty *ServiceAppCredSection `json:"applicationCredentialCloudKitty"` } // SwiftSection defines the desired state of Swift service @@ -735,6 +820,13 @@ type SwiftSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // ProxyOverride, provides the ability to override the generated manifest of several child resources. ProxyOverride Override `json:"proxyOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // OctaviaSection defines the desired state of the Octavia service @@ -754,6 +846,13 @@ type OctaviaSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // APIOverride, provides the ability to override the generated manifest of several child resources. APIOverride Override `json:"apiOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // DesignateSection defines the desired state of the Designate service @@ -773,6 +872,13 @@ type DesignateSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // APIOverride, provides the ability to override the generated manifest of several child resources. APIOverride Override `json:"apiOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // BarbicanSection defines the desired state of Barbican service @@ -792,6 +898,13 @@ type BarbicanSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // APIOverride, provides the ability to override the generated manifest of several child resources. APIOverride Override `json:"apiOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` } // RedisSection defines the desired state of the Redis service @@ -833,6 +946,97 @@ type WatcherSection struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // APIOverride, provides the ability to override the generated manifest of several child resources. APIOverride Override `json:"apiOverride,omitempty"` + + // ApplicationCredential allows service-specific overrides of the global AC configuration. + // +operator-sdk:csv:customresourcedefinitions:type=spec + // +kubebuilder:validation:Optional + // +nullable + // +kubebuilder:default={enabled:false} + ApplicationCredential *ServiceAppCredSection `json:"applicationCredential"` +} + +// +kubebuilder:validation:XValidation:rule="self.gracePeriodDays < self.expirationDays",message="gracePeriodDays must be smaller than expirationDays" +// ApplicationCredentialSection defines the desired configuration for ApplicationCredentials +type ApplicationCredentialSection struct { + // Enabled indicates whether an ApplicationCredential should be created + // +kubebuilder:validation:Optional + // +kubebuilder:default=false + Enabled bool `json:"enabled"` + + // ExpirationDays sets the lifetime in days for the AC + // +kubebuilder:validation:Optional + // +kubebuilder:default=365 + // +kubebuilder:validation:Minimum=2 + ExpirationDays *int `json:"expirationDays"` + + // GracePeriodDays sets how many days before expiration the AC should be rotated + // +kubebuilder:validation:Optional + // +kubebuilder:default=182 + // +kubebuilder:validation:Minimum=1 + GracePeriodDays *int `json:"gracePeriodDays"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default={"service"} + // +kubebuilder:validation:MinItems=1 + // Roles to assign to the ApplicationCredential + Roles []string `json:"roles"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default=false + // Whether the AC should be unrestricted + Unrestricted *bool `json:"unrestricted"` + + // AccessRules lets supply a custom list of rules + // If unset, no accessRules field is emitted + // +kubebuilder:validation:Optional + // +listType=atomic + AccessRules []ACRule `json:"accessRules,omitempty"` +} + +// +kubebuilder:validation:XValidation:rule="!(has(self.expirationDays) && has(self.gracePeriodDays)) || self.gracePeriodDays < self.expirationDays",message="gracePeriodDays must be smaller than expirationDays" +// ServiceAppCredSection allows service-specific overrides of the global AC configuration +type ServiceAppCredSection struct { + // +kubebuilder:validation:Optional + // +kubebuilder:default=false + Enabled bool `json:"enabled"` + + // +kubebuilder:validation:Optional + // +kubebuilder:validation:Minimum=2 + ExpirationDays *int `json:"expirationDays,omitempty"` + + // +kubebuilder:validation:Optional + // +kubebuilder:validation:Minimum=1 + GracePeriodDays *int `json:"gracePeriodDays,omitempty"` + + // +kubebuilder:validation:Optional + // Roles to assign to the ApplicationCredential + Roles []string `json:"roles,omitempty"` + + // +kubebuilder:validation:Optional + // Whether the AC should be unrestricted + Unrestricted *bool `json:"unrestricted,omitempty"` + + // AccessRules lets the service override either the global rules + // +kubebuilder:validation:Optional + // +listType=atomic + AccessRules []ACRule `json:"accessRules,omitempty"` +} + +// ACRule describes a single access rule for an ApplicationCredential +// +k8s:openapi-gen=true +type ACRule struct { + // Service is the name of the service to target (e.g. "identity"). + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Service string `json:"service"` + // Path is the HTTP path (e.g. "/v3/auth/tokens"). + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Path string `json:"path"` + // Method is the HTTP method to allow (e.g. "POST"). + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinLength=1 + Method string `json:"method"` } // OpenStackControlPlaneStatus defines the observed state of OpenStackControlPlane diff --git a/api/core/v1beta1/openstackcontrolplane_webhook.go b/api/core/v1beta1/openstackcontrolplane_webhook.go index 38b7c05bc..f81685357 100644 --- a/api/core/v1beta1/openstackcontrolplane_webhook.go +++ b/api/core/v1beta1/openstackcontrolplane_webhook.go @@ -810,6 +810,12 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Cinder.Template = &cinderv1.CinderSpecCore{} } r.Spec.Cinder.Template.Default() + // Default Auth fields for Application Credentials (only for CinderAPI which has Auth in TemplateCore) + if r.Spec.Cinder.Template.CinderAPI.Auth.ApplicationCredentialSecret == "" { + r.Spec.Cinder.Template.CinderAPI.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("cinder") + } + // Note: CinderScheduler and CinderVolumes don't have Auth in TemplateCore, + // their child operator webhooks will default Auth when child CRs are created initializeOverrideSpec(&r.Spec.Cinder.APIOverride.Route, true) r.Spec.Cinder.Template.SetDefaultRouteAnnotations(r.Spec.Cinder.APIOverride.Route.Annotations) } @@ -844,6 +850,11 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Glance.APIOverride = map[string]Override{} } for name, glanceAPI := range r.Spec.Glance.Template.GlanceAPIs { + // Default Auth fields for Application Credentials + if glanceAPI.Auth.ApplicationCredentialSecret == "" { + glanceAPI.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("glance") + } + var override Override var ok bool @@ -856,6 +867,8 @@ func (r *OpenStackControlPlane) DefaultServices() { glanceAPI.SetDefaultRouteAnnotations(override.Route.Annotations) r.Spec.Glance.APIOverride[name] = override } + // Update the glanceAPI with Auth defaults + r.Spec.Glance.Template.GlanceAPIs[name] = glanceAPI } // clean up the APIOverrides for each glanceAPI that has been // deleted from the ctlplane @@ -886,6 +899,14 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Ironic.Template.StorageClass = r.Spec.StorageClass } r.Spec.Ironic.Template.Default() + // Default Auth fields for Application Credentials (shared ironic user) + if r.Spec.Ironic.Template.Auth.ApplicationCredentialSecret == "" { + r.Spec.Ironic.Template.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("ironic") + } + // Default Auth for IronicInspector (uses separate ironic-inspector user) + if r.Spec.Ironic.Template.IronicInspector.Auth.ApplicationCredentialSecret == "" { + r.Spec.Ironic.Template.IronicInspector.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("ironic-inspector") + } initializeOverrideSpec(&r.Spec.Ironic.APIOverride.Route, true) initializeOverrideSpec(&r.Spec.Ironic.InspectorOverride.Route, true) @@ -909,6 +930,12 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Manila.Template = &manilav1.ManilaSpecCore{} } r.Spec.Manila.Template.Default() + // Default Auth fields for Application Credentials (only for ManilaAPI which has Auth in TemplateCore) + if r.Spec.Manila.Template.ManilaAPI.Auth.ApplicationCredentialSecret == "" { + r.Spec.Manila.Template.ManilaAPI.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("manila") + } + // Note: ManilaScheduler and ManilaShares don't have Auth in TemplateCore, + // their child operator webhooks will default Auth when child CRs are created initializeOverrideSpec(&r.Spec.Manila.APIOverride.Route, true) r.Spec.Manila.Template.SetDefaultRouteAnnotations(r.Spec.Manila.APIOverride.Route.Annotations) } @@ -932,6 +959,10 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Neutron.Template = &neutronv1.NeutronAPISpecCore{} } r.Spec.Neutron.Template.Default() + // Default Auth fields for Application Credentials + if r.Spec.Neutron.Template.Auth.ApplicationCredentialSecret == "" { + r.Spec.Neutron.Template.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("neutron") + } initializeOverrideSpec(&r.Spec.Neutron.APIOverride.Route, true) r.Spec.Neutron.Template.SetDefaultRouteAnnotations(r.Spec.Neutron.APIOverride.Route.Annotations) } @@ -942,6 +973,10 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Nova.Template = &novav1.NovaSpecCore{} } r.Spec.Nova.Template.Default() + // Default Auth fields for Application Credentials (parent level) + if r.Spec.Nova.Template.Auth.ApplicationCredentialSecret == "" { + r.Spec.Nova.Template.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("nova") + } initializeOverrideSpec(&r.Spec.Nova.APIOverride.Route, true) r.Spec.Nova.Template.SetDefaultRouteAnnotations(r.Spec.Nova.APIOverride.Route.Annotations) } @@ -968,6 +1003,10 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Placement.Template = &placementv1.PlacementAPISpecCore{} } r.Spec.Placement.Template.Default() + // Default Auth fields for Application Credentials + if r.Spec.Placement.Template.Auth.ApplicationCredentialSecret == "" { + r.Spec.Placement.Template.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("placement") + } initializeOverrideSpec(&r.Spec.Placement.APIOverride.Route, true) r.Spec.Placement.Template.SetDefaultRouteAnnotations(r.Spec.Placement.APIOverride.Route.Annotations) } @@ -987,6 +1026,19 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Telemetry.Template = &telemetryv1.TelemetrySpecCore{} } r.Spec.Telemetry.Template.Default() + // Default Auth fields for Application Credentials + // Autoscaling (Aodh) - Auth is in Aodh field + if r.Spec.Telemetry.Template.Autoscaling.Aodh.Auth.ApplicationCredentialSecret == "" { + r.Spec.Telemetry.Template.Autoscaling.Aodh.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("aodh") + } + // Ceilometer - Auth is inlined in CeilometerSpecCore + if r.Spec.Telemetry.Template.Ceilometer.Auth.ApplicationCredentialSecret == "" { + r.Spec.Telemetry.Template.Ceilometer.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("ceilometer") + } + // CloudKitty - Auth is inlined from CloudKittyTemplate + if r.Spec.Telemetry.Template.CloudKitty.Auth.ApplicationCredentialSecret == "" { + r.Spec.Telemetry.Template.CloudKitty.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("cloudkitty") + } initializeOverrideSpec(&r.Spec.Telemetry.AodhAPIOverride.Route, true) r.Spec.Telemetry.Template.Autoscaling.SetDefaultRouteAnnotations(r.Spec.Telemetry.AodhAPIOverride.Route.Annotations) } @@ -1014,6 +1066,10 @@ func (r *OpenStackControlPlane) DefaultServices() { } r.Spec.Swift.Template.Default() + // Default Auth fields for Application Credentials + if r.Spec.Swift.Template.SwiftProxy.Auth.ApplicationCredentialSecret == "" { + r.Spec.Swift.Template.SwiftProxy.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("swift") + } } // Horizon @@ -1032,6 +1088,10 @@ func (r *OpenStackControlPlane) DefaultServices() { } r.Spec.Octavia.Template.Default() + // Default Auth fields for Application Credentials (shared by all Octavia components) + if r.Spec.Octavia.Template.Auth.ApplicationCredentialSecret == "" { + r.Spec.Octavia.Template.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("octavia") + } initializeOverrideSpec(&r.Spec.Octavia.APIOverride.Route, true) r.Spec.Octavia.Template.SetDefaultRouteAnnotations(r.Spec.Octavia.APIOverride.Route.Annotations) } @@ -1042,6 +1102,12 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Barbican.Template = &barbicanv1.BarbicanSpecCore{} } r.Spec.Barbican.Template.Default() + // Default Auth fields for Application Credentials (only for BarbicanAPI which has Auth in TemplateCore) + if r.Spec.Barbican.Template.BarbicanAPI.Auth.ApplicationCredentialSecret == "" { + r.Spec.Barbican.Template.BarbicanAPI.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("barbican") + } + // Note: BarbicanWorker and BarbicanKeystoneListener don't have Auth in TemplateCore, + // their child operator webhooks will default Auth when child CRs are created initializeOverrideSpec(&r.Spec.Barbican.APIOverride.Route, true) r.Spec.Barbican.Template.SetDefaultRouteAnnotations(r.Spec.Barbican.APIOverride.Route.Annotations) } @@ -1052,6 +1118,12 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Designate.Template = &designatev1.DesignateSpecCore{} } r.Spec.Designate.Template.Default() + // Default Auth fields for Application Credentials (only for DesignateAPI which has Auth in TemplateCore) + if r.Spec.Designate.Template.DesignateAPI.Auth.ApplicationCredentialSecret == "" { + r.Spec.Designate.Template.DesignateAPI.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("designate") + } + // Note: DesignateCentral, DesignateProducer, DesignateWorker don't have Auth in TemplateCore, + // their child operator webhooks will default Auth when child CRs are created } // Redis @@ -1073,6 +1145,10 @@ func (r *OpenStackControlPlane) DefaultServices() { r.Spec.Watcher.Template = &watcherv1.WatcherSpecCore{} } r.Spec.Watcher.Template.Default() + // Default Auth fields for Application Credentials (shared by all Watcher components) + if r.Spec.Watcher.Template.Auth.ApplicationCredentialSecret == "" { + r.Spec.Watcher.Template.Auth.ApplicationCredentialSecret = keystonev1.GetACSecretName("watcher") + } if r.Spec.Watcher.Enabled { initializeOverrideSpec(&r.Spec.Watcher.APIOverride.Route, true) @@ -1085,6 +1161,12 @@ func (r *OpenStackControlPlane) DefaultServices() { } } + // Initialize ApplicationCredential (watcher specific) field to avoid null value + // This ensures consistent behavior with other services. + if r.Spec.Watcher.ApplicationCredential == nil { + r.Spec.Watcher.ApplicationCredential = &ServiceAppCredSection{Enabled: false} + } + } // DefaultLabel - adding default label to the OpenStackControlPlane @@ -1151,7 +1233,7 @@ func (r *OpenStackControlPlane) ValidateNotificationsBusInstance(basePath *field // NotificationsBusInstance is set and must be equal to an existing // deployed rabbitmq instance, otherwise we should fail because it // does not represent a valid string - for k := range(*r.Spec.Rabbitmq.Templates) { + for k := range *r.Spec.Rabbitmq.Templates { if *r.Spec.NotificationsBusInstance == k { return nil } diff --git a/api/core/v1beta1/zz_generated.deepcopy.go b/api/core/v1beta1/zz_generated.deepcopy.go index 2af599dd5..950361fe3 100644 --- a/api/core/v1beta1/zz_generated.deepcopy.go +++ b/api/core/v1beta1/zz_generated.deepcopy.go @@ -51,6 +51,61 @@ import ( "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ACRule) DeepCopyInto(out *ACRule) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ACRule. +func (in *ACRule) DeepCopy() *ACRule { + if in == nil { + return nil + } + out := new(ACRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ApplicationCredentialSection) DeepCopyInto(out *ApplicationCredentialSection) { + *out = *in + if in.ExpirationDays != nil { + in, out := &in.ExpirationDays, &out.ExpirationDays + *out = new(int) + **out = **in + } + if in.GracePeriodDays != nil { + in, out := &in.GracePeriodDays, &out.GracePeriodDays + *out = new(int) + **out = **in + } + if in.Roles != nil { + in, out := &in.Roles, &out.Roles + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Unrestricted != nil { + in, out := &in.Unrestricted, &out.Unrestricted + *out = new(bool) + **out = **in + } + if in.AccessRules != nil { + in, out := &in.AccessRules, &out.AccessRules + *out = make([]ACRule, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationCredentialSection. +func (in *ApplicationCredentialSection) DeepCopy() *ApplicationCredentialSection { + if in == nil { + return nil + } + out := new(ApplicationCredentialSection) + in.DeepCopyInto(out) + return out +} + // 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 @@ -60,6 +115,11 @@ func (in *BarbicanSection) DeepCopyInto(out *BarbicanSection) { (*in).DeepCopyInto(*out) } in.APIOverride.DeepCopyInto(&out.APIOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BarbicanSection. @@ -153,6 +213,11 @@ func (in *CinderSection) DeepCopyInto(out *CinderSection) { (*in).DeepCopyInto(*out) } in.APIOverride.DeepCopyInto(&out.APIOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CinderSection. @@ -811,6 +876,11 @@ func (in *DesignateSection) DeepCopyInto(out *DesignateSection) { (*in).DeepCopyInto(*out) } in.APIOverride.DeepCopyInto(&out.APIOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DesignateSection. @@ -864,6 +934,11 @@ func (in *GlanceSection) DeepCopyInto(out *GlanceSection) { (*out)[key] = *val.DeepCopy() } } + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlanceSection. @@ -886,6 +961,11 @@ func (in *HeatSection) DeepCopyInto(out *HeatSection) { } in.APIOverride.DeepCopyInto(&out.APIOverride) in.CnfAPIOverride.DeepCopyInto(&out.CnfAPIOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeatSection. @@ -929,6 +1009,11 @@ func (in *IronicSection) DeepCopyInto(out *IronicSection) { } in.APIOverride.DeepCopyInto(&out.APIOverride) in.InspectorOverride.DeepCopyInto(&out.InspectorOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IronicSection. @@ -971,6 +1056,11 @@ func (in *ManilaSection) DeepCopyInto(out *ManilaSection) { (*in).DeepCopyInto(*out) } in.APIOverride.DeepCopyInto(&out.APIOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManilaSection. @@ -1018,6 +1108,11 @@ func (in *NeutronSection) DeepCopyInto(out *NeutronSection) { (*in).DeepCopyInto(*out) } in.APIOverride.DeepCopyInto(&out.APIOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NeutronSection. @@ -1062,6 +1157,11 @@ func (in *NovaSection) DeepCopyInto(out *NovaSection) { (*out)[key] = *val.DeepCopy() } } + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NovaSection. @@ -1083,6 +1183,11 @@ func (in *OctaviaSection) DeepCopyInto(out *OctaviaSection) { (*in).DeepCopyInto(*out) } in.APIOverride.DeepCopyInto(&out.APIOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OctaviaSection. @@ -1221,6 +1326,7 @@ func (in *OpenStackControlPlaneSpec) DeepCopyInto(out *OpenStackControlPlaneSpec **out = **in } in.Watcher.DeepCopyInto(&out.Watcher) + in.ApplicationCredential.DeepCopyInto(&out.ApplicationCredential) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackControlPlaneSpec. @@ -1530,6 +1636,11 @@ func (in *PlacementSection) DeepCopyInto(out *PlacementSection) { (*in).DeepCopyInto(*out) } in.APIOverride.DeepCopyInto(&out.APIOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PlacementSection. @@ -1594,6 +1705,46 @@ func (in *RedisSection) DeepCopy() *RedisSection { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceAppCredSection) DeepCopyInto(out *ServiceAppCredSection) { + *out = *in + if in.ExpirationDays != nil { + in, out := &in.ExpirationDays, &out.ExpirationDays + *out = new(int) + **out = **in + } + if in.GracePeriodDays != nil { + in, out := &in.GracePeriodDays, &out.GracePeriodDays + *out = new(int) + **out = **in + } + if in.Roles != nil { + in, out := &in.Roles, &out.Roles + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Unrestricted != nil { + in, out := &in.Unrestricted, &out.Unrestricted + *out = new(bool) + **out = **in + } + if in.AccessRules != nil { + in, out := &in.AccessRules, &out.AccessRules + *out = make([]ACRule, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAppCredSection. +func (in *ServiceAppCredSection) DeepCopy() *ServiceAppCredSection { + if in == nil { + return nil + } + out := new(ServiceAppCredSection) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceDefaults) DeepCopyInto(out *ServiceDefaults) { *out = *in @@ -1623,6 +1774,11 @@ func (in *SwiftSection) DeepCopyInto(out *SwiftSection) { (*in).DeepCopyInto(*out) } in.ProxyOverride.DeepCopyInto(&out.ProxyOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwiftSection. @@ -1750,6 +1906,21 @@ func (in *TelemetrySection) DeepCopyInto(out *TelemetrySection) { in.CloudKittyAPIOverride.DeepCopyInto(&out.CloudKittyAPIOverride) in.PrometheusOverride.DeepCopyInto(&out.PrometheusOverride) in.AlertmanagerOverride.DeepCopyInto(&out.AlertmanagerOverride) + if in.ApplicationCredentialCeilometer != nil { + in, out := &in.ApplicationCredentialCeilometer, &out.ApplicationCredentialCeilometer + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } + if in.ApplicationCredentialAodh != nil { + in, out := &in.ApplicationCredentialAodh, &out.ApplicationCredentialAodh + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } + if in.ApplicationCredentialCloudKitty != nil { + in, out := &in.ApplicationCredentialCloudKitty, &out.ApplicationCredentialCloudKitty + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TelemetrySection. @@ -1771,6 +1942,11 @@ func (in *WatcherSection) DeepCopyInto(out *WatcherSection) { (*in).DeepCopyInto(*out) } in.APIOverride.DeepCopyInto(&out.APIOverride) + if in.ApplicationCredential != nil { + in, out := &in.ApplicationCredential, &out.ApplicationCredential + *out = new(ServiceAppCredSection) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatcherSection. diff --git a/api/go.mod b/api/go.mod index 4e73ea7a5..a950be44b 100644 --- a/api/go.mod +++ b/api/go.mod @@ -1,4 +1,4 @@ -module github.com/openstack-k8s-operators/openstack-operator/api +module github.com/openstack-k8s-operators/openstack-operator/apis go 1.24.4 @@ -16,8 +16,8 @@ require ( github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251223124749-eedb97238c5f github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20251213181601-3669e9f88d07 github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251206133124-593df0a7a9e1 - github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251215094837-5c05ea64c324 - github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251215094837-5c05ea64c324 + github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35 + github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251230215914-6ba873b49a35 github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20251221204257-893591a14936 github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20251220223619-1df7af154c0f github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20251125150830-633e42336356 @@ -42,6 +42,8 @@ require ( sigs.k8s.io/controller-runtime v0.19.7 ) +require github.com/openstack-k8s-operators/openstack-operator/api v0.0.0-20251202072739-b102924657dd + require ( github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -80,7 +82,7 @@ require ( github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/openshift/api v3.9.0+incompatible // indirect - github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c // indirect + github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.22.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect @@ -143,3 +145,32 @@ replace k8s.io/code-generator => k8s.io/code-generator v0.31.14 //allow-merging replace k8s.io/component-base => k8s.io/component-base v0.31.14 //allow-merging replace github.com/cert-manager/cmctl/v2 => github.com/cert-manager/cmctl/v2 v2.1.2-0.20241127223932-88edb96860cf //allow-merging + +// appcred related changes +replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/Deydra71/keystone-operator/api v0.0.0-20251211085602-3e1a3e022c81 + +replace github.com/openstack-k8s-operators/barbican-operator/api => github.com/Deydra71/barbican-operator/api v0.0.0-20260105120406-cd16c9e6c023 + +replace github.com/openstack-k8s-operators/cinder-operator/api => github.com/Deydra71/cinder-operator/api v0.0.0-20260106135056-ef7e3d21d620 + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/Deydra71/glance-operator/api v0.0.0-20260106132908-e6b383a95445 + +replace github.com/openstack-k8s-operators/swift-operator/api => github.com/Deydra71/swift-operator/api v0.0.0-20260105162410-2dc80b80c1d3 + +replace github.com/openstack-k8s-operators/manila-operator/api => github.com/Deydra71/manila-operator/api v0.0.0-20260106132024-e9a579fe2ec3 + +replace github.com/openstack-k8s-operators/neutron-operator/api => github.com/Deydra71/neutron-operator/api v0.0.0-20260106090547-e9be79e62157 + +replace github.com/openstack-k8s-operators/placement-operator/api => github.com/Deydra71/placement-operator/api v0.0.0-20260106090624-7345b8864eff + +replace github.com/openstack-k8s-operators/designate-operator/api => github.com/Deydra71/designate-operator/api v0.0.0-20260106092847-c5f4cd0c39e1 + +replace github.com/openstack-k8s-operators/octavia-operator/api => github.com/Deydra71/octavia-operator/api v0.0.0-20260106083332-ef07326114ea + +replace github.com/openstack-k8s-operators/ironic-operator/api => github.com/Deydra71/ironic-operator/api v0.0.0-20260106103928-10e4d4748f3b + +replace github.com/openstack-k8s-operators/watcher-operator/api => github.com/Deydra71/watcher-operator/api v0.0.0-20260106131110-a22b12b025f0 + +replace github.com/openstack-k8s-operators/nova-operator/api => github.com/Deydra71/nova-operator/api v0.0.0-20260107124553-d177db8d08f2 + +replace github.com/openstack-k8s-operators/telemetry-operator/api => github.com/Deydra71/telemetry-operator/api v0.0.0-20260108092627-ce6f6b9c8b67 diff --git a/api/go.sum b/api/go.sum index b45542937..d732f1b93 100644 --- a/api/go.sum +++ b/api/go.sum @@ -1,3 +1,31 @@ +github.com/Deydra71/barbican-operator/api v0.0.0-20260105120406-cd16c9e6c023 h1:Ik9FduqUis0KrlSgynUsYHkmGCOO4G6Vf78+HHnAtk0= +github.com/Deydra71/barbican-operator/api v0.0.0-20260105120406-cd16c9e6c023/go.mod h1:seOuEXaQVmfi9kZwRBXPDlyOi4TLfZFA0FYkIJ8QfjA= +github.com/Deydra71/cinder-operator/api v0.0.0-20260106135056-ef7e3d21d620 h1:sbzYnqoAURmBRWOBKKaFtKX0/+Y/33I9QiaMqEXVuYM= +github.com/Deydra71/cinder-operator/api v0.0.0-20260106135056-ef7e3d21d620/go.mod h1:u0l66SzHNcyF3S37TqBM6CnHXk5rSBFV2Mv3zMIGJwk= +github.com/Deydra71/designate-operator/api v0.0.0-20260106092847-c5f4cd0c39e1 h1:R6uqPS30Z1rWRol2Zts3P75+sIKQQ6vLs0tLT3gEpMU= +github.com/Deydra71/designate-operator/api v0.0.0-20260106092847-c5f4cd0c39e1/go.mod h1:ozik5YG2mnPbTQFNUgQIKHYZlB1aBJbnnkTu6vYxRi4= +github.com/Deydra71/glance-operator/api v0.0.0-20260106132908-e6b383a95445 h1:zbCJBq0cUBX5MAOP1kvT1WI8Do+Jnwo+QZCI56wFhSE= +github.com/Deydra71/glance-operator/api v0.0.0-20260106132908-e6b383a95445/go.mod h1:w+Z144Db80ES7gnBiFjGNnvSz+deiR2QDC+1WT2agi8= +github.com/Deydra71/ironic-operator/api v0.0.0-20260106103928-10e4d4748f3b h1:QDLQLt5vsikU4rDnGZyWj71TA4HCGobO4fNzOEY6E4Y= +github.com/Deydra71/ironic-operator/api v0.0.0-20260106103928-10e4d4748f3b/go.mod h1:5i8Xsdz+zap3XTX+iYasugR3odQH7ncL26WLUZoUAC8= +github.com/Deydra71/keystone-operator/api v0.0.0-20251211085602-3e1a3e022c81 h1:plax+NFgJJL1SrERyXAnf3jOHRhLTtBlJ2oc7d84EoU= +github.com/Deydra71/keystone-operator/api v0.0.0-20251211085602-3e1a3e022c81/go.mod h1:b98Jl8eyUw8V07l9YiuQnoMlnWC748oV8IhXH15NCC4= +github.com/Deydra71/manila-operator/api v0.0.0-20260106132024-e9a579fe2ec3 h1:HXKCRDPrt1U+gnyQpnG/Xr59qNm/uJzzb9foTJetnMI= +github.com/Deydra71/manila-operator/api v0.0.0-20260106132024-e9a579fe2ec3/go.mod h1:AqmHzvPpw7rFZRrk0LhorvWrz3goYUZ+8Pl5XHlGgh0= +github.com/Deydra71/neutron-operator/api v0.0.0-20260106090547-e9be79e62157 h1:nKE7ANvJna28s/Y3NqgqSHQUn9M1Gs50BXoUoWop4eo= +github.com/Deydra71/neutron-operator/api v0.0.0-20260106090547-e9be79e62157/go.mod h1:nL79n4965jUc1qLiQH1sFQtAhW1evP9QVx0836nB8xY= +github.com/Deydra71/nova-operator/api v0.0.0-20260107124553-d177db8d08f2 h1:DcSJOSfT21/w+yw61pzMbs0DHS6nNaXkgxkPEEiu7iU= +github.com/Deydra71/nova-operator/api v0.0.0-20260107124553-d177db8d08f2/go.mod h1:cEcrQYhrsYxeJPjtVhbsP+txnPTnaMwfgCwU4cUhQUs= +github.com/Deydra71/octavia-operator/api v0.0.0-20260106083332-ef07326114ea h1:Dg6nudjwf76XyKm6FnFgvMbzShXtY6sInedjlNsjEj0= +github.com/Deydra71/octavia-operator/api v0.0.0-20260106083332-ef07326114ea/go.mod h1:u3FFVWvV6nr5YAqpR6PDyc4UaQBgIS2RgN236utT20c= +github.com/Deydra71/placement-operator/api v0.0.0-20260106090624-7345b8864eff h1:Vbo8d4wCEFx3VKLBkiMBkRC/f3ed1CdtJfE7wZYsfgQ= +github.com/Deydra71/placement-operator/api v0.0.0-20260106090624-7345b8864eff/go.mod h1:CFYEdbpNfT9tWcWEiHzhln20yDWW1vBHIwge6+TNzmg= +github.com/Deydra71/swift-operator/api v0.0.0-20260105162410-2dc80b80c1d3 h1:GS0/evvACfp2xMOcQz7vte48iHvVxiX92WIMk6Iazew= +github.com/Deydra71/swift-operator/api v0.0.0-20260105162410-2dc80b80c1d3/go.mod h1:V/V7rgrkHQRyAJ+6NQvRjpIlIMSNC9Z6F4DkOfudCqU= +github.com/Deydra71/telemetry-operator/api v0.0.0-20260108092627-ce6f6b9c8b67 h1:CMqN7K1xMbuw80rPWtvf4436+Z8KzmLm7u0JxIaAuhk= +github.com/Deydra71/telemetry-operator/api v0.0.0-20260108092627-ce6f6b9c8b67/go.mod h1:1qz65mvwqq+Gzw/7LfUUt9eaIt2uGt4N4WPtVVCpljU= +github.com/Deydra71/watcher-operator/api v0.0.0-20260106131110-a22b12b025f0 h1:kPJsgn69Y8uzLDPrv5WuThvwsClM06aT2gvugyX8Hp4= +github.com/Deydra71/watcher-operator/api v0.0.0-20260106131110-a22b12b025f0/go.mod h1:SwQTKMUQyKGsZU9YMQUZUGSRC9pIn69bAjw4kE+C1v4= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -114,54 +142,28 @@ github.com/onsi/gomega v1.38.3 h1:eTX+W6dobAYfFeGC2PV6RwXRu/MyT+cQguijutvkpSM= github.com/onsi/gomega v1.38.3/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e h1:E1OdwSpqWuDPCedyUt0GEdoAE+r5TXy7YS21yNEo+2U= github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= -github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20251220125032-e46717ca376e h1:ti957EW6UzQ1cph7wAIQ9dBmKYFxFSKzS9KwJ2INkFE= -github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20251220125032-e46717ca376e/go.mod h1:MdPtO0nOFQuGLKWytPp26prN1143xgxY/kAUTq0v4JY= -github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20251221204540-9ad70f8debbc h1:1kDkoDnmDalpSBo2co66oU87zegZllcceadKVx7rOA8= -github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20251221204540-9ad70f8debbc/go.mod h1:mprD4SL1ZfsjJR2Xx6D5TOqOFSF3tlj1wqXWfrgbtCA= -github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20251203145024-0f6b7a8e7dc5 h1:iUSQ+Goc3KAjL+H41mf1Dqi+L8cxvTU3ooFESVSyDZw= -github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20251203145024-0f6b7a8e7dc5/go.mod h1:n5EzCMhTH/Y0YmTMrOpLUyaE94N183c6kNI8oOWsHsk= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20251221170241-a5482a4f039a h1:oMCXa+XDudWYcEYp8EeuYlUoAvkvxokS3x+rWRqzQ4M= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20251221170241-a5482a4f039a/go.mod h1:uV5Lb1kLculjXy+sXdKhR2Y1E12Hzm5qV7uQqFKy3wA= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20251213170654-5ce22bc3a2e9 h1:GkcnBLnq19MQUO6VCpKWrpCGEAxiHAl/OPIK/tmguWo= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20251213170654-5ce22bc3a2e9/go.mod h1:D3sHyJnr9aHyvj0Nvyvs48V3xaIHT7ZOuGr/1Nfrd/I= github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20251213062730-e339ac2f2851 h1:EfKq1oxaNVAkdz7vGyrvFKUA6juw9uLEI9ZPulIyCWU= github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20251213062730-e339ac2f2851/go.mod h1:0nsIeghZDuEgBfsT1Rlik+ZLBRsXoVrni2pTMP++OV0= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251223124749-eedb97238c5f h1:xcCGJ/g5vvbWhtEJCbv8UeBneI5yrMawm+CXRsJrJZo= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251223124749-eedb97238c5f/go.mod h1:ex8ou6/3ms6ovR+CMXD6XhTlNakm1GhB6UZgagVRNW8= -github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20251213181601-3669e9f88d07 h1:/jgYdfRLuROq2D3DPDDbyrZKnv99nKRfo7+uo64s68c= -github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20251213181601-3669e9f88d07/go.mod h1:Vk2hhKu65d5OP+Xw5eo0L1bRiTjiMg7wHzY+3xs4mH8= -github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251206133124-593df0a7a9e1 h1:qcgbrF9c0axkaDcFGfIA2wGz8bkaxPuXHj3mdKAyz6M= -github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251206133124-593df0a7a9e1/go.mod h1:0XsZ6Fc4hTV6a/BBP8+jiH8LR+IP5z9aStdPTDHALNk= -github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251215094837-5c05ea64c324 h1:y2awFehe8MS5YC47UAdmSSBp7qUSq61uWGWPjWEGaRc= -github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251215094837-5c05ea64c324/go.mod h1:+Me0raWPPdz8gRi9D4z1khmvUgS9vIKAVC8ckg1yJZU= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c h1:l7FO+XoQRnD4aT5p/JXVY2uezQLdC7D50KrwrTmzCfg= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c/go.mod h1:zOX7Y05keiSppIvLabuyh42QHBMhCcoskAtxFRbwXKo= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251215094837-5c05ea64c324 h1:wOGJEAhvP0NFW4zQmOZj4bYtL4Bi83sdobQR69yQNDA= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251215094837-5c05ea64c324/go.mod h1:fy1lvz3uuzzh01DKKdgroXvmJgMpJBsvl2r9eTtAll0= -github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20251221204257-893591a14936 h1:Hrnk4XmU8lMhz8zpdxeWL+HFrpBMIH738umK/lnf5CY= -github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20251221204257-893591a14936/go.mod h1:wBGm6B4bt8SyFmt2TjjCfhWilMPHCxeQFotJCaeJY2M= +github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35 h1:pF3mJ3nwq6r4qwom+rEWZNquZpcQW/iftHlJ1KPIDsk= +github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:kycZyoe7OZdW1HUghr2nI3N7wSJtNahXf6b/ypD14f4= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35 h1:IdcI8DFvW8rXtchONSzbDmhhRp1YyO2YaBJDBXr44Gk= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:zOX7Y05keiSppIvLabuyh42QHBMhCcoskAtxFRbwXKo= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251230215914-6ba873b49a35 h1:8WZYfCt1VJHa5sJRX0UhpmoXud/fn8LHQhXsakdYXuQ= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:H0aQANk8iJPRhS2Bg9n6cYb/IHF0Cks9g7+uZG04Rhk= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20251220223619-1df7af154c0f h1:Lrt+Bo/mTncK8kdd+hT1o/X6oCGl2uUMdBe+X3lrKrk= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20251220223619-1df7af154c0f/go.mod h1:KbToF6BJ5oO1/MapNRhMHED/C/OGfCPMXmIJm/G3tLg= -github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20251125150830-633e42336356 h1:YPD0uZZ3fbEfbo/HOGi/5AK+BrFC3bErg0OBJyZyRUg= -github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20251125150830-633e42336356/go.mod h1:CNJF0ekxqVqrEMLGL/hV489p0RrVoB3alMhjE9cxv1o= -github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20251127143706-407c63ad016a h1:lYmks3cHkbmBX1+I9a8gnajkfSddLAvNqakxx8GV3AA= -github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20251127143706-407c63ad016a/go.mod h1:4Bp2ias9AUXvPBOSOlEkuuegDkAcJEYB9K1UtmX4q8c= -github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20251127161151-38d49bbc1c5d h1:MrDtVqdSNQpl+3ttzzbvDx/83ZQJ5ArUGcy+XJQQcic= -github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20251127161151-38d49bbc1c5d/go.mod h1:rI8CZdEfQB+QRBR3uFmA2i/D9KxTNTTZWFH3MhpID5A= github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20251208195928-7a740b4f921d h1:vBmv0vvDVf5/V0bZUoed2TNQ+t0Z0ExPZgUyWLoXDw4= github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20251208195928-7a740b4f921d/go.mod h1:IguVL02aJlDXM9zRvSdZfcOL5aMsF3/YH5ywX6sUoNk= +github.com/openstack-k8s-operators/openstack-operator/api v0.0.0-20251202072739-b102924657dd h1:iBdbG7lUfBazkEKooKui/Bepmir2itS0TjahSnp1hwU= +github.com/openstack-k8s-operators/openstack-operator/api v0.0.0-20251202072739-b102924657dd/go.mod h1:SUyEHPvF8sV9lAw/e9JH/5QVePfimPWYw66wF0GwPuI= github.com/openstack-k8s-operators/ovn-operator/api v0.6.1-0.20251127135801-f3d54911d811 h1:H1b2RlE9EsemU/dbtV96xIXxmGBLS2UcBtdSS0bYucw= github.com/openstack-k8s-operators/ovn-operator/api v0.6.1-0.20251127135801-f3d54911d811/go.mod h1:LTrCp/cf4HFozb0ZhblhQKO0jUmmBnvD8zFocOsasAM= -github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.20251221210503-10057cebd870 h1:4uFkEf7fCuvg8B/geMrX5mSYRgVCOufpVTuEZBBAjco= -github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.20251221210503-10057cebd870/go.mod h1:IjNQ8O/dBcmPp30rA5vltBiGTTNQj1lkpfRAvSMbeDg= github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec h1:saovr368HPAKHN0aRPh8h8n9s9dn3d8Frmfua0UYRlc= github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec/go.mod h1:Nh2NEePLjovUQof2krTAg4JaAoLacqtPTZQXK6izNfg= -github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20251216163659-f7a35d4fc73b h1:tDir+gLX8xuqL9ZHY4nza4i3SFqzvrsXtP4MP3sXdas= -github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20251216163659-f7a35d4fc73b/go.mod h1:PXyt1tiqjYflYZ+ol2cAe3B7WM1uHr/ZxUCQKAzboxk= -github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20251222143830-69bf8ba39dff h1:BSopHIzA10ORyp+TNdNbFvsSfkj99DC7ZZv95xjLdck= -github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20251222143830-69bf8ba39dff/go.mod h1:JZi2/dRupf7GVitj8JY3qI34WC4MZKf7zs6Rq9W7yBQ= -github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20251222122818-fc7387823d0b h1:MtwGWQtSnK36Lq/uRJDV0REPlR8y5HKoW698eVtZeuA= -github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20251222122818-fc7387823d0b/go.mod h1:eiSdCn8z13oksg5az+Qaj9Mb3+Qgj8XA9GLpZ6IbiJo= 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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/bindata/crds/barbican.openstack.org_barbicanapis.yaml b/bindata/crds/barbican.openstack.org_barbicanapis.yaml index 5929795d5..d5ff6d803 100644 --- a/bindata/crds/barbican.openstack.org_barbicanapis.yaml +++ b/bindata/crds/barbican.openstack.org_barbicanapis.yaml @@ -52,6 +52,14 @@ spec: description: APITimeout for HAProxy and Apache defaults to Barbican APITimeout (seconds) type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Barbican Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/barbican.openstack.org_barbicans.yaml b/bindata/crds/barbican.openstack.org_barbicans.yaml index 0fd776709..73121404d 100644 --- a/bindata/crds/barbican.openstack.org_barbicans.yaml +++ b/bindata/crds/barbican.openstack.org_barbicans.yaml @@ -61,6 +61,14 @@ spec: description: APITimeout for HAProxy and Apache defaults to Barbican APITimeout (seconds) type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Barbican Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/cinder.openstack.org_cinderapis.yaml b/bindata/crds/cinder.openstack.org_cinderapis.yaml index 3764c62fb..a72db7eb5 100644 --- a/bindata/crds/cinder.openstack.org_cinderapis.yaml +++ b/bindata/crds/cinder.openstack.org_cinderapis.yaml @@ -52,6 +52,14 @@ spec: spec: description: CinderAPISpec defines the desired state of CinderAPI properties: + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Cinder Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/cinder.openstack.org_cinders.yaml b/bindata/crds/cinder.openstack.org_cinders.yaml index 0cc855df2..8bbb4d2ba 100644 --- a/bindata/crds/cinder.openstack.org_cinders.yaml +++ b/bindata/crds/cinder.openstack.org_cinders.yaml @@ -57,6 +57,14 @@ spec: description: CinderAPI - Spec definition for the API service of this Cinder deployment properties: + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Cinder Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/crds.yaml b/bindata/crds/crds.yaml index d3d89d472..b8b297d04 100644 --- a/bindata/crds/crds.yaml +++ b/bindata/crds/crds.yaml @@ -305,6 +305,52 @@ spec: type: object spec: properties: + applicationCredential: + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + default: 365 + minimum: 2 + type: integer + gracePeriodDays: + default: 182 + minimum: 1 + type: integer + roles: + default: + - service + items: + type: string + minItems: 1 + type: array + unrestricted: + default: false + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: self.gracePeriodDays < self.expirationDays barbican: properties: apiOverride: @@ -431,6 +477,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -444,6 +534,11 @@ spec: properties: apiTimeout: type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string customServiceConfigSecrets: @@ -939,6 +1034,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -950,6 +1089,11 @@ spec: type: integer cinderAPI: properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string customServiceConfigSecrets: @@ -2032,6 +2176,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -2062,6 +2250,11 @@ spec: properties: apiTimeout: type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object backendMdnsServerProtocol: type: string backendType: @@ -3911,6 +4104,50 @@ spec: type: object type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -4456,6 +4693,11 @@ spec: apiTimeout: minimum: 1 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object containerImage: type: string customServiceConfig: @@ -4839,6 +5081,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' cnfAPIOverride: properties: route: @@ -6774,6 +7060,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -6907,6 +7237,11 @@ spec: default: 60 minimum: 10 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -7168,6 +7503,11 @@ spec: type: array ironicInspector: properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -8431,6 +8771,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -8975,6 +9359,11 @@ spec: type: array manilaAPI: properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -9498,6 +9887,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -9507,6 +9940,11 @@ spec: default: 120 minimum: 1 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object corePlugin: default: ml2 type: string @@ -10328,6 +10766,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' cellOverride: additionalProperties: properties: @@ -10611,6 +11093,11 @@ spec: default: 60 minimum: 10 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object cellTemplates: additionalProperties: properties: @@ -11396,6 +11883,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -11431,6 +11962,11 @@ spec: apiTimeout: default: 120 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11473,6 +12009,11 @@ spec: properties: apiTimeout: type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11681,6 +12222,11 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11833,6 +12379,11 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -12091,6 +12642,11 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -12878,6 +13434,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -12887,6 +13487,11 @@ spec: default: 60 minimum: 10 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string databaseAccount: @@ -13953,6 +14558,50 @@ spec: type: string swift: properties: + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -14109,6 +14758,11 @@ spec: default: 60 minimum: 1 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object ceilometerEnabled: default: false type: boolean @@ -14600,6 +15254,138 @@ spec: type: string type: object type: object + applicationCredentialAodh: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' + applicationCredentialCeilometer: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' + applicationCredentialCloudKitty: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' cloudKittyApiOverride: properties: route: @@ -14869,6 +15655,11 @@ spec: apiTimeout: default: 60 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -15035,6 +15826,11 @@ spec: apiTimeout: default: 60 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -15121,6 +15917,11 @@ spec: apiTimeout: default: 60 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object cloudKittyAPI: properties: customServiceConfig: @@ -16500,6 +17301,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -16509,6 +17354,11 @@ spec: default: replicas: 1 properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string nodeSelector: @@ -16693,6 +17543,11 @@ spec: type: string type: object type: object + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string databaseAccount: diff --git a/bindata/crds/designate.openstack.org_designateapis.yaml b/bindata/crds/designate.openstack.org_designateapis.yaml index e1bb6331e..24a581334 100644 --- a/bindata/crds/designate.openstack.org_designateapis.yaml +++ b/bindata/crds/designate.openstack.org_designateapis.yaml @@ -56,6 +56,14 @@ spec: description: APITimeout for HAProxy and Apache defaults to DesignateSpecCore APITimeout (seconds) type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object backendMdnsServerProtocol: description: |- BackendTypeProtocol - Defines the backend protocol to be used between the designate-worker & diff --git a/bindata/crds/designate.openstack.org_designates.yaml b/bindata/crds/designate.openstack.org_designates.yaml index 43902724c..70a37dfe3 100644 --- a/bindata/crds/designate.openstack.org_designates.yaml +++ b/bindata/crds/designate.openstack.org_designates.yaml @@ -102,6 +102,14 @@ spec: description: APITimeout for HAProxy and Apache defaults to DesignateSpecCore APITimeout (seconds) type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object backendMdnsServerProtocol: description: |- BackendTypeProtocol - Defines the backend protocol to be used between the designate-worker & diff --git a/bindata/crds/glance.openstack.org_glanceapis.yaml b/bindata/crds/glance.openstack.org_glanceapis.yaml index 098838dd0..f25d29119 100644 --- a/bindata/crds/glance.openstack.org_glanceapis.yaml +++ b/bindata/crds/glance.openstack.org_glanceapis.yaml @@ -65,6 +65,14 @@ spec: - single - edge type: string + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: Glance Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/glance.openstack.org_glances.yaml b/bindata/crds/glance.openstack.org_glances.yaml index 77a73dd80..e80cd695c 100644 --- a/bindata/crds/glance.openstack.org_glances.yaml +++ b/bindata/crds/glance.openstack.org_glances.yaml @@ -1229,6 +1229,14 @@ spec: APITimeout minimum: 1 type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object containerImage: description: Glance Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/ironic.openstack.org_ironicapis.yaml b/bindata/crds/ironic.openstack.org_ironicapis.yaml index 88e4370e6..b65fb9ea9 100644 --- a/bindata/crds/ironic.openstack.org_ironicapis.yaml +++ b/bindata/crds/ironic.openstack.org_ironicapis.yaml @@ -57,6 +57,15 @@ spec: description: APITimeout for HAProxy, Apache minimum: 10 type: integer + auth: + description: Auth - Parameters related to authentication (inherited + from parent Ironic CR) + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Ironic API Container Image type: string diff --git a/bindata/crds/ironic.openstack.org_ironicconductors.yaml b/bindata/crds/ironic.openstack.org_ironicconductors.yaml index 02d2493a0..a8343b875 100644 --- a/bindata/crds/ironic.openstack.org_ironicconductors.yaml +++ b/bindata/crds/ironic.openstack.org_ironicconductors.yaml @@ -52,6 +52,15 @@ spec: spec: description: IronicConductorSpec defines the desired state of IronicConductor properties: + auth: + description: Auth - Parameters related to authentication (inherited + from parent Ironic CR) + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object conductorGroup: description: ConductorGroup - Ironic Conductor conductor group. type: string diff --git a/bindata/crds/ironic.openstack.org_ironicinspectors.yaml b/bindata/crds/ironic.openstack.org_ironicinspectors.yaml index 13f04d4ab..56ef2e10b 100644 --- a/bindata/crds/ironic.openstack.org_ironicinspectors.yaml +++ b/bindata/crds/ironic.openstack.org_ironicinspectors.yaml @@ -57,6 +57,14 @@ spec: description: APITimeout for HAProxy, Apache minimum: 10 type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Ironic Inspector Container Image type: string diff --git a/bindata/crds/ironic.openstack.org_ironicneutronagents.yaml b/bindata/crds/ironic.openstack.org_ironicneutronagents.yaml index cf005e341..5bf614b75 100644 --- a/bindata/crds/ironic.openstack.org_ironicneutronagents.yaml +++ b/bindata/crds/ironic.openstack.org_ironicneutronagents.yaml @@ -54,6 +54,15 @@ spec: description: IronicNeutronAgentSpec defines the desired state of ML2 baremetal - ironic-neutron-agent agents properties: + auth: + description: Auth - Parameters related to authentication (inherited + from parent Ironic CR) + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - ML2 baremtal - Ironic Neutron Agent Image diff --git a/bindata/crds/ironic.openstack.org_ironics.yaml b/bindata/crds/ironic.openstack.org_ironics.yaml index 9ea91472c..4cea34122 100644 --- a/bindata/crds/ironic.openstack.org_ironics.yaml +++ b/bindata/crds/ironic.openstack.org_ironics.yaml @@ -53,6 +53,15 @@ spec: description: APITimeout for HAProxy, Apache minimum: 10 type: integer + auth: + description: Auth - Parameters related to authentication (shared by + IronicAPI, IronicConductor, and IronicNeutronAgent) + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object customServiceConfig: default: '# add your customization here' description: |- @@ -621,6 +630,14 @@ spec: description: IronicInspector - Spec definition for the inspector service of this Ironic deployment properties: + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object customServiceConfig: default: '# add your customization here' description: |- diff --git a/bindata/crds/keystone.openstack.org_keystoneapplicationcredentials.yaml b/bindata/crds/keystone.openstack.org_keystoneapplicationcredentials.yaml new file mode 100644 index 000000000..d96ed836a --- /dev/null +++ b/bindata/crds/keystone.openstack.org_keystoneapplicationcredentials.yaml @@ -0,0 +1,238 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.18.0 + creationTimestamp: null + name: keystoneapplicationcredentials.keystone.openstack.org +spec: + group: keystone.openstack.org + names: + kind: KeystoneApplicationCredential + listKind: KeystoneApplicationCredentialList + plural: keystoneapplicationcredentials + shortNames: + - appcred + singular: keystoneapplicationcredential + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Keystone ApplicationCredential ID + jsonPath: .status.acID + name: ACID + type: string + - description: Secret holding ApplicationCredential secret + jsonPath: .status.secretName + name: SecretName + type: string + - description: Last rotation time + format: date-time + jsonPath: .status.lastRotated + name: LastRotated + type: string + - description: When rotation becomes eligible + format: date-time + jsonPath: .status.rotationEligibleAt + name: RotationEligible + type: string + - description: Status + jsonPath: .status.conditions[0].status + name: Status + type: string + - description: Message + jsonPath: .status.conditions[0].message + name: Message + type: string + name: v1beta1 + schema: + openAPIV3Schema: + description: KeystoneApplicationCredential is the Schema for the applicationcredentials + API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: KeystoneApplicationCredentialSpec defines what the user can + set + properties: + accessRules: + description: AccessRules defines which services the ApplicationCredential + is permitted to access + items: + description: ACRule defines an access rule for an ApplicationCredential + properties: + method: + description: Method is the HTTP verb to allow + enum: + - GET + - HEAD + - POST + - PUT + - PATCH + - DELETE + type: string + path: + description: Path is the API path to allow + minLength: 1 + type: string + service: + description: Service is the OpenStack service type + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + expirationDays: + default: 365 + description: ExpirationDays sets the lifetime in days for the ApplicationCredential + minimum: 2 + type: integer + gracePeriodDays: + default: 182 + description: GracePeriodDays sets how many days before expiration + the ApplicationCredential should be rotated + minimum: 1 + type: integer + passwordSelector: + description: PasswordSelector for extracting the service password + minLength: 1 + type: string + roles: + description: Roles to assign to the ApplicationCredential + items: + type: string + minItems: 1 + type: array + secret: + description: Secret containing service user password + minLength: 1 + type: string + unrestricted: + default: false + description: Unrestricted indicates whether the ApplicationCredential + may be used to create or destroy other credentials or trusts + type: boolean + userName: + description: UserName - the Keystone user under which this ApplicationCredential + is created + type: string + required: + - passwordSelector + - roles + - secret + - userName + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: self.gracePeriodDays < self.expirationDays + status: + description: KeystoneApplicationCredentialStatus defines the observed + state + properties: + acID: + description: ACID - the ID in Keystone for this ApplicationCredential + type: string + conditions: + description: Conditions + items: + description: Condition defines an observation of a API resource + operational state. + properties: + lastTransitionTime: + description: |- + Last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when + the API field changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. + type: string + severity: + description: |- + Severity provides a classification of Reason code, so the current situation is immediately + understandable and could act accordingly. + It is meant for situations where Status=False and it should be indicated if it is just + informational, warning (next reconciliation might fix it) or an error (e.g. DB create issue + and no actions to automatically resolve the issue can/should be done). + For conditions where Status=Unknown or Status=True the Severity should be SeverityNone. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + createdAt: + description: CreatedAt - timestap of creation + format: date-time + type: string + expiresAt: + description: ExpiresAt - time of validity expiration + format: date-time + type: string + lastRotated: + description: LastRotated - timestamp when credentials were last rotated + format: date-time + type: string + observedGeneration: + description: ObservedGeneration - the most recent generation observed + for this ApplicationCredential. + format: int64 + type: integer + rotationEligibleAt: + description: |- + RotationEligibleAt indicates when rotation becomes eligible (start of grace period window). + Computed as ExpiresAt - GracePeriodDays. The AC can be rotated after this timestamp. + format: date-time + type: string + secretName: + description: SecretName - name of the k8s Secret storing the ApplicationCredential + secret + type: string + securityHash: + description: |- + SecurityHash tracks the hash of security-critical spec fields (roles, accessRules, unrestricted). + Used to detect when these fields change and trigger immediate rotation. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/bindata/crds/manila.openstack.org_manilaapis.yaml b/bindata/crds/manila.openstack.org_manilaapis.yaml index 2dd27791f..61134afdf 100644 --- a/bindata/crds/manila.openstack.org_manilaapis.yaml +++ b/bindata/crds/manila.openstack.org_manilaapis.yaml @@ -52,6 +52,14 @@ spec: spec: description: ManilaAPISpec defines the desired state of ManilaAPI properties: + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Manila API Container Image URL type: string diff --git a/bindata/crds/manila.openstack.org_manilas.yaml b/bindata/crds/manila.openstack.org_manilas.yaml index d1a3cc4c4..51cdb7b0f 100644 --- a/bindata/crds/manila.openstack.org_manilas.yaml +++ b/bindata/crds/manila.openstack.org_manilas.yaml @@ -1223,6 +1223,14 @@ spec: description: ManilaAPI - Spec definition for the API service of this Manila deployment properties: + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Manila API Container Image URL type: string diff --git a/bindata/crds/neutron.openstack.org_neutronapis.yaml b/bindata/crds/neutron.openstack.org_neutronapis.yaml index 945531b89..bbef3ca2b 100644 --- a/bindata/crds/neutron.openstack.org_neutronapis.yaml +++ b/bindata/crds/neutron.openstack.org_neutronapis.yaml @@ -57,6 +57,14 @@ spec: description: APITimeout for HAProxy, Apache minimum: 1 type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: NeutronAPI Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/nova.openstack.org_nova.yaml b/bindata/crds/nova.openstack.org_nova.yaml index 99311a735..13b3b428c 100644 --- a/bindata/crds/nova.openstack.org_nova.yaml +++ b/bindata/crds/nova.openstack.org_nova.yaml @@ -371,6 +371,16 @@ spec: description: APITimeout for Route and Apache minimum: 10 type: integer + auth: + description: Auth - Parameters related to authentication (shared by + all Nova services) + properties: + applicationCredentialSecret: + description: |- + ApplicationCredentialSecret - the name of the k8s Secret that contains the + application credential data used for authentication + type: string + type: object cellTemplates: additionalProperties: description: |- diff --git a/bindata/crds/nova.openstack.org_novaapis.yaml b/bindata/crds/nova.openstack.org_novaapis.yaml index e2840ab2b..64a4943fe 100644 --- a/bindata/crds/nova.openstack.org_novaapis.yaml +++ b/bindata/crds/nova.openstack.org_novaapis.yaml @@ -66,6 +66,15 @@ spec: description: APITimeout for Route and Apache minimum: 10 type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: |- + ApplicationCredentialSecret - the name of the k8s Secret that contains the + application credential data used for authentication + type: string + type: object cell0DatabaseAccount: default: nova-cell0 description: APIDatabaseAccount - MariaDBAccount to use when accessing diff --git a/bindata/crds/nova.openstack.org_novacells.yaml b/bindata/crds/nova.openstack.org_novacells.yaml index 2f015c0d6..e274e5efa 100644 --- a/bindata/crds/nova.openstack.org_novacells.yaml +++ b/bindata/crds/nova.openstack.org_novacells.yaml @@ -55,6 +55,15 @@ spec: description: APITimeout for Route and Apache minimum: 10 type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: |- + ApplicationCredentialSecret - the name of the k8s Secret that contains the + application credential data used for authentication + type: string + type: object cellDatabaseAccount: default: nova description: CellDatabaseAccount - MariaDBAccount to use when accessing diff --git a/bindata/crds/nova.openstack.org_novacomputes.yaml b/bindata/crds/nova.openstack.org_novacomputes.yaml index 498fd2fc3..fabd2bb83 100644 --- a/bindata/crds/nova.openstack.org_novacomputes.yaml +++ b/bindata/crds/nova.openstack.org_novacomputes.yaml @@ -52,6 +52,15 @@ spec: spec: description: NovaComputeSpec defines the desired state of NovaCompute properties: + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: |- + ApplicationCredentialSecret - the name of the k8s Secret that contains the + application credential data used for authentication + type: string + type: object cellName: description: CellName is the name of the Nova Cell this NovaCompute belongs to. diff --git a/bindata/crds/nova.openstack.org_novaconductors.yaml b/bindata/crds/nova.openstack.org_novaconductors.yaml index bc4e4016d..606d86e3e 100644 --- a/bindata/crds/nova.openstack.org_novaconductors.yaml +++ b/bindata/crds/nova.openstack.org_novaconductors.yaml @@ -63,6 +63,15 @@ spec: provided then up-calls will be disabled. This filed is Required for cell0. type: string + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: |- + ApplicationCredentialSecret - the name of the k8s Secret that contains the + application credential data used for authentication + type: string + type: object cellDatabaseAccount: default: nova description: CellDatabaseAccount - MariaDBAccount to use when accessing diff --git a/bindata/crds/nova.openstack.org_novametadata.yaml b/bindata/crds/nova.openstack.org_novametadata.yaml index 6f8b86839..f18ed8254 100644 --- a/bindata/crds/nova.openstack.org_novametadata.yaml +++ b/bindata/crds/nova.openstack.org_novametadata.yaml @@ -67,6 +67,15 @@ spec: description: APITimeout for Route and Apache minimum: 10 type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: |- + ApplicationCredentialSecret - the name of the k8s Secret that contains the + application credential data used for authentication + type: string + type: object cellDatabaseAccount: default: nova description: CellDatabaseAccount - MariaDBAccount to use when accessing diff --git a/bindata/crds/nova.openstack.org_novanovncproxies.yaml b/bindata/crds/nova.openstack.org_novanovncproxies.yaml index 43f1fe5f4..0848e0b19 100644 --- a/bindata/crds/nova.openstack.org_novanovncproxies.yaml +++ b/bindata/crds/nova.openstack.org_novanovncproxies.yaml @@ -52,6 +52,15 @@ spec: spec: description: NovaNoVNCProxySpec defines the desired state of NovaNoVNCProxy properties: + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: |- + ApplicationCredentialSecret - the name of the k8s Secret that contains the + application credential data used for authentication + type: string + type: object cellDatabaseAccount: default: nova description: CellDatabaseAccount - MariaDBAccount to use when accessing diff --git a/bindata/crds/nova.openstack.org_novaschedulers.yaml b/bindata/crds/nova.openstack.org_novaschedulers.yaml index 97bf50231..44b4bd40b 100644 --- a/bindata/crds/nova.openstack.org_novaschedulers.yaml +++ b/bindata/crds/nova.openstack.org_novaschedulers.yaml @@ -61,6 +61,15 @@ spec: description: APIDatabaseHostname - hostname to use when accessing the API DB type: string + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: |- + ApplicationCredentialSecret - the name of the k8s Secret that contains the + application credential data used for authentication + type: string + type: object cell0DatabaseAccount: default: nova-cell0 description: Cell0DatabaseAccount - MariaDBAccount to use when accessing diff --git a/bindata/crds/octavia.openstack.org_octaviaamphoracontrollers.yaml b/bindata/crds/octavia.openstack.org_octaviaamphoracontrollers.yaml index a2d1a1b44..6f8416a68 100644 --- a/bindata/crds/octavia.openstack.org_octaviaamphoracontrollers.yaml +++ b/bindata/crds/octavia.openstack.org_octaviaamphoracontrollers.yaml @@ -82,6 +82,14 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Amphora Controller Container Image URL type: string diff --git a/bindata/crds/octavia.openstack.org_octaviaapis.yaml b/bindata/crds/octavia.openstack.org_octaviaapis.yaml index 8ab4cdb82..f36b90742 100644 --- a/bindata/crds/octavia.openstack.org_octaviaapis.yaml +++ b/bindata/crds/octavia.openstack.org_octaviaapis.yaml @@ -56,6 +56,14 @@ spec: description: APITimeout for HAProxy and Apache defaults to OctaviaSpecCore APITimeout (seconds) type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: Octavia Container Image URL type: string diff --git a/bindata/crds/octavia.openstack.org_octavias.yaml b/bindata/crds/octavia.openstack.org_octavias.yaml index 24e72afc6..ef07cef32 100644 --- a/bindata/crds/octavia.openstack.org_octavias.yaml +++ b/bindata/crds/octavia.openstack.org_octavias.yaml @@ -83,6 +83,15 @@ spec: default: 120 description: Octavia API timeout type: integer + auth: + description: Auth - Parameters related to authentication (shared by + all Octavia components) + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object customServiceConfig: default: '# add your customization here' description: |- @@ -162,6 +171,14 @@ spec: description: APITimeout for HAProxy and Apache defaults to OctaviaSpecCore APITimeout (seconds) type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object containerImage: description: Octavia Container Image URL type: string @@ -582,6 +599,14 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Amphora Controller Container Image URL @@ -830,6 +855,14 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Amphora Controller Container Image URL @@ -1254,6 +1287,14 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object containerImage: description: ContainerImage - Amphora Controller Container Image URL diff --git a/bindata/crds/placement.openstack.org_placementapis.yaml b/bindata/crds/placement.openstack.org_placementapis.yaml index ba8d46b6f..0aa489098 100644 --- a/bindata/crds/placement.openstack.org_placementapis.yaml +++ b/bindata/crds/placement.openstack.org_placementapis.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -57,6 +58,14 @@ spec: description: APITimeout for HAProxy, Apache minimum: 10 type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: PlacementAPI Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/swift.openstack.org_swiftproxies.yaml b/bindata/crds/swift.openstack.org_swiftproxies.yaml index 6259000e0..a074ef78d 100644 --- a/bindata/crds/swift.openstack.org_swiftproxies.yaml +++ b/bindata/crds/swift.openstack.org_swiftproxies.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -58,6 +59,14 @@ spec: 60 seconds minimum: 1 type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object ceilometerEnabled: default: false description: Enables ceilometer in the swift proxy and creates required diff --git a/bindata/crds/swift.openstack.org_swiftrings.yaml b/bindata/crds/swift.openstack.org_swiftrings.yaml index 0448278a9..08c005231 100644 --- a/bindata/crds/swift.openstack.org_swiftrings.yaml +++ b/bindata/crds/swift.openstack.org_swiftrings.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/bindata/crds/swift.openstack.org_swifts.yaml b/bindata/crds/swift.openstack.org_swifts.yaml index 3b56216b7..c1ec6c8ba 100644 --- a/bindata/crds/swift.openstack.org_swifts.yaml +++ b/bindata/crds/swift.openstack.org_swifts.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -92,6 +93,14 @@ spec: to 60 seconds minimum: 1 type: integer + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object ceilometerEnabled: default: false description: Enables ceilometer in the swift proxy and creates diff --git a/bindata/crds/swift.openstack.org_swiftstorages.yaml b/bindata/crds/swift.openstack.org_swiftstorages.yaml index c37e6ac24..2ed35ce1d 100644 --- a/bindata/crds/swift.openstack.org_swiftstorages.yaml +++ b/bindata/crds/swift.openstack.org_swiftstorages.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/bindata/crds/telemetry.openstack.org_autoscalings.yaml b/bindata/crds/telemetry.openstack.org_autoscalings.yaml index df2d8ef88..ccc0dad01 100644 --- a/bindata/crds/telemetry.openstack.org_autoscalings.yaml +++ b/bindata/crds/telemetry.openstack.org_autoscalings.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -70,6 +71,14 @@ spec: default: 60 description: APITimeout for Route and Apache type: integer + auth: + description: Auth - authentication settings for keystone integration + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - secret name for + application credential + type: string + type: object customServiceConfig: default: '# add your customization here' description: |- diff --git a/bindata/crds/telemetry.openstack.org_ceilometers.yaml b/bindata/crds/telemetry.openstack.org_ceilometers.yaml index 26489e9fe..46ac83066 100644 --- a/bindata/crds/telemetry.openstack.org_ceilometers.yaml +++ b/bindata/crds/telemetry.openstack.org_ceilometers.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -116,6 +117,14 @@ spec: default: 60 description: APITimeout for Apache type: integer + auth: + description: Auth - authentication settings for keystone integration + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - secret name for application + credential + type: string + type: object centralImage: type: string computeImage: diff --git a/bindata/crds/telemetry.openstack.org_cloudkitties.yaml b/bindata/crds/telemetry.openstack.org_cloudkitties.yaml index af6404fd3..e2a27a1f6 100644 --- a/bindata/crds/telemetry.openstack.org_cloudkitties.yaml +++ b/bindata/crds/telemetry.openstack.org_cloudkitties.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -43,6 +44,14 @@ spec: default: 60 description: APITimeout for HAProxy, Apache, and rpc_response_timeout type: integer + auth: + description: Auth - authentication settings for keystone integration + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - secret name for application + credential + type: string + type: object cloudKittyAPI: description: CloudKittyAPI - Spec definition for the API service of this CloudKitty deployment diff --git a/bindata/crds/telemetry.openstack.org_cloudkittyapis.yaml b/bindata/crds/telemetry.openstack.org_cloudkittyapis.yaml index 5baaefa33..308f35a87 100644 --- a/bindata/crds/telemetry.openstack.org_cloudkittyapis.yaml +++ b/bindata/crds/telemetry.openstack.org_cloudkittyapis.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -39,6 +40,14 @@ spec: spec: description: CloudKittyAPISpec defines the desired state of CloudKittyAPI properties: + auth: + description: Auth - authentication settings for keystone integration + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - secret name for application + credential + type: string + type: object containerImage: description: ContainerImage - CloudKitty Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/telemetry.openstack.org_cloudkittyprocs.yaml b/bindata/crds/telemetry.openstack.org_cloudkittyprocs.yaml index 595936501..cf2d48b53 100644 --- a/bindata/crds/telemetry.openstack.org_cloudkittyprocs.yaml +++ b/bindata/crds/telemetry.openstack.org_cloudkittyprocs.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -53,6 +54,14 @@ spec: description: CloudKittyProcSpec defines the desired state of CloudKitty Processor properties: + auth: + description: Auth - authentication settings for keystone integration + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - secret name for application + credential + type: string + type: object containerImage: description: ContainerImage - CloudKitty Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/telemetry.openstack.org_loggings.yaml b/bindata/crds/telemetry.openstack.org_loggings.yaml index 9d8fd1f2f..97da2ce34 100644 --- a/bindata/crds/telemetry.openstack.org_loggings.yaml +++ b/bindata/crds/telemetry.openstack.org_loggings.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/bindata/crds/telemetry.openstack.org_metricstorages.yaml b/bindata/crds/telemetry.openstack.org_metricstorages.yaml index 06788cd84..3d733e997 100644 --- a/bindata/crds/telemetry.openstack.org_metricstorages.yaml +++ b/bindata/crds/telemetry.openstack.org_metricstorages.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/bindata/crds/telemetry.openstack.org_telemetries.yaml b/bindata/crds/telemetry.openstack.org_telemetries.yaml index d3144f544..da4aeac2d 100644 --- a/bindata/crds/telemetry.openstack.org_telemetries.yaml +++ b/bindata/crds/telemetry.openstack.org_telemetries.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -73,6 +74,14 @@ spec: default: 60 description: APITimeout for Route and Apache type: integer + auth: + description: Auth - authentication settings for keystone integration + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - secret name + for application credential + type: string + type: object customServiceConfig: default: '# add your customization here' description: |- @@ -433,6 +442,14 @@ spec: default: 60 description: APITimeout for Apache type: integer + auth: + description: Auth - authentication settings for keystone integration + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - secret name for + application credential + type: string + type: object centralImage: type: string computeImage: @@ -602,6 +619,14 @@ spec: default: 60 description: APITimeout for HAProxy, Apache, and rpc_response_timeout type: integer + auth: + description: Auth - authentication settings for keystone integration + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - secret name for + application credential + type: string + type: object cloudKittyAPI: description: CloudKittyAPI - Spec definition for the API service of this CloudKitty deployment diff --git a/bindata/crds/watcher.openstack.org_watcherapis.yaml b/bindata/crds/watcher.openstack.org_watcherapis.yaml index b48fd4783..e8c5c385b 100644 --- a/bindata/crds/watcher.openstack.org_watcherapis.yaml +++ b/bindata/crds/watcher.openstack.org_watcherapis.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -53,6 +54,15 @@ spec: description: APITimeout for Route and Apache minimum: 10 type: integer + auth: + description: Auth - Parameters related to authentication (inherited + from parent Watcher CR) + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: The service specific Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/watcher.openstack.org_watcherappliers.yaml b/bindata/crds/watcher.openstack.org_watcherappliers.yaml index e7481f038..e81ef5e59 100644 --- a/bindata/crds/watcher.openstack.org_watcherappliers.yaml +++ b/bindata/crds/watcher.openstack.org_watcherappliers.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/bindata/crds/watcher.openstack.org_watcherdecisionengines.yaml b/bindata/crds/watcher.openstack.org_watcherdecisionengines.yaml index 037f185b5..c6a69f340 100644 --- a/bindata/crds/watcher.openstack.org_watcherdecisionengines.yaml +++ b/bindata/crds/watcher.openstack.org_watcherdecisionengines.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -49,6 +50,15 @@ spec: spec: description: WatcherDecisionEngineSpec defines the desired state of WatcherDecisionEngine properties: + auth: + description: Auth - Parameters related to authentication (inherited + from parent Watcher CR) + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object containerImage: description: The service specific Container Image URL (will be set to environmental default if empty) diff --git a/bindata/crds/watcher.openstack.org_watchers.yaml b/bindata/crds/watcher.openstack.org_watchers.yaml index a91bdf91e..39976b959 100644 --- a/bindata/crds/watcher.openstack.org_watchers.yaml +++ b/bindata/crds/watcher.openstack.org_watchers.yaml @@ -1,3 +1,4 @@ +--- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: @@ -56,6 +57,14 @@ spec: replicas: 1 description: APIServiceTemplate - define the watcher-api service properties: + auth: + description: Auth - Parameters related to authentication + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing + Application Credential ID and Secret + type: string + type: object customServiceConfig: description: |- CustomServiceConfig - customize the service config using this parameter to change service defaults, @@ -460,6 +469,15 @@ spec: type: string type: object type: object + auth: + description: Auth - Parameters related to authentication (shared by + all Watcher components) + properties: + applicationCredentialSecret: + description: ApplicationCredentialSecret - Secret containing Application + Credential ID and Secret + type: string + type: object customServiceConfig: description: |- CustomServiceConfig - customize the service config using this parameter to change service defaults, diff --git a/bindata/rbac/keystone-operator-rbac.yaml b/bindata/rbac/keystone-operator-rbac.yaml index e0acef4bb..4e4d3d68b 100644 --- a/bindata/rbac/keystone-operator-rbac.yaml +++ b/bindata/rbac/keystone-operator-rbac.yaml @@ -81,6 +81,24 @@ rules: - patch - update - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - secrets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update - apiGroups: - "" resources: @@ -129,6 +147,7 @@ rules: - keystone.openstack.org resources: - keystoneapis + - keystoneapplicationcredentials - keystoneendpoints - keystoneservices verbs: @@ -143,6 +162,7 @@ rules: - keystone.openstack.org resources: - keystoneapis/finalizers + - keystoneapplicationcredentials/finalizers - keystoneendpoints/finalizers - keystoneservices/finalizers verbs: @@ -152,6 +172,7 @@ rules: - keystone.openstack.org resources: - keystoneapis/status + - keystoneapplicationcredentials/status - keystoneendpoints/status - keystoneservices/status verbs: diff --git a/bindata/rbac/rbac.yaml b/bindata/rbac/rbac.yaml index 7aed4290f..a006df8fa 100644 --- a/bindata/rbac/rbac.yaml +++ b/bindata/rbac/rbac.yaml @@ -413,6 +413,7 @@ rules: - keystone.openstack.org resources: - keystoneapis + - keystoneapplicationcredentials verbs: - create - delete @@ -421,6 +422,14 @@ rules: - patch - update - watch +- apiGroups: + - keystone.openstack.org + resources: + - keystoneapplicationcredentials/status + verbs: + - get + - patch + - update - apiGroups: - machineconfiguration.openshift.io resources: diff --git a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml index 31e6663d8..18a18e12b 100644 --- a/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml +++ b/config/crd/bases/core.openstack.org_openstackcontrolplanes.yaml @@ -40,6 +40,52 @@ spec: type: object spec: properties: + applicationCredential: + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + default: 365 + minimum: 2 + type: integer + gracePeriodDays: + default: 182 + minimum: 1 + type: integer + roles: + default: + - service + items: + type: string + minItems: 1 + type: array + unrestricted: + default: false + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: self.gracePeriodDays < self.expirationDays barbican: properties: apiOverride: @@ -166,6 +212,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -179,6 +269,11 @@ spec: properties: apiTimeout: type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string customServiceConfigSecrets: @@ -674,6 +769,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -685,6 +824,11 @@ spec: type: integer cinderAPI: properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string customServiceConfigSecrets: @@ -1767,6 +1911,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -1797,6 +1985,11 @@ spec: properties: apiTimeout: type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object backendMdnsServerProtocol: type: string backendType: @@ -3646,6 +3839,50 @@ spec: type: object type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -4191,6 +4428,11 @@ spec: apiTimeout: minimum: 1 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object containerImage: type: string customServiceConfig: @@ -4574,6 +4816,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' cnfAPIOverride: properties: route: @@ -6509,6 +6795,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -6642,6 +6972,11 @@ spec: default: 60 minimum: 10 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -6903,6 +7238,11 @@ spec: type: array ironicInspector: properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -8166,6 +8506,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -8710,6 +9094,11 @@ spec: type: array manilaAPI: properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -9233,6 +9622,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -9242,6 +9675,11 @@ spec: default: 120 minimum: 1 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object corePlugin: default: ml2 type: string @@ -10063,6 +10501,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' cellOverride: additionalProperties: properties: @@ -10346,6 +10828,11 @@ spec: default: 60 minimum: 10 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object cellTemplates: additionalProperties: properties: @@ -11131,6 +11618,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -11166,6 +11697,11 @@ spec: apiTimeout: default: 120 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11208,6 +11744,11 @@ spec: properties: apiTimeout: type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11416,6 +11957,11 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11568,6 +12114,11 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -11826,6 +12377,11 @@ spec: amphoraImageOwnerID: default: "" type: string + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -12613,6 +13169,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -12622,6 +13222,11 @@ spec: default: 60 minimum: 10 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string databaseAccount: @@ -13688,6 +14293,50 @@ spec: type: string swift: properties: + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: true type: boolean @@ -13844,6 +14493,11 @@ spec: default: 60 minimum: 1 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object ceilometerEnabled: default: false type: boolean @@ -14335,6 +14989,138 @@ spec: type: string type: object type: object + applicationCredentialAodh: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' + applicationCredentialCeilometer: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' + applicationCredentialCloudKitty: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' cloudKittyApiOverride: properties: route: @@ -14604,6 +15390,11 @@ spec: apiTimeout: default: 60 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -14770,6 +15561,11 @@ spec: apiTimeout: default: 60 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: default: '# add your customization here' type: string @@ -14856,6 +15652,11 @@ spec: apiTimeout: default: 60 type: integer + auth: + properties: + applicationCredentialSecret: + type: string + type: object cloudKittyAPI: properties: customServiceConfig: @@ -16235,6 +17036,50 @@ spec: type: string type: object type: object + applicationCredential: + default: + enabled: false + nullable: true + properties: + accessRules: + items: + properties: + method: + minLength: 1 + type: string + path: + minLength: 1 + type: string + service: + minLength: 1 + type: string + required: + - method + - path + - service + type: object + type: array + x-kubernetes-list-type: atomic + enabled: + default: false + type: boolean + expirationDays: + minimum: 2 + type: integer + gracePeriodDays: + minimum: 1 + type: integer + roles: + items: + type: string + type: array + unrestricted: + type: boolean + type: object + x-kubernetes-validations: + - message: gracePeriodDays must be smaller than expirationDays + rule: '!(has(self.expirationDays) && has(self.gracePeriodDays)) + || self.gracePeriodDays < self.expirationDays' enabled: default: false type: boolean @@ -16244,6 +17089,11 @@ spec: default: replicas: 1 properties: + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string nodeSelector: @@ -16428,6 +17278,11 @@ spec: type: string type: object type: object + auth: + properties: + applicationCredentialSecret: + type: string + type: object customServiceConfig: type: string databaseAccount: diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index e2a3e6bea..284985c89 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -38,6 +38,9 @@ spec: kind: OpenStackControlPlane name: openstackcontrolplanes.core.openstack.org specDescriptors: + - description: ApplicationCredential - Parameters related to the ApplicationCredential + displayName: Application Credential + path: applicationCredential - description: Barbican - Parameters related to the Barbican service displayName: Barbican path: barbican @@ -48,6 +51,10 @@ spec: - description: TLS - overrides tls parameters for public endpoint displayName: TLS path: barbican.apiOverride.tls + - description: ApplicationCredential allows service-specific overrides of the + global AC configuration. + displayName: Application Credential + path: barbican.applicationCredential - description: Enabled - Whether Barbican service should be deployed and managed displayName: Enabled path: barbican.enabled @@ -66,6 +73,10 @@ spec: - description: TLS - overrides tls parameters for public endpoint displayName: TLS path: cinder.apiOverride.tls + - description: ApplicationCredential allows service-specific overrides of the + global AC configuration. + displayName: Application Credential + path: cinder.applicationCredential - description: Enabled - Whether Cinder service should be deployed and managed displayName: Enabled path: cinder.enabled @@ -131,6 +142,10 @@ spec: - description: TLS - overrides tls parameters for public endpoint displayName: TLS path: glance.apiOverrides.tls + - description: ApplicationCredential allows service-specific overrides of the + global AC configuration. + displayName: Application Credential + path: glance.applicationCredential - description: Enabled - Whether Glance service should be deployed and managed displayName: Enabled path: glance.enabled @@ -264,6 +279,10 @@ spec: - description: TLS - overrides tls parameters for public endpoint displayName: TLS path: neutron.apiOverride.tls + - description: ApplicationCredential allows service-specific overrides of the + global AC configuration. + displayName: Application Credential + path: neutron.applicationCredential - description: Enabled - Whether Neutron service should be deployed and managed displayName: Enabled path: neutron.enabled @@ -286,6 +305,10 @@ spec: - description: TLS - overrides tls parameters for public endpoint displayName: TLS path: nova.apiOverride.tls + - description: ApplicationCredential allows service-specific overrides of the + global AC configuration. + displayName: Application Credential + path: nova.applicationCredential - description: |- CellOverride, provides the ability to override the generated manifest of several child resources for a nova cell. cell0 never have compute nodes and therefore it won't have a noVNCProxy deployed. @@ -364,6 +387,10 @@ spec: - description: TLS - overrides tls parameters for public endpoint displayName: TLS path: placement.apiOverride.tls + - description: ApplicationCredential allows service-specific overrides of the + global AC configuration. + displayName: Application Credential + path: placement.applicationCredential - description: Enabled - Whether Placement service should be deployed and managed displayName: Enabled path: placement.enabled @@ -404,6 +431,10 @@ spec: - description: Swift - Parameters related to the Swift service displayName: Swift path: swift + - description: ApplicationCredential allows service-specific overrides of the + global AC configuration. + displayName: Application Credential + path: swift.applicationCredential - description: Enabled - Whether Swift service should be deployed and managed displayName: Enabled path: swift.enabled @@ -436,6 +467,10 @@ spec: - description: TLS - overrides tls parameters for public endpoint displayName: TLS path: telemetry.aodhApiOverride.tls + - description: ApplicationCredential allows service-specific overrides of the + global AC configuration. + displayName: Application Credential + path: telemetry.applicationCredential - description: Enabled - Whether OpenStack Telemetry services should be deployed and managed displayName: Enabled diff --git a/config/operator/manager_operator_images.yaml b/config/operator/manager_operator_images.yaml index 233231e49..88d4e0280 100644 --- a/config/operator/manager_operator_images.yaml +++ b/config/operator/manager_operator_images.yaml @@ -14,13 +14,13 @@ spec: - name: operator env: - name: RELATED_IMAGE_BARBICAN_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/barbican-operator@sha256:afb66a0f8e1aa057888f7c304cc34cfea711805d9d1f05798aceb4029fef2989 + value: quay.io/rh-ee-vfisarov/barbican-operator@sha256:1f05aec969b65b3cd76e65aab15178a69f83614be9f144f7e12ef08958c707d7 - name: RELATED_IMAGE_CINDER_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/cinder-operator@sha256:174acf70c084144827fb8f96c5401a0a8def953bf0ff8929dccd629a550491b7 + value: quay.io/rh-ee-vfisarov/cinder-operator@sha256:6dbc6fffa3a85e61e27be7337347d6378bcbf6f8112fd7c03241c1031709a68e - name: RELATED_IMAGE_DESIGNATE_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/designate-operator@sha256:900050d3501c0785b227db34b89883efe68247816e5c7427cacb74f8aa10605a + value: quay.io/rh-ee-vfisarov/designate-operator@sha256:dbe04898a7d0efa106e6415a49500d48c82c805d66a6ba5e0b05e5c6be7bb349 - name: RELATED_IMAGE_GLANCE_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/glance-operator@sha256:19345236c6b6bd5ae772e336fa6065c6e94c8990d1bf05d30073ddb95ffffb4d + value: quay.io/rh-ee-vfisarov/glance-operator@sha256:c679cdb068263f410ffe74ba570d38ff022be0913452b2d6786b62ca413fd64c - name: RELATED_IMAGE_HEAT_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/heat-operator@sha256:573d7dba212cbc32101496a7cbe01e391af9891bed3bec717f16bed4d6c23e04 - name: RELATED_IMAGE_HORIZON_OPERATOR_MANAGER_IMAGE_URL @@ -28,19 +28,19 @@ spec: - name: RELATED_IMAGE_INFRA_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/infra-operator@sha256:0144c53f5c318a2a2a690f358f5574fd4c1bd580e75e738cea935f8df95e52a9 - name: RELATED_IMAGE_IRONIC_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/ironic-operator@sha256:202756538820b5fa874d07a71ece4f048f41ccca8228d359c8cd25a00e9c0848 + value: quay.io/rh-ee-vfisarov/ironic-operator@sha256:4ee446924eef2acecc5b16cc7967e518520edee1af00fd9b8a24ae8e816e9a88 - name: RELATED_IMAGE_KEYSTONE_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/keystone-operator@sha256:879d3d679b58ae84419b7907ad092ad4d24bcc9222ce621ce464fd0fea347b0c + value: quay.io/rh-ee-vfisarov/keystone-operator@sha256:b0ae0f1f2b54eb7eecdac0a526c13761be5612e60d22628cd5afc99929738530 - name: RELATED_IMAGE_MANILA_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/manila-operator@sha256:c846ab4a49272557884db6b976f979e6b9dce1aa73e5eb7872b4472f44602a1c + value: quay.io/rh-ee-vfisarov/manila-operator@sha256:57e4e2f5ccb4d2ee14c75b40c84863d7f743a0065365c3693d9eaea9a9249293 - name: RELATED_IMAGE_MARIADB_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/mariadb-operator@sha256:c10647131e6fa6afeb11ea28e513b60f22dbfbb4ddc3727850b1fe5799890c41 - name: RELATED_IMAGE_NEUTRON_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/neutron-operator@sha256:0b3fb69f35c151895d3dffd514974a9f9fe1c77c3bca69b78b81efb183cf4557 + value: quay.io/rh-ee-vfisarov/neutron-operator@sha256:9f11b3be13e3c2ae06b8c0b76068b9f275569b6413a92f766096869a58f5ee5a - name: RELATED_IMAGE_NOVA_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/nova-operator@sha256:779f0cee6024d0fb8f259b036fe790e62aa5a3b0431ea9bf15a6e7d02e2e5670 + value: quay.io/rh-ee-vfisarov/nova-operator@sha256:99182ca363816b2350137a1856187c27a56003f65bd5317baf8b1eac3fe21134 - name: RELATED_IMAGE_OCTAVIA_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/octavia-operator@sha256:d9a3694865a7d54ee96397add18c3898886e98d079aa20876a0f4de1fa7a7168 + value: quay.io/rh-ee-vfisarov/octavia-operator@sha256:9b9e69e24070625063a687803dcb03a363c3f003c7d0c8ce5786f603c3386adf - name: RELATED_IMAGE_OPENSTACK_BAREMETAL_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/openstack-baremetal-operator@sha256:5d09c9ffa6ee479724f6da786cb35902b87578365dac2035c222f5e4f752d208 - name: RELATED_IMAGE_OVN_OPERATOR_MANAGER_IMAGE_URL @@ -50,10 +50,10 @@ spec: - name: RELATED_IMAGE_RABBITMQ_CLUSTER_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/rabbitmq-cluster-operator@sha256:893e66303c1b0bc1d00a299a3f0380bad55c8dc813c8a1c6a4aab379f5aa12a2 - name: RELATED_IMAGE_SWIFT_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/swift-operator@sha256:df69e4193043476bc71d0e06ac8bc7bbd17f7b624d495aae6b7c5e5b40c9e1e7 + value: quay.io/rh-ee-vfisarov/swift-operator@sha256:58e740acb71085f5ac3783d958ce7f52c5da94c94013b691e444ac491f502632 - name: RELATED_IMAGE_TELEMETRY_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/telemetry-operator@sha256:3c1b2858c64110448d801905fbbf3ffe7f78d264cc46ab12ab2d724842dba309 + value: quay.io/rh-ee-vfisarov/telemetry-operator@sha256:e534065adf96ef04cf6ba36bb022ceab4231b8f6921d937df01542cd94ee5398 - name: RELATED_IMAGE_TEST_OPERATOR_MANAGER_IMAGE_URL value: quay.io/openstack-k8s-operators/test-operator@sha256:4e3d234c1398039c2593611f7b0fd2a6b284cafb1563e6737876a265b9af42b6 - name: RELATED_IMAGE_WATCHER_OPERATOR_MANAGER_IMAGE_URL - value: quay.io/openstack-k8s-operators/watcher-operator@sha256:f0ece9a81e4be3dbc1ff752a951970380546d8c0dea910953f862c219444b97a + value: quay.io/rh-ee-vfisarov/watcher-operator@sha256:dd378554f7f2441941c05f673f1b7b09153e9c07679995ff2daf7858d23cb32a diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 574879be7..f16b520df 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -364,6 +364,7 @@ rules: - keystone.openstack.org resources: - keystoneapis + - keystoneapplicationcredentials verbs: - create - delete @@ -372,6 +373,14 @@ rules: - patch - update - watch +- apiGroups: + - keystone.openstack.org + resources: + - keystoneapplicationcredentials/status + verbs: + - get + - patch + - update - apiGroups: - machineconfiguration.openshift.io resources: diff --git a/config/samples/applicationcredentials/kustomization.yaml b/config/samples/applicationcredentials/kustomization.yaml new file mode 100644 index 000000000..c7cbe3ecf --- /dev/null +++ b/config/samples/applicationcredentials/kustomization.yaml @@ -0,0 +1,14 @@ +resources: +- ../base/openstackcontrolplane + +patches: +- target: + kind: OpenStackControlPlane + name: .* + patch: |- + - op: replace + path: /metadata/name + value: openstack +- target: + kind: OpenStackControlPlane + path: patch.yaml diff --git a/config/samples/applicationcredentials/patch.yaml b/config/samples/applicationcredentials/patch.yaml new file mode 100644 index 000000000..566cac6f4 --- /dev/null +++ b/config/samples/applicationcredentials/patch.yaml @@ -0,0 +1,33 @@ +apiVersion: core.openstack.org/v1beta1 +kind: OpenStackControlPlane +metadata: + name: openstack +spec: + applicationCredential: + enabled: true + expirationDays: 200 + gracePeriodDays: 90 + roles: + - service + unrestricted: false + barbican: + applicationCredential: + enabled: true + glance: + applicationCredential: + enabled: true + swift: + applicationCredential: + enabled: true + cinder: + applicationCredential: + enabled: true + expirationDays: 10 + gracePeriodDays: 5 + roles: + - admin + - service + unrestricted: true + manila: + applicationCredential: + enabled: true diff --git a/go.mod b/go.mod index 1ac310113..e3887d4bd 100644 --- a/go.mod +++ b/go.mod @@ -23,8 +23,8 @@ require ( github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251206133124-593df0a7a9e1 github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20251215094837-5c05ea64c324 github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20251215094837-5c05ea64c324 - github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251215094837-5c05ea64c324 - github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251215094837-5c05ea64c324 + github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35 + github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251230215914-6ba873b49a35 github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20251215094837-5c05ea64c324 github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20251221204257-893591a14936 github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20251220223619-1df7af154c0f @@ -32,7 +32,7 @@ require ( github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20251127143706-407c63ad016a github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20251127161151-38d49bbc1c5d github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20251208195928-7a740b4f921d - github.com/openstack-k8s-operators/openstack-operator/api v0.0.0-00010101000000-000000000000 + github.com/openstack-k8s-operators/openstack-operator/api v0.0.0-20251202072739-b102924657dd github.com/openstack-k8s-operators/ovn-operator/api v0.6.1-0.20251127135801-f3d54911d811 github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.20251221210503-10057cebd870 github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20251216163659-f7a35d4fc73b @@ -95,7 +95,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c // indirect + github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.22.0 // indirect github.com/prometheus/client_model v0.6.2 // indirect @@ -181,3 +181,32 @@ replace k8s.io/code-generator => k8s.io/code-generator v0.31.14 //allow-merging replace k8s.io/component-base => k8s.io/component-base v0.31.14 //allow-merging replace github.com/cert-manager/cmctl/v2 => github.com/cert-manager/cmctl/v2 v2.1.2-0.20241127223932-88edb96860cf //allow-merging + +// appcred related changes +replace github.com/openstack-k8s-operators/keystone-operator/api => github.com/Deydra71/keystone-operator/api v0.0.0-20251211085602-3e1a3e022c81 + +replace github.com/openstack-k8s-operators/barbican-operator/api => github.com/Deydra71/barbican-operator/api v0.0.0-20260105120406-cd16c9e6c023 + +replace github.com/openstack-k8s-operators/cinder-operator/api => github.com/Deydra71/cinder-operator/api v0.0.0-20260106135056-ef7e3d21d620 + +replace github.com/openstack-k8s-operators/glance-operator/api => github.com/Deydra71/glance-operator/api v0.0.0-20260106132908-e6b383a95445 + +replace github.com/openstack-k8s-operators/swift-operator/api => github.com/Deydra71/swift-operator/api v0.0.0-20260105162410-2dc80b80c1d3 + +replace github.com/openstack-k8s-operators/manila-operator/api => github.com/Deydra71/manila-operator/api v0.0.0-20260106132024-e9a579fe2ec3 + +replace github.com/openstack-k8s-operators/neutron-operator/api => github.com/Deydra71/neutron-operator/api v0.0.0-20260106090547-e9be79e62157 + +replace github.com/openstack-k8s-operators/placement-operator/api => github.com/Deydra71/placement-operator/api v0.0.0-20260106090624-7345b8864eff + +replace github.com/openstack-k8s-operators/designate-operator/api => github.com/Deydra71/designate-operator/api v0.0.0-20260106092847-c5f4cd0c39e1 + +replace github.com/openstack-k8s-operators/octavia-operator/api => github.com/Deydra71/octavia-operator/api v0.0.0-20260106083332-ef07326114ea + +replace github.com/openstack-k8s-operators/ironic-operator/api => github.com/Deydra71/ironic-operator/api v0.0.0-20260106103928-10e4d4748f3b + +replace github.com/openstack-k8s-operators/watcher-operator/api => github.com/Deydra71/watcher-operator/api v0.0.0-20260106131110-a22b12b025f0 + +replace github.com/openstack-k8s-operators/nova-operator/api => github.com/Deydra71/nova-operator/api v0.0.0-20260107124553-d177db8d08f2 + +replace github.com/openstack-k8s-operators/telemetry-operator/api => github.com/Deydra71/telemetry-operator/api v0.0.0-20260108092627-ce6f6b9c8b67 diff --git a/go.sum b/go.sum index cedbb7f2a..b1b745e86 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,31 @@ +github.com/Deydra71/barbican-operator/api v0.0.0-20260105120406-cd16c9e6c023 h1:Ik9FduqUis0KrlSgynUsYHkmGCOO4G6Vf78+HHnAtk0= +github.com/Deydra71/barbican-operator/api v0.0.0-20260105120406-cd16c9e6c023/go.mod h1:seOuEXaQVmfi9kZwRBXPDlyOi4TLfZFA0FYkIJ8QfjA= +github.com/Deydra71/cinder-operator/api v0.0.0-20260106135056-ef7e3d21d620 h1:sbzYnqoAURmBRWOBKKaFtKX0/+Y/33I9QiaMqEXVuYM= +github.com/Deydra71/cinder-operator/api v0.0.0-20260106135056-ef7e3d21d620/go.mod h1:u0l66SzHNcyF3S37TqBM6CnHXk5rSBFV2Mv3zMIGJwk= +github.com/Deydra71/designate-operator/api v0.0.0-20260106092847-c5f4cd0c39e1 h1:R6uqPS30Z1rWRol2Zts3P75+sIKQQ6vLs0tLT3gEpMU= +github.com/Deydra71/designate-operator/api v0.0.0-20260106092847-c5f4cd0c39e1/go.mod h1:ozik5YG2mnPbTQFNUgQIKHYZlB1aBJbnnkTu6vYxRi4= +github.com/Deydra71/glance-operator/api v0.0.0-20260106132908-e6b383a95445 h1:zbCJBq0cUBX5MAOP1kvT1WI8Do+Jnwo+QZCI56wFhSE= +github.com/Deydra71/glance-operator/api v0.0.0-20260106132908-e6b383a95445/go.mod h1:w+Z144Db80ES7gnBiFjGNnvSz+deiR2QDC+1WT2agi8= +github.com/Deydra71/ironic-operator/api v0.0.0-20260106103928-10e4d4748f3b h1:QDLQLt5vsikU4rDnGZyWj71TA4HCGobO4fNzOEY6E4Y= +github.com/Deydra71/ironic-operator/api v0.0.0-20260106103928-10e4d4748f3b/go.mod h1:5i8Xsdz+zap3XTX+iYasugR3odQH7ncL26WLUZoUAC8= +github.com/Deydra71/keystone-operator/api v0.0.0-20251211085602-3e1a3e022c81 h1:plax+NFgJJL1SrERyXAnf3jOHRhLTtBlJ2oc7d84EoU= +github.com/Deydra71/keystone-operator/api v0.0.0-20251211085602-3e1a3e022c81/go.mod h1:b98Jl8eyUw8V07l9YiuQnoMlnWC748oV8IhXH15NCC4= +github.com/Deydra71/manila-operator/api v0.0.0-20260106132024-e9a579fe2ec3 h1:HXKCRDPrt1U+gnyQpnG/Xr59qNm/uJzzb9foTJetnMI= +github.com/Deydra71/manila-operator/api v0.0.0-20260106132024-e9a579fe2ec3/go.mod h1:AqmHzvPpw7rFZRrk0LhorvWrz3goYUZ+8Pl5XHlGgh0= +github.com/Deydra71/neutron-operator/api v0.0.0-20260106090547-e9be79e62157 h1:nKE7ANvJna28s/Y3NqgqSHQUn9M1Gs50BXoUoWop4eo= +github.com/Deydra71/neutron-operator/api v0.0.0-20260106090547-e9be79e62157/go.mod h1:nL79n4965jUc1qLiQH1sFQtAhW1evP9QVx0836nB8xY= +github.com/Deydra71/nova-operator/api v0.0.0-20260107124553-d177db8d08f2 h1:DcSJOSfT21/w+yw61pzMbs0DHS6nNaXkgxkPEEiu7iU= +github.com/Deydra71/nova-operator/api v0.0.0-20260107124553-d177db8d08f2/go.mod h1:cEcrQYhrsYxeJPjtVhbsP+txnPTnaMwfgCwU4cUhQUs= +github.com/Deydra71/octavia-operator/api v0.0.0-20260106083332-ef07326114ea h1:Dg6nudjwf76XyKm6FnFgvMbzShXtY6sInedjlNsjEj0= +github.com/Deydra71/octavia-operator/api v0.0.0-20260106083332-ef07326114ea/go.mod h1:u3FFVWvV6nr5YAqpR6PDyc4UaQBgIS2RgN236utT20c= +github.com/Deydra71/placement-operator/api v0.0.0-20260106090624-7345b8864eff h1:Vbo8d4wCEFx3VKLBkiMBkRC/f3ed1CdtJfE7wZYsfgQ= +github.com/Deydra71/placement-operator/api v0.0.0-20260106090624-7345b8864eff/go.mod h1:CFYEdbpNfT9tWcWEiHzhln20yDWW1vBHIwge6+TNzmg= +github.com/Deydra71/swift-operator/api v0.0.0-20260105162410-2dc80b80c1d3 h1:GS0/evvACfp2xMOcQz7vte48iHvVxiX92WIMk6Iazew= +github.com/Deydra71/swift-operator/api v0.0.0-20260105162410-2dc80b80c1d3/go.mod h1:V/V7rgrkHQRyAJ+6NQvRjpIlIMSNC9Z6F4DkOfudCqU= +github.com/Deydra71/telemetry-operator/api v0.0.0-20260108092627-ce6f6b9c8b67 h1:CMqN7K1xMbuw80rPWtvf4436+Z8KzmLm7u0JxIaAuhk= +github.com/Deydra71/telemetry-operator/api v0.0.0-20260108092627-ce6f6b9c8b67/go.mod h1:1qz65mvwqq+Gzw/7LfUUt9eaIt2uGt4N4WPtVVCpljU= +github.com/Deydra71/watcher-operator/api v0.0.0-20260106131110-a22b12b025f0 h1:kPJsgn69Y8uzLDPrv5WuThvwsClM06aT2gvugyX8Hp4= +github.com/Deydra71/watcher-operator/api v0.0.0-20260106131110-a22b12b025f0/go.mod h1:SwQTKMUQyKGsZU9YMQUZUGSRC9pIn69bAjw4kE+C1v4= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= @@ -138,62 +166,34 @@ github.com/onsi/gomega v1.38.3 h1:eTX+W6dobAYfFeGC2PV6RwXRu/MyT+cQguijutvkpSM= github.com/onsi/gomega v1.38.3/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e h1:E1OdwSpqWuDPCedyUt0GEdoAE+r5TXy7YS21yNEo+2U= github.com/openshift/api v0.0.0-20250711200046-c86d80652a9e/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo= -github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20251220125032-e46717ca376e h1:ti957EW6UzQ1cph7wAIQ9dBmKYFxFSKzS9KwJ2INkFE= -github.com/openstack-k8s-operators/barbican-operator/api v0.6.1-0.20251220125032-e46717ca376e/go.mod h1:MdPtO0nOFQuGLKWytPp26prN1143xgxY/kAUTq0v4JY= -github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20251221204540-9ad70f8debbc h1:1kDkoDnmDalpSBo2co66oU87zegZllcceadKVx7rOA8= -github.com/openstack-k8s-operators/cinder-operator/api v0.6.1-0.20251221204540-9ad70f8debbc/go.mod h1:mprD4SL1ZfsjJR2Xx6D5TOqOFSF3tlj1wqXWfrgbtCA= -github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20251203145024-0f6b7a8e7dc5 h1:iUSQ+Goc3KAjL+H41mf1Dqi+L8cxvTU3ooFESVSyDZw= -github.com/openstack-k8s-operators/designate-operator/api v0.6.1-0.20251203145024-0f6b7a8e7dc5/go.mod h1:n5EzCMhTH/Y0YmTMrOpLUyaE94N183c6kNI8oOWsHsk= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20251221170241-a5482a4f039a h1:oMCXa+XDudWYcEYp8EeuYlUoAvkvxokS3x+rWRqzQ4M= -github.com/openstack-k8s-operators/glance-operator/api v0.6.1-0.20251221170241-a5482a4f039a/go.mod h1:uV5Lb1kLculjXy+sXdKhR2Y1E12Hzm5qV7uQqFKy3wA= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20251213170654-5ce22bc3a2e9 h1:GkcnBLnq19MQUO6VCpKWrpCGEAxiHAl/OPIK/tmguWo= github.com/openstack-k8s-operators/heat-operator/api v0.6.1-0.20251213170654-5ce22bc3a2e9/go.mod h1:D3sHyJnr9aHyvj0Nvyvs48V3xaIHT7ZOuGr/1Nfrd/I= github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20251213062730-e339ac2f2851 h1:EfKq1oxaNVAkdz7vGyrvFKUA6juw9uLEI9ZPulIyCWU= github.com/openstack-k8s-operators/horizon-operator/api v0.6.1-0.20251213062730-e339ac2f2851/go.mod h1:0nsIeghZDuEgBfsT1Rlik+ZLBRsXoVrni2pTMP++OV0= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251223124749-eedb97238c5f h1:xcCGJ/g5vvbWhtEJCbv8UeBneI5yrMawm+CXRsJrJZo= github.com/openstack-k8s-operators/infra-operator/apis v0.6.1-0.20251223124749-eedb97238c5f/go.mod h1:ex8ou6/3ms6ovR+CMXD6XhTlNakm1GhB6UZgagVRNW8= -github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20251213181601-3669e9f88d07 h1:/jgYdfRLuROq2D3DPDDbyrZKnv99nKRfo7+uo64s68c= -github.com/openstack-k8s-operators/ironic-operator/api v0.6.1-0.20251213181601-3669e9f88d07/go.mod h1:Vk2hhKu65d5OP+Xw5eo0L1bRiTjiMg7wHzY+3xs4mH8= -github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251206133124-593df0a7a9e1 h1:qcgbrF9c0axkaDcFGfIA2wGz8bkaxPuXHj3mdKAyz6M= -github.com/openstack-k8s-operators/keystone-operator/api v0.6.1-0.20251206133124-593df0a7a9e1/go.mod h1:0XsZ6Fc4hTV6a/BBP8+jiH8LR+IP5z9aStdPTDHALNk= github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20251215094837-5c05ea64c324 h1:erFyZoCaLBcDfEmuILVQcRC1IA1Q43oKMWZ/kkquQZ0= github.com/openstack-k8s-operators/lib-common/modules/ansible v0.6.1-0.20251215094837-5c05ea64c324/go.mod h1:tXxVkkk8HlATwTmDA5RTP3b+c8apfuMM15mZ2wW5iNs= github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20251215094837-5c05ea64c324 h1:YCi8k03hjF/mUwt5GLf5CxBYNuMzY9wVOpyIWWdaLZk= github.com/openstack-k8s-operators/lib-common/modules/certmanager v0.6.1-0.20251215094837-5c05ea64c324/go.mod h1:3zDlaWh4PKwFAhYM6zcKe+bAnCggnSB94v4unP4snUM= -github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251215094837-5c05ea64c324 h1:y2awFehe8MS5YC47UAdmSSBp7qUSq61uWGWPjWEGaRc= -github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251215094837-5c05ea64c324/go.mod h1:+Me0raWPPdz8gRi9D4z1khmvUgS9vIKAVC8ckg1yJZU= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c h1:l7FO+XoQRnD4aT5p/JXVY2uezQLdC7D50KrwrTmzCfg= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251122131503-b76943960b6c/go.mod h1:zOX7Y05keiSppIvLabuyh42QHBMhCcoskAtxFRbwXKo= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251215094837-5c05ea64c324 h1:wOGJEAhvP0NFW4zQmOZj4bYtL4Bi83sdobQR69yQNDA= -github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251215094837-5c05ea64c324/go.mod h1:fy1lvz3uuzzh01DKKdgroXvmJgMpJBsvl2r9eTtAll0= +github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35 h1:pF3mJ3nwq6r4qwom+rEWZNquZpcQW/iftHlJ1KPIDsk= +github.com/openstack-k8s-operators/lib-common/modules/common v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:kycZyoe7OZdW1HUghr2nI3N7wSJtNahXf6b/ypD14f4= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35 h1:IdcI8DFvW8rXtchONSzbDmhhRp1YyO2YaBJDBXr44Gk= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:zOX7Y05keiSppIvLabuyh42QHBMhCcoskAtxFRbwXKo= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251230215914-6ba873b49a35 h1:8WZYfCt1VJHa5sJRX0UhpmoXud/fn8LHQhXsakdYXuQ= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.6.1-0.20251230215914-6ba873b49a35/go.mod h1:H0aQANk8iJPRhS2Bg9n6cYb/IHF0Cks9g7+uZG04Rhk= github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20251215094837-5c05ea64c324 h1:yNEmgZjWER+W7TL1QNu7uAD4lNfnvOC5zyePP93sjlk= github.com/openstack-k8s-operators/lib-common/modules/test v0.6.1-0.20251215094837-5c05ea64c324/go.mod h1:lgYyrXEYA2BPsq4Kg6dqa+QsHgOjMPyOsEYrvyYW3jk= -github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20251221204257-893591a14936 h1:Hrnk4XmU8lMhz8zpdxeWL+HFrpBMIH738umK/lnf5CY= -github.com/openstack-k8s-operators/manila-operator/api v0.6.1-0.20251221204257-893591a14936/go.mod h1:wBGm6B4bt8SyFmt2TjjCfhWilMPHCxeQFotJCaeJY2M= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20251220223619-1df7af154c0f h1:Lrt+Bo/mTncK8kdd+hT1o/X6oCGl2uUMdBe+X3lrKrk= github.com/openstack-k8s-operators/mariadb-operator/api v0.6.1-0.20251220223619-1df7af154c0f/go.mod h1:KbToF6BJ5oO1/MapNRhMHED/C/OGfCPMXmIJm/G3tLg= -github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20251125150830-633e42336356 h1:YPD0uZZ3fbEfbo/HOGi/5AK+BrFC3bErg0OBJyZyRUg= -github.com/openstack-k8s-operators/neutron-operator/api v0.6.1-0.20251125150830-633e42336356/go.mod h1:CNJF0ekxqVqrEMLGL/hV489p0RrVoB3alMhjE9cxv1o= -github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20251127143706-407c63ad016a h1:lYmks3cHkbmBX1+I9a8gnajkfSddLAvNqakxx8GV3AA= -github.com/openstack-k8s-operators/nova-operator/api v0.6.1-0.20251127143706-407c63ad016a/go.mod h1:4Bp2ias9AUXvPBOSOlEkuuegDkAcJEYB9K1UtmX4q8c= -github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20251127161151-38d49bbc1c5d h1:MrDtVqdSNQpl+3ttzzbvDx/83ZQJ5ArUGcy+XJQQcic= -github.com/openstack-k8s-operators/octavia-operator/api v0.6.1-0.20251127161151-38d49bbc1c5d/go.mod h1:rI8CZdEfQB+QRBR3uFmA2i/D9KxTNTTZWFH3MhpID5A= github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20251208195928-7a740b4f921d h1:vBmv0vvDVf5/V0bZUoed2TNQ+t0Z0ExPZgUyWLoXDw4= github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.6.1-0.20251208195928-7a740b4f921d/go.mod h1:IguVL02aJlDXM9zRvSdZfcOL5aMsF3/YH5ywX6sUoNk= github.com/openstack-k8s-operators/ovn-operator/api v0.6.1-0.20251127135801-f3d54911d811 h1:H1b2RlE9EsemU/dbtV96xIXxmGBLS2UcBtdSS0bYucw= github.com/openstack-k8s-operators/ovn-operator/api v0.6.1-0.20251127135801-f3d54911d811/go.mod h1:LTrCp/cf4HFozb0ZhblhQKO0jUmmBnvD8zFocOsasAM= -github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.20251221210503-10057cebd870 h1:4uFkEf7fCuvg8B/geMrX5mSYRgVCOufpVTuEZBBAjco= -github.com/openstack-k8s-operators/placement-operator/api v0.6.1-0.20251221210503-10057cebd870/go.mod h1:IjNQ8O/dBcmPp30rA5vltBiGTTNQj1lkpfRAvSMbeDg= github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec h1:saovr368HPAKHN0aRPh8h8n9s9dn3d8Frmfua0UYRlc= github.com/openstack-k8s-operators/rabbitmq-cluster-operator/v2 v2.6.1-0.20250929174222-a0d328fa4dec/go.mod h1:Nh2NEePLjovUQof2krTAg4JaAoLacqtPTZQXK6izNfg= -github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20251216163659-f7a35d4fc73b h1:tDir+gLX8xuqL9ZHY4nza4i3SFqzvrsXtP4MP3sXdas= -github.com/openstack-k8s-operators/swift-operator/api v0.6.1-0.20251216163659-f7a35d4fc73b/go.mod h1:PXyt1tiqjYflYZ+ol2cAe3B7WM1uHr/ZxUCQKAzboxk= -github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20251222143830-69bf8ba39dff h1:BSopHIzA10ORyp+TNdNbFvsSfkj99DC7ZZv95xjLdck= -github.com/openstack-k8s-operators/telemetry-operator/api v0.6.1-0.20251222143830-69bf8ba39dff/go.mod h1:JZi2/dRupf7GVitj8JY3qI34WC4MZKf7zs6Rq9W7yBQ= github.com/openstack-k8s-operators/test-operator/api v0.6.1-0.20251220223050-cc44551aa6e9 h1:GvysIvrxBdCTnNZxsWz6eDVLDM/DMaXkFL6xY/fXciU= github.com/openstack-k8s-operators/test-operator/api v0.6.1-0.20251220223050-cc44551aa6e9/go.mod h1:U+zhsnBhMbC42Xt4ptV3HPVgItI7i5tgPvwlauxgXPE= -github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20251222122818-fc7387823d0b h1:MtwGWQtSnK36Lq/uRJDV0REPlR8y5HKoW698eVtZeuA= -github.com/openstack-k8s-operators/watcher-operator/api v0.6.1-0.20251222122818-fc7387823d0b/go.mod h1:eiSdCn8z13oksg5az+Qaj9Mb3+Qgj8XA9GLpZ6IbiJo= 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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/hack/export_operator_related_images.sh b/hack/export_operator_related_images.sh index 1d931e174..b106ed8c1 100644 --- a/hack/export_operator_related_images.sh +++ b/hack/export_operator_related_images.sh @@ -1,24 +1,24 @@ # NOTE: this file is automatically generated by hack/sync-bindata.sh! -export RELATED_IMAGE_BARBICAN_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/barbican-operator@sha256:afb66a0f8e1aa057888f7c304cc34cfea711805d9d1f05798aceb4029fef2989 -export RELATED_IMAGE_CINDER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/cinder-operator@sha256:174acf70c084144827fb8f96c5401a0a8def953bf0ff8929dccd629a550491b7 -export RELATED_IMAGE_DESIGNATE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/designate-operator@sha256:900050d3501c0785b227db34b89883efe68247816e5c7427cacb74f8aa10605a -export RELATED_IMAGE_GLANCE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/glance-operator@sha256:19345236c6b6bd5ae772e336fa6065c6e94c8990d1bf05d30073ddb95ffffb4d +export RELATED_IMAGE_BARBICAN_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/barbican-operator@sha256:1f05aec969b65b3cd76e65aab15178a69f83614be9f144f7e12ef08958c707d7 +export RELATED_IMAGE_CINDER_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/cinder-operator@sha256:6dbc6fffa3a85e61e27be7337347d6378bcbf6f8112fd7c03241c1031709a68e +export RELATED_IMAGE_DESIGNATE_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/designate-operator@sha256:dbe04898a7d0efa106e6415a49500d48c82c805d66a6ba5e0b05e5c6be7bb349 +export RELATED_IMAGE_GLANCE_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/glance-operator@sha256:c679cdb068263f410ffe74ba570d38ff022be0913452b2d6786b62ca413fd64c export RELATED_IMAGE_HEAT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/heat-operator@sha256:573d7dba212cbc32101496a7cbe01e391af9891bed3bec717f16bed4d6c23e04 export RELATED_IMAGE_HORIZON_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/horizon-operator@sha256:b7111c690e8fda3cb0c5969bcfa68308907fd0cf05f73ecdcb9ac1423aa7bba3 export RELATED_IMAGE_INFRA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/infra-operator@sha256:0144c53f5c318a2a2a690f358f5574fd4c1bd580e75e738cea935f8df95e52a9 -export RELATED_IMAGE_IRONIC_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/ironic-operator@sha256:202756538820b5fa874d07a71ece4f048f41ccca8228d359c8cd25a00e9c0848 -export RELATED_IMAGE_KEYSTONE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/keystone-operator@sha256:879d3d679b58ae84419b7907ad092ad4d24bcc9222ce621ce464fd0fea347b0c -export RELATED_IMAGE_MANILA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/manila-operator@sha256:c846ab4a49272557884db6b976f979e6b9dce1aa73e5eb7872b4472f44602a1c +export RELATED_IMAGE_IRONIC_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/ironic-operator@sha256:4ee446924eef2acecc5b16cc7967e518520edee1af00fd9b8a24ae8e816e9a88 +export RELATED_IMAGE_KEYSTONE_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/keystone-operator@sha256:b0ae0f1f2b54eb7eecdac0a526c13761be5612e60d22628cd5afc99929738530 +export RELATED_IMAGE_MANILA_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/manila-operator@sha256:57e4e2f5ccb4d2ee14c75b40c84863d7f743a0065365c3693d9eaea9a9249293 export RELATED_IMAGE_MARIADB_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/mariadb-operator@sha256:c10647131e6fa6afeb11ea28e513b60f22dbfbb4ddc3727850b1fe5799890c41 -export RELATED_IMAGE_NEUTRON_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/neutron-operator@sha256:0b3fb69f35c151895d3dffd514974a9f9fe1c77c3bca69b78b81efb183cf4557 -export RELATED_IMAGE_NOVA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/nova-operator@sha256:779f0cee6024d0fb8f259b036fe790e62aa5a3b0431ea9bf15a6e7d02e2e5670 -export RELATED_IMAGE_OCTAVIA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/octavia-operator@sha256:d9a3694865a7d54ee96397add18c3898886e98d079aa20876a0f4de1fa7a7168 -export RELATED_IMAGE_OPENSTACK_BAREMETAL_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/openstack-baremetal-operator@sha256:5d09c9ffa6ee479724f6da786cb35902b87578365dac2035c222f5e4f752d208 +export RELATED_IMAGE_NEUTRON_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/neutron-operator@sha256:9f11b3be13e3c2ae06b8c0b76068b9f275569b6413a92f766096869a58f5ee5a +export RELATED_IMAGE_NOVA_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/nova-operator@sha256:99182ca363816b2350137a1856187c27a56003f65bd5317baf8b1eac3fe21134 +export RELATED_IMAGE_OCTAVIA_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/octavia-operator@sha256:9b9e69e24070625063a687803dcb03a363c3f003c7d0c8ce5786f603c3386adf +export RELATED_IMAGE_OPENSTACK_BAREMETAL_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/openstack-baremetal-operator@sha256:14cfad6ea2e7f7ecc4cb2aafceb9c61514b3d04b66668832d1e4ac3b19f1ab81 export RELATED_IMAGE_OVN_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/ovn-operator@sha256:635a4aef9d6f0b799e8ec91333dbb312160c001d05b3c63f614c124e0b67cb59 export RELATED_IMAGE_PLACEMENT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/placement-operator@sha256:1b684c4ca525a279deee45980140d895e264526c5c7e0a6981d6fae6cbcaa420 export RELATED_IMAGE_RABBITMQ_CLUSTER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/rabbitmq-cluster-operator@sha256:893e66303c1b0bc1d00a299a3f0380bad55c8dc813c8a1c6a4aab379f5aa12a2 -export RELATED_IMAGE_SWIFT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/swift-operator@sha256:df69e4193043476bc71d0e06ac8bc7bbd17f7b624d495aae6b7c5e5b40c9e1e7 -export RELATED_IMAGE_TELEMETRY_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/telemetry-operator@sha256:3c1b2858c64110448d801905fbbf3ffe7f78d264cc46ab12ab2d724842dba309 -export RELATED_IMAGE_TEST_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/test-operator@sha256:4e3d234c1398039c2593611f7b0fd2a6b284cafb1563e6737876a265b9af42b6 -export RELATED_IMAGE_WATCHER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/watcher-operator@sha256:f0ece9a81e4be3dbc1ff752a951970380546d8c0dea910953f862c219444b97a +export RELATED_IMAGE_SWIFT_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/swift-operator@sha256:58e740acb71085f5ac3783d958ce7f52c5da94c94013b691e444ac491f502632 +export RELATED_IMAGE_TELEMETRY_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/telemetry-operator@sha256:e534065adf96ef04cf6ba36bb022ceab4231b8f6921d937df01542cd94ee5398 +export RELATED_IMAGE_TEST_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/test-operator@sha256:101b3e007d8c9f2e183262d7712f986ad51256448099069bc14f1ea5f997ab94 +export RELATED_IMAGE_WATCHER_OPERATOR_MANAGER_IMAGE_URL=quay.io/rh-ee-vfisarov/watcher-operator@sha256:dd378554f7f2441941c05f673f1b7b09153e9c07679995ff2daf7858d23cb32a diff --git a/internal/controller/core/openstackcontrolplane_controller.go b/internal/controller/core/openstackcontrolplane_controller.go index 909316acb..30fbcbc2d 100644 --- a/internal/controller/core/openstackcontrolplane_controller.go +++ b/internal/controller/core/openstackcontrolplane_controller.go @@ -92,6 +92,8 @@ func (r *OpenStackControlPlaneReconciler) GetLogger(ctx context.Context) logr.Lo // +kubebuilder:rbac:groups=client.openstack.org,resources=openstackclients,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=horizon.openstack.org,resources=horizons,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapis,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapplicationcredentials,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapplicationcredentials/status,verbs=get;patch;update // +kubebuilder:rbac:groups=placement.openstack.org,resources=placementapis,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=glance.openstack.org,resources=glances,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=heat.openstack.org,resources=heats,verbs=get;list;watch;create;update;patch;delete @@ -597,6 +599,13 @@ func (r *OpenStackControlPlaneReconciler) reconcileNormal(ctx context.Context, i instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneCertCleanupReadyCondition) + ctrlResult, err = openstack.ReconcileApplicationCredentials(ctx, instance, version, helper) + if err != nil { + return ctrl.Result{}, err + } else if (ctrlResult != ctrl.Result{}) { + return ctrlResult, nil + } + return ctrl.Result{}, nil } @@ -705,6 +714,7 @@ func (r *OpenStackControlPlaneReconciler) SetupWithManager( Owns(&mariadbv1.Galera{}). Owns(&memcachedv1.Memcached{}). Owns(&keystonev1.KeystoneAPI{}). + Owns(&keystonev1.KeystoneApplicationCredential{}). Owns(&placementv1.PlacementAPI{}). Owns(&glancev1.Glance{}). Owns(&cinderv1.Cinder{}). diff --git a/internal/openstack/applicationcredential.go b/internal/openstack/applicationcredential.go new file mode 100644 index 000000000..141e45d50 --- /dev/null +++ b/internal/openstack/applicationcredential.go @@ -0,0 +1,430 @@ +package openstack + +import ( + "context" + "fmt" + + keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" + "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/api/core/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +// ServiceUserConfig defines a single user for a service that needs an ApplicationCredential +type ServiceUserConfig struct { + UserName string + PasswordSelector string + Suffix string // For services that have multiple keystone service users (ironic) +} + +// servicesWithMultipleUsers defines services that have multiple Keystone users +// The function returns nil if the service is not enabled or template is not initialized +var servicesWithMultipleUsers = map[string]func(*corev1beta1.OpenStackControlPlane) []ServiceUserConfig{ + "heat": func(instance *corev1beta1.OpenStackControlPlane) []ServiceUserConfig { + if !instance.Spec.Heat.Enabled || instance.Spec.Heat.Template == nil { + return nil + } + // Note: heat_stack_domain_admin is excluded from app cred support + // as it requires special handling for domain-scoped authentication + return []ServiceUserConfig{ + { + UserName: instance.Spec.Heat.Template.ServiceUser, + PasswordSelector: instance.Spec.Heat.Template.PasswordSelectors.Service, + Suffix: "", // Main service, no suffix -> "ac-heat" + }, + } + }, + "ironic": func(instance *corev1beta1.OpenStackControlPlane) []ServiceUserConfig { + if !instance.Spec.Ironic.Enabled || instance.Spec.Ironic.Template == nil { + return nil + } + return []ServiceUserConfig{ + { + UserName: instance.Spec.Ironic.Template.ServiceUser, + PasswordSelector: instance.Spec.Ironic.Template.PasswordSelectors.Service, + Suffix: "", // Main service, no suffix -> "ac-ironic" + }, + { + UserName: instance.Spec.Ironic.Template.IronicInspector.ServiceUser, + PasswordSelector: instance.Spec.Ironic.Template.IronicInspector.PasswordSelectors.Service, + Suffix: "inspector", // -> "ac-ironic-inspector" + }, + } + }, +} + +// mergeAppCred returns a new ApplicationCredentialSection by overlaying +// service-specific values on top of the global defaults. +func mergeAppCred( + global corev1beta1.ApplicationCredentialSection, + svc *corev1beta1.ServiceAppCredSection, +) corev1beta1.ApplicationCredentialSection { + out := global + if svc != nil { + out.Enabled = svc.Enabled + + // only override expiry/grace if specified + if svc.ExpirationDays != nil { + out.ExpirationDays = svc.ExpirationDays + } + if svc.GracePeriodDays != nil { + out.GracePeriodDays = svc.GracePeriodDays + } + + // only override Roles if user set them + if len(svc.Roles) > 0 { + out.Roles = svc.Roles + } + // only override Unrestricted if user set it + if svc.Unrestricted != nil { + out.Unrestricted = svc.Unrestricted + } + // only override AccessRules if user set them + if len(svc.AccessRules) > 0 { + out.AccessRules = svc.AccessRules + } + } + + return out +} + +// ReconcileApplicationCredentials ensures an AC CR per enabled service, +// propagating its secret name, passwordSelector, and serviceUser fields. +func ReconcileApplicationCredentials( + ctx context.Context, + instance *corev1beta1.OpenStackControlPlane, + _ *corev1beta1.OpenStackVersion, + helper *helper.Helper, +) (ctrl.Result, error) { + log := GetLogger(ctx) + + // If global disabled, delete all ACs: + if !instance.Spec.ApplicationCredential.Enabled { + log.Info("Global AC disabled; deleting per-service AC CRs") + for _, svc := range []string{"glance", "nova", "swift", "ceilometer", "barbican", "cinder", "placement", "neutron", "ironic", "heat", "octavia", "manila", "designate", "watcher", "aodh", "cloudkitty"} { + if res, err := deleteServiceACs(ctx, helper, instance, svc); err != nil { + return res, err + } + } + return ctrl.Result{}, nil + } + + // Type definition for service AC configuration + type svcAC struct { + Key string + Enabled bool + ACSection *corev1beta1.ServiceAppCredSection + } + + // Collect each service's enabled flag and AC section + svcs := []svcAC{ + {"glance", instance.Spec.Glance.Enabled, instance.Spec.Glance.ApplicationCredential}, + {"nova", instance.Spec.Nova.Enabled, instance.Spec.Nova.ApplicationCredential}, + {"swift", instance.Spec.Swift.Enabled, instance.Spec.Swift.ApplicationCredential}, + {"ceilometer", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialCeilometer}, + {"barbican", instance.Spec.Barbican.Enabled, instance.Spec.Barbican.ApplicationCredential}, + {"cinder", instance.Spec.Cinder.Enabled, instance.Spec.Cinder.ApplicationCredential}, + {"placement", instance.Spec.Placement.Enabled, instance.Spec.Placement.ApplicationCredential}, + {"neutron", instance.Spec.Neutron.Enabled, instance.Spec.Neutron.ApplicationCredential}, + {"ironic", instance.Spec.Ironic.Enabled, instance.Spec.Ironic.ApplicationCredential}, + {"heat", instance.Spec.Heat.Enabled, instance.Spec.Heat.ApplicationCredential}, + {"octavia", instance.Spec.Octavia.Enabled, instance.Spec.Octavia.ApplicationCredential}, + {"manila", instance.Spec.Manila.Enabled, instance.Spec.Manila.ApplicationCredential}, + {"designate", instance.Spec.Designate.Enabled, instance.Spec.Designate.ApplicationCredential}, + {"watcher", instance.Spec.Watcher.Enabled, instance.Spec.Watcher.ApplicationCredential}, + {"aodh", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialAodh}, + {"cloudkitty", instance.Spec.Telemetry.Enabled, instance.Spec.Telemetry.ApplicationCredentialCloudKitty}, + } + global := instance.Spec.ApplicationCredential + + // Helper functions to safely access Watcher's pointer fields + getWatcherSecret := func() string { + if instance.Spec.Watcher.Template != nil && instance.Spec.Watcher.Template.Secret != nil { + return *instance.Spec.Watcher.Template.Secret + } + return "" + } + getWatcherServiceUser := func() string { + if instance.Spec.Watcher.Template != nil && instance.Spec.Watcher.Template.ServiceUser != nil { + return *instance.Spec.Watcher.Template.ServiceUser + } + return "" + } + getWatcherPasswordSelector := func() string { + if instance.Spec.Watcher.Template != nil && + instance.Spec.Watcher.Template.PasswordSelectors.Service != nil { + return *instance.Spec.Watcher.Template.PasswordSelectors.Service + } + return "" + } + + // getServiceInfo retrieves service info from Template + // When service is enabled, webhook ensures Template is initialized with defaults + // This function is only called after verifying service is enabled + getServiceInfo := func(key string) struct { + SecretName string + PasswordSelector string + ServiceUser string + } { + var secretName, passwordSelector, serviceUser string + + switch key { + case "glance": + secretName = instance.Spec.Glance.Template.Secret + passwordSelector = instance.Spec.Glance.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Glance.Template.ServiceUser + case "nova": + secretName = instance.Spec.Nova.Template.Secret + passwordSelector = instance.Spec.Nova.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Nova.Template.ServiceUser + case "swift": + secretName = instance.Spec.Swift.Template.SwiftProxy.Secret + passwordSelector = instance.Spec.Swift.Template.SwiftProxy.PasswordSelectors.Service + serviceUser = instance.Spec.Swift.Template.SwiftProxy.ServiceUser + case "ceilometer": + secretName = instance.Spec.Telemetry.Template.Ceilometer.Secret + passwordSelector = instance.Spec.Telemetry.Template.Ceilometer.PasswordSelectors.CeilometerService + serviceUser = instance.Spec.Telemetry.Template.Ceilometer.ServiceUser + case "barbican": + secretName = instance.Spec.Barbican.Template.Secret + passwordSelector = instance.Spec.Barbican.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Barbican.Template.ServiceUser + case "cinder": + secretName = instance.Spec.Cinder.Template.Secret + passwordSelector = instance.Spec.Cinder.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Cinder.Template.ServiceUser + case "placement": + secretName = instance.Spec.Placement.Template.Secret + passwordSelector = instance.Spec.Placement.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Placement.Template.ServiceUser + case "neutron": + secretName = instance.Spec.Neutron.Template.Secret + passwordSelector = instance.Spec.Neutron.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Neutron.Template.ServiceUser + case "ironic": + secretName = instance.Spec.Ironic.Template.Secret + passwordSelector = instance.Spec.Ironic.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Ironic.Template.ServiceUser + case "heat": + secretName = instance.Spec.Heat.Template.Secret + passwordSelector = instance.Spec.Heat.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Heat.Template.ServiceUser + case "octavia": + secretName = instance.Spec.Octavia.Template.Secret + passwordSelector = instance.Spec.Octavia.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Octavia.Template.ServiceUser + case "manila": + secretName = instance.Spec.Manila.Template.Secret + passwordSelector = instance.Spec.Manila.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Manila.Template.ServiceUser + case "designate": + secretName = instance.Spec.Designate.Template.Secret + passwordSelector = instance.Spec.Designate.Template.PasswordSelectors.Service + serviceUser = instance.Spec.Designate.Template.ServiceUser + case "watcher": + secretName = getWatcherSecret() + passwordSelector = getWatcherPasswordSelector() + serviceUser = getWatcherServiceUser() + case "aodh": + secretName = instance.Spec.Telemetry.Template.Autoscaling.Aodh.Secret + passwordSelector = instance.Spec.Telemetry.Template.Autoscaling.Aodh.PasswordSelectors.AodhService + serviceUser = instance.Spec.Telemetry.Template.Autoscaling.Aodh.ServiceUser + case "cloudkitty": + secretName = instance.Spec.Telemetry.Template.CloudKitty.Secret + passwordSelector = instance.Spec.Telemetry.Template.CloudKitty.PasswordSelectors.CloudKittyService + serviceUser = instance.Spec.Telemetry.Template.CloudKitty.ServiceUser + default: + return struct { + SecretName string + PasswordSelector string + ServiceUser string + }{} + } + + // If service-specific Secret is empty, use top-level Secret + if secretName == "" { + secretName = instance.Spec.Secret + } + + return struct { + SecretName string + PasswordSelector string + ServiceUser string + }{secretName, passwordSelector, serviceUser} + } + + // Loop, CreateOrPatch or delete each AC CR: + for _, svc := range svcs { + // Check if service is enabled + if !svc.Enabled { + // Delete all possible AC CRs for this service + if res, err := deleteServiceACs(ctx, helper, instance, svc.Key); err != nil { + return res, err + } + continue + } + + // Merge flags - only check AC enabled after verifying service is enabled + effective := mergeAppCred(global, svc.ACSection) + if !effective.Enabled { + // Delete all possible AC CRs for this service + if res, err := deleteServiceACs(ctx, helper, instance, svc.Key); err != nil { + return res, err + } + continue + } + + // Check if this service has multiple users + if userConfigsFn, hasMultiple := servicesWithMultipleUsers[svc.Key]; hasMultiple { + userConfigs := userConfigsFn(instance) + if userConfigs == nil || len(userConfigs) == 0 { + // Service enabled but template not ready yet + log.Info("Skipping ApplicationCredential creation: Template not initialized", "service", svc.Key) + continue + } + + // Get base service info (secretName) + svcInfo := getServiceInfo(svc.Key) + if svcInfo.SecretName == "" { + log.Info("Skipping ApplicationCredential creation: Secret name empty", "service", svc.Key) + continue + } + + // Create AC CR for each user + for _, userCfg := range userConfigs { + acName := fmt.Sprintf("ac-%s", svc.Key) + if userCfg.Suffix != "" { + acName = fmt.Sprintf("ac-%s-%s", svc.Key, userCfg.Suffix) + } + + if err := reconcileApplicationCredential( + ctx, + helper, + instance, + acName, + userCfg.UserName, + svcInfo.SecretName, + userCfg.PasswordSelector, + effective, + ); err != nil { + return ctrl.Result{}, err + } + } + } else { + // Single user service + svcInfo := getServiceInfo(svc.Key) + if svcInfo.SecretName == "" || svcInfo.PasswordSelector == "" { + log.Info("Skipping ApplicationCredential creation: Template fields empty", "service", svc.Key) + if res, err := deleteServiceACs(ctx, helper, instance, svc.Key); err != nil { + return res, err + } + continue + } + + acName := fmt.Sprintf("ac-%s", svc.Key) + if err := reconcileApplicationCredential( + ctx, + helper, + instance, + acName, + svcInfo.ServiceUser, + svcInfo.SecretName, + svcInfo.PasswordSelector, + effective, + ); err != nil { + return ctrl.Result{}, err + } + } + } + + return ctrl.Result{}, nil +} + +// reconcileApplicationCredential creates or updates a single ApplicationCredential CR +func reconcileApplicationCredential( + ctx context.Context, + helper *helper.Helper, + instance *corev1beta1.OpenStackControlPlane, + acName string, + userName string, + secretName string, + passwordSelector string, + effective corev1beta1.ApplicationCredentialSection, +) error { + log := GetLogger(ctx) + + acObj := &keystonev1.KeystoneApplicationCredential{ + ObjectMeta: metav1.ObjectMeta{ + Name: acName, + Namespace: instance.Namespace, + }, + } + + op, err := controllerutil.CreateOrPatch(ctx, helper.GetClient(), acObj, func() error { + acObj.Spec.UserName = userName + acObj.Spec.ExpirationDays = *effective.ExpirationDays + acObj.Spec.GracePeriodDays = *effective.GracePeriodDays + acObj.Spec.Secret = secretName + acObj.Spec.PasswordSelector = passwordSelector + acObj.Spec.Roles = effective.Roles + acObj.Spec.Unrestricted = *effective.Unrestricted + + if len(effective.AccessRules) > 0 { + kr := make([]keystonev1.ACRule, 0, len(effective.AccessRules)) + for _, r := range effective.AccessRules { + kr = append(kr, keystonev1.ACRule{ + Service: r.Service, + Path: r.Path, + Method: r.Method, + }) + } + acObj.Spec.AccessRules = kr + } + + return controllerutil.SetControllerReference( + helper.GetBeforeObject(), acObj, helper.GetScheme(), + ) + }) + if err != nil { + return err + } + if op != controllerutil.OperationResultNone { + log.Info("Reconciled ApplicationCredential", "name", acName, "user", userName, "operation", op) + } + return nil +} + +// deleteServiceACs deletes all AC CRs for a service (handles both single and multi-user) +func deleteServiceACs( + ctx context.Context, + helper *helper.Helper, + instance *corev1beta1.OpenStackControlPlane, + serviceKey string, +) (ctrl.Result, error) { + // List of possible AC CR names for this service + possibleNames := []string{ + fmt.Sprintf("ac-%s", serviceKey), + } + + // Add additional names for multi-user services + if serviceKey == "ironic" { + possibleNames = append(possibleNames, "ac-ironic-inspector") + } + + // Try to delete each possible CR + for _, acName := range possibleNames { + acObj := &keystonev1.KeystoneApplicationCredential{ + ObjectMeta: metav1.ObjectMeta{ + Name: acName, + Namespace: instance.Namespace, + }, + } + if res, err := EnsureDeleted(ctx, helper, acObj); err != nil { + return res, err + } + } + + return ctrl.Result{}, nil +} diff --git a/test/functional/ctlplane/openstackoperator_controller_test.go b/test/functional/ctlplane/openstackoperator_controller_test.go index 58318df1f..e2ae4e4d6 100644 --- a/test/functional/ctlplane/openstackoperator_controller_test.go +++ b/test/functional/ctlplane/openstackoperator_controller_test.go @@ -41,6 +41,7 @@ import ( cinderv1 "github.com/openstack-k8s-operators/cinder-operator/api/v1beta1" rabbitmqv1 "github.com/openstack-k8s-operators/infra-operator/apis/rabbitmq/v1beta1" topologyv1 "github.com/openstack-k8s-operators/infra-operator/apis/topology/v1beta1" + keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1" "github.com/openstack-k8s-operators/lib-common/modules/certmanager" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" @@ -3150,6 +3151,114 @@ var _ = Describe("OpenStackOperator Webhook", func() { Expect(OSCtlplane.Labels).Should(HaveKeyWithValue("core.openstack.org/openstackcontrolplane", "foo")) }) + It("Defaults Auth.ApplicationCredentialSecret for Cinder via webhook", func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["cinder"] = map[string]interface{}{ + "enabled": true, + "template": map[string]interface{}{ + "cinderAPI": map[string]interface{}{ + "replicas": 1, + }, + }, + } + DeferCleanup(th.DeleteInstance, CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec)) + + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.Cinder.Template.CinderAPI.Auth.ApplicationCredentialSecret).Should(Equal( + keystonev1.GetACSecretName("cinder"), + )) + }) + + It("Preserves custom Auth.ApplicationCredentialSecret for Glance", func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["glance"] = map[string]interface{}{ + "enabled": true, + "template": map[string]interface{}{ + "storage": map[string]interface{}{ + "storageClass": "local-storage", + "storageRequest": "10G", + }, + "glanceAPIs": map[string]interface{}{ + "default": map[string]interface{}{ + "replicas": 1, + "type": "single", + "auth": map[string]interface{}{ + "applicationCredentialSecret": "my-custom-glance-secret", + }, + }, + }, + }, + } + DeferCleanup(th.DeleteInstance, CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec)) + + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(OSCtlplane.Spec.Glance.Template.GlanceAPIs["default"].Auth.ApplicationCredentialSecret).Should(Equal( + "my-custom-glance-secret", + )) + }) + + It("Defaults Auth.ApplicationCredentialSecret for parent-level Auth services (Ironic, Watcher)", func() { + spec := GetDefaultOpenStackControlPlaneSpec() + + // Enable Ironic with required ironicConductors (array, not map!) + spec["ironic"] = map[string]interface{}{ + "enabled": true, + "template": map[string]interface{}{ + "ironicAPI": map[string]interface{}{ + "replicas": 1, + }, + "ironicConductors": []map[string]interface{}{ + { + "replicas": 1, + }, + }, + "ironicInspector": map[string]interface{}{ + "replicas": 1, + }, + }, + } + + // Enable Watcher with required dependencies (Telemetry) + spec["telemetry"] = map[string]interface{}{ + "enabled": true, + "template": map[string]interface{}{ + "ceilometer": map[string]interface{}{ + "enabled": true, + }, + "metricStorage": map[string]interface{}{ + "enabled": true, + }, + }, + } + spec["watcher"] = map[string]interface{}{ + "enabled": true, + "template": map[string]interface{}{ + "apiServiceTemplate": map[string]interface{}{ + "replicas": 1, + }, + }, + } + + DeferCleanup(th.DeleteInstance, CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec)) + + OSCtlplane := GetOpenStackControlPlane(names.OpenStackControlplaneName) + + // Ironic has Auth at parent IronicSpecCore level + Expect(OSCtlplane.Spec.Ironic.Template.Auth.ApplicationCredentialSecret).Should(Equal( + keystonev1.GetACSecretName("ironic"), + )) + + // IronicInspector has separate Auth (different Keystone user) + Expect(OSCtlplane.Spec.Ironic.Template.IronicInspector.Auth.ApplicationCredentialSecret).Should(Equal( + keystonev1.GetACSecretName("ironic-inspector"), + )) + + // Watcher has Auth at parent WatcherSpecCore level + Expect(OSCtlplane.Spec.Watcher.Template.Auth.ApplicationCredentialSecret).Should(Equal( + keystonev1.GetACSecretName("watcher"), + )) + }) + It("calls placement validation webhook", func() { spec := GetDefaultOpenStackControlPlaneSpec() spec["tls"] = GetTLSPublicSpec() @@ -4063,7 +4172,233 @@ var _ = Describe("OpenStackOperator controller nova cell deletion", func() { g.Expect(k8s_errors.IsNotFound(err)).To(BeTrue()) }, timeout, interval).Should(Succeed()) }) + }) + }) +}) + +var _ = Describe("Application Credentials configuration in control plane", func() { + When("global application credentials are enabled", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["applicationCredential"] = map[string]interface{}{ + "enabled": true, + "expirationDays": 365, + "gracePeriodDays": 182, + "roles": []string{"service"}, + "unrestricted": false, + } + spec["cinder"] = map[string]interface{}{ + "enabled": true, + "applicationCredential": map[string]interface{}{ + "enabled": true, + "expirationDays": 100, + "gracePeriodDays": 50, + "roles": []string{"custom", "role"}, + "unrestricted": true, + }, + } + + DeferCleanup(th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + + It("should fill defaults correctly", func() { + Eventually(func(g Gomega) { + cp := GetOpenStackControlPlane(names.OpenStackControlplaneName) + g.Expect(cp.Spec.ApplicationCredential.Enabled).To(BeTrue()) + g.Expect(*cp.Spec.ApplicationCredential.ExpirationDays).To(Equal(365)) + g.Expect(*cp.Spec.ApplicationCredential.GracePeriodDays).To(Equal(182)) + g.Expect(cp.Spec.ApplicationCredential.Roles).To(ConsistOf("service")) + g.Expect(*cp.Spec.ApplicationCredential.Unrestricted).To(BeFalse()) + + ac := cp.Spec.Cinder.ApplicationCredential + g.Expect(ac).NotTo(BeNil()) + g.Expect(*ac.ExpirationDays).To(Equal(100)) + g.Expect(*ac.GracePeriodDays).To(Equal(50)) + g.Expect(ac.Roles).To(ConsistOf("custom", "role")) + g.Expect(*ac.Unrestricted).To(BeTrue()) + }, timeout, interval).Should(Succeed()) + }) + + It("should configure ApplicationCredential with service-specific overrides and global defaults", func() { + cp := GetOpenStackControlPlane(names.OpenStackControlplaneName) + + // Verify global AC configuration + global := cp.Spec.ApplicationCredential + Expect(global.Enabled).To(BeTrue()) + Expect(*global.ExpirationDays).To(Equal(365)) + Expect(*global.GracePeriodDays).To(Equal(182)) + Expect(global.Roles).To(ConsistOf("service")) + Expect(*global.Unrestricted).To(BeFalse()) + + // Verify Cinder has service-specific overrides + Expect(cp.Spec.Cinder.Enabled).To(BeTrue()) + Expect(cp.Spec.Cinder.ApplicationCredential).NotTo(BeNil()) + Expect(cp.Spec.Cinder.ApplicationCredential.Enabled).To(BeTrue()) + cinderAC := cp.Spec.Cinder.ApplicationCredential + Expect(*cinderAC.ExpirationDays).To(Equal(100)) + Expect(*cinderAC.GracePeriodDays).To(Equal(50)) + Expect(cinderAC.Roles).To(ConsistOf("custom", "role")) + Expect(*cinderAC.Unrestricted).To(BeTrue()) + + // Verify Glance and Manila inherit global defaults (no service-specific AC overrides) + // The service specific values are nil/empty, they inherit the global defaults with mergeAppCred function + Expect(cp.Spec.Glance.Enabled).To(BeTrue()) + Expect(cp.Spec.Manila.Enabled).To(BeTrue()) + Expect(cp.Spec.Manila.Template).NotTo(BeNil()) + + if cp.Spec.Glance.ApplicationCredential != nil { + glanceAC := cp.Spec.Glance.ApplicationCredential + Expect(glanceAC.ExpirationDays).To(BeNil()) + Expect(glanceAC.GracePeriodDays).To(BeNil()) + Expect(glanceAC.Roles).To(BeEmpty()) + Expect(glanceAC.Unrestricted).To(BeNil()) + } + + if cp.Spec.Manila.ApplicationCredential != nil { + manilaAC := cp.Spec.Manila.ApplicationCredential + Expect(manilaAC.ExpirationDays).To(BeNil()) + Expect(manilaAC.GracePeriodDays).To(BeNil()) + Expect(manilaAC.Roles).To(BeEmpty()) + Expect(manilaAC.Unrestricted).To(BeNil()) + } + }) + }) + + When("global application credentials are disabled", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["applicationCredential"] = map[string]interface{}{"enabled": false} + spec["cinder"] = map[string]interface{}{ + "enabled": true, + "applicationCredential": map[string]interface{}{ + "enabled": true, + }, + } + spec["glance"] = map[string]interface{}{ + "enabled": true, + } + + DeferCleanup(th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + + It("should have global AC disabled in spec", func() { + cp := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(cp.Spec.ApplicationCredential.Enabled).To(BeFalse()) + }) + }) + + When("service-specific application credentials are disabled", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["applicationCredential"] = map[string]interface{}{"enabled": true} + spec["glance"] = map[string]interface{}{ + "enabled": true, + "applicationCredential": map[string]interface{}{ + "enabled": false, + }, + } + spec["cinder"] = map[string]interface{}{ + "enabled": true, + "applicationCredential": map[string]interface{}{ + "enabled": true, + }, + } + + DeferCleanup(th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + + It("should have service-specific AC disabled in spec", func() { + cp := GetOpenStackControlPlane(names.OpenStackControlplaneName) + + // Glance is disabled + Expect(cp.Spec.Glance.Enabled).To(BeTrue()) + Expect(cp.Spec.Glance.ApplicationCredential).NotTo(BeNil()) + Expect(cp.Spec.Glance.ApplicationCredential.Enabled).To(BeFalse()) + + // Cidner is enabled + Expect(cp.Spec.Cinder.Enabled).To(BeTrue()) + Expect(cp.Spec.Cinder.ApplicationCredential).NotTo(BeNil()) + Expect(cp.Spec.Cinder.ApplicationCredential.Enabled).To(BeTrue()) + }) + }) + + When("Heat service with application credentials enabled", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["applicationCredential"] = map[string]interface{}{ + "enabled": true, + "expirationDays": 365, + "gracePeriodDays": 182, + } + spec["heat"] = map[string]interface{}{ + "enabled": true, + "template": map[string]interface{}{ + "databaseInstance": "openstack", + "secret": "osp-secret", + "apiTimeout": 60, + }, + "applicationCredential": map[string]interface{}{ + "enabled": true, + }, + } + + DeferCleanup(th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + + It("should configure ApplicationCredential in spec for Heat service", func() { + // Verify the spec is configured correctly for Heat AC + cp := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(cp.Spec.Heat.Enabled).To(BeTrue()) + Expect(cp.Spec.Heat.ApplicationCredential).NotTo(BeNil()) + Expect(cp.Spec.Heat.ApplicationCredential.Enabled).To(BeTrue()) + Expect(cp.Spec.Heat.Template).NotTo(BeNil()) + }) + }) + + When("Ironic service with application credentials enabled", func() { + BeforeEach(func() { + spec := GetDefaultOpenStackControlPlaneSpec() + spec["applicationCredential"] = map[string]interface{}{ + "enabled": true, + "expirationDays": 365, + "gracePeriodDays": 182, + } + spec["ironic"] = map[string]interface{}{ + "enabled": true, + "template": map[string]interface{}{ + "databaseInstance": "openstack", + "secret": "osp-secret", + "ironicConductors": []map[string]interface{}{ + { + "replicas": 1, + }, + }, + }, + "applicationCredential": map[string]interface{}{ + "enabled": true, + }, + } + + DeferCleanup(th.DeleteInstance, + CreateOpenStackControlPlane(names.OpenStackControlplaneName, spec), + ) + }) + It("should configure ApplicationCredential in spec for Ironic service", func() { + // Verify the spec is configured correctly for Ironic AC + cp := GetOpenStackControlPlane(names.OpenStackControlplaneName) + Expect(cp.Spec.Ironic.Enabled).To(BeTrue()) + Expect(cp.Spec.Ironic.ApplicationCredential).NotTo(BeNil()) + Expect(cp.Spec.Ironic.ApplicationCredential.Enabled).To(BeTrue()) + Expect(cp.Spec.Ironic.Template).NotTo(BeNil()) }) }) }) diff --git a/test/kuttl/common/osp_check_appcred_id.sh b/test/kuttl/common/osp_check_appcred_id.sh new file mode 100755 index 000000000..455dd9d5e --- /dev/null +++ b/test/kuttl/common/osp_check_appcred_id.sh @@ -0,0 +1,249 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Script to verify Application Credential IDs and AC secrets are correctly configured in OpenStack service pods +# Usage: osp_check_appcred_id.sh + +if [[ $# -lt 2 ]]; then + echo "Usage: $0 " >&2 + echo " SERVICE: barbican, glance, swift, cinder, manila (or 'all' for supported services)" >&2 + exit 1 +fi + +NAMESPACE="$1" +REQUESTED_SERVICE="$2" +DEBUG=${DEBUG:-0} + +declare -a FAILED_CHECKS=() + +# Service definitions: service_name -> "config_path|resource_type/resource_name:container,resource_type/resource_name:container" +# resource_type can be: deploy (deployment) or sts (statefulset) +declare -A SERVICES=( + [barbican]="/etc/barbican/barbican.conf.d/00-default.conf|deploy/barbican-api:barbican-api" + [cinder]="/etc/cinder/cinder.conf.d/00-default.conf|sts/cinder-api:cinder-api,sts/cinder-scheduler:cinder-scheduler" + [glance]="/etc/glance/glance-api.conf.d/00-default.conf|sts/glance-default-external-api:glance-api,sts/glance-default-internal-api:glance-api" + [swift]="/etc/swift/proxy-server.conf.d/00-proxy-server.conf|deploy/swift-proxy:proxy-server" + [manila]="/etc/manila/manila.conf.d/00-config.conf|sts/manila-api:manila-api,sts/manila-scheduler:manila-scheduler" + # TODO: Add remaining services when they support application credentials in their operators: + # [nova]="/etc/nova/nova.conf|sts/nova-api:nova-api,sts/nova-cell0-conductor:nova-conductor,sts/nova-cell1-conductor:nova-conductor,sts/nova-metadata:nova-metadata,sts/nova-scheduler:nova-scheduler" + [neutron]="/etc/neutron/neutron.conf.d/01-default.conf|deploy/neutron:neutron-server" + [placement]="/etc/placement/placement.conf|deploy/placement:placement-api" + # [ceilometer]="/etc/ceilometer/ceilometer.conf|sts/ceilometer:ceilometer-central" + # [aodh]="/etc/aodh/aodh.conf|sts/aodh-api:aodh-api" + # [heat]="/etc/heat/heat.conf|sts/heat-api:heat-api" + # [ironic]="/etc/ironic/ironic.conf|sts/ironic-api:ironic-api" + [octavia]="/etc/octavia/octavia.conf|sts/octavia-api:octavia-api" + # [designate]="/etc/designate/designate.conf|sts/designate-api:designate-api" + # [watcher]="/etc/watcher/watcher.conf|sts/watcher-api:watcher-api" +) + +RESOURCE_TYPE="keystoneapplicationcredential" + +debug() { + [[ $DEBUG -ge 1 ]] && echo "[DEBUG] $*" >&2 +} + +error() { + echo "[ERROR] $*" >&2 +} + +# Add a failed check to the global list +add_failed_check() { + local service="$1" resource_spec="$2" container="$3" reason="$4" + FAILED_CHECKS+=("$service: $resource_spec/$container - $reason") +} + +# Convert resource type shorthand to full name +get_resource_type() { + case "$1" in + deploy) echo "deployment" ;; + sts) echo "statefulset" ;; + *) echo "$1" ;; + esac +} + +# Extract application credential field from config file in pod +get_app_cred_field_from_pod() { + local resource_spec="$1" container="$2" config_path="$3" field_name="$4" + local output + + debug "Executing: oc exec -n $NAMESPACE $resource_spec -c $container -- sh -c \"grep '^[[:space:]]*${field_name}[[:space:]]*=' '$config_path' | sed 's/^[^=]*=[[:space:]]*//' | sed 's/[[:space:]]*$//' | head -1\"" + + if output=$(oc exec -n "$NAMESPACE" "$resource_spec" -c "$container" -- \ + sh -c "grep '^[[:space:]]*${field_name}[[:space:]]*=' '$config_path' | sed 's/^[^=]*=[[:space:]]*//' | sed 's/[[:space:]]*$//' | head -1" 2>/dev/null); then + debug "Successfully extracted $field_name from $resource_spec/$container: $output" + echo "$output" + return 0 + fi + + error "Failed to extract $field_name from $resource_spec/$container" + return 1 +} + +# Check a single service +check_service() { + local service="$1" + local service_def="${SERVICES[$service]}" + local config_path="${service_def%%|*}" + local targets="${service_def##*|}" + + echo "Checking service: $service" + + # Get expected Application Credential data from Kubernetes resources + local cr_name="ac-$service" + local expected_id expected_secret + + # Get AC ID from the KeystoneApplicationCredential status + if ! expected_id=$(oc get "$RESOURCE_TYPE" "$cr_name" -n "$NAMESPACE" -o jsonpath='{.status.acID}' 2>/dev/null); then + error "Failed to get Application Credential ID from $RESOURCE_TYPE/$cr_name" + add_failed_check "$service" "$cr_name" "N/A" "Failed to get Application Credential ID from Kubernetes resource" + return 1 + fi + + if [[ -z "$expected_id" ]]; then + error "$RESOURCE_TYPE/$cr_name has empty .status.acID" + add_failed_check "$service" "$cr_name" "N/A" "Empty .status.acID in Kubernetes resource" + return 1 + fi + + # Get AC Secret from the associated secret (base64 decoded) + local secret_name + if ! secret_name=$(oc get "$RESOURCE_TYPE" "$cr_name" -n "$NAMESPACE" -o jsonpath='{.status.secretName}' 2>/dev/null); then + error "Failed to get secret name from $RESOURCE_TYPE/$cr_name" + add_failed_check "$service" "$cr_name" "N/A" "Failed to get secret name from Kubernetes resource" + return 1 + fi + + if [[ -z "$secret_name" ]]; then + error "$RESOURCE_TYPE/$cr_name has empty .status.secretName" + add_failed_check "$service" "$cr_name" "N/A" "Empty .status.secretName in Kubernetes resource" + return 1 + fi + + # Get and decode the AC_SECRET from the Kubernetes secret + if ! expected_secret=$(oc get secret "$secret_name" -n "$NAMESPACE" -o jsonpath='{.data.AC_SECRET}' 2>/dev/null | base64 -d); then + error "Failed to get AC_SECRET from secret/$secret_name" + add_failed_check "$service" "$secret_name" "N/A" "Failed to get AC_SECRET from Kubernetes secret" + return 1 + fi + + if [[ -z "$expected_secret" ]]; then + error "secret/$secret_name has empty AC_SECRET" + add_failed_check "$service" "$secret_name" "N/A" "Empty AC_SECRET in Kubernetes secret" + return 1 + fi + + echo " Expected ID: $expected_id" + echo " Expected Secret: ${expected_secret:0:20}..." + + local failed=0 + + # Check each resource/container pair + IFS=',' read -ra TARGET_LIST <<< "$targets" + for target in "${TARGET_LIST[@]}"; do + local resource_spec="${target%%:*}" # e.g., "deploy/swift-proxy" + local container="${target##*:}" # e.g., "proxy-server" + + # Parse resource type and name + local resource_type_short="${resource_spec%%/*}" # e.g., "deploy" + local resource_name="${resource_spec##*/}" # e.g., "swift-proxy" + local resource_type_full=$(get_resource_type "$resource_type_short") + + # Skip if resource doesn't exist + if ! oc get "$resource_type_full" "$resource_name" -n "$NAMESPACE" >/dev/null 2>&1; then + echo " Skipping $resource_type_full/$resource_name (not found)" + continue + fi + + # Check Application Credential ID + local actual_id + if ! actual_id=$(get_app_cred_field_from_pod "$resource_type_full/$resource_name" "$container" "$config_path" "application_credential_id"); then + add_failed_check "$service" "$resource_spec" "$container" "Failed to extract application_credential_id from pod" + failed=1 + elif [[ -z "$actual_id" ]]; then + error " $resource_spec/$container: application_credential_id not found in $config_path" + add_failed_check "$service" "$resource_spec" "$container" "application_credential_id not found in config file" + failed=1 + elif [[ "$actual_id" != "$expected_id" ]]; then + echo " $resource_spec/$container: Found ID: $actual_id" + error " $resource_spec/$container: ID mismatch (got: $actual_id, expected: $expected_id)" + add_failed_check "$service" "$resource_spec" "$container" "ID mismatch (got: $actual_id, expected: $expected_id)" + failed=1 + else + echo " $resource_spec/$container: Found ID: $actual_id" + echo " $resource_spec/$container: ID matches" + fi + + # Check Application Credential Secret + local actual_secret + if ! actual_secret=$(get_app_cred_field_from_pod "$resource_type_full/$resource_name" "$container" "$config_path" "application_credential_secret"); then + add_failed_check "$service" "$resource_spec" "$container" "Failed to extract application_credential_secret from pod" + failed=1 + elif [[ -z "$actual_secret" ]]; then + error " $resource_spec/$container: application_credential_secret not found in $config_path" + add_failed_check "$service" "$resource_spec" "$container" "application_credential_secret not found in config file" + failed=1 + elif [[ "$actual_secret" != "$expected_secret" ]]; then + echo " $resource_spec/$container: Found Secret: ${actual_secret:0:20}..." + error " $resource_spec/$container: Secret mismatch (got: ${actual_secret:0:20}..., expected: ${expected_secret:0:20}...)" + add_failed_check "$service" "$resource_spec" "$container" "Secret mismatch" + failed=1 + else + echo " $resource_spec/$container: Found Secret: ${actual_secret:0:20}..." + echo " $resource_spec/$container: Secret matches" + fi + done + + return $failed +} + +# Print summary of failed checks +print_failed_checks_summary() { + if [[ ${#FAILED_CHECKS[@]} -eq 0 ]]; then + return + fi + + echo + echo "FAILED APPLICATION CREDENTIAL CHECKS:" + for failure in "${FAILED_CHECKS[@]}"; do + echo " $failure" + done +} + +# Main execution +main() { + local services_to_check=() + + if [[ "$REQUESTED_SERVICE" == "all" ]]; then + services_to_check=("${!SERVICES[@]}") + else + if [[ -z "${SERVICES[$REQUESTED_SERVICE]:-}" ]]; then + error "Service '$REQUESTED_SERVICE' is not supported" + echo "Supported services: ${!SERVICES[*]}" >&2 + exit 1 + fi + services_to_check=("$REQUESTED_SERVICE") + fi + + local overall_failed=0 + + for service in "${services_to_check[@]}"; do + if ! check_service "$service"; then + overall_failed=1 + fi + echo + done + + # Print summary of failures + print_failed_checks_summary + + if [[ $overall_failed -eq 0 ]]; then + echo "All Application Credential checks passed" + else + echo "Some Application Credential checks failed" + fi + + exit $overall_failed +} + +main diff --git a/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/01-assert-deploy-openstack.yaml b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/01-assert-deploy-openstack.yaml new file mode 120000 index 000000000..762a8cf31 --- /dev/null +++ b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/01-assert-deploy-openstack.yaml @@ -0,0 +1 @@ +../../common/assert-sample-deployment.yaml \ No newline at end of file diff --git a/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/01-deploy-openstack.yaml b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/01-deploy-openstack.yaml new file mode 100644 index 000000000..6c9d0887d --- /dev/null +++ b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/01-deploy-openstack.yaml @@ -0,0 +1,5 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + oc kustomize ../../../../config/samples/base/openstackcontrolplane | oc apply -n $NAMESPACE -f - diff --git a/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/02-assert-appcred-crs.yaml b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/02-assert-appcred-crs.yaml new file mode 100644 index 000000000..8e526419a --- /dev/null +++ b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/02-assert-appcred-crs.yaml @@ -0,0 +1,84 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +commands: + - script: |- + set -euo pipefail + NS="${NAMESPACE}" + + wait_ready() { oc wait appcred/$1 -n "$NS" --for=condition=Ready --timeout=120s; } + + # ---- ac-barbican ---- + wait_ready ac-barbican + + EXP=$(oc get appcred ac-barbican -n "$NS" -o jsonpath='{.spec.expirationDays}') + [ "${EXP:-}" -eq 200 ] + + GRP=$(oc get appcred ac-barbican -n "$NS" -o jsonpath='{.spec.gracePeriodDays}') + [ "${GRP:-}" -eq 90 ] + + ROL=$(oc get appcred ac-barbican -n "$NS" -o jsonpath='{.spec.roles[*]}') + case " $ROL " in *" service "*) ;; *) exit 1;; esac + + UNR=$(oc get appcred ac-barbican -n "$NS" -o jsonpath='{.spec.unrestricted}' 2>/dev/null || echo "") + [ "${UNR:-false}" = "false" ] + + # ---- ac-cinder ---- + wait_ready ac-cinder + + EXP=$(oc get appcred ac-cinder -n "$NS" -o jsonpath='{.spec.expirationDays}') + [ "${EXP:-}" -eq 10 ] + + GRP=$(oc get appcred ac-cinder -n "$NS" -o jsonpath='{.spec.gracePeriodDays}') + [ "${GRP:-}" -eq 5 ] + + ROL=$(oc get appcred ac-cinder -n "$NS" -o jsonpath='{.spec.roles[*]}') + case " $ROL " in *" admin "*) ;; *) exit 1;; esac + case " $ROL " in *" service "*) ;; *) exit 1;; esac + + UNR=$(oc get appcred ac-cinder -n "$NS" -o jsonpath='{.spec.unrestricted}' 2>/dev/null || echo "") + [ "${UNR}" = "true" ] + + # ---- ac-swift ---- + wait_ready ac-swift + + EXP=$(oc get appcred ac-swift -n "$NS" -o jsonpath='{.spec.expirationDays}') + [ "${EXP:-}" -eq 200 ] + + GRP=$(oc get appcred ac-swift -n "$NS" -o jsonpath='{.spec.gracePeriodDays}') + [ "${GRP:-}" -eq 90 ] + + ROL=$(oc get appcred ac-swift -n "$NS" -o jsonpath='{.spec.roles[*]}') + case " $ROL " in *" service "*) ;; *) exit 1;; esac + + UNR=$(oc get appcred ac-swift -n "$NS" -o jsonpath='{.spec.unrestricted}' 2>/dev/null || echo "") + [ "${UNR:-false}" = "false" ] + + # ---- ac-glance ---- + wait_ready ac-glance + + EXP=$(oc get appcred ac-glance -n "$NS" -o jsonpath='{.spec.expirationDays}') + [ "${EXP:-}" -eq 200 ] + + GRP=$(oc get appcred ac-glance -n "$NS" -o jsonpath='{.spec.gracePeriodDays}') + [ "${GRP:-}" -eq 90 ] + + ROL=$(oc get appcred ac-glance -n "$NS" -o jsonpath='{.spec.roles[*]}') + case " $ROL " in *" service "*) ;; *) exit 1;; esac + + UNR=$(oc get appcred ac-glance -n "$NS" -o jsonpath='{.spec.unrestricted}' 2>/dev/null || echo "") + [ "${UNR:-false}" = "false" ] + + # ---- ac-manila ---- + wait_ready ac-manila + + EXP=$(oc get appcred ac-manila -n "$NS" -o jsonpath='{.spec.expirationDays}') + [ "${EXP:-}" -eq 200 ] + + GRP=$(oc get appcred ac-manila -n "$NS" -o jsonpath='{.spec.gracePeriodDays}') + [ "${GRP:-}" -eq 90 ] + + ROL=$(oc get appcred ac-manila -n "$NS" -o jsonpath='{.spec.roles[*]}') + case " $ROL " in *" service "*) ;; *) exit 1;; esac + + UNR=$(oc get appcred ac-manila -n "$NS" -o jsonpath='{.spec.unrestricted}' 2>/dev/null || echo "") + [ "${UNR:-false}" = "false" ] diff --git a/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/02-deploy-appcred-config.yaml b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/02-deploy-appcred-config.yaml new file mode 100644 index 000000000..3cb5652ca --- /dev/null +++ b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/02-deploy-appcred-config.yaml @@ -0,0 +1,5 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + oc kustomize ../../../../config/samples/applicationcredentials | oc apply -n $NAMESPACE -f - diff --git a/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/03-get-appcred-ids.yaml b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/03-get-appcred-ids.yaml new file mode 100644 index 000000000..d0491d3cb --- /dev/null +++ b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/03-get-appcred-ids.yaml @@ -0,0 +1,28 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + echo "Waiting 60 seconds for OpenStack control plane to be fully ready..." + echo "Control plane switches to ready state before service pods catch up with AC changes" + sleep 60 + + echo "Gather and save appcred IDs" + # TODO: Uncomment services here when they support application credentials in their operators + # Currently implemented: barbican, cinder, glance, swift, manila + # Future support: nova, neutron, placement, ceilometer, ironic, heat, octavia, designate, watcher, aodh + bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE barbican + bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE cinder + bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE glance + bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE swift + bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE manila + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE nova + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE neutron + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE placement + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE ceilometer + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE ironic + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE heat + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE octavia + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE designate + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE watcher + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE aodh + # bash -s < ../../common/osp_check_appcred_id.sh $NAMESPACE all diff --git a/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/07-cleanup.yaml b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/07-cleanup.yaml new file mode 100644 index 000000000..df9df9fe0 --- /dev/null +++ b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/07-cleanup.yaml @@ -0,0 +1,11 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: +- apiVersion: core.openstack.org/v1beta1 + kind: OpenStackControlPlane + name: openstack +commands: +- script: | + oc delete secret --ignore-not-found=true combined-ca-bundle -n $NAMESPACE + oc delete secret -l service-cert -n $NAMESPACE + oc delete secret -l ca-cert -n $NAMESPACE diff --git a/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/07-errors-cleanup.yaml b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/07-errors-cleanup.yaml new file mode 120000 index 000000000..4d7b8362e --- /dev/null +++ b/tests/kuttl/tests/ctlplane-basic-deployment-with-appcred/07-errors-cleanup.yaml @@ -0,0 +1 @@ +../../common/errors_cleanup_openstack.yaml \ No newline at end of file