diff --git a/.github/workflows/helm-docs.yaml b/.github/workflows/helm-docs.yaml
new file mode 100644
index 000000000..352c7bf57
--- /dev/null
+++ b/.github/workflows/helm-docs.yaml
@@ -0,0 +1,23 @@
+name: Verify Helm Docs up-to-date
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ generate:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.ref }}
+ - name: Run helm-docs
+ uses: losisin/helm-docs-github-action@v1
+ with:
+ fail-on-diff: false
+ chart-search-root: charts/
+ template-files: README.md.gotmpl
+ git-push: true
+ git-push-user-name: "openmfp-technical-user"
+ git-push-user-email: "openmfp@gmail.com"
+ git-commit-message: "chore: update Helm documentation"
\ No newline at end of file
diff --git a/.github/workflows/keycloak.yaml b/.github/workflows/keycloak.yaml
new file mode 100644
index 000000000..7acef9401
--- /dev/null
+++ b/.github/workflows/keycloak.yaml
@@ -0,0 +1,28 @@
+name: Build Keycloak
+on:
+ push:
+ paths:
+ - 'charts/keycloak/**'
+ - '.github/workflows/keycloak.yaml'
+
+jobs:
+ pipeline:
+ concurrency:
+ group: keycloak-${{ github.ref }}
+ cancel-in-progress: true
+ uses: openmfp/gha/.github/workflows/pipeline-chart.yml@main
+ with:
+ chartFolder: charts
+ chartName: keycloak
+ additionalTestFilesCommand: ''
+ chartRepos: 'bitnami=https://charts.bitnami.com/bitnami,openfga=https://openfga.github.io/helm-charts'
+ secrets: inherit
+
+ updateVersionFile:
+ if: ${{ github.ref == 'refs/heads/main' }}
+ needs: [pipeline]
+ uses: openmfp/gha/.github/workflows/job-update-version-file.yml@main
+ secrets: inherit
+ with:
+ componentVersionKey: "keycloak"
+ version: ${{ needs.pipeline.outputs.version }}
\ No newline at end of file
diff --git a/charts/account-operator-crds/Chart.yaml b/charts/account-operator-crds/Chart.yaml
index f28f61693..dd9a1f280 100644
--- a/charts/account-operator-crds/Chart.yaml
+++ b/charts/account-operator-crds/Chart.yaml
@@ -4,6 +4,6 @@ description: A Helm chart for Kubernetes
type: application
-version: 0.1.6
+version: 0.1.7
appVersion: "1.16.0"
diff --git a/charts/account-operator-crds/README.md b/charts/account-operator-crds/README.md
index 50a5c1f6d..a7619fc9a 100644
--- a/charts/account-operator-crds/README.md
+++ b/charts/account-operator-crds/README.md
@@ -1,12 +1,35 @@
# account-operator-crds
-  
-
A Helm chart for Kubernetes
+  
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
## Values
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| kcp.enabled | bool | `false` | Enable KCP |
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/charts/account-operator-crds/README.md.gotmpl b/charts/account-operator-crds/README.md.gotmpl
new file mode 100644
index 000000000..94146d84e
--- /dev/null
+++ b/charts/account-operator-crds/README.md.gotmpl
@@ -0,0 +1,33 @@
+{{ template "chart.header" . }}
+{{ template "chart.description" . }}
+
+{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+{{ template "chart.requirementsSection" . }}
+
+{{ template "chart.valuesHeader" . }}
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+{{ template "chart.valuesTable" . }}
+
+{{ template "helm-docs.versionFooter" . }}
diff --git a/charts/account-operator/Chart.lock b/charts/account-operator/Chart.lock
index 4ba972e60..b5ee809ee 100644
--- a/charts/account-operator/Chart.lock
+++ b/charts/account-operator/Chart.lock
@@ -1,9 +1,9 @@
dependencies:
- name: account-operator-crds
- repository: file://../account-operator-crds
+ repository: oci://ghcr.io/openmfp/helm-charts
version: 0.1.6
- name: common
- repository: file://../common
+ repository: oci://ghcr.io/openmfp/helm-charts
version: 0.1.5
-digest: sha256:5dcb2935c71c2e917170ef3b54c5ea586ab30269a5ec960353bfcbb362c073e1
-generated: "2024-11-27T20:12:23.434477831+02:00"
+digest: sha256:906c653c1bbf56adabd5ef2154f13e02dc698affbbb4e1e6c849a36fa6e0a714
+generated: "2024-12-04T16:19:50.856906714+02:00"
diff --git a/charts/account-operator/Chart.yaml b/charts/account-operator/Chart.yaml
index 3163cdb6c..cfe89b60f 100644
--- a/charts/account-operator/Chart.yaml
+++ b/charts/account-operator/Chart.yaml
@@ -2,13 +2,13 @@ apiVersion: v2
name: account-operator
description: A Helm chart for Kubernetes
type: application
-version: 0.4.24
+version: 0.5.0
appVersion: "0.111.0"
dependencies:
- name: account-operator-crds
version: 0.1.6
condition: crds.enabled
- repository: file://../account-operator-crds
+ repository: oci://ghcr.io/openmfp/helm-charts
- name: common
version: 0.1.5
- repository: file://../common
+ repository: oci://ghcr.io/openmfp/helm-charts
diff --git a/charts/account-operator/README.md b/charts/account-operator/README.md
index a749e6901..7dfb9a982 100644
--- a/charts/account-operator/README.md
+++ b/charts/account-operator/README.md
@@ -1,18 +1,39 @@
# account-operator
-  
-
A Helm chart for Kubernetes
+  
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
## Requirements
| Repository | Name | Version |
|------------|------|---------|
-| file://../account-operator-crds | account-operator-crds | 0.1.6 |
-| file://../common | common | 0.1.5 |
+| oci://ghcr.io/openmfp/helm-charts | account-operator-crds | 0.1.6 |
+| oci://ghcr.io/openmfp/helm-charts | common | 0.1.5 |
## Values
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| crds.enabled | bool | `true` | Enable CRDs |
@@ -38,3 +59,5 @@ A Helm chart for Kubernetes
| webhooks.certDir | string | `"/certs"` | The directory for webhook certificates |
| webhooks.enabled | bool | `false` | Enable webhooks |
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/charts/account-operator/README.md.gotmpl b/charts/account-operator/README.md.gotmpl
new file mode 100644
index 000000000..94146d84e
--- /dev/null
+++ b/charts/account-operator/README.md.gotmpl
@@ -0,0 +1,33 @@
+{{ template "chart.header" . }}
+{{ template "chart.description" . }}
+
+{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+{{ template "chart.requirementsSection" . }}
+
+{{ template "chart.valuesHeader" . }}
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+{{ template "chart.valuesTable" . }}
+
+{{ template "helm-docs.versionFooter" . }}
diff --git a/charts/account-operator/charts/account-operator-crds-0.1.6.tgz b/charts/account-operator/charts/account-operator-crds-0.1.6.tgz
index d7dbe12e9..0a94811ee 100644
Binary files a/charts/account-operator/charts/account-operator-crds-0.1.6.tgz and b/charts/account-operator/charts/account-operator-crds-0.1.6.tgz differ
diff --git a/charts/account-operator/charts/common-0.1.5.tgz b/charts/account-operator/charts/common-0.1.5.tgz
index 17b38ee60..706e7e231 100644
Binary files a/charts/account-operator/charts/common-0.1.5.tgz and b/charts/account-operator/charts/common-0.1.5.tgz differ
diff --git a/charts/common/Chart.yaml b/charts/common/Chart.yaml
index ac360c91d..482eb51ec 100644
--- a/charts/common/Chart.yaml
+++ b/charts/common/Chart.yaml
@@ -4,4 +4,4 @@ description: A Helm chart for Kubernetes
type: library
-version: 0.1.5
+version: 0.1.6
diff --git a/charts/common/README.md b/charts/common/README.md
index 1530d9276..644ae83d8 100644
--- a/charts/common/README.md
+++ b/charts/common/README.md
@@ -2,7 +2,7 @@
A Helm chart for Kubernetes
- 
+ 
## Additional Information
@@ -52,3 +52,5 @@ Example
| defaults.securityContext.runAsGroup | int | `3000` | group id to run the container |
| defaults.securityContext.runAsUser | int | `1000` | user id to run the container |
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/charts/common/test-chart/charts/common-0.1.5.tgz b/charts/common/test-chart/charts/common-0.1.5.tgz
index 689530f88..3552f6f1f 100644
Binary files a/charts/common/test-chart/charts/common-0.1.5.tgz and b/charts/common/test-chart/charts/common-0.1.5.tgz differ
diff --git a/charts/example-content/Chart.lock b/charts/example-content/Chart.lock
index a35e3fded..4615eb988 100644
--- a/charts/example-content/Chart.lock
+++ b/charts/example-content/Chart.lock
@@ -1,6 +1,6 @@
dependencies:
- name: common
- repository: file://../common
+ repository: oci://ghcr.io/openmfp/helm-charts
version: 0.1.5
-digest: sha256:22600e7bfcab429b2e013cb3ff4ad21252274de627cccb908c95cc025ef150ce
-generated: "2024-11-27T19:50:11.199614661+02:00"
+digest: sha256:bd35b46dc5ab1c0af864e9e8a6ce2fdba5055019fc3f337841c7e54d00a6a5cd
+generated: "2024-12-04T16:19:58.461614709+02:00"
diff --git a/charts/example-content/Chart.yaml b/charts/example-content/Chart.yaml
index 31fe2e0d8..c4926e518 100644
--- a/charts/example-content/Chart.yaml
+++ b/charts/example-content/Chart.yaml
@@ -2,8 +2,8 @@ apiVersion: v2
appVersion: "0.126.0"
description: Helm Chart for the openmfp Portal
name: example-content
-version: 0.110.8
+version: 0.110.9
dependencies:
- name: common
version: 0.1.5
- repository: file://../common
+ repository: oci://ghcr.io/openmfp/helm-charts
diff --git a/charts/example-content/README.MD b/charts/example-content/README.MD
deleted file mode 100644
index b0913446c..000000000
--- a/charts/example-content/README.MD
+++ /dev/null
@@ -1,21 +0,0 @@
-# example-content
-
- 
-
-Helm Chart for the openmfp Portal
-
-## Requirements
-
-| Repository | Name | Version |
-|------------|------|---------|
-| file://../common | common | 0.1.5 |
-
-## Values
-
-| Key | Type | Default | Description |
-|-----|------|---------|-------------|
-| image.name | string | `"ghcr.io/openmfp/example-content"` | The image name |
-| istio.virtualService.hosts[0] | string | `"your-host.com"` | |
-| istio.virtualService.matchers[0].match[0].uri.exact | string | `"/ui/example-content"` | |
-| istio.virtualService.matchers[0].match[1].uri.prefix | string | `"/ui/example-content/"` | |
-
diff --git a/charts/example-content/README.md b/charts/example-content/README.md
index 8660f5348..3ae453df8 100644
--- a/charts/example-content/README.md
+++ b/charts/example-content/README.md
@@ -1,17 +1,38 @@
# example-content
- 
-
Helm Chart for the openmfp Portal
+ 
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
## Requirements
| Repository | Name | Version |
|------------|------|---------|
-| file://../common | common | 0.1.5 |
+| oci://ghcr.io/openmfp/helm-charts | common | 0.1.5 |
## Values
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| image.name | string | `"ghcr.io/openmfp/example-content"` | The image name |
@@ -19,3 +40,5 @@ Helm Chart for the openmfp Portal
| istio.virtualService.matchers[0].match[0].uri.exact | string | `"/ui/example-content"` | |
| istio.virtualService.matchers[0].match[1].uri.prefix | string | `"/ui/example-content/"` | |
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/charts/example-content/README.md.gotmpl b/charts/example-content/README.md.gotmpl
new file mode 100644
index 000000000..94146d84e
--- /dev/null
+++ b/charts/example-content/README.md.gotmpl
@@ -0,0 +1,33 @@
+{{ template "chart.header" . }}
+{{ template "chart.description" . }}
+
+{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+{{ template "chart.requirementsSection" . }}
+
+{{ template "chart.valuesHeader" . }}
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+{{ template "chart.valuesTable" . }}
+
+{{ template "helm-docs.versionFooter" . }}
diff --git a/charts/example-content/charts/common-0.1.5.tgz b/charts/example-content/charts/common-0.1.5.tgz
index da1b3a71b..706e7e231 100644
Binary files a/charts/example-content/charts/common-0.1.5.tgz and b/charts/example-content/charts/common-0.1.5.tgz differ
diff --git a/charts/extension-manager-operator-crds/Chart.yaml b/charts/extension-manager-operator-crds/Chart.yaml
index 5eebe9c2c..44f7f1807 100644
--- a/charts/extension-manager-operator-crds/Chart.yaml
+++ b/charts/extension-manager-operator-crds/Chart.yaml
@@ -15,7 +15,7 @@ type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 0.1.3
+version: 0.1.4
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
diff --git a/charts/extension-manager-operator-crds/README.md b/charts/extension-manager-operator-crds/README.md
index 8ac00bcf6..6edd2b8d8 100644
--- a/charts/extension-manager-operator-crds/README.md
+++ b/charts/extension-manager-operator-crds/README.md
@@ -1,6 +1,34 @@
# extension-manager-operator-crds
-  
-
A Helm chart for Kubernetes
+  
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+## Values
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/charts/extension-manager-operator-crds/README.md.gotmpl b/charts/extension-manager-operator-crds/README.md.gotmpl
new file mode 100644
index 000000000..94146d84e
--- /dev/null
+++ b/charts/extension-manager-operator-crds/README.md.gotmpl
@@ -0,0 +1,33 @@
+{{ template "chart.header" . }}
+{{ template "chart.description" . }}
+
+{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+{{ template "chart.requirementsSection" . }}
+
+{{ template "chart.valuesHeader" . }}
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+{{ template "chart.valuesTable" . }}
+
+{{ template "helm-docs.versionFooter" . }}
diff --git a/charts/extension-manager-operator/Chart.lock b/charts/extension-manager-operator/Chart.lock
index ce05994b9..7d242f030 100644
--- a/charts/extension-manager-operator/Chart.lock
+++ b/charts/extension-manager-operator/Chart.lock
@@ -1,9 +1,9 @@
dependencies:
- name: extension-manager-operator-crds
- repository: file://../extension-manager-operator-crds
+ repository: oci://ghcr.io/openmfp/helm-charts
version: 0.1.3
- name: common
- repository: file://../common
+ repository: oci://ghcr.io/openmfp/helm-charts
version: 0.1.5
-digest: sha256:c866935aba532b7089a518053501d5e44863e0fc7ee4e6f6b5df9f324596f55b
-generated: "2024-11-22T16:15:55.20032089+02:00"
+digest: sha256:2688423cd8e784a91db8fe3503866ca5284da8c8aa1596dbf43f3786bc2f9404
+generated: "2024-12-04T16:44:54.438153194+02:00"
diff --git a/charts/extension-manager-operator/Chart.yaml b/charts/extension-manager-operator/Chart.yaml
index 4ac6bc96b..c503b407e 100644
--- a/charts/extension-manager-operator/Chart.yaml
+++ b/charts/extension-manager-operator/Chart.yaml
@@ -2,13 +2,13 @@ apiVersion: v2
name: extension-manager-operator
description: A Helm chart for extension-manager-operator
type: application
-version: 0.22.35
+version: 0.22.36
appVersion: "0.77.0"
dependencies:
- name: extension-manager-operator-crds
version: 0.1.3
condition: crds.enabled
- repository: file://../extension-manager-operator-crds
+ repository: oci://ghcr.io/openmfp/helm-charts
- name: common
version: 0.1.5
- repository: file://../common
+ repository: oci://ghcr.io/openmfp/helm-charts
diff --git a/charts/extension-manager-operator/README.md b/charts/extension-manager-operator/README.md
index 4e552b051..c945efcf8 100644
--- a/charts/extension-manager-operator/README.md
+++ b/charts/extension-manager-operator/README.md
@@ -1,18 +1,39 @@
# extension-manager-operator
-  
-
A Helm chart for extension-manager-operator
+  
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
## Requirements
| Repository | Name | Version |
|------------|------|---------|
-| file://../common | common | 0.1.5 |
-| file://../extension-manager-operator-crds | extension-manager-operator-crds | 0.1.3 |
+| oci://ghcr.io/openmfp/helm-charts | common | 0.1.5 |
+| oci://ghcr.io/openmfp/helm-charts | extension-manager-operator-crds | 0.1.3 |
## Values
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| commonAnnotations | object | `{}` | |
@@ -20,3 +41,5 @@ A Helm chart for extension-manager-operator
| image.name | string | `"ghcr.io/openmfp/extension-content-operator"` | |
| image.tag | string | `"0.16.0"` | |
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/charts/extension-manager-operator/README.md.gotmpl b/charts/extension-manager-operator/README.md.gotmpl
new file mode 100644
index 000000000..94146d84e
--- /dev/null
+++ b/charts/extension-manager-operator/README.md.gotmpl
@@ -0,0 +1,33 @@
+{{ template "chart.header" . }}
+{{ template "chart.description" . }}
+
+{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+{{ template "chart.requirementsSection" . }}
+
+{{ template "chart.valuesHeader" . }}
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+{{ template "chart.valuesTable" . }}
+
+{{ template "helm-docs.versionFooter" . }}
diff --git a/charts/extension-manager-operator/charts/common-0.1.5.tgz b/charts/extension-manager-operator/charts/common-0.1.5.tgz
index bc56a6f9b..706e7e231 100644
Binary files a/charts/extension-manager-operator/charts/common-0.1.5.tgz and b/charts/extension-manager-operator/charts/common-0.1.5.tgz differ
diff --git a/charts/extension-manager-operator/charts/extension-manager-operator-crds-0.1.3.tgz b/charts/extension-manager-operator/charts/extension-manager-operator-crds-0.1.3.tgz
index f9db5e92a..9dfa88c17 100644
Binary files a/charts/extension-manager-operator/charts/extension-manager-operator-crds-0.1.3.tgz and b/charts/extension-manager-operator/charts/extension-manager-operator-crds-0.1.3.tgz differ
diff --git a/charts/infra/.helmignore b/charts/infra/.helmignore
new file mode 100644
index 000000000..0e8a0eb36
--- /dev/null
+++ b/charts/infra/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/infra/Chart.lock b/charts/infra/Chart.lock
new file mode 100644
index 000000000..0919a9844
--- /dev/null
+++ b/charts/infra/Chart.lock
@@ -0,0 +1,6 @@
+dependencies:
+- name: common
+ repository: oci://ghcr.io/openmfp/helm-charts
+ version: 0.1.5
+digest: sha256:bd35b46dc5ab1c0af864e9e8a6ce2fdba5055019fc3f337841c7e54d00a6a5cd
+generated: "2024-12-04T16:20:09.59362191+02:00"
diff --git a/charts/infra/Chart.yaml b/charts/infra/Chart.yaml
new file mode 100644
index 000000000..0035ad9ec
--- /dev/null
+++ b/charts/infra/Chart.yaml
@@ -0,0 +1,11 @@
+apiVersion: v2
+name: infra
+description: A Helm chart for Kubernetes
+type: application
+version: 0.57.2
+appVersion: "1.16.0"
+
+dependencies:
+ - name: common
+ version: 0.1.5
+ repository: oci://ghcr.io/openmfp/helm-charts
diff --git a/charts/infra/README.md b/charts/infra/README.md
new file mode 100644
index 000000000..af44e86c5
--- /dev/null
+++ b/charts/infra/README.md
@@ -0,0 +1,56 @@
+# infra
+
+A Helm chart for Kubernetes
+
+  
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+## Requirements
+
+| Repository | Name | Version |
+|------------|------|---------|
+| oci://ghcr.io/openmfp/helm-charts | common | 0.1.5 |
+
+## Values
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| certificate.gardener.enabled | bool | `false` | |
+| externalSecrets.accountOperatorSaKubeconfig | string | `"account-operator-sa-kubeconfig"` | |
+| fga.enabled | bool | `true` | |
+| fga.stores | list | `[]` | |
+| gateway.annotations | object | `{}` | |
+| gateway.apiVersion | string | `"networking.istio.io/v1"` | |
+| gateway.name | string | `"gateway"` | |
+| gateway.selector.istio | string | `"gateway"` | |
+| gateway.servers[0].hosts[0] | string | `"*"` | |
+| gateway.servers[0].port.name | string | `"http"` | |
+| gateway.servers[0].port.number | int | `8080` | |
+| gateway.servers[0].port.protocol | string | `"HTTP"` | |
+| kcp.enabled | bool | `false` | |
+| keycloak.enabled | bool | `false` | |
+| keycloak.hosts[0] | string | `"login.microsoftonline.com"` | |
+| rbac.clusterRole.enabled | bool | `false` | |
+
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/charts/infra/README.md.gotmpl b/charts/infra/README.md.gotmpl
new file mode 100644
index 000000000..94146d84e
--- /dev/null
+++ b/charts/infra/README.md.gotmpl
@@ -0,0 +1,33 @@
+{{ template "chart.header" . }}
+{{ template "chart.description" . }}
+
+{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+{{ template "chart.requirementsSection" . }}
+
+{{ template "chart.valuesHeader" . }}
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+{{ template "chart.valuesTable" . }}
+
+{{ template "helm-docs.versionFooter" . }}
diff --git a/charts/infra/charts/common-0.1.5.tgz b/charts/infra/charts/common-0.1.5.tgz
new file mode 100644
index 000000000..706e7e231
Binary files /dev/null and b/charts/infra/charts/common-0.1.5.tgz differ
diff --git a/charts/infra/templates/cluster-role.yaml b/charts/infra/templates/cluster-role.yaml
new file mode 100644
index 000000000..ec8339334
--- /dev/null
+++ b/charts/infra/templates/cluster-role.yaml
@@ -0,0 +1,30 @@
+{{- if ((.Values.rbac).clusterRole).enabled -}}
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: openmfp-cluster-reader
+rules:
+- apiGroups:
+ - core.openmfp.io
+ resources:
+ - '*'
+ verbs:
+ - get
+ - list
+ - watch
+
+---
+
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: openmfp-cluster-reader
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: gardener.cloud:system:read-only
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+ kind: Group
+ name: /portal
+{{- end -}}
diff --git a/charts/infra/templates/external-secret-account-operator.yaml b/charts/infra/templates/external-secret-account-operator.yaml
new file mode 100644
index 000000000..6bb0c566f
--- /dev/null
+++ b/charts/infra/templates/external-secret-account-operator.yaml
@@ -0,0 +1,22 @@
+{{- if eq (include "common.hasNestedKey" (dict "Values" .Values "key" "externalSecrets.enabled")) "true" }}
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: account-operator-sa-kubeconfig
+ namespace: {{ .Release.Namespace }}
+spec:
+ refreshInterval: "10m"
+ secretStoreRef:
+ name: environment-store
+ kind: SecretStore
+ target:
+ name: account-operator-sa-kubeconfig
+ creationPolicy: Owner
+ deletionPolicy: Retain
+ data:
+ - secretKey: kubeconfig
+ remoteRef:
+ key: {{ .Values.externalSecrets.accountOperatorSaKubeconfig }}
+ property: kubeconfig
+ conversionStrategy: Default
+{{ end }}
diff --git a/charts/infra/templates/gateway.yaml b/charts/infra/templates/gateway.yaml
new file mode 100644
index 000000000..8b1723d55
--- /dev/null
+++ b/charts/infra/templates/gateway.yaml
@@ -0,0 +1,14 @@
+apiVersion: {{ .Values.gateway.apiVersion }}
+kind: Gateway
+metadata:
+ name: {{ .Values.gateway.name}}
+ namespace: {{ .Release.Namespace }}
+{{- if .Values.gateway.annotations }}
+ annotations:
+ {{- toYaml .Values.gateway.annotations | nindent 4 }}
+{{- end }}
+spec:
+ selector:
+{{ .Values.gateway.selector | toYaml | indent 4 }}
+ servers:
+{{ toYaml .Values.gateway.servers | indent 4 }}
\ No newline at end of file
diff --git a/charts/infra/templates/kcp-service-entry.yaml b/charts/infra/templates/kcp-service-entry.yaml
new file mode 100644
index 000000000..4f509e5e2
--- /dev/null
+++ b/charts/infra/templates/kcp-service-entry.yaml
@@ -0,0 +1,16 @@
+{{- if and .Values.kcp.enabled .Values.kcp.host -}}
+apiVersion: networking.istio.io/v1beta1
+kind: ServiceEntry
+metadata:
+ name: kcp-workspaces
+ namespace: {{ .Release.Namespace }}
+spec:
+ hosts:
+ - {{ .Values.kcp.host }}
+ location: MESH_EXTERNAL
+ ports:
+ - name: https
+ number: 443
+ protocol: TLS
+ resolution: DNS
+{{- end -}}
diff --git a/charts/infra/templates/keycloak-service-entry.yaml b/charts/infra/templates/keycloak-service-entry.yaml
new file mode 100644
index 000000000..e3b34d0e9
--- /dev/null
+++ b/charts/infra/templates/keycloak-service-entry.yaml
@@ -0,0 +1,15 @@
+{{- if (.Values.keycloak).enabled -}}
+apiVersion: networking.istio.io/v1beta1
+kind: ServiceEntry
+metadata:
+ name: auth
+spec:
+ hosts:
+ {{- .Values.keycloak.hosts | toYaml | nindent 2 }}
+ location: MESH_EXTERNAL
+ ports:
+ - name: https
+ number: 443
+ protocol: TLS
+ resolution: DNS
+{{- end -}}
diff --git a/charts/infra/templates/store.yaml b/charts/infra/templates/store.yaml
new file mode 100644
index 000000000..095a2989a
--- /dev/null
+++ b/charts/infra/templates/store.yaml
@@ -0,0 +1,13 @@
+{{- if (.Values.fga).enabled }}
+{{- range .Values.fga.stores }}
+---
+apiVersion: core.openmfp.io/v1alpha1
+kind: Store
+metadata:
+ name: {{ .name }}
+ namespace: {{ .namespace }}
+spec:
+ coreModule: |
+ {{ .coreModuleName | nindent 4 }}
+{{- end}}
+{{- end }}
\ No newline at end of file
diff --git a/charts/infra/test-values.yaml b/charts/infra/test-values.yaml
new file mode 100644
index 000000000..1ec678a07
--- /dev/null
+++ b/charts/infra/test-values.yaml
@@ -0,0 +1,36 @@
+gateway:
+ apiVersion: networking.istio.io/v1
+ name: gateway
+ selector:
+ istio: gateway
+ servers:
+ - port:
+ number: 8080
+ name: http
+ protocol: HTTP
+ hosts:
+ - "*"
+
+kcp:
+ enabled: false
+# host: ""
+
+auth:
+# host: ""
+
+externalSecrets:
+ accountOperatorSaKubeconfig: account-operator-sa-kubeconfig
+ enabled: false
+
+stores:
+ - name: test
+ namespace: test
+ coreModuleName: |
+ module core
+
+ type user
+
+ type account
+ relations
+ define owner: [user]
+ define member: [user] or owner
\ No newline at end of file
diff --git a/charts/infra/tests/__snapshot__/snapshot_test.yaml.snap b/charts/infra/tests/__snapshot__/snapshot_test.yaml.snap
new file mode 100644
index 000000000..22130d2fa
--- /dev/null
+++ b/charts/infra/tests/__snapshot__/snapshot_test.yaml.snap
@@ -0,0 +1,76 @@
+disables externalsecrets:
+ 1: |
+ apiVersion: external-secrets.io/v1beta1
+ kind: ExternalSecret
+ metadata:
+ name: account-operator-sa-kubeconfig
+ namespace: NAMESPACE
+ spec:
+ data:
+ - remoteRef:
+ conversionStrategy: Default
+ key: null
+ property: kubeconfig
+ secretKey: kubeconfig
+ refreshInterval: 10m
+ secretStoreRef:
+ kind: SecretStore
+ name: environment-store
+ target:
+ creationPolicy: Owner
+ deletionPolicy: Retain
+ name: account-operator-sa-kubeconfig
+ 2: |
+ apiVersion: networking.istio.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway
+ namespace: NAMESPACE
+ spec:
+ selector:
+ istio: gateway
+ servers:
+ - hosts:
+ - '*'
+ port:
+ name: http
+ number: 8080
+ protocol: HTTP
+matches the snapshot:
+ 1: |
+ apiVersion: external-secrets.io/v1beta1
+ kind: ExternalSecret
+ metadata:
+ name: account-operator-sa-kubeconfig
+ namespace: NAMESPACE
+ spec:
+ data:
+ - remoteRef:
+ conversionStrategy: Default
+ key: account-operator-sa-kubeconfig
+ property: kubeconfig
+ secretKey: kubeconfig
+ refreshInterval: 10m
+ secretStoreRef:
+ kind: SecretStore
+ name: environment-store
+ target:
+ creationPolicy: Owner
+ deletionPolicy: Retain
+ name: account-operator-sa-kubeconfig
+ 2: |
+ apiVersion: networking.istio.io/v1
+ kind: Gateway
+ metadata:
+ name: gateway
+ namespace: NAMESPACE
+ spec:
+ selector:
+ istio: gateway
+ servers:
+ - hosts:
+ - '*'
+ port:
+ name: http
+ number: 8080
+ protocol: HTTP
diff --git a/charts/infra/tests/snapshot_test.yaml b/charts/infra/tests/snapshot_test.yaml
new file mode 100644
index 000000000..895fa1414
--- /dev/null
+++ b/charts/infra/tests/snapshot_test.yaml
@@ -0,0 +1,14 @@
+suite: snapshot
+values:
+ - ../test-values.yaml
+tests:
+ - it: matches the snapshot
+ asserts:
+ - matchSnapshot: {}
+ - it: disables externalsecrets
+ set:
+ externalSecrets:
+ accountOperatorSaKubeconfig: null
+ asserts:
+ - matchSnapshot: {}
+
diff --git a/charts/infra/values.yaml b/charts/infra/values.yaml
new file mode 100644
index 000000000..9029650e1
--- /dev/null
+++ b/charts/infra/values.yaml
@@ -0,0 +1,37 @@
+gateway:
+ annotations: {}
+ apiVersion: networking.istio.io/v1
+ name: gateway
+ selector:
+ istio: gateway
+ servers:
+ - port:
+ number: 8080
+ name: http
+ protocol: HTTP
+ hosts:
+ - "*"
+
+rbac:
+ clusterRole:
+ enabled: false
+
+kcp:
+ enabled: false
+# host: ""
+
+keycloak:
+ enabled: false
+ hosts:
+ - "login.microsoftonline.com"
+
+externalSecrets:
+ accountOperatorSaKubeconfig: account-operator-sa-kubeconfig
+
+fga:
+ enabled: true
+ stores: []
+
+certificate:
+ gardener:
+ enabled: false
diff --git a/charts/keycloak/.helmignore b/charts/keycloak/.helmignore
new file mode 100644
index 000000000..0e8a0eb36
--- /dev/null
+++ b/charts/keycloak/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/charts/keycloak/Chart.lock b/charts/keycloak/Chart.lock
new file mode 100644
index 000000000..a0ac12e64
--- /dev/null
+++ b/charts/keycloak/Chart.lock
@@ -0,0 +1,9 @@
+dependencies:
+- name: keycloak
+ repository: oci://registry-1.docker.io/bitnamicharts
+ version: 24.2.2
+- name: common
+ repository: oci://ghcr.io/openmfp/helm-charts
+ version: 0.1.5
+digest: sha256:3b23658edd14e81d3de341695459e716eef161c8b9b8f3d9200b6a066cc8002d
+generated: "2024-12-04T16:20:15.57612556+02:00"
diff --git a/charts/keycloak/Chart.yaml b/charts/keycloak/Chart.yaml
new file mode 100644
index 000000000..38ac677b7
--- /dev/null
+++ b/charts/keycloak/Chart.yaml
@@ -0,0 +1,33 @@
+apiVersion: v2
+name: keycloak
+description: A Helm chart for Kubernetes
+
+# A chart can be either an 'application' or a 'library' chart.
+#
+# Application charts are a collection of templates that can be packaged into versioned archives
+# to be deployed.
+#
+# Library charts provide useful utilities or functions for the chart developer. They're included as
+# a dependency of application charts to inject those utilities and functions into the rendering
+# pipeline. Library charts do not define any templates and therefore cannot be deployed.
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.59.21
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "1.16.0"
+
+dependencies:
+ - name: keycloak
+ alias: keycloak
+ version: 24.2.2
+ repository: oci://registry-1.docker.io/bitnamicharts
+ - name: common
+ version: 0.1.5
+ repository: oci://ghcr.io/openmfp/helm-charts
diff --git a/charts/keycloak/README.md b/charts/keycloak/README.md
new file mode 100644
index 000000000..ada4af0ec
--- /dev/null
+++ b/charts/keycloak/README.md
@@ -0,0 +1,61 @@
+# keycloak
+
+A Helm chart for Kubernetes
+
+  
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+## Requirements
+
+| Repository | Name | Version |
+|------------|------|---------|
+| oci://ghcr.io/openmfp/helm-charts | common | 0.1.5 |
+| oci://registry-1.docker.io/bitnamicharts | keycloak(keycloak) | 24.2.2 |
+
+## Values
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+| Key | Type | Default | Description |
+|-----|------|---------|-------------|
+| crossplane.clients.openmfp.name | string | `"OpenMFP"` | name of the client |
+| crossplane.clients.openmfp.validRedirectUris | list | `["http://localhost:8000/callback*"]` | valid redirect uris for the client |
+| crossplane.clients.openmfp.validRedirectUris[0] | string | `"http://localhost:8000/callback*"` | keycloak callback url |
+| crossplane.enabled | bool | `false` | toggle to enable/disable crossplane |
+| crossplane.identityProviders | object | `{"sap":{"authorizationUrl":"https://login.microsoftonline.com/42f7676c-f455-423c-82f6-dc2d99791af7/oauth2/v2.0/authorize","clientId":"82b4c72c-ff99-4df6-ba4f-fb634d1fc491","clientSecretRef":{"key":"client-secret","name":"sap-client-secret","namespace":"openmfp-system"},"clientSecretRemoteRef":"dxp-core-team/manual-secrets/sap-client-secret","issuer":"https://login.microsoftonline.com/42f7676c-f455-423c-82f6-dc2d99791af7/v2.0","tokenUrl":"https://login.microsoftonline.com/42f7676c-f455-423c-82f6-dc2d99791af7/oauth2/v2.0/token"}}` | crossplane identity providers config |
+| crossplane.providerConfig | object | `{"name":"keycloak-provider-config","namespace":"openmfp-system"}` | crossplane provider config |
+| crossplane.realm | object | `{"displayName":"OpenMFP","name":"openmfp","registrationAllowed":false}` | crossplane realm config |
+| debug | bool | `false` | debug mode |
+| domain | object | `{"name":"openmfp.org","pathPrefix":""}` | domain configuration |
+| externalSecrets | object | `{"keycloakAdminRemoteRef":"dxp-core-team/manual-secrets/keycloak-admin","postgres-adminRemoteRef":"dxp-core-team/manual-secrets/postgres-admin-password"}` | external secrets configuration |
+| istio.virtualservice.hosts | list | `["auth.openmfp.org"]` | istio virtual service hosts |
+| job | object | `{"annotations":{"argocd.argoproj.io/hook":"PostSync"},"serviceAccount":"keycloak-client-creation"}` | job configuration |
+| keycloak | object | `{"extraEnvVars":"- name: KEYCLOAK_USER\n value: keycloak-admin\n- name: KEYCLOAK_PASSWORD\n valueFrom:\n secretKeyRef:\n name: keycloak-admin\n key: secret\n","postgresql":{"auth":{"existingSecret":"","secretKeys":{"adminPasswordKey":"password","userPasswordKey":"password"}}}}` | configuration passed to the child 'keyclaok' chart https://github.com/bitnami/charts/tree/main/bitnami/keycloak |
+| keycloakConfig.admin | object | `{"password":{"valueFrom":{"secretKeyRef":{"key":"secret","name":"keycloak-admin"}}},"username":{"value":"keycloak-admin"}}` | admin user configuration |
+| keycloakConfig.client | object | `{"name":"openmfp","targetSecret":{"name":"portal-client-secret-openmfp","namespace":"openmfp-system"},"tokenLifespan":3600}` | client configuration |
+| keycloakConfig.realm | object | `{"name":"master"}` | realm configuration |
+| keycloakConfig.redirectUrls | list | `[]` | redirect urls |
+| keycloakConfig.url | string | `"http://keycloak-http.openmfp-system.svc.cluster.local:8080"` | url of the keycloak server |
+| keycloakConfig.userRegistration.enabled | bool | `true` | toggle to enable/disable user registration |
+| service | object | `{"name":"keycloak"}` | service configuration |
+
+----------------------------------------------
+Autogenerated from chart metadata using [helm-docs v1.14.2](https://github.com/norwoodj/helm-docs/releases/v1.14.2)
diff --git a/charts/keycloak/README.md.gotmpl b/charts/keycloak/README.md.gotmpl
new file mode 100644
index 000000000..94146d84e
--- /dev/null
+++ b/charts/keycloak/README.md.gotmpl
@@ -0,0 +1,33 @@
+{{ template "chart.header" . }}
+{{ template "chart.description" . }}
+
+{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }}
+
+## Additional Information
+
+The `common` chart is a library of common resources that are shared across all other charts in the repository. It has no templates, but provides helm template functions and default values that can be used by other charts.
+
+{{ template "chart.requirementsSection" . }}
+
+{{ template "chart.valuesHeader" . }}
+
+The values in the `defaults:` section can be reused from other charts by using the lookup function "common.getKeyValue". It implements lookup on three levels:
+
+1. Looks for `keyOverride` in the chart's values.yaml
+2. Looks for `global.key` in the chart's or parent chart's values.yaml
+3. Uses the `key` in the chart's values.yaml
+4. Uses the `common.defaults.key` value from the table below.
+
+1 has precendence over 2 over 3 over 4 respectively. This approach allows for individual charts to have minimal configuration, while still being able to override parameters locally.
+
+Example
+```
+1) .Values.deployment.resources.limits.memoryOveride = 4096MB
+2) .Values.global.deployment.resources.limits.memory = 2048MB
+3) .Values.deployment.resources.limits.memory = 1024MB
+4) .Values.common.defaults.deployment.resources.limits.memory = default 512MB
+```
+
+{{ template "chart.valuesTable" . }}
+
+{{ template "helm-docs.versionFooter" . }}
diff --git a/charts/keycloak/charts/common-0.1.5.tgz b/charts/keycloak/charts/common-0.1.5.tgz
new file mode 100644
index 000000000..706e7e231
Binary files /dev/null and b/charts/keycloak/charts/common-0.1.5.tgz differ
diff --git a/charts/keycloak/charts/keycloak-24.2.2.tgz b/charts/keycloak/charts/keycloak-24.2.2.tgz
new file mode 100644
index 000000000..63e82a58b
Binary files /dev/null and b/charts/keycloak/charts/keycloak-24.2.2.tgz differ
diff --git a/charts/keycloak/templates/crossplane/client.yaml b/charts/keycloak/templates/crossplane/client.yaml
new file mode 100644
index 000000000..f5ca758dc
--- /dev/null
+++ b/charts/keycloak/templates/crossplane/client.yaml
@@ -0,0 +1,45 @@
+{{- if .Values.crossplane.enabled -}}
+{{- range $key, $val := .Values.crossplane.clients }}
+---
+apiVersion: openidclient.keycloak.crossplane.io/v1alpha1
+kind: Client
+metadata:
+ name: {{ $key }}
+spec:
+ forProvider:
+ enabled: true
+ accessType: CONFIDENTIAL
+ clientId: {{ $key }}
+ standardFlowEnabled: true
+ name: {{ $val.name }}
+ realmIdRef:
+ name: {{ $.Values.crossplane.realm.name }}
+ validRedirectUris: {{ toYaml $val.validRedirectUris | nindent 6 }}
+ providerConfigRef:
+ name: {{ $.Values.crossplane.providerConfig.name }}
+ writeConnectionSecretToRef:
+ name: {{ $.Values.keycloakConfig.client.targetSecret.name }}
+ namespace: {{ $.Values.keycloakConfig.client.targetSecret.namespace }}
+
+---
+
+apiVersion: openidclient.keycloak.crossplane.io/v1alpha1
+kind: ClientDefaultScopes
+metadata:
+ name: {{ $key }}-default-scopes
+spec:
+ forProvider:
+ clientIdRef:
+ name: {{ $key }}
+ defaultScopes:
+ - profile
+ - email
+ - basic
+ - acr
+ - groups
+ realmIdRef:
+ name: {{ $.Values.crossplane.realm.name }}
+ providerConfigRef:
+ name: {{ $.Values.crossplane.providerConfig.name }}
+{{ end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/charts/keycloak/templates/crossplane/external-secrets.yaml b/charts/keycloak/templates/crossplane/external-secrets.yaml
new file mode 100644
index 000000000..b3137d7c0
--- /dev/null
+++ b/charts/keycloak/templates/crossplane/external-secrets.yaml
@@ -0,0 +1,54 @@
+{{- if and .Values.externalSecrets.enabled .Values.crossplane.enabled -}}
+{{- range $key, $val := .Values.crossplane.identityProviders }}
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: {{ include "common.entity.name" $ }}-{{ $key }}
+ namespace: openmfp-system
+spec:
+ refreshInterval: "10m"
+ secretStoreRef:
+ name: environment-store
+ kind: SecretStore
+ target:
+ name: {{ $val.clientSecretRef.name }}
+ creationPolicy: Owner
+ deletionPolicy: Retain
+ data:
+ - secretKey: {{ $val.clientSecretRef.key }}
+ remoteRef:
+ key: {{ $val.clientSecretRemoteRef }}
+ property: {{ $val.clientSecretRef.key }}
+ conversionStrategy: Default
+---
+{{ end -}}
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: {{ include "common.entity.name" . }}-provider-config
+ namespace: openmfp-system
+spec:
+ refreshInterval: "10m"
+ secretStoreRef:
+ name: environment-store
+ kind: SecretStore
+ target:
+ name: {{ .Values.crossplane.providerConfig.name }}
+ template:
+ engineVersion: v2
+ data:
+ config: |
+ {
+ "client_id":"admin-cli",
+ "username": "{{ .Values.keycloakConfig.admin.username.value }}",
+ "password": "{{ `{{ .password }}` }}",
+ "url": "{{ .Values.keycloakConfig.url }}",
+ "realm": "master"
+ }
+ data:
+ - secretKey: password
+ remoteRef:
+ key: {{ .Values.externalSecrets.keycloakAdminRemoteRef }}
+ property: password
+ conversionStrategy: Default
+{{- end -}}
\ No newline at end of file
diff --git a/charts/keycloak/templates/crossplane/group.yaml b/charts/keycloak/templates/crossplane/group.yaml
new file mode 100644
index 000000000..9e19c0d07
--- /dev/null
+++ b/charts/keycloak/templates/crossplane/group.yaml
@@ -0,0 +1,61 @@
+{{- if .Values.crossplane.enabled -}}
+apiVersion: defaults.keycloak.crossplane.io/v1alpha1
+kind: DefaultGroups
+metadata:
+ name: default
+spec:
+ forProvider:
+ groupIdsRefs:
+ - name: portal
+ realmIdRef:
+ name: {{ .Values.crossplane.realm.name }}
+ providerConfigRef:
+ name: {{ .Values.crossplane.providerConfig.name }}
+---
+
+apiVersion: group.keycloak.crossplane.io/v1alpha1
+kind: Group
+metadata:
+ name: portal
+spec:
+ forProvider:
+ name: portal
+ realmIdRef:
+ name: {{ .Values.crossplane.realm.name }}
+ providerConfigRef:
+ name: {{ .Values.crossplane.providerConfig.name }}
+
+---
+
+apiVersion: openidclient.keycloak.crossplane.io/v1alpha1
+kind: ClientScope
+metadata:
+ name: groups-client-scope
+spec:
+ forProvider:
+ description: When requested, this scope will map a user's group memberships to
+ a claim
+ includeInTokenScope: true
+ name: groups
+ realmIdRef:
+ name: {{ .Values.crossplane.realm.name }}
+ providerConfigRef:
+ name: {{ .Values.crossplane.providerConfig.name }}
+
+---
+
+apiVersion: openidgroup.keycloak.crossplane.io/v1alpha1
+kind: GroupMembershipProtocolMapper
+metadata:
+ name: group-membership-mapper
+spec:
+ forProvider:
+ claimName: groups
+ clientIdRef:
+ name: groups-client-scope
+ name: group-membership-mapper
+ realmIdRef:
+ name: {{ .Values.crossplane.realm.name }}
+ providerConfigRef:
+ name: {{ .Values.crossplane.providerConfig.name }}
+{{- end -}}
\ No newline at end of file
diff --git a/charts/keycloak/templates/crossplane/identity-provider.yaml b/charts/keycloak/templates/crossplane/identity-provider.yaml
new file mode 100644
index 000000000..06ac78482
--- /dev/null
+++ b/charts/keycloak/templates/crossplane/identity-provider.yaml
@@ -0,0 +1,59 @@
+{{- if .Values.crossplane.enabled -}}
+{{- range $key, $val := .Values.crossplane.identityProviders }}
+apiVersion: oidc.keycloak.crossplane.io/v1alpha1
+kind: IdentityProvider
+metadata:
+ name: {{ $key }}
+spec:
+ forProvider:
+ alias: {{ $key }}
+ realmRef:
+ name: {{ $.Values.crossplane.realm.name }}
+ authorizationUrl: {{ $val.authorizationUrl }}
+ tokenUrl: {{ $val.tokenUrl }}
+ issuer: {{ $val.issuer }}
+ clientId: {{ $val.clientId }}
+ clientSecretSecretRef: {{ $val.clientSecretRef | toYaml | nindent 6 }}
+ defaultScopes: openid email profile
+ trustEmail: true
+ hideOnLoginPage: true
+ providerConfigRef:
+ name: {{ $.Values.crossplane.providerConfig.name }}
+---
+apiVersion: identityprovider.keycloak.crossplane.io/v1alpha1
+kind: IdentityProviderMapper
+metadata:
+ name: lastname
+spec:
+ forProvider:
+ realmRef:
+ name: {{ $.Values.crossplane.realm.name }}
+ extraConfig:
+ Claim: last_name
+ UserAttribute: lastName
+ syncMode: INHERIT
+ identityProviderAlias: {{ $key }}
+ identityProviderMapper: 'oidc-user-attribute-idp-mapper'
+ name: last_name
+ providerConfigRef:
+ name: {{ $.Values.crossplane.providerConfig.name }}
+---
+apiVersion: identityprovider.keycloak.crossplane.io/v1alpha1
+kind: IdentityProviderMapper
+metadata:
+ name: firstname
+spec:
+ forProvider:
+ realmRef:
+ name: {{ $.Values.crossplane.realm.name }}
+ extraConfig:
+ Claim: first_name
+ UserAttribute: firstName
+ syncMode: INHERIT
+ identityProviderAlias: {{ $key }}
+ identityProviderMapper: 'oidc-user-attribute-idp-mapper'
+ name: first_name
+ providerConfigRef:
+ name: {{ $.Values.crossplane.providerConfig.name }}
+{{ end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/charts/keycloak/templates/crossplane/provider-config.yaml b/charts/keycloak/templates/crossplane/provider-config.yaml
new file mode 100644
index 000000000..54fa599c9
--- /dev/null
+++ b/charts/keycloak/templates/crossplane/provider-config.yaml
@@ -0,0 +1,31 @@
+{{- if .Values.crossplane.enabled -}}
+apiVersion: keycloak.crossplane.io/v1beta1
+kind: ProviderConfig
+metadata:
+ name: {{ .Values.crossplane.providerConfig.name }}
+ namespace: {{ .Values.crossplane.providerConfig.namespace }}
+spec:
+ credentials:
+ source: Secret
+ secretRef:
+ name: {{ .Values.crossplane.providerConfig.name }}
+ namespace: {{ .Values.crossplane.providerConfig.namespace }}
+ key: config
+{{- if not .Values.externalSecrets.enabled }}
+---
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ .Values.crossplane.providerConfig.name }}
+ namespace: {{ .Values.crossplane.providerConfig.namespace }}
+stringData:
+ config: |
+ {
+ "client_id":"admin-cli",
+ "username": "{{ .Values.keycloakConfig.admin.username.value }}",
+ "password": "admin",
+ "url": "{{ .Values.keycloakConfig.url }}",
+ "realm": "master"
+ }
+{{- end -}}
+{{- end -}}
\ No newline at end of file
diff --git a/charts/keycloak/templates/crossplane/realm.yaml b/charts/keycloak/templates/crossplane/realm.yaml
new file mode 100644
index 000000000..b0432f5c7
--- /dev/null
+++ b/charts/keycloak/templates/crossplane/realm.yaml
@@ -0,0 +1,20 @@
+{{- if .Values.crossplane.enabled -}}
+apiVersion: realm.keycloak.crossplane.io/v1alpha1
+kind: Realm
+metadata:
+ name: {{ .Values.crossplane.realm.name}}
+spec:
+ forProvider:
+ accessCodeLifespan: 1h
+ attributes:
+ organizationsEnabled: "true"
+ displayName: {{ .Values.crossplane.realm.displayName }}
+ displayNameHtml: {{ .Values.crossplane.realm.displayName }}
+ enabled: true
+ realm: {{ .Values.crossplane.realm.name }}
+ loginWithEmailAllowed: true
+ registrationEmailAsUsername: true
+ registrationAllowed: {{ .Values.crossplane.realm.registrationAllowed }}
+ providerConfigRef:
+ name: {{ .Values.crossplane.providerConfig.name }}
+{{- end -}}
\ No newline at end of file
diff --git a/charts/keycloak/templates/external-secrets.yaml b/charts/keycloak/templates/external-secrets.yaml
new file mode 100644
index 000000000..1cbe9eef5
--- /dev/null
+++ b/charts/keycloak/templates/external-secrets.yaml
@@ -0,0 +1,45 @@
+{{- if eq (include "common.hasNestedKey" (dict "Values" .Values "key" "externalSecrets.enabled")) "true" }}
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: {{ include "common.entity.name" . }}-admin
+ namespace: openmfp-system
+spec:
+ refreshInterval: "10m"
+ secretStoreRef:
+ name: environment-store
+ kind: SecretStore
+ target:
+ name: keycloak-admin
+ creationPolicy: Owner
+ deletionPolicy: Retain
+ data:
+ - secretKey: secret
+ remoteRef:
+ key: {{ .Values.externalSecrets.keycloakAdminRemoteRef }}
+ property: password
+ conversionStrategy: Default
+
+---
+
+apiVersion: external-secrets.io/v1beta1
+kind: ExternalSecret
+metadata:
+ name: {{ include "common.entity.name" . }}-postgres
+ namespace: openmfp-system
+spec:
+ refreshInterval: "10m"
+ secretStoreRef:
+ name: environment-store
+ kind: SecretStore
+ target:
+ name: postgres-admin-password
+ creationPolicy: Owner
+ deletionPolicy: Retain
+ data:
+ - secretKey: password
+ remoteRef:
+ key: {{ .Values.externalSecrets.postgresAdminRemoteRef }}
+ property: password
+ conversionStrategy: Default
+ {{- end }}
\ No newline at end of file
diff --git a/charts/keycloak/templates/istio-virtualservice.yaml b/charts/keycloak/templates/istio-virtualservice.yaml
new file mode 100644
index 000000000..b887882d2
--- /dev/null
+++ b/charts/keycloak/templates/istio-virtualservice.yaml
@@ -0,0 +1,29 @@
+{{- if eq (include "common.getNestedValue" (dict "Values" .Values "key" "istio.enabled")) "true" -}}
+apiVersion: networking.istio.io/v1beta1
+kind: VirtualService
+metadata:
+ name: {{ include "common.entity.name" . }}
+spec:
+ hosts:
+ {{ .Values.istio.virtualservice.hosts | toYaml | nindent 4 }}
+ gateways:
+ - {{ .Release.Namespace}}/{{ include "common.getKeyValue" (dict "Values" .Values "key" "istio.gateway.name") }}
+ http:
+ - route:
+ - destination:
+ host: {{ .Values.service.name }}.{{ .Release.Namespace }}.svc.cluster.local
+ port:
+ number: {{ .Values.service.port }}
+ {{- if .Values.domain.pathPrefix }}
+ match:
+ - uri:
+ prefix: {{ .Values.domain.pathPrefix }}
+ {{ end }}
+ {{- if eq (include "common.getNestedValue" (dict "Values" .Values "key" "istio.https.enabled")) "true" }}
+ headers:
+ request:
+ set:
+ X-Forwarded-Proto: "https"
+ {{ end }}
+
+{{- end }}
\ No newline at end of file
diff --git a/charts/keycloak/templates/job-keycloak-configuration.yaml b/charts/keycloak/templates/job-keycloak-configuration.yaml
new file mode 100644
index 000000000..4a4b5a8f9
--- /dev/null
+++ b/charts/keycloak/templates/job-keycloak-configuration.yaml
@@ -0,0 +1,305 @@
+{{- if not .Values.crossplane.enabled -}}
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: {{ include "common.entity.name" . }}-configuration
+ annotations:
+ {{ range $key, $value := .Values.job.annotations }}
+ {{ $key }}: {{ $value }}
+ {{ end }}
+spec:
+ activeDeadlineSeconds: 1800
+ template:
+ spec:
+ automountServiceAccountToken: true
+ serviceAccountName: {{ .Values.job.serviceAccount}}
+ imagePullSecrets:
+ - name: {{ include "common.imagePullSecret" . | nindent 2 }}
+ containers:
+ - name: {{ include "common.entity.name" . }}
+ image: ghcr.io/openmfp/charts/job/curl-jq:latest
+ command: ["/bin/sh", "-c"]
+ args:
+ - |
+ #!/bin/sh
+ set +e
+ {{- if .Values.debug }}
+ set -x
+ {{- end }}
+
+ REALM={{ .Values.keycloakConfig.realm.name }}
+
+ function quitIstio {
+ {{- if eq (include "common.getNestedValue" (dict "Values" .Values "key" "istio.quitSidecar")) "true" }}
+ curl -s -X POST http://localhost:15000/quitquitquit
+ {{- end }}
+ }
+
+ MAX_RETRIES=15
+ RETRY_DELAY=5
+
+ for i in $(seq 1 $MAX_RETRIES); do
+ # Get the admin token
+ TOKEN=$(curl -s --location --request POST "$KEYCLOAK_URL/realms/{{ .Values.keycloakConfig.realm.name }}/protocol/openid-connect/token" \
+ --header 'Content-Type: application/x-www-form-urlencoded' \
+ --data-urlencode "username=$KEYCLOAK_USER" \
+ --data-urlencode "password=$KEYCLOAK_PASSWORD" \
+ --data-urlencode 'grant_type=password' \
+ --data-urlencode 'client_id=admin-cli' | jq -r '.access_token')
+
+ if [ -n "$TOKEN" ]; then
+ break
+ elif [ $i -eq $MAX_RETRIES ]; then
+ echo "Failed to get token after $MAX_RETRIES attempts, exiting"
+ quitIstio
+ exit 1
+ else
+ echo "Failed to get token, attempt $i/$MAX_RETRIES. Retrying in $RETRY_DELAY seconds..."
+ sleep $RETRY_DELAY
+ fi
+ done
+
+ {{- if .Values.keycloakConfig.userRegistration.enabled }}
+ echo "Patch the realm to allow for user registration"
+ curl -s -X PUT -H 'Content-Type: application/json' -H "Authorization: bearer $TOKEN" -d '{"registrationAllowed": true, "registrationEmailAsUsername": true}' $KEYCLOAK_URL/admin/realms/$REALM
+ {{- end }}
+
+ CLIENT_ID=$(curl -s -H "Authorization: Bearer $TOKEN" "$KEYCLOAK_URL/admin/realms/$REALM/clients" | jq -r '.[] | select(.clientId=="openmfp") | .id')
+ if [ -z "$CLIENT_ID" ]; then
+ echo "Creating client '{{ .Values.keycloakConfig.client.name }}'"
+ CREATE_CLIENT_PAYLOAD=$(cat <OpenMFP
+ enabled: true
+ loginWithEmailAllowed: true
+ realm: openmfp
+ registrationAllowed: false
+ registrationEmailAsUsername: true
+ providerConfigRef:
+ name: keycloak-provider-config
diff --git a/charts/keycloak/tests/__snapshot__/external-secrets_test.yaml.snap b/charts/keycloak/tests/__snapshot__/external-secrets_test.yaml.snap
new file mode 100644
index 000000000..3294e4bb5
--- /dev/null
+++ b/charts/keycloak/tests/__snapshot__/external-secrets_test.yaml.snap
@@ -0,0 +1,43 @@
+matches the snapshot:
+ 1: |
+ apiVersion: external-secrets.io/v1beta1
+ kind: ExternalSecret
+ metadata:
+ name: RELEASE-NAME-keycloak-admin
+ namespace: openmfp-system
+ spec:
+ data:
+ - remoteRef:
+ conversionStrategy: Default
+ key: dxp-core-team/manual-secrets/keycloak-admin
+ property: password
+ secretKey: secret
+ refreshInterval: 10m
+ secretStoreRef:
+ kind: SecretStore
+ name: environment-store
+ target:
+ creationPolicy: Owner
+ deletionPolicy: Retain
+ name: keycloak-admin
+ 2: |
+ apiVersion: external-secrets.io/v1beta1
+ kind: ExternalSecret
+ metadata:
+ name: RELEASE-NAME-keycloak-postgres
+ namespace: openmfp-system
+ spec:
+ data:
+ - remoteRef:
+ conversionStrategy: Default
+ key: null
+ property: password
+ secretKey: password
+ refreshInterval: 10m
+ secretStoreRef:
+ kind: SecretStore
+ name: environment-store
+ target:
+ creationPolicy: Owner
+ deletionPolicy: Retain
+ name: postgres-admin-password
diff --git a/charts/keycloak/tests/__snapshot__/istio_test.yaml.snap b/charts/keycloak/tests/__snapshot__/istio_test.yaml.snap
new file mode 100644
index 000000000..f5490678d
--- /dev/null
+++ b/charts/keycloak/tests/__snapshot__/istio_test.yaml.snap
@@ -0,0 +1,37 @@
+matches the snapshot:
+ 1: |
+ apiVersion: networking.istio.io/v1beta1
+ kind: VirtualService
+ metadata:
+ name: RELEASE-NAME-keycloak
+ spec:
+ gateways:
+ - openmfp-system/test
+ hosts:
+ - keycloak.openmfp.org
+ http:
+ - route:
+ - destination:
+ host: keycloak.openmfp-system.svc.cluster.local
+ port:
+ number: null
+matches the snapshot (with path prefix):
+ 1: |
+ apiVersion: networking.istio.io/v1beta1
+ kind: VirtualService
+ metadata:
+ name: RELEASE-NAME-keycloak
+ spec:
+ gateways:
+ - openmfp-system/test
+ hosts:
+ - keycloak.openmfp.org
+ http:
+ - match:
+ - uri:
+ prefix: /auth
+ route:
+ - destination:
+ host: keycloak.openmfp-system.svc.cluster.local
+ port:
+ number: null
diff --git a/charts/keycloak/tests/__snapshot__/job_test.yaml.snap b/charts/keycloak/tests/__snapshot__/job_test.yaml.snap
new file mode 100644
index 000000000..39fdf7272
--- /dev/null
+++ b/charts/keycloak/tests/__snapshot__/job_test.yaml.snap
@@ -0,0 +1,309 @@
+matches the snapshot:
+ 1: |
+ apiVersion: batch/v1
+ kind: Job
+ metadata:
+ annotations:
+ argocd.argoproj.io/hook: PostSync
+ name: RELEASE-NAME-keycloak-configuration
+ spec:
+ activeDeadlineSeconds: 1800
+ imagePullSecrets:
+ - containers:
+ - args:
+ - |
+ #!/bin/sh
+ set +e
+
+ REALM=master
+
+ function quitIstio {
+ curl -s -X POST http://localhost:15000/quitquitquit
+ }
+
+ MAX_RETRIES=15
+ RETRY_DELAY=5
+
+ for i in $(seq 1 $MAX_RETRIES); do
+ # Get the admin token
+ TOKEN=$(curl -s --location --request POST "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" \
+ --header 'Content-Type: application/x-www-form-urlencoded' \
+ --data-urlencode "username=$KEYCLOAK_USER" \
+ --data-urlencode "password=$KEYCLOAK_PASSWORD" \
+ --data-urlencode 'grant_type=password' \
+ --data-urlencode 'client_id=admin-cli' | jq -r '.access_token')
+
+ if [ -n "$TOKEN" ]; then
+ break
+ elif [ $i -eq $MAX_RETRIES ]; then
+ echo "Failed to get token after $MAX_RETRIES attempts, exiting"
+ quitIstio
+ exit 1
+ else
+ echo "Failed to get token, attempt $i/$MAX_RETRIES. Retrying in $RETRY_DELAY seconds..."
+ sleep $RETRY_DELAY
+ fi
+ done
+ echo "Patch the realm to allow for user registration"
+ curl -s -X PUT -H 'Content-Type: application/json' -H "Authorization: bearer $TOKEN" -d '{"registrationAllowed": true, "registrationEmailAsUsername": true}' $KEYCLOAK_URL/admin/realms/$REALM
+
+ CLIENT_ID=$(curl -s -H "Authorization: Bearer $TOKEN" "$KEYCLOAK_URL/admin/realms/$REALM/clients" | jq -r '.[] | select(.clientId=="openmfp") | .id')
+ if [ -z "$CLIENT_ID" ]; then
+ echo "Creating client 'openmfp'"
+ CREATE_CLIENT_PAYLOAD=$(cat <