From 5f7551fed193637fe6cd082742c6991e26e47369 Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Wed, 9 Oct 2024 13:10:23 -0500 Subject: [PATCH 01/14] Add OIDC Federation Settings This templates the OIDC federation settings needed to configure Keystone to perform federation authentication. --- .../keystone.openstack.org_keystoneapis.yaml | 87 ++++++++++++++++++- api/v1beta1/keystoneapi_types.go | 87 ++++++++++++++++++- api/v1beta1/zz_generated.deepcopy.go | 20 +++++ .../keystone.openstack.org_keystoneapis.yaml | 87 ++++++++++++++++++- ...ne_v1beta1_keystoneapi_tls_federation.yaml | 43 +++++++++ controllers/keystoneapi_controller.go | 73 ++++++++++++++-- templates/keystoneapi/config/httpd.conf | 47 +++++++++- templates/keystoneapi/config/keystone.conf | 11 +++ .../functional/keystoneapi_controller_test.go | 11 --- 9 files changed, 440 insertions(+), 26 deletions(-) create mode 100644 config/samples/keystone_v1beta1_keystoneapi_tls_federation.yaml diff --git a/api/bases/keystone.openstack.org_keystoneapis.yaml b/api/bases/keystone.openstack.org_keystoneapis.yaml index 8611326c..2076f48d 100644 --- a/api/bases/keystone.openstack.org_keystoneapis.yaml +++ b/api/bases/keystone.openstack.org_keystoneapis.yaml @@ -134,6 +134,76 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + oidcFederation: + description: KeystoneFederationSpec to provide the configuration values + for OIDC Federation + properties: + keystoneFederationIdentityProviderName: + default: "" + description: KeystoneFederationIdentityProviderName + type: string + oidcCacheType: + default: memcache + description: OIDCCacheType + type: string + oidcClaimDelimiter: + default: ; + description: OIDCClaimDelimiter + type: string + oidcClaimPrefix: + default: OIDC- + description: OIDCClaimPrefix + type: string + oidcClientID: + default: "" + description: OIDCClientID + type: string + oidcIntrospectionEndpoint: + default: "" + description: OIDCIntrospectionEndpoint + type: string + oidcMemCacheServers: + description: OIDCMemCacheServers + type: string + oidcPassClaimsAs: + default: both + description: OIDCPassClaimsAs + type: string + oidcPassUserInfoAs: + default: claims + description: OIDCPassUserInfoAs + type: string + oidcProviderMetadataURL: + default: "" + description: OIDCProviderMetadataURL + type: string + oidcResponseType: + default: id_token + description: OIDCResponseType + type: string + oidcScope: + default: openid email profile + description: OIDCScope + type: string + remoteIDAttribute: + default: HTTP_OIDC_ISS + description: RemoteIDAttribute + type: string + required: + - keystoneFederationIdentityProviderName + - oidcCacheType + - oidcClaimDelimiter + - oidcClaimPrefix + - oidcClientID + - oidcIntrospectionEndpoint + - oidcMemCacheServers + - oidcPassClaimsAs + - oidcPassUserInfoAs + - oidcProviderMetadataURL + - oidcResponseType + - oidcScope + - remoteIDAttribute + type: object override: description: Override, provides the ability to override the generated manifest of several child resources. @@ -295,14 +365,27 @@ spec: passwordSelectors: default: admin: AdminPassword - description: PasswordSelectors - Selectors to identify the AdminUser - password from the Secret + keystoneOIDCClientSecret: KeystoneClientSecret + keystoneOIDCCryptoPassphrase: KeystoneCryptoPassphrase + description: PasswordSelectors - Selectors to identify the AdminUser, + KeystoneOIDCClient, and KeystoneOIDCCryptoPassphrase passwords from + the Secret properties: admin: default: AdminPassword description: Admin - Selector to get the keystone Admin password from the Secret type: string + keystoneOIDCClientSecret: + default: KeystoneClientSecret + description: OIDCClientSecret - Selector to get the IdP client + secret from the Secret + type: string + keystoneOIDCCryptoPassphrase: + default: KeystoneCryptoPassphrase + description: OIDCCryptoPassphrase - Selector to get the OIDC crypto + passphrase from the Secret + type: string type: object preserveJobs: default: false diff --git a/api/v1beta1/keystoneapi_types.go b/api/v1beta1/keystoneapi_types.go index a0d86aff..0d03ed45 100644 --- a/api/v1beta1/keystoneapi_types.go +++ b/api/v1beta1/keystoneapi_types.go @@ -132,8 +132,8 @@ type KeystoneAPISpecCore struct { FernetMaxActiveKeys *int32 `json:"fernetMaxActiveKeys"` // +kubebuilder:validation:Optional - // +kubebuilder:default={admin: AdminPassword} - // PasswordSelectors - Selectors to identify the AdminUser password from the Secret + // +kubebuilder:default={admin: AdminPassword, keystoneOIDCClientSecret: KeystoneClientSecret, keystoneOIDCCryptoPassphrase: KeystoneCryptoPassphrase} + // PasswordSelectors - Selectors to identify the AdminUser, KeystoneOIDCClient, and KeystoneOIDCCryptoPassphrase passwords from the Secret PasswordSelectors PasswordSelector `json:"passwordSelectors"` // +kubebuilder:validation:Optional @@ -184,6 +184,10 @@ type KeystoneAPISpecCore struct { // +operator-sdk:csv:customresourcedefinitions:type=spec // TLS - Parameters related to the TLS TLS tls.API `json:"tls,omitempty"` + + // +kubebuilder:validation:Optional + // +OIDCFederation - parameters to configure keystone for OIDC federation + OIDCFederation *KeystoneFederationSpec `json:"oidcFederation,omitempty"` } // APIOverrideSpec to override the generated manifest of several child resources. @@ -199,6 +203,83 @@ type PasswordSelector struct { // +kubebuilder:default="AdminPassword" // Admin - Selector to get the keystone Admin password from the Secret Admin string `json:"admin"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default="KeystoneClientSecret" + // OIDCClientSecret - Selector to get the IdP client secret from the Secret + KeystoneOIDCClientSecret string `json:"keystoneOIDCClientSecret"` + + // +kubebuilder:validation:Optional + // +kubebuilder:default="KeystoneCryptoPassphrase" + // OIDCCryptoPassphrase - Selector to get the OIDC crypto passphrase from the Secret + KeystoneOIDCCryptoPassphrase string `json:"keystoneOIDCCryptoPassphrase"` +} + +// KeystoneFederationSpec to provide the configuration values for OIDC Federation +type KeystoneFederationSpec struct { + // +kubebuilder:validation:Required + // +kubebuilder:default="OIDC-" + // OIDCClaimPrefix + OIDCClaimPrefix string `json:"oidcClaimPrefix"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="id_token" + // OIDCResponseType + OIDCResponseType string `json:"oidcResponseType"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="openid email profile" + // OIDCScope + OIDCScope string `json:"oidcScope"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="" + // OIDCProviderMetadataURL + OIDCProviderMetadataURL string `json:"oidcProviderMetadataURL"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="" + // OIDCIntrospectionEndpoint + OIDCIntrospectionEndpoint string `json:"oidcIntrospectionEndpoint"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="" + // OIDCClientID + OIDCClientID string `json:"oidcClientID"` + + // +kubebuilder:validation:Required + // +kubebuilder:default=";" + // OIDCClaimDelimiter + OIDCClaimDelimiter string `json:"oidcClaimDelimiter"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="claims" + // OIDCPassUserInfoAs + OIDCPassUserInfoAs string `json:"oidcPassUserInfoAs"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="both" + // OIDCPassClaimsAs + OIDCPassClaimsAs string `json:"oidcPassClaimsAs"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="memcache" + // OIDCCacheType + OIDCCacheType string `json:"oidcCacheType"` + + // +kubebuilder:validaton:Required + // OIDCMemCacheServers + OIDCMemCacheServers string `json:"oidcMemCacheServers"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="HTTP_OIDC_ISS" + // RemoteIDAttribute + RemoteIDAttribute string `json:"remoteIDAttribute"` + + // +kubebuilder:validation:Required + // +kubebuilder:default="" + // KeystoneFederationIdentityProviderName + KeystoneFederationIdentityProviderName string `json:"keystoneFederationIdentityProviderName"` } // HttpdCustomization - customize the httpd service @@ -233,7 +314,7 @@ type KeystoneAPIStatus struct { // TransportURLSecret - Secret containing RabbitMQ transportURL TransportURLSecret string `json:"transportURLSecret,omitempty"` - //ObservedGeneration - the most recent generation observed for this service. If the observed generation is less than the spec generation, then the controller has not processed the latest changes. + // ObservedGeneration - the most recent generation observed for this service. If the observed generation is less than the spec generation, then the controller has not processed the latest changes. ObservedGeneration int64 `json:"observedGeneration,omitempty"` } diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 6f1a04b2..205feff2 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -204,6 +204,11 @@ func (in *KeystoneAPISpecCore) DeepCopyInto(out *KeystoneAPISpecCore) { } in.Override.DeepCopyInto(&out.Override) in.TLS.DeepCopyInto(&out.TLS) + if in.OIDCFederation != nil { + in, out := &in.OIDCFederation, &out.OIDCFederation + *out = new(KeystoneFederationSpec) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeystoneAPISpecCore. @@ -412,6 +417,21 @@ func (in *KeystoneEndpointStatus) DeepCopy() *KeystoneEndpointStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KeystoneFederationSpec) DeepCopyInto(out *KeystoneFederationSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeystoneFederationSpec. +func (in *KeystoneFederationSpec) DeepCopy() *KeystoneFederationSpec { + if in == nil { + return nil + } + out := new(KeystoneFederationSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KeystoneService) DeepCopyInto(out *KeystoneService) { *out = *in diff --git a/config/crd/bases/keystone.openstack.org_keystoneapis.yaml b/config/crd/bases/keystone.openstack.org_keystoneapis.yaml index 8611326c..2076f48d 100644 --- a/config/crd/bases/keystone.openstack.org_keystoneapis.yaml +++ b/config/crd/bases/keystone.openstack.org_keystoneapis.yaml @@ -134,6 +134,76 @@ spec: description: NodeSelector to target subset of worker nodes running this service type: object + oidcFederation: + description: KeystoneFederationSpec to provide the configuration values + for OIDC Federation + properties: + keystoneFederationIdentityProviderName: + default: "" + description: KeystoneFederationIdentityProviderName + type: string + oidcCacheType: + default: memcache + description: OIDCCacheType + type: string + oidcClaimDelimiter: + default: ; + description: OIDCClaimDelimiter + type: string + oidcClaimPrefix: + default: OIDC- + description: OIDCClaimPrefix + type: string + oidcClientID: + default: "" + description: OIDCClientID + type: string + oidcIntrospectionEndpoint: + default: "" + description: OIDCIntrospectionEndpoint + type: string + oidcMemCacheServers: + description: OIDCMemCacheServers + type: string + oidcPassClaimsAs: + default: both + description: OIDCPassClaimsAs + type: string + oidcPassUserInfoAs: + default: claims + description: OIDCPassUserInfoAs + type: string + oidcProviderMetadataURL: + default: "" + description: OIDCProviderMetadataURL + type: string + oidcResponseType: + default: id_token + description: OIDCResponseType + type: string + oidcScope: + default: openid email profile + description: OIDCScope + type: string + remoteIDAttribute: + default: HTTP_OIDC_ISS + description: RemoteIDAttribute + type: string + required: + - keystoneFederationIdentityProviderName + - oidcCacheType + - oidcClaimDelimiter + - oidcClaimPrefix + - oidcClientID + - oidcIntrospectionEndpoint + - oidcMemCacheServers + - oidcPassClaimsAs + - oidcPassUserInfoAs + - oidcProviderMetadataURL + - oidcResponseType + - oidcScope + - remoteIDAttribute + type: object override: description: Override, provides the ability to override the generated manifest of several child resources. @@ -295,14 +365,27 @@ spec: passwordSelectors: default: admin: AdminPassword - description: PasswordSelectors - Selectors to identify the AdminUser - password from the Secret + keystoneOIDCClientSecret: KeystoneClientSecret + keystoneOIDCCryptoPassphrase: KeystoneCryptoPassphrase + description: PasswordSelectors - Selectors to identify the AdminUser, + KeystoneOIDCClient, and KeystoneOIDCCryptoPassphrase passwords from + the Secret properties: admin: default: AdminPassword description: Admin - Selector to get the keystone Admin password from the Secret type: string + keystoneOIDCClientSecret: + default: KeystoneClientSecret + description: OIDCClientSecret - Selector to get the IdP client + secret from the Secret + type: string + keystoneOIDCCryptoPassphrase: + default: KeystoneCryptoPassphrase + description: OIDCCryptoPassphrase - Selector to get the OIDC crypto + passphrase from the Secret + type: string type: object preserveJobs: default: false diff --git a/config/samples/keystone_v1beta1_keystoneapi_tls_federation.yaml b/config/samples/keystone_v1beta1_keystoneapi_tls_federation.yaml new file mode 100644 index 00000000..460bb411 --- /dev/null +++ b/config/samples/keystone_v1beta1_keystoneapi_tls_federation.yaml @@ -0,0 +1,43 @@ +apiVersion: keystone.openstack.org/v1beta1 +kind: KeystoneAPI +metadata: + name: keystone +spec: + adminProject: admin + adminUser: admin + customServiceConfig: | + [DEFAULT] + debug = true + databaseInstance: openstack + databaseAccount: keystone + preserveJobs: false + region: regionOne + secret: osp-secret + resources: + requests: + memory: "500Mi" + cpu: "1.0" + tls: + api: + # secret holding tls.crt and tls.key for the APIs internal k8s service + internal: + secretName: cert-keystone-internal-svc + # secret holding tls.crt and tls.key for the APIs public k8s service + public: + secretName: cert-keystone-public-svc + # secret holding the tls-ca-bundle.pem to be used as a deploymend env CA bundle + caBundleSecretName: combined-ca-bundle + oidcFederation: + keystoneFederationIdentityProviderName: my_federation_provider_name + oidcCacheType: memcache + oidcClaimDelimiter: ; + oidcClaimPrefix: OIDC- + oidcClientID: my_federation_client_id + oidcIntrospectionEndpoint: my_federation_introspection_endpoint + oidcMemCacheServers: "" + oidcPassClaimsAs: both + oidcPassUserInfoAs: claims + oidcProviderMetadataURL: my_federation_provider_metadata_url + oidcResponseType: id_token + oidcScope: openid email profile + remoteIDAttribute: HTTP_OIDC_ISS diff --git a/controllers/keystoneapi_controller.go b/controllers/keystoneapi_controller.go index d788affc..378cfabf 100644 --- a/controllers/keystoneapi_controller.go +++ b/controllers/keystoneapi_controller.go @@ -1185,6 +1185,16 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( databaseAccount := db.GetAccount() dbSecret := db.GetSecret() + var endpointPublic string + enableFederation := false + if instance.Spec.OIDCFederation != nil { + enableFederation = true + endpointPublic, err = instance.GetEndpoint(endpoint.EndpointPublic) + if err != nil { + return err + } + } + templateParameters := map[string]interface{}{ "memcachedServers": mc.GetMemcachedServerListString(), "memcachedServersWithInet": mc.GetMemcachedServerListWithInetString(), @@ -1196,9 +1206,37 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( instance.Status.DatabaseHostname, keystone.DatabaseName, ), - "ProcessNumber": instance.Spec.HttpdCustomization.ProcessNumber, - "enableSecureRBAC": instance.Spec.EnableSecureRBAC, - "fernetMaxActiveKeys": instance.Spec.FernetMaxActiveKeys, + "enableSecureRBAC": instance.Spec.EnableSecureRBAC, + "ProcessNumber": instance.Spec.HttpdCustomization.ProcessNumber, + "enableFederation": enableFederation, + "federationTrustedDashboard": fmt.Sprintf("%s/dashboard/auth/websso/", endpointPublic), + "federationRemoteIDAttribute": instance.Spec.OIDCFederation.RemoteIDAttribute, + "fernetMaxActiveKeys": instance.Spec.FernetMaxActiveKeys, + } + + var OIDCClientSecret string + var OIDCCryptoPassphrase string + + if enableFederation { + ospSecret, _, err := oko_secret.GetSecret( + ctx, + h, + instance.Spec.Secret, + instance.Namespace) + if err != nil { + return err + } + + OIDCClientSecret := string(ospSecret.Data[instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret]) + if OIDCClientSecret == "" { + return fmt.Errorf("OIDCClientSecret cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret) + } + + OIDCCryptoPassphrase := string(ospSecret.Data[instance.Spec.PasswordSelectors.KeystoneOIDCCryptoPassphrase]) + if OIDCCryptoPassphrase == "" { + return fmt.Errorf("OIDCCryptoPassphrase cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCCryptoPassphrase) + } + } // create httpd vhost template parameters @@ -1207,11 +1245,29 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( endptConfig := map[string]interface{}{} endptConfig["ServerName"] = fmt.Sprintf("%s-%s.%s.svc", instance.Name, endpt.String(), instance.Namespace) endptConfig["TLS"] = false // default TLS to false, and set it bellow to true if enabled + endptConfig["EnableFederation"] = enableFederation + endptConfig["OIDCClaimPrefix"] = instance.Spec.OIDCFederation.OIDCClaimPrefix + endptConfig["OIDCResponseType"] = instance.Spec.OIDCFederation.OIDCResponseType + endptConfig["OIDCScope"] = instance.Spec.OIDCFederation.OIDCScope + endptConfig["OIDCProviderMetadataURL"] = instance.Spec.OIDCFederation.OIDCProviderMetadataURL + endptConfig["OIDCIntrospectionEndpoint"] = instance.Spec.OIDCFederation.OIDCIntrospectionEndpoint + endptConfig["OIDCClientID"] = instance.Spec.OIDCFederation.OIDCClientID + endptConfig["OIDCClientSecret"] = OIDCClientSecret + endptConfig["OIDCCryptoPassphrase"] = OIDCCryptoPassphrase + endptConfig["OIDCPassUserInfoAs"] = instance.Spec.OIDCFederation.OIDCPassUserInfoAs + endptConfig["OIDCPassClaimsAs"] = instance.Spec.OIDCFederation.OIDCPassClaimsAs + endptConfig["OIDCClaimDelimiter"] = instance.Spec.OIDCFederation.OIDCClaimDelimiter + endptConfig["OIDCCacheType"] = instance.Spec.OIDCFederation.OIDCCacheType + endptConfig["OIDCMemCacheServers"] = mc.GetMemcachedServerListString() + endptConfig["KeystoneFederationIdentityProviderName"] = instance.Spec.OIDCFederation.KeystoneFederationIdentityProviderName + endptConfig["KeystoneEndpoint"], _ = instance.GetEndpoint(endpoint.EndpointPublic) + if instance.Spec.TLS.API.Enabled(endpt) { endptConfig["TLS"] = true endptConfig["SSLCertificateFile"] = fmt.Sprintf("/etc/pki/tls/certs/%s.crt", endpt.String()) endptConfig["SSLCertificateKeyFile"] = fmt.Sprintf("/etc/pki/tls/private/%s.key", endpt.String()) } + httpdVhostConfig[endpt.String()] = endptConfig } templateParameters["VHosts"] = httpdVhostConfig @@ -1366,7 +1422,8 @@ func (r *KeystoneAPIReconciler) ensureFernetKeys( } annotations := map[string]string{ - fernetAnnotation: now.Format(time.RFC3339)} + fernetAnnotation: now.Format(time.RFC3339), + } tmpl := []util.Template{ { @@ -1463,6 +1520,11 @@ func (r *KeystoneAPIReconciler) ensureFernetKeys( return nil } + fernetKeys := make(map[string]string, len(secret.Data)) + for k, v := range secret.Data { + fernetKeys[k] = string(v[:]) + } + secret.Annotations[fernetAnnotation] = now.Format(time.RFC3339) // use update to apply changes to the secret, since EnsureSecrets @@ -1506,7 +1568,6 @@ func (r *KeystoneAPIReconciler) ensureDB( h *helper.Helper, instance *keystonev1.KeystoneAPI, ) (*mariadbv1.Database, ctrl.Result, error) { - // ensure MariaDBAccount exists. This account record may be created by // openstack-operator or the cloud operator up front without a specific // MariaDBDatabase configured yet. Otherwise, a MariaDBAccount CR is @@ -1517,7 +1578,6 @@ func (r *KeystoneAPIReconciler) ensureDB( ctx, h, instance.Spec.DatabaseAccount, instance.Namespace, false, keystone.DatabaseUsernamePrefix, ) - if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( mariadbv1.MariaDBAccountReadyCondition, @@ -1545,7 +1605,6 @@ func (r *KeystoneAPIReconciler) ensureDB( // create or patch the DB ctrlResult, err := db.CreateOrPatchAll(ctx, h) - if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( condition.DBReadyCondition, diff --git a/templates/keystoneapi/config/httpd.conf b/templates/keystoneapi/config/httpd.conf index 641b6ddf..4c12a502 100644 --- a/templates/keystoneapi/config/httpd.conf +++ b/templates/keystoneapi/config/httpd.conf @@ -51,11 +51,56 @@ CustomLog /dev/stdout proxy env=forwarded SSLCertificateKeyFile "{{ $vhost.SSLCertificateKeyFile }}" {{- end }} - ## WSGI configuration + ## WSGI configuration WSGIApplicationGroup %{GLOBAL} WSGIDaemonProcess {{ $endpt }} display-name={{ $endpt }} group=keystone processes={{ $.ProcessNumber }} threads=1 user=keystone WSGIProcessGroup {{ $endpt }} WSGIScriptAlias / "/usr/bin/keystone-wsgi-public" WSGIPassAuthorization On + + +{{- if $vhost.EnableFederation }} + # LoadModule auth_openidc_module modules/mod_auth_openidc.so + OIDCClaimPrefix "{{ $vhost.OIDCClaimPrefix }}" + OIDCResponseType "{{ $vhost.OIDCResponseType }}" + OIDCScope "{{ $vhost.OIDCScope }}" + OIDCProviderMetadataURL "{{ $vhost.OIDCProviderMetadataURL }}" + OIDCClientID "{{ $vhost.OIDCClientID }}" + OIDCClientSecret "{{ $vhost.OIDCClientSecret }}" + OIDCCryptoPassphrase "{{ $vhost.OIDCCryptoPassphrase }}" + OIDCClaimDelimiter "{{ $vhost.OIDCClaimDelimiter }}" + OIDCPassUserInfoAs "{{ $vhost.OIDCPassUserInfoAs }}" + OIDCPassClaimsAs "{{ $vhost.OIDCPassClaimsAs }}" + + OIDCCacheType "{{ $vhost.OIDCCacheType }}" + OIDCMemCacheServers "{{ $vhost.OIDCMemCacheServers }}" + + + # The following directives are necessary to support websso from Horizon + # (Per https://docs.openstack.org/keystone/pike/advanced-topics/federation/websso.html) + OIDCRedirectURI "{{ $vhost.KeystoneEndpoint }}/v3/auth/OS-FEDERATION/identity_providers/{{ $vhost.KeystoneFederationIdentityProviderName }}/protocols/openid/websso" + OIDCRedirectURI "{{ $vhost.KeystoneEndpoint }}/v3/auth/OS-FEDERATION/websso/openid" + + + AuthType "openid-connect" + Require valid-user + + + + AuthType "openid-connect" + Require valid-user + + + OIDCOAuthClientID "{{ $vhost.OIDCClientID }}" + OIDCOAuthClientSecret "{{ $vhost.OIDCClientSecret }}" + OIDCOAuthIntrospectionEndpoint "{{ $vhost.OIDCIntrospectionEndpoint }}" + + + AuthType oauth20 + Require valid-user + + +{{- end }} + {{ end }} diff --git a/templates/keystoneapi/config/keystone.conf b/templates/keystoneapi/config/keystone.conf index f2a2165b..d5f5a1cc 100644 --- a/templates/keystoneapi/config/keystone.conf +++ b/templates/keystoneapi/config/keystone.conf @@ -12,6 +12,17 @@ memcache_servers={{ .memcachedServersWithInet }} enabled=true tls_enabled={{ .memcachedTLS }} +{{if .enableFederation }} +[federation] +trusted_dashboard={{ .federationTrustedDashboard }} + +[openid] +remote_id_attribute={{ .federationRemoteIDAttribute }} + +[auth] +methods = password,token,oauth1,mapped,application_credential,openid +{{ end }} + [database] max_retries=-1 db_max_retries=-1 diff --git a/tests/functional/keystoneapi_controller_test.go b/tests/functional/keystoneapi_controller_test.go index c041641d..0a515b12 100644 --- a/tests/functional/keystoneapi_controller_test.go +++ b/tests/functional/keystoneapi_controller_test.go @@ -41,7 +41,6 @@ import ( ) var _ = Describe("Keystone controller", func() { - var keystoneAPIName types.NamespacedName var keystoneAccountName types.NamespacedName var keystoneDatabaseName types.NamespacedName @@ -56,7 +55,6 @@ var _ = Describe("Keystone controller", func() { var cronJobName types.NamespacedName BeforeEach(func() { - keystoneAPIName = types.NamespacedName{ Name: "keystone", Namespace: namespace, @@ -424,7 +422,6 @@ var _ = Describe("Keystone controller", func() { Namespace: namespace, }) }) - }) When("DB sync is completed", func() { @@ -965,7 +962,6 @@ var _ = Describe("Keystone controller", func() { configData = string(scrt.Data["my.cnf"]) Expect(configData).To( ContainSubstring("[client]\nssl-ca=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem\nssl=1")) - }) It("it creates deployment with CA and service certs mounted", func() { @@ -1434,7 +1430,6 @@ var _ = Describe("Keystone controller", func() { } } }, timeout, interval).Should(Succeed()) - }) }) @@ -1584,7 +1579,6 @@ var _ = Describe("Keystone controller", func() { // needs to make it all the way to the end where the mariadb finalizers // are removed from unused accounts since that's part of what we are testing SetupCR: func(accountName types.NamespacedName) { - spec := GetDefaultKeystoneAPISpec() spec["databaseAccount"] = accountName.Name @@ -1627,17 +1621,14 @@ var _ = Describe("Keystone controller", func() { condition.DeploymentReadyCondition, corev1.ConditionTrue, ) - }, // Change the account name in the service to a new name UpdateAccount: func(newAccountName types.NamespacedName) { - Eventually(func(g Gomega) { keystoneapi := GetKeystoneAPI(keystoneAPIName) keystoneapi.Spec.DatabaseAccount = newAccountName.Name g.Expect(th.K8sClient.Update(ctx, keystoneapi)).Should(Succeed()) }, timeout, interval).Should(Succeed()) - }, // delete the keystone instance to exercise finalizer removal DeleteCR: func() { @@ -1656,12 +1647,10 @@ var _ = Describe("Keystone controller", func() { ContainSubstring(fmt.Sprintf("connection=mysql+pymysql://%s:%s@hostname-for-openstack.%s.svc/keystone?read_default_file=/etc/my.cnf", username, password, namespace))) }, timeout, interval).Should(Succeed()) - }) mariadbSuite.RunConfigHashSuite(func() string { deployment := th.GetDeployment(deploymentName) return GetEnvVarValue(deployment.Spec.Template.Spec.Containers[0].Env, "CONFIG_HASH", "") }) - }) From ea56a81d946caf2799427fe897fa776d6ed3ce01 Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Mon, 2 Dec 2024 13:32:52 -0600 Subject: [PATCH 02/14] Rebase temp commit --- controllers/keystoneapi_controller.go | 20 +++++++++++++++++++- tests/functional/base_test.go | 4 +++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/controllers/keystoneapi_controller.go b/controllers/keystoneapi_controller.go index 378cfabf..7dc094e9 100644 --- a/controllers/keystoneapi_controller.go +++ b/controllers/keystoneapi_controller.go @@ -716,7 +716,7 @@ func (r *KeystoneAPIReconciler) reconcileNormal( // NOTE: VerifySecret handles the "not found" error and returns RequeueAfter ctrl.Result if so, so we don't // need to check the error type here // - hash, result, err := oko_secret.VerifySecret(ctx, types.NamespacedName{Name: instance.Spec.Secret, Namespace: instance.Namespace}, []string{"AdminPassword"}, helper.GetClient(), time.Second*10) + hash, result, err := oko_secret.VerifySecret(ctx, types.NamespacedName{Name: instance.Spec.Secret, Namespace: instance.Namespace}, []string{"AdminPassword", "KeystoneOIDCClientSecret", "KeystoneOIDCCryptoPassphrase"}, helper.GetClient(), time.Second*10) if err != nil { instance.Status.Conditions.Set(condition.FalseCondition( condition.InputReadyCondition, @@ -1211,7 +1211,10 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( "enableFederation": enableFederation, "federationTrustedDashboard": fmt.Sprintf("%s/dashboard/auth/websso/", endpointPublic), "federationRemoteIDAttribute": instance.Spec.OIDCFederation.RemoteIDAttribute, +<<<<<<< HEAD "fernetMaxActiveKeys": instance.Spec.FernetMaxActiveKeys, +======= +>>>>>>> 3ba233c (Rebase temp commit) } var OIDCClientSecret string @@ -1227,6 +1230,7 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( return err } +<<<<<<< HEAD OIDCClientSecret := string(ospSecret.Data[instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret]) if OIDCClientSecret == "" { return fmt.Errorf("OIDCClientSecret cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret) @@ -1237,6 +1241,17 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( return fmt.Errorf("OIDCCryptoPassphrase cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCCryptoPassphrase) } +======= + OIDCClientSecret = string(ospSecret.Data[instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret]) + if OIDCClientSecret == "" { + return fmt.Errorf("OIDCClientSecret cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret) + } + + OIDCCryptoPassphrase = string(ospSecret.Data[instance.Spec.PasswordSelectors.KeystoneOIDCCryptoPassphrase]) + if OIDCCryptoPassphrase == "" { + return fmt.Errorf("OIDCCryptoPassphrase cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCCryptoPassphrase) + } +>>>>>>> 3ba233c (Rebase temp commit) } // create httpd vhost template parameters @@ -1261,7 +1276,10 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( endptConfig["OIDCMemCacheServers"] = mc.GetMemcachedServerListString() endptConfig["KeystoneFederationIdentityProviderName"] = instance.Spec.OIDCFederation.KeystoneFederationIdentityProviderName endptConfig["KeystoneEndpoint"], _ = instance.GetEndpoint(endpoint.EndpointPublic) +<<<<<<< HEAD +======= +>>>>>>> 3ba233c (Rebase temp commit) if instance.Spec.TLS.API.Enabled(endpt) { endptConfig["TLS"] = true endptConfig["SSLCertificateFile"] = fmt.Sprintf("/etc/pki/tls/certs/%s.crt", endpt.String()) diff --git a/tests/functional/base_test.go b/tests/functional/base_test.go index f318d672..e2a87486 100644 --- a/tests/functional/base_test.go +++ b/tests/functional/base_test.go @@ -90,7 +90,9 @@ func CreateKeystoneAPISecret(namespace string, name string) *corev1.Secret { return th.CreateSecret( types.NamespacedName{Namespace: namespace, Name: name}, map[string][]byte{ - "AdminPassword": []byte("12345678"), + "AdminPassword": []byte("12345678"), + "KeystoneOIDCClientSecret": []byte("secret"), + "KeystoneOIDCCryptoPassphrase": []byte("openstack"), }, ) } From 5404ccf2e75222e22dc71a38aeca0d1c4d3acec8 Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Mon, 2 Dec 2024 21:33:42 -0600 Subject: [PATCH 03/14] Fix formatting --- controllers/keystoneapi_controller.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/controllers/keystoneapi_controller.go b/controllers/keystoneapi_controller.go index 7dc094e9..5ea1fafb 100644 --- a/controllers/keystoneapi_controller.go +++ b/controllers/keystoneapi_controller.go @@ -1211,10 +1211,14 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( "enableFederation": enableFederation, "federationTrustedDashboard": fmt.Sprintf("%s/dashboard/auth/websso/", endpointPublic), "federationRemoteIDAttribute": instance.Spec.OIDCFederation.RemoteIDAttribute, +<<<<<<< HEAD <<<<<<< HEAD "fernetMaxActiveKeys": instance.Spec.FernetMaxActiveKeys, ======= >>>>>>> 3ba233c (Rebase temp commit) +======= + "fernetMaxActiveKeys": instance.Spec.FernetMaxActiveKeys, +>>>>>>> 98b420d (Fix formatting) } var OIDCClientSecret string @@ -1276,10 +1280,6 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( endptConfig["OIDCMemCacheServers"] = mc.GetMemcachedServerListString() endptConfig["KeystoneFederationIdentityProviderName"] = instance.Spec.OIDCFederation.KeystoneFederationIdentityProviderName endptConfig["KeystoneEndpoint"], _ = instance.GetEndpoint(endpoint.EndpointPublic) -<<<<<<< HEAD - -======= ->>>>>>> 3ba233c (Rebase temp commit) if instance.Spec.TLS.API.Enabled(endpt) { endptConfig["TLS"] = true endptConfig["SSLCertificateFile"] = fmt.Sprintf("/etc/pki/tls/certs/%s.crt", endpt.String()) From 113bf3556a13945f1274847b33518a7b6dded627 Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Fri, 6 Dec 2024 12:43:54 -0600 Subject: [PATCH 04/14] Change settings to optional --- .../keystone.openstack.org_keystoneapis.yaml | 13 +-------- api/v1beta1/keystoneapi_types.go | 27 ++++++++++--------- .../keystone.openstack.org_keystoneapis.yaml | 13 +-------- 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/api/bases/keystone.openstack.org_keystoneapis.yaml b/api/bases/keystone.openstack.org_keystoneapis.yaml index 2076f48d..13a59bf6 100644 --- a/api/bases/keystone.openstack.org_keystoneapis.yaml +++ b/api/bases/keystone.openstack.org_keystoneapis.yaml @@ -163,6 +163,7 @@ spec: description: OIDCIntrospectionEndpoint type: string oidcMemCacheServers: + default: "" description: OIDCMemCacheServers type: string oidcPassClaimsAs: @@ -190,19 +191,7 @@ spec: description: RemoteIDAttribute type: string required: - - keystoneFederationIdentityProviderName - - oidcCacheType - - oidcClaimDelimiter - - oidcClaimPrefix - - oidcClientID - - oidcIntrospectionEndpoint - oidcMemCacheServers - - oidcPassClaimsAs - - oidcPassUserInfoAs - - oidcProviderMetadataURL - - oidcResponseType - - oidcScope - - remoteIDAttribute type: object override: description: Override, provides the ability to override the generated diff --git a/api/v1beta1/keystoneapi_types.go b/api/v1beta1/keystoneapi_types.go index 0d03ed45..460f2b32 100644 --- a/api/v1beta1/keystoneapi_types.go +++ b/api/v1beta1/keystoneapi_types.go @@ -217,66 +217,67 @@ type PasswordSelector struct { // KeystoneFederationSpec to provide the configuration values for OIDC Federation type KeystoneFederationSpec struct { - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="OIDC-" // OIDCClaimPrefix OIDCClaimPrefix string `json:"oidcClaimPrefix"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="id_token" // OIDCResponseType OIDCResponseType string `json:"oidcResponseType"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="openid email profile" // OIDCScope OIDCScope string `json:"oidcScope"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="" // OIDCProviderMetadataURL OIDCProviderMetadataURL string `json:"oidcProviderMetadataURL"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="" // OIDCIntrospectionEndpoint OIDCIntrospectionEndpoint string `json:"oidcIntrospectionEndpoint"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="" // OIDCClientID OIDCClientID string `json:"oidcClientID"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default=";" // OIDCClaimDelimiter OIDCClaimDelimiter string `json:"oidcClaimDelimiter"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="claims" // OIDCPassUserInfoAs OIDCPassUserInfoAs string `json:"oidcPassUserInfoAs"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="both" // OIDCPassClaimsAs OIDCPassClaimsAs string `json:"oidcPassClaimsAs"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="memcache" // OIDCCacheType OIDCCacheType string `json:"oidcCacheType"` - // +kubebuilder:validaton:Required + // +kubebuilder:validaton:Optional + // +kubebuilder:default="" // OIDCMemCacheServers OIDCMemCacheServers string `json:"oidcMemCacheServers"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="HTTP_OIDC_ISS" // RemoteIDAttribute RemoteIDAttribute string `json:"remoteIDAttribute"` - // +kubebuilder:validation:Required + // +kubebuilder:validation:Optional // +kubebuilder:default="" // KeystoneFederationIdentityProviderName KeystoneFederationIdentityProviderName string `json:"keystoneFederationIdentityProviderName"` diff --git a/config/crd/bases/keystone.openstack.org_keystoneapis.yaml b/config/crd/bases/keystone.openstack.org_keystoneapis.yaml index 2076f48d..13a59bf6 100644 --- a/config/crd/bases/keystone.openstack.org_keystoneapis.yaml +++ b/config/crd/bases/keystone.openstack.org_keystoneapis.yaml @@ -163,6 +163,7 @@ spec: description: OIDCIntrospectionEndpoint type: string oidcMemCacheServers: + default: "" description: OIDCMemCacheServers type: string oidcPassClaimsAs: @@ -190,19 +191,7 @@ spec: description: RemoteIDAttribute type: string required: - - keystoneFederationIdentityProviderName - - oidcCacheType - - oidcClaimDelimiter - - oidcClaimPrefix - - oidcClientID - - oidcIntrospectionEndpoint - oidcMemCacheServers - - oidcPassClaimsAs - - oidcPassUserInfoAs - - oidcProviderMetadataURL - - oidcResponseType - - oidcScope - - remoteIDAttribute type: object override: description: Override, provides the ability to override the generated From ed85d5b6ae3df4d0994286f43fa4e99a6b27ff9c Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Mon, 9 Dec 2024 11:57:03 -0600 Subject: [PATCH 05/14] Remove oidcMemcacheServers param --- api/bases/keystone.openstack.org_keystoneapis.yaml | 6 ------ api/v1beta1/keystoneapi_types.go | 5 ----- .../bases/keystone.openstack.org_keystoneapis.yaml | 6 ------ go.mod | 11 ++++++++++- go.sum | 13 +++++++++++++ 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/api/bases/keystone.openstack.org_keystoneapis.yaml b/api/bases/keystone.openstack.org_keystoneapis.yaml index 13a59bf6..475267f4 100644 --- a/api/bases/keystone.openstack.org_keystoneapis.yaml +++ b/api/bases/keystone.openstack.org_keystoneapis.yaml @@ -162,10 +162,6 @@ spec: default: "" description: OIDCIntrospectionEndpoint type: string - oidcMemCacheServers: - default: "" - description: OIDCMemCacheServers - type: string oidcPassClaimsAs: default: both description: OIDCPassClaimsAs @@ -190,8 +186,6 @@ spec: default: HTTP_OIDC_ISS description: RemoteIDAttribute type: string - required: - - oidcMemCacheServers type: object override: description: Override, provides the ability to override the generated diff --git a/api/v1beta1/keystoneapi_types.go b/api/v1beta1/keystoneapi_types.go index 460f2b32..9edacc67 100644 --- a/api/v1beta1/keystoneapi_types.go +++ b/api/v1beta1/keystoneapi_types.go @@ -267,11 +267,6 @@ type KeystoneFederationSpec struct { // OIDCCacheType OIDCCacheType string `json:"oidcCacheType"` - // +kubebuilder:validaton:Optional - // +kubebuilder:default="" - // OIDCMemCacheServers - OIDCMemCacheServers string `json:"oidcMemCacheServers"` - // +kubebuilder:validation:Optional // +kubebuilder:default="HTTP_OIDC_ISS" // RemoteIDAttribute diff --git a/config/crd/bases/keystone.openstack.org_keystoneapis.yaml b/config/crd/bases/keystone.openstack.org_keystoneapis.yaml index 13a59bf6..475267f4 100644 --- a/config/crd/bases/keystone.openstack.org_keystoneapis.yaml +++ b/config/crd/bases/keystone.openstack.org_keystoneapis.yaml @@ -162,10 +162,6 @@ spec: default: "" description: OIDCIntrospectionEndpoint type: string - oidcMemCacheServers: - default: "" - description: OIDCMemCacheServers - type: string oidcPassClaimsAs: default: both description: OIDCPassClaimsAs @@ -190,8 +186,6 @@ spec: default: HTTP_OIDC_ISS description: RemoteIDAttribute type: string - required: - - oidcMemCacheServers type: object override: description: Override, provides the ability to override the generated diff --git a/go.mod b/go.mod index 7008c8f8..3b169183 100644 --- a/go.mod +++ b/go.mod @@ -8,12 +8,21 @@ require ( github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.5 github.com/onsi/ginkgo/v2 v2.20.1 github.com/onsi/gomega v1.34.1 +<<<<<<< HEAD github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241217075239-1fc4566cc5ab github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240213125925-e40975f3db7e github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0 +======= + github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241209150727-cbad718905d9 + github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240213125925-e40975f3db7e + github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241114091812-6dc9fd0961dc + github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241114091812-6dc9fd0961dc + github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241114091812-6dc9fd0961dc + github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241209142852-f7ff11df7e37 +>>>>>>> 1779ae5 (Remove oidcMemcacheServers param) go.uber.org/zap v1.27.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.29.10 @@ -75,7 +84,7 @@ require ( k8s.io/apiextensions-apiserver v0.29.10 // indirect k8s.io/component-base v0.29.10 // indirect k8s.io/klog/v2 v2.120.1 // indirect - k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect + &k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 9270d6c7..5a8cda9b 100644 --- a/go.sum +++ b/go.sum @@ -78,6 +78,7 @@ github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094 h1:J1wuGhVxpsHykZBa6Beb1gQ96Ptej9AE/BvwCBiRj1E= github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4= +<<<<<<< HEAD github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241217075239-1fc4566cc5ab h1:Pm9zQyhrs/zGAk9jvyt0hSBP28aHsFdWyI99M/lvFxU= github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241217075239-1fc4566cc5ab/go.mod h1:SSYBbFbgQbOwyY2cQNet7fSdQHHPb2rLo6GXE97Awp8= github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e h1:hf4kVQBkyG79WcHBxdQ25QrDBbGFdarebS1Tc0Xclq4= @@ -88,6 +89,18 @@ github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.202412161138 github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0 h1:XBx1TuyKhgtWAigYVcdqTUzIwWRYHN63pfa0zxHB12M= github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0/go.mod h1:Uyc8m+72l3rVm6jKb8FRUrQbjMWyifc5m0K+Ge0QV80= +======= +github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241209150727-cbad718905d9 h1:EMeHQ9tArdGwOnJiPWxXlxb4onnMCZCjgpZbYYDG5yg= +github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241209150727-cbad718905d9/go.mod h1:Fkg09ogWFffMgA5XQzauXDv1bYvyxf9hl4VeHX8O2Tk= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241114091812-6dc9fd0961dc h1:Ufa/q/nC9wmKblvsc0kJppsXHOJoY4fbUamb3ItWCOk= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241114091812-6dc9fd0961dc/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241114091812-6dc9fd0961dc h1:q68lNZwCrKgLgcakrDu5VtpiWuC1pzQZKlb1M33EPMI= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241114091812-6dc9fd0961dc/go.mod h1:IASoGvp5QM/tBJUd/8i8uIjj4DBnI+64Ydh4r7pmnvA= +github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241114091812-6dc9fd0961dc h1:knyjd0eg4DyY+dTDHSrE9QwrZ0mtr7MpASCrmhW+5pw= +github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241114091812-6dc9fd0961dc/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= +github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241209142852-f7ff11df7e37 h1:dAn6djYwVe4rn1U+KCGTR8k2c3ixZJ1JbzUmtwJ5Itk= +github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241209142852-f7ff11df7e37/go.mod h1:348EPtAdpE2LxHAH4bHdCMNP7HyX6DevwEsF9DQ0S2k= +>>>>>>> 1779ae5 (Remove oidcMemcacheServers param) github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= From e53f4aab8e7f82c07057220b7bb5a5d58f5d948e Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Mon, 9 Dec 2024 12:00:15 -0600 Subject: [PATCH 06/14] Update api go.mod to match main --- api/go.mod | 6 ++++++ api/go.sum | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/api/go.mod b/api/go.mod index ec8cdab9..c9da1727 100644 --- a/api/go.mod +++ b/api/go.mod @@ -7,9 +7,15 @@ require ( github.com/google/uuid v1.6.0 github.com/gophercloud/gophercloud v1.14.1 github.com/onsi/gomega v1.34.1 +<<<<<<< HEAD github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e +======= + github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a + github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333 + github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333 +>>>>>>> bea7f45 (Update api go.mod to match main) golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 k8s.io/api v0.29.10 k8s.io/apimachinery v0.29.10 diff --git a/api/go.sum b/api/go.sum index d34a372c..5201926d 100644 --- a/api/go.sum +++ b/api/go.sum @@ -80,12 +80,21 @@ github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094 h1:J1wuGhVxpsHykZBa6Beb1gQ96Ptej9AE/BvwCBiRj1E= github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4= +<<<<<<< HEAD github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e h1:hf4kVQBkyG79WcHBxdQ25QrDBbGFdarebS1Tc0Xclq4= github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e h1:HFo4OqPY0x4ZQeaWI2YGonTXAGTQFt+rOEJlfZVhS7s= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:IASoGvp5QM/tBJUd/8i8uIjj4DBnI+64Ydh4r7pmnvA= github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e h1:/iWDp3j+ET3gE5IjKHtdZaPd4SQyLHB/4L5jB16cV3I= github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= +======= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a h1:izLb1IVe6pXuQ6Y49CIAkN7yS9qe2fDptRlhxMHSYv4= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333 h1:XWxFOmOYPC6V5KUDkzU20vQOsha1PPNQzzqkNv926mg= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333/go.mod h1:IASoGvp5QM/tBJUd/8i8uIjj4DBnI+64Ydh4r7pmnvA= +github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333 h1:zUlxLqucrLMNDp6dc3I7eYWZyGVE7tLrPyWR/n+VD9w= +github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= +>>>>>>> bea7f45 (Update api go.mod to match main) github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= From 065c0c824efb88ee5631d8f5237e04c6faf74be3 Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Mon, 9 Dec 2024 12:03:16 -0600 Subject: [PATCH 07/14] Update go.mod to match main --- go.mod | 9 +++++++++ go.sum | 13 +++++++++++++ 2 files changed, 22 insertions(+) diff --git a/go.mod b/go.mod index 3b169183..ddc9891f 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.5 github.com/onsi/ginkgo/v2 v2.20.1 github.com/onsi/gomega v1.34.1 +<<<<<<< HEAD <<<<<<< HEAD github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241217075239-1fc4566cc5ab github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240213125925-e40975f3db7e @@ -23,6 +24,14 @@ require ( github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241114091812-6dc9fd0961dc github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241209142852-f7ff11df7e37 >>>>>>> 1779ae5 (Remove oidcMemcacheServers param) +======= + github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241030094454-1ea50ac03c59 + github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240213125925-e40975f3db7e + github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a + github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333 + github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333 + github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0 +>>>>>>> 1ef836e (Update go.mod to match main) go.uber.org/zap v1.27.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.29.10 diff --git a/go.sum b/go.sum index 5a8cda9b..9efa551d 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,7 @@ github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeD github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094 h1:J1wuGhVxpsHykZBa6Beb1gQ96Ptej9AE/BvwCBiRj1E= github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4= <<<<<<< HEAD +<<<<<<< HEAD github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241217075239-1fc4566cc5ab h1:Pm9zQyhrs/zGAk9jvyt0hSBP28aHsFdWyI99M/lvFxU= github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241217075239-1fc4566cc5ab/go.mod h1:SSYBbFbgQbOwyY2cQNet7fSdQHHPb2rLo6GXE97Awp8= github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e h1:hf4kVQBkyG79WcHBxdQ25QrDBbGFdarebS1Tc0Xclq4= @@ -101,6 +102,18 @@ github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.202411140918 github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241209142852-f7ff11df7e37 h1:dAn6djYwVe4rn1U+KCGTR8k2c3ixZJ1JbzUmtwJ5Itk= github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241209142852-f7ff11df7e37/go.mod h1:348EPtAdpE2LxHAH4bHdCMNP7HyX6DevwEsF9DQ0S2k= >>>>>>> 1779ae5 (Remove oidcMemcacheServers param) +======= +github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241030094454-1ea50ac03c59 h1:qSteLhmz5jDUEI4FUB/gFc+UI5p5tU+Edy/RKtaxNQQ= +github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241030094454-1ea50ac03c59/go.mod h1:1khEYHcLFRF0wBT7bFM7IHTmY7u3eTxwowOvNY/A3qo= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a h1:izLb1IVe6pXuQ6Y49CIAkN7yS9qe2fDptRlhxMHSYv4= +github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333 h1:XWxFOmOYPC6V5KUDkzU20vQOsha1PPNQzzqkNv926mg= +github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333/go.mod h1:IASoGvp5QM/tBJUd/8i8uIjj4DBnI+64Ydh4r7pmnvA= +github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333 h1:zUlxLqucrLMNDp6dc3I7eYWZyGVE7tLrPyWR/n+VD9w= +github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= +github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0 h1:XBx1TuyKhgtWAigYVcdqTUzIwWRYHN63pfa0zxHB12M= +github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0/go.mod h1:Uyc8m+72l3rVm6jKb8FRUrQbjMWyifc5m0K+Ge0QV80= +>>>>>>> 1ef836e (Update go.mod to match main) github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= From 1af3f6523b781b950f5aaada9d21abb785fb3bd2 Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Mon, 9 Dec 2024 13:08:35 -0600 Subject: [PATCH 08/14] Rebase fixups --- controllers/keystoneapi_controller.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/controllers/keystoneapi_controller.go b/controllers/keystoneapi_controller.go index 5ea1fafb..9a16454f 100644 --- a/controllers/keystoneapi_controller.go +++ b/controllers/keystoneapi_controller.go @@ -1211,14 +1211,7 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( "enableFederation": enableFederation, "federationTrustedDashboard": fmt.Sprintf("%s/dashboard/auth/websso/", endpointPublic), "federationRemoteIDAttribute": instance.Spec.OIDCFederation.RemoteIDAttribute, -<<<<<<< HEAD -<<<<<<< HEAD "fernetMaxActiveKeys": instance.Spec.FernetMaxActiveKeys, -======= ->>>>>>> 3ba233c (Rebase temp commit) -======= - "fernetMaxActiveKeys": instance.Spec.FernetMaxActiveKeys, ->>>>>>> 98b420d (Fix formatting) } var OIDCClientSecret string @@ -1234,18 +1227,6 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( return err } -<<<<<<< HEAD - OIDCClientSecret := string(ospSecret.Data[instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret]) - if OIDCClientSecret == "" { - return fmt.Errorf("OIDCClientSecret cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret) - } - - OIDCCryptoPassphrase := string(ospSecret.Data[instance.Spec.PasswordSelectors.KeystoneOIDCCryptoPassphrase]) - if OIDCCryptoPassphrase == "" { - return fmt.Errorf("OIDCCryptoPassphrase cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCCryptoPassphrase) - } - -======= OIDCClientSecret = string(ospSecret.Data[instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret]) if OIDCClientSecret == "" { return fmt.Errorf("OIDCClientSecret cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCClientSecret) @@ -1255,7 +1236,6 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( if OIDCCryptoPassphrase == "" { return fmt.Errorf("OIDCCryptoPassphrase cannot be empty, no password found for selector %s in secret %s", ospSecret.Name, instance.Spec.PasswordSelectors.KeystoneOIDCCryptoPassphrase) } ->>>>>>> 3ba233c (Rebase temp commit) } // create httpd vhost template parameters From f89b3a9e9fb1e3c5a1f099af5ca52010d2d32e77 Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Mon, 9 Dec 2024 13:12:49 -0600 Subject: [PATCH 09/14] Remove old fernet key loop --- controllers/keystoneapi_controller.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/controllers/keystoneapi_controller.go b/controllers/keystoneapi_controller.go index 9a16454f..e5440a28 100644 --- a/controllers/keystoneapi_controller.go +++ b/controllers/keystoneapi_controller.go @@ -1518,11 +1518,6 @@ func (r *KeystoneAPIReconciler) ensureFernetKeys( return nil } - fernetKeys := make(map[string]string, len(secret.Data)) - for k, v := range secret.Data { - fernetKeys[k] = string(v[:]) - } - secret.Annotations[fernetAnnotation] = now.Format(time.RFC3339) // use update to apply changes to the secret, since EnsureSecrets From f3134872cfc8f668eedc599bb86a194aa66bb16e Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Tue, 10 Dec 2024 09:30:24 -0600 Subject: [PATCH 10/14] Fix nil pointer dereference --- controllers/keystoneapi_controller.go | 36 +++++++++++++++------------ 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/controllers/keystoneapi_controller.go b/controllers/keystoneapi_controller.go index e5440a28..6484e175 100644 --- a/controllers/keystoneapi_controller.go +++ b/controllers/keystoneapi_controller.go @@ -1186,6 +1186,7 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( dbSecret := db.GetSecret() var endpointPublic string + var federationRemoteIDAttribute string enableFederation := false if instance.Spec.OIDCFederation != nil { enableFederation = true @@ -1193,6 +1194,7 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( if err != nil { return err } + federationRemoteIDAttribute = instance.Spec.OIDCFederation.RemoteIDAttribute } templateParameters := map[string]interface{}{ @@ -1210,7 +1212,7 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( "ProcessNumber": instance.Spec.HttpdCustomization.ProcessNumber, "enableFederation": enableFederation, "federationTrustedDashboard": fmt.Sprintf("%s/dashboard/auth/websso/", endpointPublic), - "federationRemoteIDAttribute": instance.Spec.OIDCFederation.RemoteIDAttribute, + "federationRemoteIDAttribute": federationRemoteIDAttribute, "fernetMaxActiveKeys": instance.Spec.FernetMaxActiveKeys, } @@ -1245,21 +1247,23 @@ func (r *KeystoneAPIReconciler) generateServiceConfigMaps( endptConfig["ServerName"] = fmt.Sprintf("%s-%s.%s.svc", instance.Name, endpt.String(), instance.Namespace) endptConfig["TLS"] = false // default TLS to false, and set it bellow to true if enabled endptConfig["EnableFederation"] = enableFederation - endptConfig["OIDCClaimPrefix"] = instance.Spec.OIDCFederation.OIDCClaimPrefix - endptConfig["OIDCResponseType"] = instance.Spec.OIDCFederation.OIDCResponseType - endptConfig["OIDCScope"] = instance.Spec.OIDCFederation.OIDCScope - endptConfig["OIDCProviderMetadataURL"] = instance.Spec.OIDCFederation.OIDCProviderMetadataURL - endptConfig["OIDCIntrospectionEndpoint"] = instance.Spec.OIDCFederation.OIDCIntrospectionEndpoint - endptConfig["OIDCClientID"] = instance.Spec.OIDCFederation.OIDCClientID - endptConfig["OIDCClientSecret"] = OIDCClientSecret - endptConfig["OIDCCryptoPassphrase"] = OIDCCryptoPassphrase - endptConfig["OIDCPassUserInfoAs"] = instance.Spec.OIDCFederation.OIDCPassUserInfoAs - endptConfig["OIDCPassClaimsAs"] = instance.Spec.OIDCFederation.OIDCPassClaimsAs - endptConfig["OIDCClaimDelimiter"] = instance.Spec.OIDCFederation.OIDCClaimDelimiter - endptConfig["OIDCCacheType"] = instance.Spec.OIDCFederation.OIDCCacheType - endptConfig["OIDCMemCacheServers"] = mc.GetMemcachedServerListString() - endptConfig["KeystoneFederationIdentityProviderName"] = instance.Spec.OIDCFederation.KeystoneFederationIdentityProviderName - endptConfig["KeystoneEndpoint"], _ = instance.GetEndpoint(endpoint.EndpointPublic) + if enableFederation { + endptConfig["OIDCClaimPrefix"] = instance.Spec.OIDCFederation.OIDCClaimPrefix + endptConfig["OIDCResponseType"] = instance.Spec.OIDCFederation.OIDCResponseType + endptConfig["OIDCScope"] = instance.Spec.OIDCFederation.OIDCScope + endptConfig["OIDCProviderMetadataURL"] = instance.Spec.OIDCFederation.OIDCProviderMetadataURL + endptConfig["OIDCIntrospectionEndpoint"] = instance.Spec.OIDCFederation.OIDCIntrospectionEndpoint + endptConfig["OIDCClientID"] = instance.Spec.OIDCFederation.OIDCClientID + endptConfig["OIDCClientSecret"] = OIDCClientSecret + endptConfig["OIDCCryptoPassphrase"] = OIDCCryptoPassphrase + endptConfig["OIDCPassUserInfoAs"] = instance.Spec.OIDCFederation.OIDCPassUserInfoAs + endptConfig["OIDCPassClaimsAs"] = instance.Spec.OIDCFederation.OIDCPassClaimsAs + endptConfig["OIDCClaimDelimiter"] = instance.Spec.OIDCFederation.OIDCClaimDelimiter + endptConfig["OIDCCacheType"] = instance.Spec.OIDCFederation.OIDCCacheType + endptConfig["OIDCMemCacheServers"] = mc.GetMemcachedServerListString() + endptConfig["KeystoneFederationIdentityProviderName"] = instance.Spec.OIDCFederation.KeystoneFederationIdentityProviderName + endptConfig["KeystoneEndpoint"], _ = instance.GetEndpoint(endpoint.EndpointPublic) + } if instance.Spec.TLS.API.Enabled(endpt) { endptConfig["TLS"] = true endptConfig["SSLCertificateFile"] = fmt.Sprintf("/etc/pki/tls/certs/%s.crt", endpt.String()) From 695fd14a3c0dc10c197283cdd1b79d1b33b8fa2f Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Tue, 17 Dec 2024 13:02:41 -0600 Subject: [PATCH 11/14] Update password names --- .../keystone.openstack.org_keystoneapis.yaml | 8 +- api/v1beta1/keystoneapi_types.go | 6 +- .../keystone.openstack.org_keystoneapis.yaml | 8 +- .../functional/keystoneapi_controller_test.go | 87 +++++++++++++++++++ 4 files changed, 98 insertions(+), 11 deletions(-) diff --git a/api/bases/keystone.openstack.org_keystoneapis.yaml b/api/bases/keystone.openstack.org_keystoneapis.yaml index 475267f4..1b34f8dd 100644 --- a/api/bases/keystone.openstack.org_keystoneapis.yaml +++ b/api/bases/keystone.openstack.org_keystoneapis.yaml @@ -348,8 +348,8 @@ spec: passwordSelectors: default: admin: AdminPassword - keystoneOIDCClientSecret: KeystoneClientSecret - keystoneOIDCCryptoPassphrase: KeystoneCryptoPassphrase + keystoneOIDCClientSecret: KeystoneOIDCClientSecret + keystoneOIDCCryptoPassphrase: KeystoneOIDCCryptoPassphrase description: PasswordSelectors - Selectors to identify the AdminUser, KeystoneOIDCClient, and KeystoneOIDCCryptoPassphrase passwords from the Secret @@ -360,12 +360,12 @@ spec: from the Secret type: string keystoneOIDCClientSecret: - default: KeystoneClientSecret + default: KeystoneOIDCClientSecret description: OIDCClientSecret - Selector to get the IdP client secret from the Secret type: string keystoneOIDCCryptoPassphrase: - default: KeystoneCryptoPassphrase + default: KeystoneOIDCCryptoPassphrase description: OIDCCryptoPassphrase - Selector to get the OIDC crypto passphrase from the Secret type: string diff --git a/api/v1beta1/keystoneapi_types.go b/api/v1beta1/keystoneapi_types.go index 9edacc67..3f274887 100644 --- a/api/v1beta1/keystoneapi_types.go +++ b/api/v1beta1/keystoneapi_types.go @@ -132,7 +132,7 @@ type KeystoneAPISpecCore struct { FernetMaxActiveKeys *int32 `json:"fernetMaxActiveKeys"` // +kubebuilder:validation:Optional - // +kubebuilder:default={admin: AdminPassword, keystoneOIDCClientSecret: KeystoneClientSecret, keystoneOIDCCryptoPassphrase: KeystoneCryptoPassphrase} + // +kubebuilder:default={admin: AdminPassword, keystoneOIDCClientSecret: KeystoneOIDCClientSecret, keystoneOIDCCryptoPassphrase: KeystoneOIDCCryptoPassphrase} // PasswordSelectors - Selectors to identify the AdminUser, KeystoneOIDCClient, and KeystoneOIDCCryptoPassphrase passwords from the Secret PasswordSelectors PasswordSelector `json:"passwordSelectors"` @@ -205,12 +205,12 @@ type PasswordSelector struct { Admin string `json:"admin"` // +kubebuilder:validation:Optional - // +kubebuilder:default="KeystoneClientSecret" + // +kubebuilder:default="KeystoneOIDCClientSecret" // OIDCClientSecret - Selector to get the IdP client secret from the Secret KeystoneOIDCClientSecret string `json:"keystoneOIDCClientSecret"` // +kubebuilder:validation:Optional - // +kubebuilder:default="KeystoneCryptoPassphrase" + // +kubebuilder:default="KeystoneOIDCCryptoPassphrase" // OIDCCryptoPassphrase - Selector to get the OIDC crypto passphrase from the Secret KeystoneOIDCCryptoPassphrase string `json:"keystoneOIDCCryptoPassphrase"` } diff --git a/config/crd/bases/keystone.openstack.org_keystoneapis.yaml b/config/crd/bases/keystone.openstack.org_keystoneapis.yaml index 475267f4..1b34f8dd 100644 --- a/config/crd/bases/keystone.openstack.org_keystoneapis.yaml +++ b/config/crd/bases/keystone.openstack.org_keystoneapis.yaml @@ -348,8 +348,8 @@ spec: passwordSelectors: default: admin: AdminPassword - keystoneOIDCClientSecret: KeystoneClientSecret - keystoneOIDCCryptoPassphrase: KeystoneCryptoPassphrase + keystoneOIDCClientSecret: KeystoneOIDCClientSecret + keystoneOIDCCryptoPassphrase: KeystoneOIDCCryptoPassphrase description: PasswordSelectors - Selectors to identify the AdminUser, KeystoneOIDCClient, and KeystoneOIDCCryptoPassphrase passwords from the Secret @@ -360,12 +360,12 @@ spec: from the Secret type: string keystoneOIDCClientSecret: - default: KeystoneClientSecret + default: KeystoneOIDCClientSecret description: OIDCClientSecret - Selector to get the IdP client secret from the Secret type: string keystoneOIDCCryptoPassphrase: - default: KeystoneCryptoPassphrase + default: KeystoneOIDCCryptoPassphrase description: OIDCCryptoPassphrase - Selector to get the OIDC crypto passphrase from the Secret type: string diff --git a/tests/functional/keystoneapi_controller_test.go b/tests/functional/keystoneapi_controller_test.go index 0a515b12..d88e8ecb 100644 --- a/tests/functional/keystoneapi_controller_test.go +++ b/tests/functional/keystoneapi_controller_test.go @@ -1560,6 +1560,93 @@ var _ = Describe("Keystone controller", func() { }) }) + When("A KeystoneAPI is created with OIDC Federation configuration", func() { + BeforeEach(func() { + spec := GetDefaultKeystoneAPISpec() + spec["oidcFederation"] = map[string]interface{}{ + "idpName": "myidp", + "idpURL": "https://idp.example.com", + "idpClientID": "client123", + "idpClientSecret": "secret123", + "idpMetadataURL": "https://idp.example.com/.well-known/openid-configuration", + "idpUserInfoURL": "https://idp.example.com/userinfo", + "idpAuthURL": "https://idp.example.com/auth", + "idpTokenURL": "https://idp.example.com/token", + "idpRemoteIDClaim": "sub", + "idpUsernameClaim": "preferred_username", + "idpScopeClaim": "scope", + "idpRolesClaim": "roles", + "idpDomainName": "Default", + "idpDefaultProject": "demo", + "idpDefaultRole": "member", + "idpScopedTokenGroup": "oidc", + } + + DeferCleanup( + k8sClient.Delete, ctx, CreateKeystoneMessageBusSecret(namespace, "rabbitmq-secret")) + DeferCleanup(th.DeleteInstance, CreateKeystoneAPI(keystoneAPIName, spec)) + DeferCleanup( + k8sClient.Delete, ctx, CreateKeystoneAPISecret(namespace, SecretName)) + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, "memcached", memcachedSpec)) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + namespace, + GetKeystoneAPI(keystoneAPIName).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + mariadb.SimulateMariaDBAccountCompleted(keystoneAccountName) + mariadb.SimulateMariaDBDatabaseCompleted(keystoneDatabaseName) + infra.SimulateTransportURLReady(types.NamespacedName{ + Name: fmt.Sprintf("%s-keystone-transport", keystoneAPIName.Name), + Namespace: namespace, + }) + infra.SimulateMemcachedReady(types.NamespacedName{ + Name: "memcached", + Namespace: namespace, + }) + th.SimulateJobSuccess(dbSyncJobName) + th.SimulateJobSuccess(bootstrapJobName) + th.SimulateDeploymentReplicaReady(deploymentName) + }) + + It("should configure OIDC in httpd.conf and keystone.conf", func() { + scrt := th.GetSecret(keystoneAPIConfigDataName) + Expect(scrt).ShouldNot(BeNil()) + + // Verify httpd.conf OIDC configuration + httpdConf := string(scrt.Data["httpd.conf"]) + Expect(httpdConf).Should(ContainSubstring("LoadModule auth_openidc_module modules/mod_auth_openidc.so")) + Expect(httpdConf).Should(ContainSubstring("OIDCProviderMetadataURL https://idp.example.com/.well-known/openid-configuration")) + Expect(httpdConf).Should(ContainSubstring("OIDCClientID client123")) + Expect(httpdConf).Should(ContainSubstring("OIDCClientSecret secret123")) + Expect(httpdConf).Should(ContainSubstring("OIDCRedirectURI https://keystone-public.")) + Expect(httpdConf).Should(ContainSubstring("/v3/OS-FEDERATION/identity_providers/myidp/protocols/openid/auth")) + Expect(httpdConf).Should(ContainSubstring("OIDCRemoteUserClaim preferred_username")) + Expect(httpdConf).Should(ContainSubstring("OIDCProviderTokenEndpointAuth client_secret_basic")) + Expect(httpdConf).Should(ContainSubstring("OIDCScope \"openid profile email\"")) + + // Verify keystone.conf federation configuration + keystoneConf := string(scrt.Data["keystone.conf"]) + Expect(keystoneConf).Should(ContainSubstring("[auth]")) + Expect(keystoneConf).Should(ContainSubstring("methods = password,token,oauth1,openid")) + Expect(keystoneConf).Should(ContainSubstring("[federation]")) + Expect(keystoneConf).Should(ContainSubstring("remote_id_attribute = HTTP_OIDC_ISS")) + Expect(keystoneConf).Should(ContainSubstring("[openid]")) + Expect(keystoneConf).Should(ContainSubstring("remote_id_claim = sub")) + Expect(keystoneConf).Should(ContainSubstring("username_claim = preferred_username")) + Expect(keystoneConf).Should(ContainSubstring("scope_claim = scope")) + Expect(keystoneConf).Should(ContainSubstring("roles_claim = roles")) + Expect(keystoneConf).Should(ContainSubstring("domain_name = Default")) + Expect(keystoneConf).Should(ContainSubstring("default_project = demo")) + Expect(keystoneConf).Should(ContainSubstring("default_role = member")) + Expect(keystoneConf).Should(ContainSubstring("scoped_token_group = oidc")) + }) + }) + // Run MariaDBAccount suite tests. these are pre-packaged ginkgo tests // that exercise standard account create / update patterns that should be // common to all controllers that ensure MariaDBAccount CRs. From 60d68838ab84768113616c5ebfd3bf0c9ecab61e Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Thu, 19 Dec 2024 09:27:41 -0600 Subject: [PATCH 12/14] Update test --- templates/keystoneapi/config/httpd.conf | 7 +- tests/functional/base_test.go | 3 +- .../functional/keystoneapi_controller_test.go | 197 ++++++++++-------- 3 files changed, 113 insertions(+), 94 deletions(-) diff --git a/templates/keystoneapi/config/httpd.conf b/templates/keystoneapi/config/httpd.conf index 4c12a502..4d79ab15 100644 --- a/templates/keystoneapi/config/httpd.conf +++ b/templates/keystoneapi/config/httpd.conf @@ -51,16 +51,14 @@ CustomLog /dev/stdout proxy env=forwarded SSLCertificateKeyFile "{{ $vhost.SSLCertificateKeyFile }}" {{- end }} - ## WSGI configuration + ## WSGI configuration WSGIApplicationGroup %{GLOBAL} WSGIDaemonProcess {{ $endpt }} display-name={{ $endpt }} group=keystone processes={{ $.ProcessNumber }} threads=1 user=keystone WSGIProcessGroup {{ $endpt }} WSGIScriptAlias / "/usr/bin/keystone-wsgi-public" WSGIPassAuthorization On - -{{- if $vhost.EnableFederation }} - # LoadModule auth_openidc_module modules/mod_auth_openidc.so +{{ if $vhost.EnableFederation }} OIDCClaimPrefix "{{ $vhost.OIDCClaimPrefix }}" OIDCResponseType "{{ $vhost.OIDCResponseType }}" OIDCScope "{{ $vhost.OIDCScope }}" @@ -75,7 +73,6 @@ CustomLog /dev/stdout proxy env=forwarded OIDCCacheType "{{ $vhost.OIDCCacheType }}" OIDCMemCacheServers "{{ $vhost.OIDCMemCacheServers }}" - # The following directives are necessary to support websso from Horizon # (Per https://docs.openstack.org/keystone/pike/advanced-topics/federation/websso.html) OIDCRedirectURI "{{ $vhost.KeystoneEndpoint }}/v3/auth/OS-FEDERATION/identity_providers/{{ $vhost.KeystoneFederationIdentityProviderName }}/protocols/openid/websso" diff --git a/tests/functional/base_test.go b/tests/functional/base_test.go index e2a87486..fa2fcda3 100644 --- a/tests/functional/base_test.go +++ b/tests/functional/base_test.go @@ -65,7 +65,6 @@ func GetTLSKeystoneAPISpec() map[string]interface{} { } func CreateKeystoneAPI(name types.NamespacedName, spec map[string]interface{}) client.Object { - raw := map[string]interface{}{ "apiVersion": "keystone.openstack.org/v1beta1", "kind": "KeystoneAPI", @@ -91,7 +90,7 @@ func CreateKeystoneAPISecret(namespace string, name string) *corev1.Secret { types.NamespacedName{Namespace: namespace, Name: name}, map[string][]byte{ "AdminPassword": []byte("12345678"), - "KeystoneOIDCClientSecret": []byte("secret"), + "KeystoneOIDCClientSecret": []byte("secret123"), "KeystoneOIDCCryptoPassphrase": []byte("openstack"), }, ) diff --git a/tests/functional/keystoneapi_controller_test.go b/tests/functional/keystoneapi_controller_test.go index d88e8ecb..1ed59158 100644 --- a/tests/functional/keystoneapi_controller_test.go +++ b/tests/functional/keystoneapi_controller_test.go @@ -1112,6 +1112,116 @@ var _ = Describe("Keystone controller", func() { }) }) + When("A TLS KeystoneAPI is created with an OIDC Federation configuration", func() { + BeforeEach(func() { + spec := GetTLSKeystoneAPISpec() + /* serviceOverride := map[string]interface{}{} + serviceOverride["public"] = map[string]interface{}{ + "endpointURL": "https://keystone-openstack.apps-crc.testing", + } + spec["override"] = map[string]interface{}{ + "service": serviceOverride, + } */ + spec["oidcFederation"] = map[string]interface{}{ + "keystoneFederationIdentityProviderName": "myidp", + "oidcCacheType": "memcache", + "oidcClaimDelimiter": ";", + "oidcClaimPrefix": "OIDC-", + "oidcClientID": "client123", + "oidcIntrospectionEndpoint": "https://idp.example.com/token/introspect", + "oidcPassClaimsAs": "both", + "oidcPassUserInfoAs": "claims", + "oidcProviderMetadataURL": "https://idp.example.com/.well-known/openid-configuration", + "oidcResponseType": "id_token", + "oidcScope": "openid email profile", + "remoteIDAttribute": "HTTP_OIDC_ISS", + } + + DeferCleanup(k8sClient.Delete, ctx, th.CreateCABundleSecret(caBundleSecretName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(internalCertSecretName)) + DeferCleanup(k8sClient.Delete, ctx, th.CreateCertSecret(publicCertSecretName)) + DeferCleanup(th.DeleteInstance, CreateKeystoneAPI(keystoneAPIName, spec)) + DeferCleanup( + k8sClient.Delete, ctx, CreateKeystoneMessageBusSecret(namespace, "rabbitmq-secret")) + DeferCleanup( + k8sClient.Delete, ctx, CreateKeystoneAPISecret(namespace, SecretName)) + DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, "memcached", memcachedSpec)) + DeferCleanup( + mariadb.DeleteDBService, + mariadb.CreateDBService( + namespace, + GetKeystoneAPI(keystoneAPIName).Spec.DatabaseInstance, + corev1.ServiceSpec{ + Ports: []corev1.ServicePort{{Port: 3306}}, + }, + ), + ) + mariadb.SimulateMariaDBAccountCompleted(keystoneAccountName) + mariadb.SimulateMariaDBDatabaseCompleted(keystoneDatabaseName) + infra.SimulateTransportURLReady(types.NamespacedName{ + Name: fmt.Sprintf("%s-keystone-transport", keystoneAPIName.Name), + Namespace: namespace, + }) + infra.SimulateMemcachedReady(types.NamespacedName{ + Name: "memcached", + Namespace: namespace, + }) + th.SimulateJobSuccess(dbSyncJobName) + th.SimulateJobSuccess(bootstrapJobName) + th.SimulateDeploymentReplicaReady(deploymentName) + }) + + /* It("registers LoadBalancer services keystone endpoints", func() { + instance := keystone.GetKeystoneAPI(keystoneAPIName) + Expect(instance).NotTo(BeNil()) + Expect(instance.Status.APIEndpoints).To(HaveKeyWithValue("public", "https://keystone-openstack.apps-crc.testing")) + Expect(instance.Status.APIEndpoints).To(HaveKeyWithValue("internal", "https://keystone-internal."+keystoneAPIName.Namespace+".svc:5000")) + + th.ExpectCondition( + keystoneAPIName, + ConditionGetterFunc(KeystoneConditionGetter), + condition.ReadyCondition, + corev1.ConditionTrue, + ) + }) */ + + It("should configure OIDC in httpd.conf and keystone.conf", func() { + scrt := th.GetSecret(keystoneAPIConfigDataName) + Expect(scrt).ShouldNot(BeNil()) + + // Verify httpd.conf OIDC configuration + httpdConf := string(scrt.Data["httpd.conf"]) + Expect(httpdConf).Should(ContainSubstring("OIDCClaimPrefix \"OIDC-\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCResponseType \"id_token\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCScope \"openid email profile\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCProviderMetadataURL https://idp.example.com/.well-known/openid-configuration")) + Expect(httpdConf).Should(ContainSubstring("OIDCClientID \"client123\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCClientSecret \"secret123\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCCryptoPassphrase \"openstack\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCCClaimDelimiter \";\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCCPassUserInfoAs \"claims\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCCPassClaimsAs \"both\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCCacheType \"memcache\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCRedirectURI \"https://keystone-openstack.apps-crc.testing/v3/auth/OS-FEDERATION/identity_providers/myidp/protocols/openid/websso\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCRedirectURI \"https://keystone-openstack.apps-crc.testing/v3/auth/OS-FEDERATION/websso/openid\"")) + Expect(httpdConf).Should(ContainSubstring("LocationMatch \"/v3/auth/OS-FEDERATION/websso/openid\"")) + Expect(httpdConf).Should(ContainSubstring("LocationMatch \"/v3/auth/OS-FEDERATION/identity_providers/myidp/protocols/openid/websso\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCAuthClientID \"client123\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCAuthClientSecret \"secret123\"")) + Expect(httpdConf).Should(ContainSubstring("OIDCAuthIntrospectionEndpoint \"https://idp.example.com/token/introspect\"")) + Expect(httpdConf).Should(ContainSubstring("Location ~ \"/v3/auth/OS-FEDERATION/identity_providers/myidp/protocols/openid/auth\"")) + + // Verify keystone.conf federation configuration + keystoneConf := string(scrt.Data["keystone.conf"]) + Expect(keystoneConf).Should(ContainSubstring("[federation]")) + Expect(keystoneConf).Should(ContainSubstring("trusted_dashboard=https://keystone-openstack.apps-crc.testing/dashboard/auth/websso/")) + Expect(keystoneConf).Should(ContainSubstring("[openid]")) + Expect(keystoneConf).Should(ContainSubstring("remote_id_attribute = HTTP_OIDC_ISS")) + Expect(keystoneConf).Should(ContainSubstring("[auth]")) + Expect(keystoneConf).Should(ContainSubstring("methods = password,token,oauth1,mapped,application_credential,openid")) + }) + }) + When("When FernetMaxActiveKeys is created with a number lower than 3", func() { It("should fail", func() { err := InterceptGomegaFailure( @@ -1560,93 +1670,6 @@ var _ = Describe("Keystone controller", func() { }) }) - When("A KeystoneAPI is created with OIDC Federation configuration", func() { - BeforeEach(func() { - spec := GetDefaultKeystoneAPISpec() - spec["oidcFederation"] = map[string]interface{}{ - "idpName": "myidp", - "idpURL": "https://idp.example.com", - "idpClientID": "client123", - "idpClientSecret": "secret123", - "idpMetadataURL": "https://idp.example.com/.well-known/openid-configuration", - "idpUserInfoURL": "https://idp.example.com/userinfo", - "idpAuthURL": "https://idp.example.com/auth", - "idpTokenURL": "https://idp.example.com/token", - "idpRemoteIDClaim": "sub", - "idpUsernameClaim": "preferred_username", - "idpScopeClaim": "scope", - "idpRolesClaim": "roles", - "idpDomainName": "Default", - "idpDefaultProject": "demo", - "idpDefaultRole": "member", - "idpScopedTokenGroup": "oidc", - } - - DeferCleanup( - k8sClient.Delete, ctx, CreateKeystoneMessageBusSecret(namespace, "rabbitmq-secret")) - DeferCleanup(th.DeleteInstance, CreateKeystoneAPI(keystoneAPIName, spec)) - DeferCleanup( - k8sClient.Delete, ctx, CreateKeystoneAPISecret(namespace, SecretName)) - DeferCleanup(infra.DeleteMemcached, infra.CreateMemcached(namespace, "memcached", memcachedSpec)) - DeferCleanup( - mariadb.DeleteDBService, - mariadb.CreateDBService( - namespace, - GetKeystoneAPI(keystoneAPIName).Spec.DatabaseInstance, - corev1.ServiceSpec{ - Ports: []corev1.ServicePort{{Port: 3306}}, - }, - ), - ) - mariadb.SimulateMariaDBAccountCompleted(keystoneAccountName) - mariadb.SimulateMariaDBDatabaseCompleted(keystoneDatabaseName) - infra.SimulateTransportURLReady(types.NamespacedName{ - Name: fmt.Sprintf("%s-keystone-transport", keystoneAPIName.Name), - Namespace: namespace, - }) - infra.SimulateMemcachedReady(types.NamespacedName{ - Name: "memcached", - Namespace: namespace, - }) - th.SimulateJobSuccess(dbSyncJobName) - th.SimulateJobSuccess(bootstrapJobName) - th.SimulateDeploymentReplicaReady(deploymentName) - }) - - It("should configure OIDC in httpd.conf and keystone.conf", func() { - scrt := th.GetSecret(keystoneAPIConfigDataName) - Expect(scrt).ShouldNot(BeNil()) - - // Verify httpd.conf OIDC configuration - httpdConf := string(scrt.Data["httpd.conf"]) - Expect(httpdConf).Should(ContainSubstring("LoadModule auth_openidc_module modules/mod_auth_openidc.so")) - Expect(httpdConf).Should(ContainSubstring("OIDCProviderMetadataURL https://idp.example.com/.well-known/openid-configuration")) - Expect(httpdConf).Should(ContainSubstring("OIDCClientID client123")) - Expect(httpdConf).Should(ContainSubstring("OIDCClientSecret secret123")) - Expect(httpdConf).Should(ContainSubstring("OIDCRedirectURI https://keystone-public.")) - Expect(httpdConf).Should(ContainSubstring("/v3/OS-FEDERATION/identity_providers/myidp/protocols/openid/auth")) - Expect(httpdConf).Should(ContainSubstring("OIDCRemoteUserClaim preferred_username")) - Expect(httpdConf).Should(ContainSubstring("OIDCProviderTokenEndpointAuth client_secret_basic")) - Expect(httpdConf).Should(ContainSubstring("OIDCScope \"openid profile email\"")) - - // Verify keystone.conf federation configuration - keystoneConf := string(scrt.Data["keystone.conf"]) - Expect(keystoneConf).Should(ContainSubstring("[auth]")) - Expect(keystoneConf).Should(ContainSubstring("methods = password,token,oauth1,openid")) - Expect(keystoneConf).Should(ContainSubstring("[federation]")) - Expect(keystoneConf).Should(ContainSubstring("remote_id_attribute = HTTP_OIDC_ISS")) - Expect(keystoneConf).Should(ContainSubstring("[openid]")) - Expect(keystoneConf).Should(ContainSubstring("remote_id_claim = sub")) - Expect(keystoneConf).Should(ContainSubstring("username_claim = preferred_username")) - Expect(keystoneConf).Should(ContainSubstring("scope_claim = scope")) - Expect(keystoneConf).Should(ContainSubstring("roles_claim = roles")) - Expect(keystoneConf).Should(ContainSubstring("domain_name = Default")) - Expect(keystoneConf).Should(ContainSubstring("default_project = demo")) - Expect(keystoneConf).Should(ContainSubstring("default_role = member")) - Expect(keystoneConf).Should(ContainSubstring("scoped_token_group = oidc")) - }) - }) - // Run MariaDBAccount suite tests. these are pre-packaged ginkgo tests // that exercise standard account create / update patterns that should be // common to all controllers that ensure MariaDBAccount CRs. From 44bd8f7bf69615ee28fe1461900ac7eeef1a4381 Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Tue, 7 Jan 2025 07:58:59 -0600 Subject: [PATCH 13/14] Add public endpoint simulation We need a public endpoint to build some redirect urls --- tests/functional/keystoneapi_controller_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/functional/keystoneapi_controller_test.go b/tests/functional/keystoneapi_controller_test.go index 1ed59158..3e5a1c38 100644 --- a/tests/functional/keystoneapi_controller_test.go +++ b/tests/functional/keystoneapi_controller_test.go @@ -45,6 +45,7 @@ var _ = Describe("Keystone controller", func() { var keystoneAccountName types.NamespacedName var keystoneDatabaseName types.NamespacedName var keystoneAPIConfigDataName types.NamespacedName + var keystoneEndpointName types.NamespacedName var dbSyncJobName types.NamespacedName var bootstrapJobName types.NamespacedName var deploymentName types.NamespacedName @@ -83,6 +84,10 @@ var _ = Describe("Keystone controller", func() { Name: "keystone-config-data", Namespace: namespace, } + keystoneEndpointName = types.NamespacedName{ + Name: "public", + Namespace: namespace, + } caBundleSecretName = types.NamespacedName{ Name: CABundleSecretName, Namespace: namespace, @@ -1168,6 +1173,7 @@ var _ = Describe("Keystone controller", func() { }) th.SimulateJobSuccess(dbSyncJobName) th.SimulateJobSuccess(bootstrapJobName) + keystone.SimulateKeystoneEndpointReady(keystoneEndpointName) th.SimulateDeploymentReplicaReady(deploymentName) }) From 48d040fdfa94cd71f4c3653c6930fd574855f1d2 Mon Sep 17 00:00:00 2001 From: Dave Wilde Date: Tue, 7 Jan 2025 08:10:08 -0600 Subject: [PATCH 14/14] Fix go mods --- api/go.mod | 6 ------ api/go.sum | 9 --------- go.mod | 20 +------------------- go.sum | 26 -------------------------- 4 files changed, 1 insertion(+), 60 deletions(-) diff --git a/api/go.mod b/api/go.mod index c9da1727..ec8cdab9 100644 --- a/api/go.mod +++ b/api/go.mod @@ -7,15 +7,9 @@ require ( github.com/google/uuid v1.6.0 github.com/gophercloud/gophercloud v1.14.1 github.com/onsi/gomega v1.34.1 -<<<<<<< HEAD github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e -======= - github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a - github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333 - github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333 ->>>>>>> bea7f45 (Update api go.mod to match main) golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 k8s.io/api v0.29.10 k8s.io/apimachinery v0.29.10 diff --git a/api/go.sum b/api/go.sum index 5201926d..d34a372c 100644 --- a/api/go.sum +++ b/api/go.sum @@ -80,21 +80,12 @@ github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094 h1:J1wuGhVxpsHykZBa6Beb1gQ96Ptej9AE/BvwCBiRj1E= github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4= -<<<<<<< HEAD github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e h1:hf4kVQBkyG79WcHBxdQ25QrDBbGFdarebS1Tc0Xclq4= github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e h1:HFo4OqPY0x4ZQeaWI2YGonTXAGTQFt+rOEJlfZVhS7s= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:IASoGvp5QM/tBJUd/8i8uIjj4DBnI+64Ydh4r7pmnvA= github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e h1:/iWDp3j+ET3gE5IjKHtdZaPd4SQyLHB/4L5jB16cV3I= github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= -======= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a h1:izLb1IVe6pXuQ6Y49CIAkN7yS9qe2fDptRlhxMHSYv4= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333 h1:XWxFOmOYPC6V5KUDkzU20vQOsha1PPNQzzqkNv926mg= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333/go.mod h1:IASoGvp5QM/tBJUd/8i8uIjj4DBnI+64Ydh4r7pmnvA= -github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333 h1:zUlxLqucrLMNDp6dc3I7eYWZyGVE7tLrPyWR/n+VD9w= -github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= ->>>>>>> bea7f45 (Update api go.mod to match main) github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/go.mod b/go.mod index ddc9891f..7008c8f8 100644 --- a/go.mod +++ b/go.mod @@ -8,30 +8,12 @@ require ( github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.5 github.com/onsi/ginkgo/v2 v2.20.1 github.com/onsi/gomega v1.34.1 -<<<<<<< HEAD -<<<<<<< HEAD github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241217075239-1fc4566cc5ab github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240213125925-e40975f3db7e github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0 -======= - github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241209150727-cbad718905d9 - github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240213125925-e40975f3db7e - github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241114091812-6dc9fd0961dc - github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241114091812-6dc9fd0961dc - github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241114091812-6dc9fd0961dc - github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241209142852-f7ff11df7e37 ->>>>>>> 1779ae5 (Remove oidcMemcacheServers param) -======= - github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241030094454-1ea50ac03c59 - github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240213125925-e40975f3db7e - github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a - github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333 - github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333 - github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0 ->>>>>>> 1ef836e (Update go.mod to match main) go.uber.org/zap v1.27.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.29.10 @@ -93,7 +75,7 @@ require ( k8s.io/apiextensions-apiserver v0.29.10 // indirect k8s.io/component-base v0.29.10 // indirect k8s.io/klog/v2 v2.120.1 // indirect - &k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect + k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 9efa551d..9270d6c7 100644 --- a/go.sum +++ b/go.sum @@ -78,8 +78,6 @@ github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094 h1:J1wuGhVxpsHykZBa6Beb1gQ96Ptej9AE/BvwCBiRj1E= github.com/openshift/api v0.0.0-20240830023148-b7d0481c9094/go.mod h1:CxgbWAlvu2iQB0UmKTtRu1YfepRg1/vJ64n2DlIEVz4= -<<<<<<< HEAD -<<<<<<< HEAD github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241217075239-1fc4566cc5ab h1:Pm9zQyhrs/zGAk9jvyt0hSBP28aHsFdWyI99M/lvFxU= github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241217075239-1fc4566cc5ab/go.mod h1:SSYBbFbgQbOwyY2cQNet7fSdQHHPb2rLo6GXE97Awp8= github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241216113837-d172b3ac0f4e h1:hf4kVQBkyG79WcHBxdQ25QrDBbGFdarebS1Tc0Xclq4= @@ -90,30 +88,6 @@ github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.202412161138 github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241216113837-d172b3ac0f4e/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0 h1:XBx1TuyKhgtWAigYVcdqTUzIwWRYHN63pfa0zxHB12M= github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0/go.mod h1:Uyc8m+72l3rVm6jKb8FRUrQbjMWyifc5m0K+Ge0QV80= -======= -github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241209150727-cbad718905d9 h1:EMeHQ9tArdGwOnJiPWxXlxb4onnMCZCjgpZbYYDG5yg= -github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241209150727-cbad718905d9/go.mod h1:Fkg09ogWFffMgA5XQzauXDv1bYvyxf9hl4VeHX8O2Tk= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241114091812-6dc9fd0961dc h1:Ufa/q/nC9wmKblvsc0kJppsXHOJoY4fbUamb3ItWCOk= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241114091812-6dc9fd0961dc/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241114091812-6dc9fd0961dc h1:q68lNZwCrKgLgcakrDu5VtpiWuC1pzQZKlb1M33EPMI= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241114091812-6dc9fd0961dc/go.mod h1:IASoGvp5QM/tBJUd/8i8uIjj4DBnI+64Ydh4r7pmnvA= -github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241114091812-6dc9fd0961dc h1:knyjd0eg4DyY+dTDHSrE9QwrZ0mtr7MpASCrmhW+5pw= -github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241114091812-6dc9fd0961dc/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= -github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241209142852-f7ff11df7e37 h1:dAn6djYwVe4rn1U+KCGTR8k2c3ixZJ1JbzUmtwJ5Itk= -github.com/openstack-k8s-operators/mariadb-operator/api v0.5.1-0.20241209142852-f7ff11df7e37/go.mod h1:348EPtAdpE2LxHAH4bHdCMNP7HyX6DevwEsF9DQ0S2k= ->>>>>>> 1779ae5 (Remove oidcMemcacheServers param) -======= -github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241030094454-1ea50ac03c59 h1:qSteLhmz5jDUEI4FUB/gFc+UI5p5tU+Edy/RKtaxNQQ= -github.com/openstack-k8s-operators/infra-operator/apis v0.5.1-0.20241030094454-1ea50ac03c59/go.mod h1:1khEYHcLFRF0wBT7bFM7IHTmY7u3eTxwowOvNY/A3qo= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a h1:izLb1IVe6pXuQ6Y49CIAkN7yS9qe2fDptRlhxMHSYv4= -github.com/openstack-k8s-operators/lib-common/modules/common v0.5.1-0.20241113144931-ff1fd2dcd04a/go.mod h1:YpNTuJhDWhbXM50O3qBkhO7M+OOyRmWkNVmJ4y3cyFs= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333 h1:XWxFOmOYPC6V5KUDkzU20vQOsha1PPNQzzqkNv926mg= -github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241029151503-4878b3fa3333/go.mod h1:IASoGvp5QM/tBJUd/8i8uIjj4DBnI+64Ydh4r7pmnvA= -github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333 h1:zUlxLqucrLMNDp6dc3I7eYWZyGVE7tLrPyWR/n+VD9w= -github.com/openstack-k8s-operators/lib-common/modules/test v0.5.1-0.20241029151503-4878b3fa3333/go.mod h1:LV0jo5etIsGyINpmB37i4oWR8zU6ApIuh7fsqGGA41o= -github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0 h1:XBx1TuyKhgtWAigYVcdqTUzIwWRYHN63pfa0zxHB12M= -github.com/openstack-k8s-operators/mariadb-operator/api v0.5.0/go.mod h1:Uyc8m+72l3rVm6jKb8FRUrQbjMWyifc5m0K+Ge0QV80= ->>>>>>> 1ef836e (Update go.mod to match main) github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=