From 765fe820bbc09ae8cedccdd635e6137dee01832f Mon Sep 17 00:00:00 2001 From: Robert Hoppe Date: Tue, 19 Oct 2021 09:13:02 +0200 Subject: [PATCH 1/7] Push changes to black DefaultRoles --- pkg/common/client.go | 12 ++++++++++++ pkg/common/client_state.go | 3 +++ 2 files changed, 15 insertions(+) diff --git a/pkg/common/client.go b/pkg/common/client.go index fd5c49718..ed06074d1 100644 --- a/pkg/common/client.go +++ b/pkg/common/client.go @@ -87,6 +87,9 @@ func (c *Client) CreateRealm(realm *v1alpha1.KeycloakRealm) error { } func (c *Client) CreateClient(client *v1alpha1.KeycloakAPIClient, realmName string) error { + // Pace Keycloak 15 Workaround Fix + client.DefaultRoles = nil + return c.create(client, fmt.Sprintf("realms/%s/clients", realmName), "client") } @@ -273,6 +276,10 @@ func (c *Client) GetClient(clientID, realmName string) (*v1alpha1.KeycloakAPICli result, err := c.get(fmt.Sprintf("realms/%s/clients/%s", realmName, clientID), "client", func(body []byte) (T, error) { client := &v1alpha1.KeycloakAPIClient{} err := json.Unmarshal(body, client) + + // Pace Keycloak 15 Workaround Fix + client.DefaultRoles = nil + return client, err }) if err != nil { @@ -468,7 +475,11 @@ func (c *Client) UpdateClientScopes(specClient *v1alpha1.KeycloakAPIClient, real scopeNameToID[scope.Name] = scope.ID } + // Pace Keycloak 15 Workaround Fix + specClient.DefaultRoles = nil + logrus.Infof("Syncing scopes for client with clientID %s/%s", realmName, specClient.ClientID) + for _, resourceScope := range specClient.DefaultClientScopes { addScope := true for _, scope := range currentClientScopes { @@ -490,6 +501,7 @@ func (c *Client) UpdateClientScopes(specClient *v1alpha1.KeycloakAPIClient, real return errors.Wrapf(err, "Could not add scope %s to client %s on realm %s", id, specClient.ID, realmName) } } + for _, scope := range currentClientScopes { removeScope := true for _, resourceScope := range specClient.DefaultClientScopes { diff --git a/pkg/common/client_state.go b/pkg/common/client_state.go index 013ee414e..8e2a8adc4 100644 --- a/pkg/common/client_state.go +++ b/pkg/common/client_state.go @@ -35,6 +35,9 @@ func (i *ClientState) Read(context context.Context, cr *kc.KeycloakClient, realm return nil } + // Pace Keycloak 15 Workaround Fix + client.DefaultRoles = nil + clientSecret, err := realmClient.GetClientSecret(cr.Spec.Client.ID, i.Realm.Spec.Realm.Realm) if err != nil { return err From 5ce79b340d84c441da58790461ac4d929c0c7b13 Mon Sep 17 00:00:00 2001 From: Robert Hoppe Date: Tue, 19 Oct 2021 09:16:37 +0200 Subject: [PATCH 2/7] Push the fun --- pkg/apis/keycloak/v1alpha1/keycloak_types.go | 4 +- pkg/common/cluster_state.go | 2 +- .../keycloak/keycloak_migrations.go | 1 - .../keycloak/keycloak_reconciler.go | 4 +- .../keycloak/keycloak_reconciler_test.go | 2 +- .../keycloakclient_reconciler_test.go | 3 +- pkg/model/constants.go | 54 +++++++-------- pkg/model/keycloak_configmap_startup.go | 5 +- pkg/model/keycloak_deployment.go | 66 +++++++++---------- pkg/model/keycloak_probes.go | 2 +- pkg/model/rhsso_deployment.go | 8 +-- 11 files changed, 72 insertions(+), 79 deletions(-) diff --git a/pkg/apis/keycloak/v1alpha1/keycloak_types.go b/pkg/apis/keycloak/v1alpha1/keycloak_types.go index 4be978627..f33275cbc 100644 --- a/pkg/apis/keycloak/v1alpha1/keycloak_types.go +++ b/pkg/apis/keycloak/v1alpha1/keycloak_types.go @@ -176,6 +176,6 @@ func (i *Keycloak) UpdateStatusSecondaryResources(kind string, resourceName stri type KeycloakRelatedImages struct { // If set, operator will use it instead of the default Keycloak image // +optional - Keycloak string `json:"keycloak,omitempty"` + Keycloak string `json:"keycloak,omitempty"` ImagePullSecrets []string `json:"imagePullSecrets,omitempty"` -} \ No newline at end of file +} diff --git a/pkg/common/cluster_state.go b/pkg/common/cluster_state.go index 88d307538..935353bfd 100644 --- a/pkg/common/cluster_state.go +++ b/pkg/common/cluster_state.go @@ -51,7 +51,7 @@ type ClusterState struct { KeycloakDeployment *v12.StatefulSet KeycloakAdminSecret *v1.Secret KeycloakIngress *v1beta1.Ingress - KeycloakStartupConfigMap *v1.ConfigMap + KeycloakStartupConfigMap *v1.ConfigMap KeycloakRoute *v13.Route PostgresqlServiceEndpoints *v1.Endpoints PodDisruptionBudget *v1beta12.PodDisruptionBudget diff --git a/pkg/controller/keycloak/keycloak_migrations.go b/pkg/controller/keycloak/keycloak_migrations.go index cd6001928..1dca46ee7 100644 --- a/pkg/controller/keycloak/keycloak_migrations.go +++ b/pkg/controller/keycloak/keycloak_migrations.go @@ -55,7 +55,6 @@ func needsMigration(cr *v1alpha1.Keycloak, currentState *common.ClusterState) bo desiredImage = cr.Spec.ImageOverrides.Keycloak } - if cr.Spec.Profile == common.RHSSOProfile { desiredImage = model.RHSSOImage } diff --git a/pkg/controller/keycloak/keycloak_reconciler.go b/pkg/controller/keycloak/keycloak_reconciler.go index 06c765678..5c626f48e 100644 --- a/pkg/controller/keycloak/keycloak_reconciler.go +++ b/pkg/controller/keycloak/keycloak_reconciler.go @@ -317,7 +317,6 @@ func (i *KeycloakReconciler) getKeycloakDeploymentOrRHSSODesiredState(clusterSta // deploymentReconciled = model.RHSSODeploymentReconciled(cr, clusterState.KeycloakDeployment, clusterState.DatabaseSecret) //} - //return common.GenericUpdateAction{ // Ref: deploymentReconciled, // Msg: "Update " + deploymentName + " Deployment (StatefulSet)", @@ -381,7 +380,6 @@ func (i *KeycloakReconciler) getPodDisruptionBudgetDesiredState(clusterState *co return nil } - func (i *KeycloakReconciler) getKeycloakStartupScriptDesiredState(clusterState *common.ClusterState, cr *kc.Keycloak) common.ClusterAction { if clusterState.KeycloakStartupConfigMap == nil { return common.GenericCreateAction{ @@ -394,4 +392,4 @@ func (i *KeycloakReconciler) getKeycloakStartupScriptDesiredState(clusterState * Ref: model.KeycloakConfigMapStartupReconiled(cr, clusterState.KeycloakStartupConfigMap), Msg: "Update Keycloak Startup ConfigMap", } -} \ No newline at end of file +} diff --git a/pkg/controller/keycloak/keycloak_reconciler_test.go b/pkg/controller/keycloak/keycloak_reconciler_test.go index eac592e18..16d86698d 100644 --- a/pkg/controller/keycloak/keycloak_reconciler_test.go +++ b/pkg/controller/keycloak/keycloak_reconciler_test.go @@ -387,4 +387,4 @@ func TestKeycloakReconciler_Test_Should_Update_PDB(t *testing.T) { assert.Equal(t, len(desiredState), 10) assert.IsType(t, common.GenericUpdateAction{}, desiredState[9]) assert.IsType(t, model.PodDisruptionBudget(cr), desiredState[9].(common.GenericUpdateAction).Ref) -} \ No newline at end of file +} diff --git a/pkg/controller/keycloakclient/keycloakclient_reconciler_test.go b/pkg/controller/keycloakclient/keycloakclient_reconciler_test.go index ed307592b..93ca55fde 100644 --- a/pkg/controller/keycloakclient/keycloakclient_reconciler_test.go +++ b/pkg/controller/keycloakclient/keycloakclient_reconciler_test.go @@ -1,4 +1,3 @@ - package keycloakclient import ( @@ -210,4 +209,4 @@ func TestKeycloakClientReconciler_Test_Marshal_Client_directAccessGrantsEnabled( // then assert.Nil(t, err, "Client couldn't be marshalled") assert.True(t, strings.Contains(s, "\"directAccessGrantsEnabled\":false"), "Element directAccessGrantsEnabled should not be omitted if false, as keycloaks default is true") -} \ No newline at end of file +} diff --git a/pkg/model/constants.go b/pkg/model/constants.go index 641e5c990..751f3a4fe 100644 --- a/pkg/model/constants.go +++ b/pkg/model/constants.go @@ -2,40 +2,40 @@ package model // Constants for a community Keycloak installation const ( - ApplicationName = "keycloak" - MonitoringKey = "middleware" - DatabaseSecretName = ApplicationName + "-db-secret" - PostgresqlPersistentVolumeName = ApplicationName + "-postgresql-claim" - PostgresqlBackupPersistentVolumeName = ApplicationName + "-backup" - PostgresqlDeploymentName = ApplicationName + "-postgresql" - KeycloakProbesName = ApplicationName + "-probes" - PostgresqlDeploymentComponent = "database" - PostgresqlServiceName = ApplicationName + "-postgresql" - PostgresqlImage = "postgres:11.5" - KeycloakImage = "quay.io/keycloak/keycloak:8.0.2" - KeycloakInitContainerImage = "quay.io/keycloak/keycloak-init-container:master" - RHSSOImage = "registry.access.redhat.com/redhat-sso-7/sso73-openshift:1.0-15" - BackupImage = "quay.io/integreatly/backup-container:1.0.10" - KeycloakDiscoveryServiceName = ApplicationName + "-discovery" - KeycloakDeploymentName = ApplicationName - KeycloakDeploymentComponent = "keycloak" - PostgresqlBackupComponent = "database-backup" - PostgresqlDatabase = "root" - PostgresqlPersistentVolumeCapacity = "1Gi" - DatabaseSecretUsernameProperty = "POSTGRES_USERNAME" // nolint - DatabaseSecretPasswordProperty = "POSTGRES_PASSWORD" // nolint + ApplicationName = "keycloak" + MonitoringKey = "middleware" + DatabaseSecretName = ApplicationName + "-db-secret" + PostgresqlPersistentVolumeName = ApplicationName + "-postgresql-claim" + PostgresqlBackupPersistentVolumeName = ApplicationName + "-backup" + PostgresqlDeploymentName = ApplicationName + "-postgresql" + KeycloakProbesName = ApplicationName + "-probes" + PostgresqlDeploymentComponent = "database" + PostgresqlServiceName = ApplicationName + "-postgresql" + PostgresqlImage = "postgres:11.5" + KeycloakImage = "quay.io/keycloak/keycloak:8.0.2" + KeycloakInitContainerImage = "quay.io/keycloak/keycloak-init-container:master" + RHSSOImage = "registry.access.redhat.com/redhat-sso-7/sso73-openshift:1.0-15" + BackupImage = "quay.io/integreatly/backup-container:1.0.10" + KeycloakDiscoveryServiceName = ApplicationName + "-discovery" + KeycloakDeploymentName = ApplicationName + KeycloakDeploymentComponent = "keycloak" + PostgresqlBackupComponent = "database-backup" + PostgresqlDatabase = "root" + PostgresqlPersistentVolumeCapacity = "1Gi" + DatabaseSecretUsernameProperty = "POSTGRES_USERNAME" // nolint + DatabaseSecretPasswordProperty = "POSTGRES_PASSWORD" // nolint // Required by the Integreately Backup Image - DatabaseSecretHostProperty = "POSTGRES_HOST" // nolint + DatabaseSecretHostProperty = "POSTGRES_HOST" // nolint // Required by the Integreately Backup Image - DatabaseSecretDatabaseProperty = "POSTGRES_DATABASE" // nolint + DatabaseSecretDatabaseProperty = "POSTGRES_DATABASE" // nolint // Required by the Integreately Backup Image DatabaseSecretSuperuserProperty = "POSTGRES_SUPERUSER" // nolint DatabaseSecretExternalAddressProperty = "POSTGRES_EXTERNAL_ADDRESS" // nolint DatabaseSecretExternalPortProperty = "POSTGRES_EXTERNAL_PORT" // nolint KeycloakServicePort = 8080 - KeycloakServicePortSSL = 8443 - KeycloakPodPort = 8080 - KeycloakPodPortSSL = 8443 + KeycloakServicePortSSL = 8443 + KeycloakPodPort = 8080 + KeycloakPodPortSSL = 8443 PostgresDefaultPort = 5432 AdminUsernameProperty = "ADMIN_USERNAME" // nolint AdminPasswordProperty = "ADMIN_PASSWORD" // nolint diff --git a/pkg/model/keycloak_configmap_startup.go b/pkg/model/keycloak_configmap_startup.go index 641303888..cc762528b 100644 --- a/pkg/model/keycloak_configmap_startup.go +++ b/pkg/model/keycloak_configmap_startup.go @@ -1,11 +1,12 @@ package model import ( + "strings" + kc "github.com/keycloak/keycloak-operator/pkg/apis/keycloak/v1alpha1" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - "strings" ) func GetStartupScriptConfigMapContent(cr *kc.Keycloak) map[string]string { diff --git a/pkg/model/keycloak_deployment.go b/pkg/model/keycloak_deployment.go index db8ac33af..bf2fd8982 100644 --- a/pkg/model/keycloak_deployment.go +++ b/pkg/model/keycloak_deployment.go @@ -20,7 +20,6 @@ const ( ProbeTimeBetweenRunsSeconds = 30 ) - func GetServiceEnvVar(suffix string) string { serviceName := strings.ToUpper(PostgresqlServiceName) serviceName = strings.ReplaceAll(serviceName, "-", "_") @@ -122,23 +121,23 @@ func getKeycloakEnv(cr *v1alpha1.Keycloak, dbSecret *v1.Secret) []v1.EnvVar { }, } - if len(cr.Spec.ExtraEnv) > 0 { - for k, v := range cr.Spec.ExtraEnv { - defaultEnv = append(defaultEnv, v1.EnvVar{ - Name: k, - Value: v, - }) - } - } - - if cr.Spec.ExternalAccess.Enabled { - defaultEnv = append(defaultEnv, v1.EnvVar{ - Name: "PROXY_ADDRESS_FORWARDING", + if len(cr.Spec.ExtraEnv) > 0 { + for k, v := range cr.Spec.ExtraEnv { + defaultEnv = append(defaultEnv, v1.EnvVar{ + Name: k, + Value: v, + }) + } + } + + if cr.Spec.ExternalAccess.Enabled { + defaultEnv = append(defaultEnv, v1.EnvVar{ + Name: "PROXY_ADDRESS_FORWARDING", Value: "true", }) - } + } - return defaultEnv + return defaultEnv } func KeycloakDeployment(cr *v1alpha1.Keycloak, dbSecret *v1.Secret) *v13.StatefulSet { @@ -169,9 +168,9 @@ func KeycloakDeployment(cr *v1alpha1.Keycloak, dbSecret *v1.Secret) *v13.Statefu }, }, Spec: v1.PodSpec{ - InitContainers: KeycloakExtensionsInitContainers(cr), - Volumes: KeycloakVolumes(cr), - Affinity: cr.Spec.Affinity, + InitContainers: KeycloakExtensionsInitContainers(cr), + Volumes: KeycloakVolumes(cr), + Affinity: cr.Spec.Affinity, ImagePullSecrets: GetKeycloakImagePullSecrets(cr), Containers: []v1.Container{ { @@ -195,8 +194,8 @@ func KeycloakDeployment(cr *v1alpha1.Keycloak, dbSecret *v1.Secret) *v13.Statefu Protocol: "TCP", }, }, - VolumeMounts: KeycloakVolumeMounts(cr, KeycloakExtensionPath), - Env: getKeycloakEnv(cr, dbSecret), + VolumeMounts: KeycloakVolumeMounts(cr, KeycloakExtensionPath), + Env: getKeycloakEnv(cr, dbSecret), LivenessProbe: livenessProbe(), ReadinessProbe: readinessProbe(), }, @@ -207,24 +206,22 @@ func KeycloakDeployment(cr *v1alpha1.Keycloak, dbSecret *v1.Secret) *v13.Statefu } } - func GetKeycloakImagePullSecrets(cr *v1alpha1.Keycloak) []v1.LocalObjectReference { if cr.Spec.ImageOverrides.ImagePullSecrets != nil && len(cr.Spec.ImageOverrides.ImagePullSecrets) > 0 { imagePullSecrets := []v1.LocalObjectReference{} - for _,v := range cr.Spec.ImageOverrides.ImagePullSecrets { + for _, v := range cr.Spec.ImageOverrides.ImagePullSecrets { - imagePullSecrets = append(imagePullSecrets, v1.LocalObjectReference{ - Name: v, - }) - } + imagePullSecrets = append(imagePullSecrets, v1.LocalObjectReference{ + Name: v, + }) + } return imagePullSecrets } - return []v1.LocalObjectReference{} } @@ -275,10 +272,10 @@ func KeycloakDeploymentReconciled(cr *v1alpha1.Keycloak, currentState *v13.State Protocol: "TCP", }, }, - VolumeMounts: KeycloakVolumeMounts(cr, KeycloakExtensionPath), + VolumeMounts: KeycloakVolumeMounts(cr, KeycloakExtensionPath), LivenessProbe: livenessProbe(), ReadinessProbe: readinessProbe(), - Env: getKeycloakEnv(cr, dbSecret), + Env: getKeycloakEnv(cr, dbSecret), }, } reconciled.Spec.Template.Spec.InitContainers = KeycloakExtensionsInitContainers(cr) @@ -301,15 +298,15 @@ func KeycloakVolumeMounts(cr *v1alpha1.Keycloak, extensionsPath string) []v1.Vol if !cr.Spec.ServingCertDisabled { volumeMounts = append(volumeMounts, v1.VolumeMount{ - Name: ServingCertSecretName, - MountPath: "/etc/x509/https", + Name: ServingCertSecretName, + MountPath: "/etc/x509/https", }) } if cr.Spec.StartupScript.Enabled { volumeMounts = append(volumeMounts, v1.VolumeMount{ - Name: "keycloak-startup", - ReadOnly: true, + Name: "keycloak-startup", + ReadOnly: true, MountPath: "/opt/jboss/startup-scripts", }) } @@ -401,7 +398,7 @@ func readinessProbe() *v1.Probe { InitialDelaySeconds: ReadinessProbeInitialDelay, TimeoutSeconds: ProbeTimeoutSeconds, PeriodSeconds: ProbeTimeBetweenRunsSeconds, - FailureThreshold: 10, + FailureThreshold: 10, } } @@ -435,6 +432,5 @@ func GetReconciledKeycloakImage(cr *v1alpha1.Keycloak, currentImage string) stri return currentImage } - return KeycloakImage } diff --git a/pkg/model/keycloak_probes.go b/pkg/model/keycloak_probes.go index 394dcb757..00ddebc28 100644 --- a/pkg/model/keycloak_probes.go +++ b/pkg/model/keycloak_probes.go @@ -62,4 +62,4 @@ func KeycloakProbesSelector(cr *v1alpha1.Keycloak) client.ObjectKey { Name: KeycloakProbesName, Namespace: cr.Namespace, } -} \ No newline at end of file +} diff --git a/pkg/model/rhsso_deployment.go b/pkg/model/rhsso_deployment.go index 7ad92a5f0..c4ad6c69b 100644 --- a/pkg/model/rhsso_deployment.go +++ b/pkg/model/rhsso_deployment.go @@ -151,8 +151,8 @@ func RHSSODeployment(cr *v1alpha1.Keycloak, dbSecret *v1.Secret) *v13.StatefulSe Protocol: "TCP", }, }, - VolumeMounts: KeycloakVolumeMounts(cr, RhssoExtensionPath), - Env: getRHSSOEnv(cr, dbSecret), + VolumeMounts: KeycloakVolumeMounts(cr, RhssoExtensionPath), + Env: getRHSSOEnv(cr, dbSecret), LivenessProbe: livenessProbe(), ReadinessProbe: readinessProbe(), }, @@ -199,10 +199,10 @@ func RHSSODeploymentReconciled(cr *v1alpha1.Keycloak, currentState *v13.Stateful Protocol: "TCP", }, }, - VolumeMounts: KeycloakVolumeMounts(cr, RhssoExtensionPath), + VolumeMounts: KeycloakVolumeMounts(cr, RhssoExtensionPath), LivenessProbe: livenessProbe(), ReadinessProbe: readinessProbe(), - Env: getRHSSOEnv(cr, dbSecret), + Env: getRHSSOEnv(cr, dbSecret), }, } reconciled.Spec.Template.Spec.InitContainers = KeycloakExtensionsInitContainers(cr) From 0fb9a421ad0a3aff01965539ed4b61ac72fc8591 Mon Sep 17 00:00:00 2001 From: Robert Hoppe Date: Tue, 19 Oct 2021 10:53:36 +0200 Subject: [PATCH 3/7] Add info about Body --- pkg/common/client.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/common/client.go b/pkg/common/client.go index ed06074d1..97f1a205e 100644 --- a/pkg/common/client.go +++ b/pkg/common/client.go @@ -374,7 +374,9 @@ func (c *Client) update(obj T, resourcePath, resourceName string) error { return nil } - logrus.Infof("Calling PUT %s", fmt.Sprintf("%s/auth/admin/%s", c.URL, resourcePath)) + logrus.Infof("Calling PUT %s with body: %s", fmt.Sprintf("%s/auth/admin/%s", c.URL, resourcePath), string(jsonValue)) + + req, err := http.NewRequest( "PUT", fmt.Sprintf("%s/auth/admin/%s", c.URL, resourcePath), From 46b6647d7805514b118bc1c45220fd2f506a5cb6 Mon Sep 17 00:00:00 2001 From: Robert Hoppe Date: Tue, 19 Oct 2021 10:53:58 +0200 Subject: [PATCH 4/7] Push changes --- pkg/common/client.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/common/client.go b/pkg/common/client.go index 97f1a205e..750427b5f 100644 --- a/pkg/common/client.go +++ b/pkg/common/client.go @@ -376,7 +376,6 @@ func (c *Client) update(obj T, resourcePath, resourceName string) error { logrus.Infof("Calling PUT %s with body: %s", fmt.Sprintf("%s/auth/admin/%s", c.URL, resourcePath), string(jsonValue)) - req, err := http.NewRequest( "PUT", fmt.Sprintf("%s/auth/admin/%s", c.URL, resourcePath), From 960b1446299a8ed9540fb600f88627422dee60bf Mon Sep 17 00:00:00 2001 From: Robert Hoppe Date: Tue, 19 Oct 2021 13:25:25 +0200 Subject: [PATCH 5/7] Init some fun --- pkg/common/client.go | 12 ++++++++++++ pkg/common/client_state.go | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/pkg/common/client.go b/pkg/common/client.go index 750427b5f..5afd65da8 100644 --- a/pkg/common/client.go +++ b/pkg/common/client.go @@ -90,6 +90,10 @@ func (c *Client) CreateClient(client *v1alpha1.KeycloakAPIClient, realmName stri // Pace Keycloak 15 Workaround Fix client.DefaultRoles = nil + if client.RedirectUris == nil { + client.RedirectUris = make([]string, 0) + } + return c.create(client, fmt.Sprintf("realms/%s/clients", realmName), "client") } @@ -280,6 +284,10 @@ func (c *Client) GetClient(clientID, realmName string) (*v1alpha1.KeycloakAPICli // Pace Keycloak 15 Workaround Fix client.DefaultRoles = nil + if client.RedirectUris == nil { + client.RedirectUris = make([]string, 0) + } + return client, err }) if err != nil { @@ -479,6 +487,10 @@ func (c *Client) UpdateClientScopes(specClient *v1alpha1.KeycloakAPIClient, real // Pace Keycloak 15 Workaround Fix specClient.DefaultRoles = nil + if specClient.RedirectUris == nil { + specClient.RedirectUris = make([]string, 0) + } + logrus.Infof("Syncing scopes for client with clientID %s/%s", realmName, specClient.ClientID) for _, resourceScope := range specClient.DefaultClientScopes { diff --git a/pkg/common/client_state.go b/pkg/common/client_state.go index 8e2a8adc4..d056a1b5b 100644 --- a/pkg/common/client_state.go +++ b/pkg/common/client_state.go @@ -38,6 +38,10 @@ func (i *ClientState) Read(context context.Context, cr *kc.KeycloakClient, realm // Pace Keycloak 15 Workaround Fix client.DefaultRoles = nil + if client.RedirectUris == nil { + client.RedirectUris = make([]string, 0) + } + clientSecret, err := realmClient.GetClientSecret(cr.Spec.Client.ID, i.Realm.Spec.Realm.Realm) if err != nil { return err From 5f193a82c2ca86d369b06f7b3a7bc3999f75f055 Mon Sep 17 00:00:00 2001 From: Robert Hoppe Date: Tue, 19 Oct 2021 14:44:01 +0200 Subject: [PATCH 6/7] Adjustment of ruther init --- pkg/common/client.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/common/client.go b/pkg/common/client.go index 5afd65da8..975b2cbcb 100644 --- a/pkg/common/client.go +++ b/pkg/common/client.go @@ -540,6 +540,13 @@ func (c *Client) UpdateRealm(realm *v1alpha1.KeycloakRealm) error { } func (c *Client) UpdateClient(specClient *v1alpha1.KeycloakAPIClient, realmName string) error { + // Pace Keycloak 15 Workaround Fix + specClient.DefaultRoles = nil + + if specClient.RedirectUris == nil { + specClient.RedirectUris = make([]string, 0) + } + err := c.update(specClient, fmt.Sprintf("realms/%s/clients/%s", realmName, specClient.ID), "client") if err != nil { return err From 2e7f13cc2b08aac169bdef5a56d6f1937a2b6231 Mon Sep 17 00:00:00 2001 From: Robert Hoppe Date: Thu, 21 Oct 2021 09:20:14 +0200 Subject: [PATCH 7/7] Remove verbosity --- pkg/apis/monkeypatch/monkeypatch.go | 105 ++++++++++++++++++++++++++++ pkg/common/client.go | 20 ++++-- pkg/common/client_state.go | 8 +-- 3 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 pkg/apis/monkeypatch/monkeypatch.go diff --git a/pkg/apis/monkeypatch/monkeypatch.go b/pkg/apis/monkeypatch/monkeypatch.go new file mode 100644 index 000000000..f8bf285b6 --- /dev/null +++ b/pkg/apis/monkeypatch/monkeypatch.go @@ -0,0 +1,105 @@ +package monkeypatch + +import "github.com/keycloak/keycloak-operator/pkg/apis/keycloak/v1alpha1" + +type KeycloakAPIClient struct { + // Client ID. If not specified, automatically generated. + // +optional + ID string `json:"id,omitempty"` + // Client ID. + // +kubebuilder:validation:Required + ClientID string `json:"clientId"` + // Client name. + // +optional + Name string `json:"name,omitempty"` + // Surrogate Authentication Required option. + // +optional + SurrogateAuthRequired bool `json:"surrogateAuthRequired,omitempty"` + // Client enabled flag. + // +optional + Enabled bool `json:"enabled,omitempty"` + // What Client authentication type to use. + // +optional + ClientAuthenticatorType string `json:"clientAuthenticatorType,omitempty"` + // Client Secret. The Operator will automatically create a Secret based on this value. + // +optional + Secret string `json:"secret,omitempty"` + // Application base URL. + // +optional + BaseURL string `json:"baseUrl,omitempty"` + // Application Admin URL. + // +optional + AdminURL string `json:"adminUrl,omitempty"` + // Application root URL. + // +optional + RootURL string `json:"rootUrl,omitempty"` + // Client description. + // +optional + Description string `json:"description,omitempty"` + // Default Client roles. + // +optional + DefaultRoles []string `json:"defaultRoles,omitempty"` + // Default Client scopes. + // optional + DefaultClientScopes []string `json:"defaultClientScopes,omitempty"` + // A list of valid Redirection URLs. + // +optional + RedirectUris []string `json:"redirectUris"` + // A list of valid Web Origins. + // +optional + WebOrigins []string `json:"webOrigins,omitempty"` + // Not Before setting. + // +optional + NotBefore int `json:"notBefore,omitempty"` + // True if a client supports only Bearer Tokens. + // +optional + BearerOnly bool `json:"bearerOnly"` + // True if Consent Screen is required. + // +optional + ConsentRequired bool `json:"consentRequired"` + // True if Standard flow is enabled. + // +optional + StandardFlowEnabled bool `json:"standardFlowEnabled"` + // True if Implicit flow is enabled. + // +optional + ImplicitFlowEnabled bool `json:"implicitFlowEnabled"` + // True if Direct Grant is enabled. + // +optional + DirectAccessGrantsEnabled bool `json:"directAccessGrantsEnabled"` + // True if Service Accounts are enabled. + // +optional + ServiceAccountsEnabled bool `json:"serviceAccountsEnabled"` + // True if this is a public Client. + // +optional + PublicClient bool `json:"publicClient"` + // True if this client supports Front Channel logout. + // +optional + FrontchannelLogout bool `json:"frontchannelLogout,omitempty"` + // Protocol used for this Client. + // +optional + Protocol string `json:"protocol,omitempty"` + // Client Attributes. + // +optional + Attributes map[string]string `json:"attributes,omitempty"` + // True if Full Scope is allowed. + // +optional + FullScopeAllowed bool `json:"fullScopeAllowed,omitempty"` + // Node registration timeout. + // +optional + NodeReRegistrationTimeout int `json:"nodeReRegistrationTimeout,omitempty"` + // Protocol Mappers. + // +optional + ProtocolMappers []v1alpha1.KeycloakProtocolMapper `json:"protocolMappers,omitempty"` + // True to use a Template Config. + // +optional + UseTemplateConfig bool `json:"useTemplateConfig,omitempty"` + // True to use Template Scope. + // +optional + UseTemplateScope bool `json:"useTemplateScope,omitempty"` + // True to use Template Mappers. + // +optional + UseTemplateMappers bool `json:"useTemplateMappers,omitempty"` + // Access options. + // +optional + Access map[string]bool `json:"access,omitempty"` +} diff --git a/pkg/common/client.go b/pkg/common/client.go index 975b2cbcb..bfbee4597 100644 --- a/pkg/common/client.go +++ b/pkg/common/client.go @@ -5,6 +5,7 @@ import ( "crypto/tls" "encoding/json" "fmt" + "github.com/keycloak/keycloak-operator/pkg/apis/monkeypatch" "io" "io/ioutil" "net/http" @@ -50,6 +51,9 @@ func (c *Client) create(obj T, resourcePath, resourceName string) error { return nil } + logrus.Infof("Calling POST %s", fmt.Sprintf("%s/auth/admin/%s", c.URL, resourcePath)) + logrus.Debugf("Calling POST with body: %s", string(jsonValue)) + req, err := http.NewRequest( "POST", fmt.Sprintf("%s/auth/admin/%s", c.URL, resourcePath), @@ -91,10 +95,10 @@ func (c *Client) CreateClient(client *v1alpha1.KeycloakAPIClient, realmName stri client.DefaultRoles = nil if client.RedirectUris == nil { - client.RedirectUris = make([]string, 0) + client.RedirectUris = make([]string, 1) } - return c.create(client, fmt.Sprintf("realms/%s/clients", realmName), "client") + return c.create(c.MonkeyPatchKeycloakAPIClient(client), fmt.Sprintf("realms/%s/clients", realmName), "client") } func (c *Client) CreateUser(user *v1alpha1.KeycloakAPIUser, realmName string) error { @@ -382,7 +386,8 @@ func (c *Client) update(obj T, resourcePath, resourceName string) error { return nil } - logrus.Infof("Calling PUT %s with body: %s", fmt.Sprintf("%s/auth/admin/%s", c.URL, resourcePath), string(jsonValue)) + logrus.Infof("Calling PUT %s", fmt.Sprintf("%s/auth/admin/%s", c.URL, resourcePath)) + logrus.Debugf("Calling PUT with body: %s", string(jsonValue)) req, err := http.NewRequest( "PUT", @@ -468,6 +473,12 @@ func (c *Client) updateClientScope(method, clientID, scopeID, realmName string) return nil } +// MonkeyPatchKeycloakAPIClient does monkey patching to adjust the tags. +func (c *Client) MonkeyPatchKeycloakAPIClient(specClient *v1alpha1.KeycloakAPIClient) (*monkeypatch.KeycloakAPIClient) { + var patchClient monkeypatch.KeycloakAPIClient = monkeypatch.KeycloakAPIClient(*specClient) + return &patchClient +} + func (c *Client) UpdateClientScopes(specClient *v1alpha1.KeycloakAPIClient, realmName string) error { // First get the available scopes for the current realm availableScopes, err := c.ListAllClientScopes(realmName) @@ -547,10 +558,11 @@ func (c *Client) UpdateClient(specClient *v1alpha1.KeycloakAPIClient, realmName specClient.RedirectUris = make([]string, 0) } - err := c.update(specClient, fmt.Sprintf("realms/%s/clients/%s", realmName, specClient.ID), "client") + err := c.update(c.MonkeyPatchKeycloakAPIClient(specClient), fmt.Sprintf("realms/%s/clients/%s", realmName, specClient.ID), "client") if err != nil { return err } + // Updating (default)ClientScopes requires separate API calls. return c.UpdateClientScopes(specClient, realmName) } diff --git a/pkg/common/client_state.go b/pkg/common/client_state.go index d056a1b5b..ca768ded9 100644 --- a/pkg/common/client_state.go +++ b/pkg/common/client_state.go @@ -2,6 +2,7 @@ package common import ( "context" + "github.com/sirupsen/logrus" kc "github.com/keycloak/keycloak-operator/pkg/apis/keycloak/v1alpha1" "github.com/keycloak/keycloak-operator/pkg/model" @@ -35,12 +36,7 @@ func (i *ClientState) Read(context context.Context, cr *kc.KeycloakClient, realm return nil } - // Pace Keycloak 15 Workaround Fix - client.DefaultRoles = nil - - if client.RedirectUris == nil { - client.RedirectUris = make([]string, 0) - } + logrus.Infof("Reading Client-State: %+v", client) clientSecret, err := realmClient.GetClientSecret(cr.Spec.Client.ID, i.Realm.Spec.Realm.Realm) if err != nil {