[PLATFORM] Add Keycloak ONAP REALM import

As part of the ServiceMesh solution Keycloak will be used
to enable a central authentication and authorization for ONAP
Service Access. This chart provides the import of a default
ONAP Realm to an existing Keycloak Instance (alternative
to a combined KC+REALM installation).
It contains clients for the planned portal-ng.
Make all subcomponents selectable

Issue-ID: OOM-3021

Signed-off-by: Andreas Geissler <andreas-geissler@telekom.de>
Change-Id: I677a3b9e200299c2cde7774e09db6cf33ac510b7
diff --git a/kubernetes/platform/components/keycloak-init/.helmignore b/kubernetes/platform/components/keycloak-init/.helmignore
new file mode 100644
index 0000000..cf02291
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/.helmignore
@@ -0,0 +1,25 @@
+# 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/
+ci/
+examples/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/kubernetes/platform/components/keycloak-init/Chart.yaml b/kubernetes/platform/components/keycloak-init/Chart.yaml
new file mode 100644
index 0000000..44ca0fa
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/Chart.yaml
@@ -0,0 +1,35 @@
+#============LICENSE_START========================================================
+# ================================================================================
+# Copyright © 2022 Deutsche Telekom
+# ================================================================================
+# Original licence (https://github.com/codecentric/helm-charts/blob/master/LICENSE)
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+apiVersion: v2
+version: 12.0.0
+description: ONAP Realm creation and configuration
+name: keycloak-init
+sources:
+- https://github.com/adorsys/keycloak-config-cli
+
+# Keycloakx chart version: 1.6.0
+dependencies:
+  - name: common
+    version: ~12.x-0
+    repository: '@local'
+  - name: serviceAccount
+    version: ~12.x-0
+    repository: '@local'
+  - name: keycloak-config-cli
+    version: 5.3.1
+    repository: 'file://components/keycloak-config-cli'
diff --git a/kubernetes/platform/components/keycloak-init/Makefile b/kubernetes/platform/components/keycloak-init/Makefile
new file mode 100644
index 0000000..5970a97
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/Makefile
@@ -0,0 +1,60 @@
+# Copyright © 2020 Samsung Electronics
+# Modifications Copyright © 2020 Nokia
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
+OUTPUT_DIR := $(ROOT_DIR)/../../dist
+PACKAGE_DIR := $(OUTPUT_DIR)/packages
+SECRET_DIR := $(OUTPUT_DIR)/secrets
+
+EXCLUDES :=
+HELM_BIN := helm
+ifneq ($(SKIP_LINT),TRUE)
+	HELM_LINT_CMD := $(HELM_BIN) lint
+else
+	HELM_LINT_CMD := echo "Skipping linting of"
+endif
+
+HELM_CHARTS := $(filter-out $(EXCLUDES), $(sort $(patsubst %/.,%,$(wildcard */.))))
+HELM_VER := $(shell $(HELM_BIN) version --template "{{.Version}}")
+
+.PHONY: $(EXCLUDES) $(HELM_CHARTS)
+
+all: $(HELM_CHARTS)
+
+$(HELM_CHARTS):
+	@echo "\n[$@]"
+	@make package-$@
+
+make-%:
+	@if [ -f $*/Makefile ]; then make -C $*; fi
+
+dep-%: make-%
+	@if [ -f $*/Chart.yaml ]; then $(HELM_BIN) dep up $*; fi
+
+lint-%: dep-%
+	@if [ -f $*/Chart.yaml ]; then $(HELM_LINT_CMD) $*; fi
+
+package-%: lint-%
+	@mkdir -p $(PACKAGE_DIR)
+	@if [ -f $*/Chart.yaml ]; then PACKAGE_NAME=$$($(HELM_BIN) package -d $(PACKAGE_DIR) $* | cut -d":" -f2) && $(HELM_BIN) cm-push -f $$PACKAGE_NAME local; fi
+	@sleep 3
+	#@$(HELM_BIN) repo index $(PACKAGE_DIR)
+
+clean:
+	@rm -f */Chart.lock
+	@rm -f *tgz */charts/*tgz
+	@rm -rf $(PACKAGE_DIR)
+%:
+	@:
diff --git a/kubernetes/platform/components/keycloak-init/components/Makefile b/kubernetes/platform/components/keycloak-init/components/Makefile
new file mode 100644
index 0000000..4ecfbc5
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/components/Makefile
@@ -0,0 +1,59 @@
+# Copyright © 2020 Samsung Electronics, Orange, Nokia
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
+OUTPUT_DIR := $(ROOT_DIR)/../dist
+PACKAGE_DIR := $(OUTPUT_DIR)/packages
+SECRET_DIR := $(OUTPUT_DIR)/secrets
+
+EXCLUDES := dist resources templates charts
+HELM_BIN := helm
+ifneq ($(SKIP_LINT),TRUE)
+	HELM_LINT_CMD := $(HELM_BIN) lint
+else
+	HELM_LINT_CMD := echo "Skipping linting of"
+endif
+
+HELM_CHARTS := $(filter-out $(EXCLUDES), $(sort $(patsubst %/.,%,$(wildcard */.))))
+HELM_VER := $(shell $(HELM_BIN) version --template "{{.Version}}")
+
+.PHONY: $(EXCLUDES) $(HELM_CHARTS)
+
+all: $(HELM_CHARTS)
+
+$(HELM_CHARTS):
+	@echo "\n[$@]"
+	@make package-$@
+
+make-%:
+	@if [ -f $*/Makefile ]; then make -C $*; fi
+
+dep-%: make-%
+	@if [ -f $*/Chart.yaml ]; then $(HELM_BIN) dep up $*; fi
+
+lint-%: dep-%
+	@if [ -f $*/Chart.yaml ]; then $(HELM_LINT_CMD) $*; fi
+
+package-%: lint-%
+	@mkdir -p $(PACKAGE_DIR)
+	@if [ -f $*/Chart.yaml ]; then PACKAGE_NAME=$$($(HELM_BIN) package -d $(PACKAGE_DIR) $* | cut -d":" -f2) && $(HELM_BIN) cm-push -f $$PACKAGE_NAME local; fi
+	@sleep 3
+	#@$(HELM_BIN) repo index $(PACKAGE_DIR)
+
+clean:
+	@rm -f */Chart.lock
+	@rm -f *tgz */charts/*tgz
+	@rm -rf $(PACKAGE_DIR)
+%:
+	@:
diff --git a/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/.helmignore b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/.helmignore
new file mode 100644
index 0000000..0e8a0eb
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/.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/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/Chart.yaml b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/Chart.yaml
new file mode 100644
index 0000000..c248ba0
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/Chart.yaml
@@ -0,0 +1,45 @@
+#============LICENSE_START========================================================
+# ================================================================================
+# Copyright © adorsys GmbH & Co. KG
+# Modifications © 2022 Deutsche Telekom
+# ================================================================================
+# Original licence (https://github.com/codecentric/helm-charts/blob/master/LICENSE)
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============LICENSE_END=========================================================
+apiVersion: v2
+name: keycloak-config-cli
+description: Import JSON-formatted configuration files into Keycloak - Configuration as Code for Keycloak.
+home: https://github.com/adorsys/keycloak-config-cli
+version: 5.3.1
+appVersion: 5.3.1-19.0.1
+maintainers:
+  - name: jkroepke
+    email: joe@adorsys.de
+    url: https://github.com/jkroepke
+keywords:
+  - keycloak
+  - config
+  - import
+  - json
+  - continuous-integration
+  - keycloak-config-cli
+sources:
+  - https://github.com/adorsys/keycloak-config-cli
+
+dependencies:
+  - name: common
+    version: ~12.x-0
+    repository: '@local'
+  - name: repositoryGenerator
+    version: ~12.x-0
+    repository: '@local'
\ No newline at end of file
diff --git a/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/resources/realm/onap-realm.json b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/resources/realm/onap-realm.json
new file mode 100644
index 0000000..8b79e99
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/resources/realm/onap-realm.json
@@ -0,0 +1,312 @@
+{
+  "id": "ONAP",
+  "realm": "ONAP",
+  "enabled": true,
+  "roles": {
+    "realm": [
+      {
+        "name": "onap_admin",
+        "description": "User role for administration tasks in the portal.",
+        "composite": false,
+        "clientRole": false,
+        "containerId": "onap",
+        "attributes": {}
+      },
+      {
+        "name": "user",
+        "composite": false,
+        "clientRole": false,
+        "containerId": "onap",
+        "attributes": {}
+      },
+      {
+        "name": "admin",
+        "composite": false,
+        "clientRole": false,
+        "containerId": "onap",
+        "attributes": {}
+      },
+      {
+        "name": "onap_designer",
+        "description": "User role for designer tasks in the portal.",
+        "composite": false,
+        "clientRole": false,
+        "containerId": "onap",
+        "attributes": {}
+      },
+      {
+        "name": "offline_access",
+        "description": "${role_offline-access}",
+        "composite": false,
+        "clientRole": false,
+        "containerId": "onap",
+        "attributes": {}
+      },
+      {
+        "name": "onap_operator",
+        "description": "User role for operator tasks in the portal.",
+        "composite": false,
+        "clientRole": false,
+        "containerId": "onap",
+        "attributes": {}
+      },
+      {
+        "name": "uma_authorization",
+        "description": "${role_uma_authorization}",
+        "composite": false,
+        "clientRole": false,
+        "containerId": "onap",
+        "attributes": {}
+      },
+      {
+        "name": "default-roles-onap",
+        "description": "${role_default-roles}",
+        "composite": true,
+        "composites": {
+          "realm": [
+            "offline_access",
+            "uma_authorization"
+          ],
+          "client": {
+            "account": [
+              "view-profile",
+              "manage-account"
+            ]
+          }
+        },
+        "clientRole": false,
+        "containerId": "onap",
+        "attributes": {}
+      }
+    ]
+  },
+  "clients": [
+    {
+      "clientId": "portal-app",
+      "surrogateAuthRequired": false,
+      "enabled": true,
+      "alwaysDisplayInConsole": false,
+      "clientAuthenticatorType": "client-secret",
+      "redirectUris": [
+        "{{ .Values.portalUrl }}/*",
+        "http://localhost/*"
+      ],
+      "webOrigins": [
+        "*"
+      ],
+      "notBefore": 0,
+      "bearerOnly": false,
+      "consentRequired": false,
+      "standardFlowEnabled": true,
+      "implicitFlowEnabled": false,
+      "directAccessGrantsEnabled": true,
+      "serviceAccountsEnabled": false,
+      "publicClient": true,
+      "frontchannelLogout": false,
+      "protocol": "openid-connect",
+      "attributes": {
+        "oidc.ciba.grant.enabled": "false",
+        "backchannel.logout.session.required": "true",
+        "post.logout.redirect.uris": "{{ .Values.portalUrl }}/*",
+        "oauth2.device.authorization.grant.enabled": "false",
+        "display.on.consent.screen": "false",
+        "backchannel.logout.revoke.offline.tokens": "false"
+      },
+      "authenticationFlowBindingOverrides": {},
+      "fullScopeAllowed": true,
+      "nodeReRegistrationTimeout": -1,
+      "protocolMappers": [
+        {
+          "name": "User-Roles",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-realm-role-mapper",
+          "consentRequired": false,
+          "config": {
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "roles",
+            "multivalued": "true",
+            "userinfo.token.claim": "true"
+          }
+        },
+        {
+          "name": "SDC-User",
+          "protocol": "openid-connect",
+          "protocolMapper": "oidc-usermodel-attribute-mapper",
+          "consentRequired": false,
+          "config": {
+            "userinfo.token.claim": "true",
+            "user.attribute": "sdc_user",
+            "id.token.claim": "true",
+            "access.token.claim": "true",
+            "claim.name": "sdc_user",
+            "jsonType.label": "String"
+          }
+        }
+      ],
+      "defaultClientScopes": [
+        "web-origins",
+        "acr",
+        "profile",
+        "roles",
+        "email"
+      ],
+      "optionalClientScopes": [
+        "address",
+        "phone",
+        "offline_access",
+        "microprofile-jwt"
+      ]
+    }, {
+      "clientId" : "portal-bff",
+      "surrogateAuthRequired" : false,
+      "enabled" : true,
+      "alwaysDisplayInConsole" : false,
+      "clientAuthenticatorType" : "client-secret",
+      "secret" : "pKOuVH1bwRZoNzp5P5t4GV8CqcCJYVtr",
+      "redirectUris" : [ ],
+      "webOrigins" : [ ],
+      "notBefore" : 0,
+      "bearerOnly" : false,
+      "consentRequired" : false,
+      "standardFlowEnabled" : false,
+      "implicitFlowEnabled" : false,
+      "directAccessGrantsEnabled" : false,
+      "serviceAccountsEnabled" : true,
+      "publicClient" : false,
+      "frontchannelLogout" : false,
+      "protocol" : "openid-connect",
+      "attributes" : {
+        "saml.force.post.binding" : "false",
+        "saml.multivalued.roles" : "false",
+        "frontchannel.logout.session.required" : "false",
+        "oauth2.device.authorization.grant.enabled" : "false",
+        "backchannel.logout.revoke.offline.tokens" : "false",
+        "saml.server.signature.keyinfo.ext" : "false",
+        "use.refresh.tokens" : "true",
+        "oidc.ciba.grant.enabled" : "false",
+        "backchannel.logout.session.required" : "true",
+        "client_credentials.use_refresh_token" : "false",
+        "require.pushed.authorization.requests" : "false",
+        "saml.client.signature" : "false",
+        "saml.allow.ecp.flow" : "false",
+        "id.token.as.detached.signature" : "false",
+        "saml.assertion.signature" : "false",
+        "client.secret.creation.time" : "1665048112",
+        "saml.encrypt" : "false",
+        "saml.server.signature" : "false",
+        "exclude.session.state.from.auth.response" : "false",
+        "saml.artifact.binding" : "false",
+        "saml_force_name_id_format" : "false",
+        "acr.loa.map" : "{}",
+        "tls.client.certificate.bound.access.tokens" : "false",
+        "saml.authnstatement" : "false",
+        "display.on.consent.screen" : "false",
+        "token.response.type.bearer.lower-case" : "false",
+        "saml.onetimeuse.condition" : "false"
+      },
+      "authenticationFlowBindingOverrides" : { },
+      "fullScopeAllowed" : true,
+      "nodeReRegistrationTimeout" : -1,
+      "protocolMappers" : [ {
+        "name" : "Client Host",
+        "protocol" : "openid-connect",
+        "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+        "consentRequired" : false,
+        "config" : {
+          "user.session.note" : "clientHost",
+          "id.token.claim" : "true",
+          "access.token.claim" : "true",
+          "claim.name" : "clientHost",
+          "jsonType.label" : "String"
+        }
+      }, {
+        "name" : "Client IP Address",
+        "protocol" : "openid-connect",
+        "protocolMapper" : "oidc-usersessionmodel-note-mapper",
+        "consentRequired" : false,
+        "config" : {
+          "user.session.note" : "clientAddress",
+          "id.token.claim" : "true",
+          "access.token.claim" : "true",
+          "claim.name" : "clientAddress",
+          "jsonType.label" : "String"
+        }
+      } ],
+      "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ],
+      "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ]
+    }],
+  "users": [
+    {
+      "createdTimestamp" : 1664965113698,
+      "username" : "onap-admin",
+      "enabled" : true,
+      "totp" : false,
+      "emailVerified" : false,
+      "attributes" : {
+        "sdc_user" : [ "cs0008" ]
+      },
+      "credentials" : [ {
+        "type" : "password",
+        "createdDate" : 1664965134586,
+        "secretData" : "{\"value\":\"nD4K4x8HEgk6xlWIAgzZOE+EOjdbovJfEa7N3WXwIMCWCfdXpn7Riys7hZhI1NbKcc9QPI9j8LQB/JSuZVcXKA==\",\"salt\":\"T8X9A9tT2cyLvEjHFo+zuQ==\",\"additionalParameters\":{}}",
+        "credentialData" : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}"
+      } ],
+      "disableableCredentialTypes" : [ ],
+      "requiredActions" : [ ],
+      "realmRoles" : [ "default-roles-onap", "onap_admin" ],
+      "notBefore" : 0,
+      "groups" : [ ]
+    }, {
+      "createdTimestamp" : 1665048354760,
+      "username" : "onap-designer",
+      "enabled" : true,
+      "totp" : false,
+      "emailVerified" : false,
+      "attributes" : {
+        "sec_user" : [ "cs0008" ]
+      },
+      "credentials" : [ ],
+      "disableableCredentialTypes" : [ ],
+      "requiredActions" : [ ],
+      "realmRoles" : [ "default-roles-onap", "onap_designer" ],
+      "notBefore" : 0,
+      "groups" : [ ]
+    }, {
+      "createdTimestamp" : 1665048547054,
+      "username" : "onap-operator",
+      "enabled" : true,
+      "totp" : false,
+      "emailVerified" : false,
+      "attributes" : {
+        "sdc_user" : [ "cs0008" ]
+      },
+      "credentials" : [ ],
+      "disableableCredentialTypes" : [ ],
+      "requiredActions" : [ ],
+      "realmRoles" : [ "default-roles-onap", "onap_operator" ],
+      "notBefore" : 0,
+      "groups" : [ ]
+    }, {
+      "createdTimestamp" : 1665048112458,
+      "username" : "service-account-portal-bff",
+      "enabled" : true,
+      "totp" : false,
+      "emailVerified" : false,
+      "serviceAccountClientId" : "portal-bff",
+      "credentials" : [ ],
+      "disableableCredentialTypes" : [ ],
+      "requiredActions" : [ ],
+      "realmRoles" : [ "default-roles-onap" ],
+      "clientRoles" : {
+        "realm-management" : [ "manage-realm", "manage-users" ]
+      },
+      "notBefore" : 0,
+      "groups" : [ ]
+    }
+  ],
+  "attributes": {
+    "frontendUrl": "{{ .Values.portalUrl }}/auth/",
+    "acr.loa.map": "{\"ABC\":\"5\"}"
+  }
+}
diff --git a/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/_helpers.tpl b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/_helpers.tpl
new file mode 100644
index 0000000..cc1ad7a
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/_helpers.tpl
@@ -0,0 +1,68 @@
+{{/*
+  # Copyright © adorsys GmbH & Co. KG
+  #
+  # Licensed under the Apache License, Version 2.0 (the "License");
+  # you may not use this file except in compliance with the License.
+  # You may obtain a copy of the License at
+  #
+  #       http://www.apache.org/licenses/LICENSE-2.0
+  #
+  # Unless required by applicable law or agreed to in writing, software
+  # distributed under the License is distributed on an "AS IS" BASIS,
+  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  # See the License for the specific language governing permissions and
+  # limitations under the License.
+*/}}
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "keycloak-config-cli.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "keycloak-config-cli.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "keycloak-config-cli.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "keycloak-config-cli.labels" -}}
+helm.sh/chart: {{ include "keycloak-config-cli.chart" . }}
+{{ include "keycloak-config-cli.selectorLabels" . }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Selector labels
+*/}}
+{{- define "keycloak-config-cli.selectorLabels" -}}
+app.kubernetes.io/name: {{ include "keycloak-config-cli.name" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- end }}
+
diff --git a/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/job.yaml b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/job.yaml
new file mode 100644
index 0000000..322db2b
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/job.yaml
@@ -0,0 +1,103 @@
+{{/*
+  # Copyright © adorsys GmbH & Co. KG
+  # Modifications © 2022, Deutsche Telekom
+  #
+  # Licensed under the Apache License, Version 2.0 (the "License");
+  # you may not use this file except in compliance with the License.
+  # You may obtain a copy of the License at
+  #
+  #       http://www.apache.org/licenses/LICENSE-2.0
+  #
+  # Unless required by applicable law or agreed to in writing, software
+  # distributed under the License is distributed on an "AS IS" BASIS,
+  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  # See the License for the specific language governing permissions and
+  # limitations under the License.
+*/}}
+---
+apiVersion: batch/v1
+kind: Job
+metadata:
+  {{- with .Values.annotations }}
+  annotations:
+  {{- toYaml . | nindent 4 }}
+  {{- end }}
+  name: {{ template "keycloak-config-cli.fullname" . }}
+  labels:
+  {{- include "keycloak-config-cli.labels" . | nindent 4 }}
+spec:
+  backoffLimit: {{ .Values.backoffLimit }}
+  template:
+    metadata:
+      {{- with .Values.podAnnotations }}
+      annotations:
+      {{- . | nindent 8 }}
+      {{- end }}
+      labels:
+      {{- include "keycloak-config-cli.selectorLabels" . | nindent 8 }}
+      {{- with .Values.podLabels }}
+    {{- toYaml . | nindent 8 }}
+    {{- end }}
+    spec:
+      {{- with .Values.image.pullSecrets }}
+      imagePullSecrets:
+      {{- toYaml . | nindent 8 }}
+      {{- end }}
+      restartPolicy: Never
+      containers:
+        - name: keycloak-config-cli
+          image: "{{ include "repositoryGenerator.dockerHubRepository" . }}/{{ .Values.image.repository }}:{{ tpl .Values.image.tag $ }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          {{- with .Values.resources }}
+          resources:
+          {{- toYaml . | nindent 10 }}
+          {{- end }}
+          env:
+            {{- range $name, $value := .Values.env }}
+            - name: {{ $name | quote }}
+              value: {{ tpl $value $ | quote }}
+            {{- end }}
+            {{- range $name, $value := .Values.secrets }}
+            - name: {{ $name | quote }}
+              valueFrom:
+                secretKeyRef:
+                  name: "{{ template "keycloak-config-cli.fullname" $ }}"
+                  key: {{ $name | quote }}
+            {{- end }}
+            {{- if and .Values.existingSecret .Values.existingSecretKey }}
+            - name: "KEYCLOAK_PASSWORD"
+              valueFrom:
+                secretKeyRef:
+                  name: "{{ tpl .Values.existingSecret . }}"
+                  key: "{{ .Values.existingSecretKey }}"
+          {{- end }}
+          {{- with .Values.securityContext }}
+          securityContext:
+          {{- toYaml . | nindent 10 }}
+          {{- end }}
+          volumeMounts:
+            - name: config
+              mountPath: /config
+            {{- with .Values.extraVolumeMounts }}
+            {{- tpl . $ | nindent 12 }}
+            {{- end }}
+        {{ include "common.waitForJobContainer" . | indent 8 | trim }}
+      volumes:
+        - name: config
+          secret:
+            {{- if .Values.existingConfigSecret }}
+            secretName: "{{ tpl .Values.existingConfigSecret $ }}"
+            {{- else }}
+            secretName: "{{ template "keycloak-config-cli.fullname" . }}-config-realms"
+            {{- end }}
+            defaultMode: 0555
+        {{- with .Values.extraVolumes }}
+        {{- tpl . $ | nindent 8 }}
+        {{- end }}
+      {{- with .Values.serviceAccount }}
+      serviceAccountName: "{{ tpl . $ }}"
+      {{- end }}
+      {{- with .Values.securityContext }}
+      securityContext:
+      {{- toYaml . | nindent 8 }}
+  {{- end }}
diff --git a/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/realms.yaml b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/realms.yaml
new file mode 100644
index 0000000..fa9363e
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/realms.yaml
@@ -0,0 +1,32 @@
+{{/*
+  # Copyright © adorsys GmbH & Co. KG
+  #
+  # Licensed under the Apache License, Version 2.0 (the "License");
+  # you may not use this file except in compliance with the License.
+  # You may obtain a copy of the License at
+  #
+  #       http://www.apache.org/licenses/LICENSE-2.0
+  #
+  # Unless required by applicable law or agreed to in writing, software
+  # distributed under the License is distributed on an "AS IS" BASIS,
+  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  # See the License for the specific language governing permissions and
+  # limitations under the License.
+*/}}
+{{ if not .Values.existingConfigSecret }}
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ template "keycloak-config-cli.fullname" . }}-config-realms
+  labels:
+  {{- include "keycloak-config-cli.labels" . | nindent 4 }}
+data:
+  {{- range $name, $config := .Values.config }}
+    {{- if hasKey $config "file" }}
+  {{ $name }}.json: "{{ tpl ($.Files.Get $config.file) $ | b64enc }}"
+    {{- else if hasKey $config "inline" }}
+  {{ $name }}.json: "{{ tpl (toJson $config.inline) $ | b64enc }}"
+    {{- end }}
+  {{- end }}
+{{- end }}
diff --git a/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/secrets.yaml b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/secrets.yaml
new file mode 100644
index 0000000..9450528
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/templates/secrets.yaml
@@ -0,0 +1,28 @@
+{{/*
+  # Copyright © adorsys GmbH & Co. KG
+  #
+  # Licensed under the Apache License, Version 2.0 (the "License");
+  # you may not use this file except in compliance with the License.
+  # You may obtain a copy of the License at
+  #
+  #       http://www.apache.org/licenses/LICENSE-2.0
+  #
+  # Unless required by applicable law or agreed to in writing, software
+  # distributed under the License is distributed on an "AS IS" BASIS,
+  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  # See the License for the specific language governing permissions and
+  # limitations under the License.
+*/}}
+{{ if .Values.secrets }}
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ template "keycloak-config-cli.fullname" . }}
+  labels:
+  {{- include "keycloak-config-cli.labels" . | nindent 4 }}
+data:
+  {{- range $name, $value := .Values.secrets }}
+    {{ $name }}: "{{ tpl $value $ | b64enc }}"
+  {{- end }}
+  {{- end }}
diff --git a/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/values.yaml b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/values.yaml
new file mode 100644
index 0000000..e54a4c7
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/components/keycloak-config-cli/values.yaml
@@ -0,0 +1,100 @@
+# Copyright © adorsys GmbH & Co. KG
+# Modifications © 2022, Deutsche Telekom
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+---
+global:
+  pullPolicy: Always
+  persistence: {}
+  dockerHubRepository: docker.io
+
+fullnameOverride: ""
+nameOverride: ""
+
+#keycloakUrl: "https://keycloak-ui.simpledemo.onap.org/auth/"
+portalUrl: "https://portal-ng-ui.simpledemo.onap.org"
+
+image:
+  repository: adorsys/keycloak-config-cli
+  tag: "{{ .Chart.AppVersion }}"
+  pullPolicy: IfNotPresent
+  ## Optionally specify an array of imagePullSecrets.
+  ## Secrets must be manually created in the namespace.
+  ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
+  ##
+  pullSecrets: []
+  # - myRegistryKeySecretName
+
+# Count of re(!)tries. A value of 2 means 3 tries in total.
+backoffLimit: 1
+
+# annotations of the Job. Define helm post hook here
+# currently disabled to see the results and to be compliant with ArgoCD
+#annotations:
+#  "helm.sh/hook": "post-install,post-upgrade,post-rollback"
+#  "helm.sh/hook-delete-policy": "hook-succeeded,before-hook-creation"
+#  "helm.sh/hook-weight": "5"
+
+labels: {}
+
+resources: {}
+  # limits:
+  #   cpu: "100m"
+  #   memory: "1024Mi"
+  # requests:
+  #   cpu: "100m"
+#   memory: "1024Mi"
+
+env:
+  KEYCLOAK_URL: http://keycloak:8080
+  KEYCLOAK_USER: admin
+  IMPORT_PATH: /config/
+
+secrets: {}
+#  KEYCLOAK_PASSWORD:
+
+# Specifies an existing secret to be used for the admin password
+existingSecret: ""
+
+# The key in the existing secret that stores the password
+existingSecretKey: password
+
+securityContext: {}
+containerSecurityContext: {}
+
+## Additional pod labels
+## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
+podLabels: {}
+
+## Extra Annotations to be added to pod
+podAnnotations: {}
+
+config: {}
+  # <realm name>:
+  #   inline:
+  #     realm: <realm name>
+  #     clients: []
+  # <realm name>:
+  #   file: <path>
+
+existingConfigSecret: ""
+
+# Add additional volumes, e.g. for custom secrets
+extraVolumes: ""
+
+# Add additional volumes mounts, e. g. for custom secrets
+extraVolumeMounts: ""
+
+wait_for_job_container:
+  containers:
+    - 'keycloak-config-cli'
diff --git a/kubernetes/platform/components/keycloak-init/templates/ingress.yaml b/kubernetes/platform/components/keycloak-init/templates/ingress.yaml
new file mode 100644
index 0000000..6ca7cec
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/templates/ingress.yaml
@@ -0,0 +1,21 @@
+{{/*
+#  ============LICENSE_START=======================================================
+#   Copyright (C) 2022 Deutsche Telekom
+#  ================================================================================
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+#
+#  SPDX-License-Identifier: Apache-2.0
+#  ============LICENSE_END=========================================================
+*/}}
+
+{{ include "common.ingress" . }}
\ No newline at end of file
diff --git a/kubernetes/platform/components/keycloak-init/values.yaml b/kubernetes/platform/components/keycloak-init/values.yaml
new file mode 100644
index 0000000..5e97514
--- /dev/null
+++ b/kubernetes/platform/components/keycloak-init/values.yaml
@@ -0,0 +1,46 @@
+# Copyright © 2022, Deutsche Telekom
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+global:
+  # Global ingress configuration
+  ingress:
+    enabled: false
+    virtualhost:
+      baseurl: "simpledemo.onap.org"
+
+keycloak-config-cli:
+  #existingSecret: "keycloak-keycloakx-admin-creds"
+  env:
+    KEYCLOAK_URL: http://keycloak-http.keycloak.svc.cluster.local/auth/
+  secrets:
+    KEYCLOAK_PASSWORD: secret
+  config:
+    onap:
+      file: resources/realm/onap-realm.json
+
+ingress:
+  service:
+    - baseaddr: "keycloak-ui"
+      name: "keycloak-http.keycloak.svc.cluster.local"
+      path: "/auth"
+      port: 80
+  # If `true`, an Ingress is created
+  enabled: false
+  config:
+    ssl: "redirect"
+
+serviceAccount:
+  nameOverride: keycloak-init
+  roles:
+    - read