Skip to content

Commit

Permalink
Merge pull request #197 from vshn/keycloak/config
Browse files Browse the repository at this point in the history
Add feature to allow setting a custom configuration for keycloak
  • Loading branch information
TheBigLee authored Jul 22, 2024
2 parents ad25173 + 81028c2 commit fbe36c8
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 4 deletions.
11 changes: 11 additions & 0 deletions apis/vshn/v1/dbaas_vshn_keycloak.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,17 @@ type VSHNKeycloakServiceSpec struct {
// The themes need to be be placed in the `/themes` directory of the custom image.
// the providers need to be placed in the `/providers` directory of the custom image.
CustomizationImage VSHNKeycloakCustomizationImage `json:"customizationImage,omitempty"`

// CustomConfigurationRef can be used to provide a configmap containing configurations for the
// keycloak instance. The config is a JSON file based on the keycloak export files.
// The referenced configmap, must have the configuration in a field called `keycloak-config.json`
CustomConfigurationRef *string `json:"configuration,omitempty"`

// CustomEnvVariablesRef can be used to provide custom environment variables from a
// provided secret for the keycloak instance. The environment variables provided
// can for example be used in the custom JSON configuration provided in the `Configuration`
// field with `$(env:<ENV_VAR_NAME>:-<some_default_value>)`
CustomEnvVariablesRef *string `json:"customEnvVariables,omitempty"`
}

type VSHNKeycloakCustomizationImage struct {
Expand Down
10 changes: 10 additions & 0 deletions apis/vshn/v1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions crds/vshn.appcat.vshn.io_vshnkeycloaks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4836,6 +4836,19 @@ spec:
service:
description: Service contains keycloak DBaaS specific properties
properties:
configuration:
description: |-
CustomConfigurationRef can be used to provide a configmap containing configurations for the
keycloak instance. The config is a JSON file based on the keycloak export files.
The referenced configmap, must have the configuration in a field called `keycloak-config.json`
type: string
customEnvVariables:
description: |-
CustomEnvVariablesRef can be used to provide custom environment variables from a
provided secret for the keycloak instance. The environment variables provided
can for example be used in the custom JSON configuration provided in the `Configuration`
field with `$(env:<ENV_VAR_NAME>:-<some_default_value>)`
type: string
customizationImage:
description: |-
CustomizationImage can be used to provide an image with custom themes and providers.
Expand Down
13 changes: 13 additions & 0 deletions crds/vshn.appcat.vshn.io_xvshnkeycloaks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5558,6 +5558,19 @@ spec:
service:
description: Service contains keycloak DBaaS specific properties
properties:
configuration:
description: |-
CustomConfigurationRef can be used to provide a configmap containing configurations for the
keycloak instance. The config is a JSON file based on the keycloak export files.
The referenced configmap, must have the configuration in a field called `keycloak-config.json`
type: string
customEnvVariables:
description: |-
CustomEnvVariablesRef can be used to provide custom environment variables from a
provided secret for the keycloak instance. The environment variables provided
can for example be used in the custom JSON configuration provided in the `Configuration`
field with `$(env:<ENV_VAR_NAME>:-<some_default_value>)`
type: string
customizationImage:
description: |-
CustomizationImage can be used to provide an image with custom themes and providers.
Expand Down
125 changes: 121 additions & 4 deletions pkg/comp-functions/functions/vshnkeycloak/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,21 @@ func newValues(ctx context.Context, svc *runtime.ServiceRuntime, comp *vshnv1.VS
},
}

if comp.Spec.Parameters.Service.CustomConfigurationRef != nil {
extraVolumesMap = append(extraVolumesMap, map[string]any{
"name": "keycloak-configs",
"configMap": map[string]any{
"name": comp.Spec.Parameters.Service.CustomConfigurationRef,
"items": []map[string]string{
{
"key": "keycloak-config.json",
"path": "keycloak-config.json",
},
},
},
})
}

extraVolumes, err := toYAML(extraVolumesMap)
if err != nil {
return nil, err
Expand Down Expand Up @@ -294,14 +309,28 @@ func newValues(ctx context.Context, svc *runtime.ServiceRuntime, comp *vshnv1.VS
},
}

if comp.Spec.Parameters.Service.CustomConfigurationRef != nil {
extraVolumeMountsMap = append(extraVolumeMountsMap, map[string]any{
"name": "keycloak-configs",
"mountPath": "/opt/keycloak/setup/keycloak-config.json",
"subPath": "keycloak-config.json",
})
}

extraVolumeMounts, err := toYAML(extraVolumeMountsMap)
if err != nil {
return nil, err
}

envFrom := ""
if comp.Spec.Parameters.Service.CustomEnvVariablesRef != nil {
envFrom = "[secretRef: {name: " + *comp.Spec.Parameters.Service.CustomEnvVariablesRef + "}]"
}

values = map[string]any{
"replicas": comp.Spec.Parameters.Instances,
"extraEnv": extraEnv,
"extraEnvFrom": envFrom,
"extraVolumes": extraVolumes,
"extraVolumeMounts": extraVolumeMounts,

Expand Down Expand Up @@ -371,6 +400,20 @@ func newValues(ctx context.Context, svc *runtime.ServiceRuntime, comp *vshnv1.VS
}

func newRelease(ctx context.Context, svc *runtime.ServiceRuntime, comp *vshnv1.VSHNKeycloak, adminSecret string) (*xhelmv1.Release, error) {

if comp.Spec.Parameters.Service.CustomConfigurationRef != nil {
err := copyConfigMap(comp, svc)
if err != nil {
return nil, fmt.Errorf("cannot copy keycloak config configmap to instance namespace: %w", err)
}
}
if comp.Spec.Parameters.Service.CustomEnvVariablesRef != nil {
err := copySecret(comp, svc)
if err != nil {
return nil, fmt.Errorf("cannot copy keycloak env variable secret to instance namespace: %w", err)
}
}

values, err := newValues(ctx, svc, comp, adminSecret)
if err != nil {
return nil, err
Expand All @@ -386,7 +429,7 @@ func newRelease(ctx context.Context, svc *runtime.ServiceRuntime, comp *vshnv1.V
return nil, fmt.Errorf("cannot set keycloak version for release: %w", err)
}

err = addInitContainer(comp, svc, values, observedVersion)
err = addInitContainer(comp, values, observedVersion)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -496,7 +539,7 @@ func addServiceAccount(comp *vshnv1.VSHNKeycloak, svc *runtime.ServiceRuntime, v
return nil
}

func addInitContainer(comp *vshnv1.VSHNKeycloak, svc *runtime.ServiceRuntime, values map[string]any, version string) error {
func addInitContainer(comp *vshnv1.VSHNKeycloak, values map[string]any, version string) error {
extraInitContainersMap := []map[string]any{
{
"name": providerInitName,
Expand Down Expand Up @@ -539,7 +582,7 @@ ls -lh /custom-setup`,
},
},
}
extraInitContainersMap, err := addCustomInitContainer(comp, svc, extraInitContainersMap)
extraInitContainersMap, err := addCustomInitContainer(comp, extraInitContainersMap)
if err != nil {
return err
}
Expand All @@ -554,7 +597,7 @@ ls -lh /custom-setup`,
return nil
}

func addCustomInitContainer(comp *vshnv1.VSHNKeycloak, svc *runtime.ServiceRuntime, extraInitContainersMap []map[string]any) ([]map[string]any, error) {
func addCustomInitContainer(comp *vshnv1.VSHNKeycloak, extraInitContainersMap []map[string]any) ([]map[string]any, error) {
if comp.Spec.Parameters.Service.CustomizationImage.Image != "" {

extraInitContainersThemeProvidersMap := map[string]any{
Expand Down Expand Up @@ -587,3 +630,77 @@ exit 0`,
}
return extraInitContainersMap, nil
}

func copyConfigMap(comp *vshnv1.VSHNKeycloak, svc *runtime.ServiceRuntime) error {

cmObjectName := comp.GetName() + "-config-claim-observer"

cmClaimObserver := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: *comp.Spec.Parameters.Service.CustomConfigurationRef,
Namespace: comp.GetClaimNamespace(),
},
}
err := svc.SetDesiredKubeObserveObject(cmClaimObserver, cmObjectName)

if err != nil {
svc.Log.Info("Can't observe Keycloak config Configmap")
svc.AddResult(runtime.NewFatalResult(fmt.Errorf("cannot get configMap: %w", err)))
}

configMapClaim := &corev1.ConfigMap{}
err = svc.GetObservedKubeObject(configMapClaim, cmObjectName)
if err != nil {
svc.Log.Info("cannot get observed Keycloak config map")
svc.AddResult(runtime.NewWarningResult("cannot get observed Keycloak config map"))
}

configMapInstance := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: *comp.Spec.Parameters.Service.CustomConfigurationRef,
Namespace: comp.GetInstanceNamespace(),
Labels: configMapClaim.Labels,
Annotations: configMapClaim.Annotations,
},
Data: configMapClaim.Data,
}

return svc.SetDesiredKubeObject(configMapInstance, comp.GetName()+"-config-map")
}

func copySecret(comp *vshnv1.VSHNKeycloak, svc *runtime.ServiceRuntime) error {

secretObjectName := comp.GetName() + "-env-secret-claim-observer"

secretClaimObserver := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: *comp.Spec.Parameters.Service.CustomEnvVariablesRef,
Namespace: comp.GetClaimNamespace(),
},
}
err := svc.SetDesiredKubeObserveObject(secretClaimObserver, secretObjectName)

if err != nil {
svc.Log.Info("Can't observe Keycloak env variable secret")
svc.AddResult(runtime.NewFatalResult(fmt.Errorf("cannot get secret: %w", err)))
}

secretClaim := &corev1.Secret{}
err = svc.GetObservedKubeObject(secretClaim, secretObjectName)
if err != nil {
svc.Log.Info("cannot get observed Keycloak env variable secret")
svc.AddResult(runtime.NewWarningResult("cannot get observed Keycloak env variable secret"))
}

secretInstance := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: *comp.Spec.Parameters.Service.CustomEnvVariablesRef,
Namespace: comp.GetInstanceNamespace(),
Labels: secretClaim.Labels,
Annotations: secretClaim.Annotations,
},
Data: secretClaim.Data,
}

return svc.SetDesiredKubeObject(secretInstance, comp.GetName()+"-env-secret")
}

0 comments on commit fbe36c8

Please sign in to comment.