Skip to content

Commit

Permalink
Merge pull request #133 from vshn/add/keycloak_maintenance
Browse files Browse the repository at this point in the history
Add support for custom themes and providers
  • Loading branch information
Kidswiss authored Feb 28, 2024
2 parents 0076d52 + c142264 commit 4342f8e
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 10 deletions.
14 changes: 14 additions & 0 deletions apis/vshn/v1/dbaas_vshn_keycloak.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
v1 "github.com/vshn/appcat/v4/apis/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

Expand Down Expand Up @@ -100,6 +101,19 @@ type VSHNKeycloakServiceSpec struct {
// PostgreSQLParameters can be used to set any supported setting in the
// underlying PostgreSQL instance.
PostgreSQLParameters *VSHNPostgreSQLParameters `json:"postgreSQLParameters,omitempty"`

// CustomizationImage can be used to provide an image with custom themes and providers.
// 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"`
}

type VSHNKeycloakCustomizationImage struct {
// Path to a valid image
Image string `json:"image,omitempty"`

// Reference to an imagePullSecret
ImagePullSecretRef corev1.SecretReference `json:"imagePullSecretRef,omitempty"`
}

// VSHNKeycloakSettings contains Keycloak specific settings.
Expand Down
17 changes: 17 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.

18 changes: 18 additions & 0 deletions crds/vshn.appcat.vshn.io_vshnkeycloaks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ spec:
service:
description: Service contains keycloak DBaaS specific properties
properties:
customizationImage:
description: CustomizationImage can be used to provide an image with custom themes and providers. 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.
properties:
image:
description: Path to a valid image
type: string
imagePullSecretRef:
description: Reference to an imagePullSecret
properties:
name:
description: name is unique within a namespace to reference a secret resource.
type: string
namespace:
description: namespace defines the space within which the secret name must be unique.
type: string
type: object
x-kubernetes-map-type: atomic
type: object
fqdn:
description: FQDN contains the FQDN which will be used for the ingress. If it's not set, no ingress will be deployed. This also enables strict hostname checking for this FQDN.
type: string
Expand Down
24 changes: 24 additions & 0 deletions crds/vshn.appcat.vshn.io_xvshnkeycloaks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,30 @@ spec:
service:
description: Service contains keycloak DBaaS specific properties
properties:
customizationImage:
description: CustomizationImage can be used to provide an
image with custom themes and providers. 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.
properties:
image:
description: Path to a valid image
type: string
imagePullSecretRef:
description: Reference to an imagePullSecret
properties:
name:
description: name is unique within a namespace to
reference a secret resource.
type: string
namespace:
description: namespace defines the space within which
the secret name must be unique.
type: string
type: object
x-kubernetes-map-type: atomic
type: object
fqdn:
description: FQDN contains the FQDN which will be used for
the ingress. If it's not set, no ingress will be deployed.
Expand Down
118 changes: 108 additions & 10 deletions pkg/comp-functions/functions/vshnkeycloak/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (
"fmt"

"dario.cat/mergo"
xkubev1 "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1"
xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"

xfnproto "github.com/crossplane/function-sdk-go/proto/v1beta1"
xhelmv1 "github.com/vshn/appcat/v4/apis/helm/release/v1beta1"
sgv1 "github.com/vshn/appcat/v4/apis/stackgres/v1"
Expand All @@ -20,6 +22,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/ptr"
"sigs.k8s.io/yaml"
)

Expand All @@ -36,6 +39,7 @@ const (
registryURL = "docker-registry.inventage.com:10121/keycloak-competence-center/keycloak-managed"
providerInitName = "copy-original-providers"
realmInitName = "copy-original-realm-setup"
customImagePullsecretName = "customimagepullsecret"
)

// DeployKeycloak deploys a keycloak instance via the codecentric Helm Chart.
Expand Down Expand Up @@ -265,6 +269,10 @@ func newValues(ctx context.Context, svc *runtime.ServiceRuntime, comp *vshnv1.VS
"name": "custom-providers",
"emptyDir": nil,
},
{
"name": "custom-themes",
"emptyDir": nil,
},
{
"name": "custom-setup",
"emptyDir": nil,
Expand All @@ -291,6 +299,10 @@ func newValues(ctx context.Context, svc *runtime.ServiceRuntime, comp *vshnv1.VS
"name": "custom-providers",
"mountPath": "/opt/keycloak/providers",
},
{
"name": "custom-themes",
"mountPath": "/opt/keycloak/themes",
},
{
"name": "custom-setup",
"mountPath": "/opt/keycloak/setup",
Expand Down Expand Up @@ -332,14 +344,6 @@ func newValues(ctx context.Context, svc *runtime.ServiceRuntime, comp *vshnv1.VS
"username": string(cd[vshnpostgres.PostgresqlUser]),
"password": string(cd[vshnpostgres.PostgresqlPassword]),
},
"serviceAccount": map[string]any{
"automountServiceAccountToken": "false",
"imagePullSecrets": []map[string]any{
{
"name": pullsecretName,
},
},
},
"resources": map[string]any{
"requests": map[string]any{
"memory": res.ReqMem,
Expand Down Expand Up @@ -395,7 +399,12 @@ 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(values, observedVersion)
err = addInitContainer(comp, svc, values, observedVersion)
if err != nil {
return nil, err
}

err = addServiceAccount(comp, svc, values)
if err != nil {
return nil, err
}
Expand All @@ -412,6 +421,30 @@ func toYAML(obj any) (string, error) {
return string(yamlBytes), err
}

func copyCustomImagePullSecret(comp *vshnv1.VSHNKeycloak, svc *runtime.ServiceRuntime) error {
secretInstance := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: customImagePullsecretName,
Namespace: comp.GetInstanceNamespace(),
},
Type: corev1.SecretTypeDockerConfigJson,
}
secretClaimRef := xkubev1.Reference{
PatchesFrom: &xkubev1.PatchesFrom{
DependsOn: xkubev1.DependsOn{
APIVersion: "v1",
Kind: "Secret",
Namespace: comp.Spec.Parameters.Service.CustomizationImage.ImagePullSecretRef.DeepCopy().Namespace,
Name: comp.Spec.Parameters.Service.CustomizationImage.ImagePullSecretRef.Name,
},
FieldPath: ptr.To("data"),
},
ToFieldPath: ptr.To("data"),
}

return svc.SetDesiredKubeObject(secretInstance, comp.GetName()+"-custom-image-pull-secret", runtime.KubeOptionAddRefs(secretClaimRef))
}

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

username := svc.Config.Data["registry_username"]
Expand Down Expand Up @@ -449,7 +482,34 @@ func addPullSecret(comp *vshnv1.VSHNKeycloak, svc *runtime.ServiceRuntime) error
return svc.SetDesiredKubeObject(secret, comp.GetName()+"-pull-secret")
}

func addInitContainer(values map[string]any, version string) error {
func addServiceAccount(comp *vshnv1.VSHNKeycloak, svc *runtime.ServiceRuntime, values map[string]any) error {

pullSecrets := []map[string]any{
{
"name": pullsecretName,
},
}

if comp.Spec.Parameters.Service.CustomizationImage.ImagePullSecretRef.Name != "" {
err := copyCustomImagePullSecret(comp, svc)
if err != nil {
return err
}
customImagePullSecret := map[string]any{
"name": customImagePullsecretName,
}
pullSecrets = append(pullSecrets, customImagePullSecret)
}

values["serviceAccount"] = map[string]any{
"automountServiceAccountToken": "false",
"imagePullSecrets": pullSecrets,
}

return nil
}

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

extraInitContainers, err := toYAML(extraInitContainersMap)
if err != nil {
Expand All @@ -502,3 +566,37 @@ ls -lh /custom-setup`,

return nil
}

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

extraInitContainersThemeProvidersMap := map[string]any{
"name": "copy-custom-themes-providers",
"image": comp.Spec.Parameters.Service.CustomizationImage.Image,
"imagePullPolicy": "Always",
"command": []string{
"sh",
},
"args": []string{
"-c",
`echo "Copying custom themes..."
cp -Rv /themes/* /custom-themes
echo "Copying custom providers..."
cp -Rv /providers/* /custom-providers
exit 0`,
},
"volumeMounts": []map[string]any{
{
"name": "custom-providers",
"mountPath": "/custom-providers",
},
{
"name": "custom-themes",
"mountPath": "/custom-themes",
},
},
}
extraInitContainersMap = append(extraInitContainersMap, extraInitContainersThemeProvidersMap)
}
return extraInitContainersMap, nil
}

0 comments on commit 4342f8e

Please sign in to comment.