diff options
Diffstat (limited to 'kubernetes/authentication')
55 files changed, 4616 insertions, 0 deletions
diff --git a/kubernetes/authentication/.helmignore b/kubernetes/authentication/.helmignore new file mode 100644 index 0000000000..cf02291a2a --- /dev/null +++ b/kubernetes/authentication/.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/authentication/Chart.yaml b/kubernetes/authentication/Chart.yaml new file mode 100644 index 0000000000..e8400aeb81 --- /dev/null +++ b/kubernetes/authentication/Chart.yaml @@ -0,0 +1,38 @@ +#============LICENSE_START======================================================== +# ================================================================================ +# Copyright © 2024 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: 14.0.1 +description: ONAP Realm creation, Oauth2Proxy installation and configuration +name: authentication +sources: +- https://github.com/adorsys/keycloak-config-cli + +# Keycloakx chart version: 1.6.0 +dependencies: + - name: common + version: ~13.x-0 + repository: '@local' + - name: serviceAccount + version: ~13.x-0 + repository: '@local' + - name: onap-keycloak-config-cli + version: 5.12.0 + repository: 'file://components/keycloak-config-cli' + - name: onap-oauth2-proxy + version: 7.5.4 + repository: 'file://components/oauth2-proxy' diff --git a/kubernetes/authentication/Makefile b/kubernetes/authentication/Makefile new file mode 100644 index 0000000000..f47666e135 --- /dev/null +++ b/kubernetes/authentication/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 := 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/authentication/README.md b/kubernetes/authentication/README.md new file mode 100644 index 0000000000..306e2f9645 --- /dev/null +++ b/kubernetes/authentication/README.md @@ -0,0 +1,305 @@ +# Helm Chart for Authentication Application + +This component delivers: + +- Keycloak Realm creation and import +- (Optionally) creation of AuthenticationPolicies for Ingress to enable + OAuth Authentication and RoleBased access to Ingress APIs and UIs + +## REALM Configuration settings + +- In the configuration section "realmSettings" multiple REALMs can be configured +- Each REALM configuration has the following sections: + - [General REALM settings](#general-realm-settings) + - [CLIENT definitions](#client-definitions) + - (optional) [CLIENT SCOPE definitions](#client-scope-definitions) + - (optional) [Access control definitions](#access-control-definitions) + - (optional) [GROUP definitions](#group-definitions) + - (optional) [USER definitions](#user-definitions) + - (optional) [IDENTITY PROVIDER definitions](#identity-provider-and-mapper-definitions) + - (optional) [SMTP server definitions](#smtp-server-definitions) + +### General REALM settings + +This sections sets the realm general attributes shown in Keycloak + +```yaml +realmSettings: + - name: <Realm ID> - unique ID for a realm (e.g. "ONAP") + displayName: <Display Name> - (optional) Keycloak Display Name (e.g. "ONAP Realm") + themes: - (optional) Keycloak Theme settings + login: <login theme> - (optional) Keycloak Theme for Login UI (e.g. "base") + admin: <admin theme> - (optional) Keycloak Theme for Admin UI (e.g. "base") + account: <account theme> - (optional) Keycloak Theme for Account UI (e.g. "base") + email: <email theme> - (optional) Keycloak Theme for Email UI (e.g. "base") + attributes: + frontendUrl: "<Keycloak URL>" - External Url for Keycloak access (e.g. "https://keycloak-$PARAM_BASE_URL/") +``` + +### CLIENT definitions + +In this section each realm authentication client is defined e.g. portal-bff, oauth2-proxy, grafana + +possible "attribute" settings (maybe more): + - id.token.as.detached.signature: "false" + - exclude.session.state.from.auth.response: "false" + - tls.client.certificate.bound.access.tokens: "false" + - saml.allow.ecp.flow: "false" + - saml.assertion.signature: "false" + - saml.force.post.binding: "false" + - saml.multivalued.roles: "false" + - saml.encrypt: "false" + - saml.server.signature: "false" + - saml.server.signature.keyinfo.ext: "false" + - saml.artifact.binding: "false" + - saml_force_name_id_format: "false" + - saml.client.signature: "false" + - saml.authnstatement: "false" + - saml.onetimeuse.condition: "false" + - oidc.ciba.grant.enabled: "false" + - frontchannel.logout.session.required: "true" + - backchannel.logout.session.required: "true" + - backchannel.logout.revoke.offline.tokens: "false" + - client_credentials.use_refresh_token: "false" + - acr.loa.map: "{}" + - require.pushed.authorization.requests: "false" + - oauth2.device.authorization.grant.enabled: "false" + - display.on.consent.screen: "false" + - token.response.type.bearer.lower-case: "false" + - use.refresh.tokens: "true" + - post.logout.redirect.uris: '<url>' + +```yaml + clients: + oauth2_proxy: + clientId: "<client ID>" - client ID + name: "<client name>" - (optional) client name + secret: <client secret> - (optional) client secret + clientAuthenticatorType: <type> - (optional) auth type (default: client-secret) + protocol: <protocol> - (optional) auth protocol (default: openid-connect) + description: "<description>" - (optional) client description + baseUrl: "<base path>" - (optional) url subpath (e.g. /application) + rootUrl: "<root URL>" - (optional) root url + adminUrl: "<admin URL>" - (optional) admin url + bearerOnly: "<false|true>" - (optional) bearerOnly (default: false) + consentRequired: "<false|true>" - (optional) consentRequired (default: false) + standardFlowEnabled: "<false|true>" - (optional) standardFlowEnabled (default: true) + implicitFlowEnabled: "<false|true>" - (optional) implicitFlowEnabled (default: false) + directAccessGrantsEnabled: "<false|true>" - (optional) directAccessGrantsEnabled (default: true) + serviceAccountsEnabled: "<false|true>" - (optional) serviceAccountsEnabled (default: false) + frontchannelLogout: "<false|true>" - (optional) frontend channel logout (default: true) + surrogateAuthRequired: "<false|true>" - (optional) surrogate Auth Required (default: false) + publicClient: "<false|true>" - (optional) public Client (default: false) + attributes: - (optional) attributes settings (see code) + post.logout.redirect.uris: '<url>' - example + protocolMappers: - (optional) protocol mappers + - name: "Audience for Oauth2Proxy" - examples + protocolMapper: "oidc-audience-mapper" + config: + included.client.audience: "oauth2-proxy-onap" + id.token.claim: "false" + access.token.claim: "true" + included.custom.audience: "oauth2-proxy-onap" + - name: "SDC-User" + protocolMapper: "oidc-usermodel-attribute-mapper" + config: + multivalued: "false" + userinfo.token.claim: "true" + user.attribute: "sdc_user" + id.token.claim: "true" + access.token.claim: "true" + claim.name: "sdc_user" + jsonType.label: "String" + additionalDefaultScopes: + - "onap_roles" + redirectUris: + - "https://portal-$PARAM_BASE_URL/*" + - "http://localhost/*" + webOrigins: + - "https://argocd-$PARAM_BASE_URL" + defaultClientScopes: + - "web-origins" + - "profile" + - "acr" + - "email" + - "roles" + - "groups" +``` + +### CLIENT SCOPE definitions + +Here additional scopes besides the default scopes can be defined and set as default client scope + +default scopes: + + - roles + - groups + - acr + - profile + - address + - web-origin + - phone + - email + - offline_access + - role_list + - microprofile-jwt + +```yaml + defaultClientScopes: + - "onap_roles" + additionalClientScopes: + - name: onap_roles + description: OpenID Connect scope for add user onap roles to the access token + protocolMappers: + - name: aud + protocol: openid-connect + protocolMapper: oidc-audience-mapper + consentRequired: false + config: + included.client.audience: oauth2-proxy + id.token.claim: 'false' + access.token.claim: 'true' + - name: client roles + protocol: openid-connect + protocolMapper: oidc-usermodel-client-role-mapper + consentRequired: false + config: + multivalued: 'true' + userinfo.token.claim: 'false' + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: onap_roles + jsonType.label: String + usermodel.clientRoleMapping.clientId: oauth2-proxy +``` + +### Access control definitions + +In this section additional roles (assignableRoles) besides the default roles can be set. + +default roles: + - user + - admin + - offline_access + - uma_authorization + - default-roles-<realm> + +(optional) accessRoles can be defined. +These access roles are used in the Ingress "Auhorization Policy" to restrict the access to certain services +The access role is assigned to a realm client (e.g. oauth2_proxy) + +```yaml + accessControl: + assignableRoles: + - name: onap-operator-read + description: "Allows to perform GET operations for all ONAP components" + associatedAccessRoles: [ "dmaap-bc-api-read", ... ] + accessRoles: + "oauth2_proxy": + - name: dmaap-bc-api-read + methodsAllowed: ["GET"] + servicePrefix: dmaap-bc-api +``` + +### GROUP definitions + +```yaml + groups: - (optional) Group definitions + - name: <group name> - Group name + path: /path> - Group URL path + roles: [ <role>,... ] - (optional) List of Realm roles +``` + +### USER definitions + +```yaml + initialUsers: - (optional) List of initial users + - username: <user name> - Name of the User + firstName: <first name> - (optional) First Name + lastName: <last name> - (optional) Last Name + email: <email> - (optional) Email Address + emailVerified : <true|false>- (optional)Email verified + credentials: - (optional) credentials + - type: password - (optional) initial password (<pwd>: encrypted password, <salt>: used salt) + secretData: "{\"value\":\"<pwd>\",\"salt\":\"<salt>\"}" + credentialData: "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\"}" + attributes: - (optional) additional attributes + sdc_user: - example attribute + - "cs0008" + realmRoles: - (optional) assigned realm roles + - <role name> + groups: - (optional) group membership + - <group name> +``` + +### Identity Provider and Mapper definitions + +```yaml + identityProviders: + - name: "gitlab" + displayName: "gitlab" + config: + userInfoUrl: "https://gitlab.devops.telekom.de/oauth/userinfo" + validateSignature: "true" + clientId: "ee4e0db734157e9cdad16733656ba285f2f813354aa7c590a8693e48ed156860" + tokenUrl: "https://gitlab.devops.telekom.de/oauth/token" + jwksUrl: "https://gitlab.devops.telekom.de/oauth/discovery/keys" + issuer: "https://gitlab.devops.telekom.de" + useJwksUrl: "true" + authorizationUrl: "https://gitlab.devops.telekom.de/oauth/authorize" + clientAuthMethod: "client_secret_post" + syncMode: "IMPORT" + clientSecret: "gloas-35267790bf6fb7c4b507aea11db46d80174cb8ef4192e77424803b595eef735e" + defaultScope: "openid read_user email" + identityProviderMappers: + - name: "argo-admins" + identityProviderAlias: "gitlab" + identityProviderMapper: "oidc-advanced-group-idp-mapper" + config: + claims: "[{\"key\":\"groups_direct\",\"value\":\"dt-rc\"}]" + syncMode: "FORCE" + group: "/ArgoCDAdmins" + - name: "ArgoCDRestricted" + identityProviderAlias: "gitlab" + identityProviderMapper: "oidc-advanced-group-idp-mapper" + config: + claims: "[{\"key\":\"groups_direct\",\"value\":\"\"}]" + syncMode: "FORCE" + group: "/ArgoCDRestricted" + - name: "lastName " + identityProviderAlias: "gitlab" + identityProviderMapper: "oidc-user-attribute-idp-mapper" + config: + claim: "nickname" + syncMode: "FORCE" + user.attribute: "lastName" +``` + +### SMTP Server definitions + +```yaml + smtpServer: + password: "<password>" + starttls: "true" + auth: "true" + port: "587" + host: "<mailserver>" + from: "<mail-address>" + fromDisplayName: "onapsupport" + ssl: "false" + user: "onapsupport" +``` + +## Ingress Authentication settings + +Activating the Ingress Authentication (enabled: true) will create AuthorizationPolicy resources for each defined "accessControl.accessRoles" in a REALM definition. + +``` +ingressAuthentication: + enabled: false + exceptions: + - '{{ include "ingress.config.host" (dict "dot" . "baseaddr" "keycloak-ui") }}' + - '{{ include "ingress.config.host" (dict "dot" . "baseaddr" "portal-ui") }}' + - '{{ include "ingress.config.host" (dict "dot" . "baseaddr" "minio-console") }}' + - '{{ include "ingress.config.host" (dict "dot" . "baseaddr" "uui-server") }}' +``` diff --git a/kubernetes/authentication/components/Makefile b/kubernetes/authentication/components/Makefile new file mode 100644 index 0000000000..4ecfbc53cc --- /dev/null +++ b/kubernetes/authentication/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/authentication/components/keycloak-config-cli/.helmignore b/kubernetes/authentication/components/keycloak-config-cli/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/kubernetes/authentication/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/authentication/components/keycloak-config-cli/Chart.yaml b/kubernetes/authentication/components/keycloak-config-cli/Chart.yaml new file mode 100644 index 0000000000..80e5d27c9f --- /dev/null +++ b/kubernetes/authentication/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: onap-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.12.0 +appVersion: 5.12.0 +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: ~13.x-0 + repository: '@local' + - name: repositoryGenerator + version: ~13.x-0 + repository: '@local'
\ No newline at end of file diff --git a/kubernetes/authentication/components/keycloak-config-cli/templates/_helpers.tpl b/kubernetes/authentication/components/keycloak-config-cli/templates/_helpers.tpl new file mode 100644 index 0000000000..cc1ad7ad8d --- /dev/null +++ b/kubernetes/authentication/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/authentication/components/keycloak-config-cli/templates/job.yaml b/kubernetes/authentication/components/keycloak-config-cli/templates/job.yaml new file mode 100644 index 0000000000..322db2b7a1 --- /dev/null +++ b/kubernetes/authentication/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/authentication/components/keycloak-config-cli/templates/realms.yaml b/kubernetes/authentication/components/keycloak-config-cli/templates/realms.yaml new file mode 100644 index 0000000000..fa9363e9d0 --- /dev/null +++ b/kubernetes/authentication/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/authentication/components/keycloak-config-cli/templates/secrets.yaml b/kubernetes/authentication/components/keycloak-config-cli/templates/secrets.yaml new file mode 100644 index 0000000000..94505289e6 --- /dev/null +++ b/kubernetes/authentication/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/authentication/components/keycloak-config-cli/values.yaml b/kubernetes/authentication/components/keycloak-config-cli/values.yaml new file mode 100644 index 0000000000..46c67dd220 --- /dev/null +++ b/kubernetes/authentication/components/keycloak-config-cli/values.yaml @@ -0,0 +1,97 @@ +# 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: "" + +image: + repository: adorsys/keycloak-config-cli + tag: "{{ .Chart.AppVersion }}-22.0.4" + 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/authentication/components/oauth2-proxy/.helmignore b/kubernetes/authentication/components/oauth2-proxy/.helmignore new file mode 100644 index 0000000000..825c007791 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/.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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj + +OWNERS diff --git a/kubernetes/authentication/components/oauth2-proxy/Chart.yaml b/kubernetes/authentication/components/oauth2-proxy/Chart.yaml new file mode 100644 index 0000000000..3bcf687241 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/Chart.yaml @@ -0,0 +1,48 @@ +name: onap-oauth2-proxy +version: 7.5.4 +apiVersion: v2 +appVersion: 7.6.0 +home: https://oauth2-proxy.github.io/oauth2-proxy/ +description: A reverse proxy that provides authentication with Google, Github or other providers +keywords: + - kubernetes + - oauth + - oauth2 + - authentication + - google + - github + - redis +dependencies: + - name: redis + version: 19.1.0 + repository: https://charts.bitnami.com/bitnami + alias: redis + condition: redis.enabled + - name: common + version: ~13.x-0 + repository: '@local' + - name: repositoryGenerator + version: ~13.x-0 + repository: '@local' + +sources: + - https://github.com/oauth2-proxy/oauth2-proxy + - https://github.com/oauth2-proxy/manifests +maintainers: + - name: desaintmartin + email: cedric@desaintmartin.fr + - name: tlawrie + - name: NickMeves + email: nicholas.meves@gmail.com + - name: JoelSpeed + email: joel.speed@hotmail.co.uk + - name: pierluigilenoci + email: pierluigi.lenoci@gmail.com +kubeVersion: ">=1.9.0-0" +annotations: + artifacthub.io/changes: | + - kind: changed + description: Wait for redis script fixes for cluster and sentinel + links: + - name: Github PR + url: https://github.com/oauth2-proxy/manifests/issues/205 diff --git a/kubernetes/authentication/components/oauth2-proxy/README.md b/kubernetes/authentication/components/oauth2-proxy/README.md new file mode 100644 index 0000000000..55a5e44429 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/README.md @@ -0,0 +1,338 @@ +# oauth2-proxy + +[oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy) is a reverse proxy and static file server that provides authentication using Providers (Google, GitHub, and others) to validate accounts by email, domain or group. + +## TL;DR; + +```console +$ helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests +$ helm install my-release oauth2-proxy/oauth2-proxy +``` + +## Introduction + +This chart bootstraps an oauth2-proxy deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm install my-release oauth2-proxy/oauth2-proxy +``` + +The command deploys oauth2-proxy on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm uninstall my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Upgrading an existing Release to a new major version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an +incompatible breaking change needing manual actions. + +### To 1.0.0 + +This version upgrades oauth2-proxy to v4.0.0. Please see the [changelog](https://github.com/oauth2-proxy/oauth2-proxy/blob/v4.0.0/CHANGELOG.md#v400) in order to upgrade. + +### To 2.0.0 + +Version 2.0.0 of this chart introduces support for Kubernetes v1.16.x by way of addressing the deprecation of the Deployment object apiVersion `apps/v1beta2`. See [the v1.16 API deprecations page](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/) for more information. + +Due to [this issue](https://github.com/helm/helm/issues/6583) there may be errors performing a `helm upgrade` of this chart from versions earlier than 2.0.0. + +### To 3.0.0 + +Version 3.0.0 introduces support for [EKS IAM roles for service accounts](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) by adding a managed service account to the chart. This is a breaking change since the service account is enabled by default. To disable this behaviour set `serviceAccount.enabled` to `false` + +### To 4.0.0 + +Version 4.0.0 adds support for the new Ingress apiVersion **networking.k8s.io/v1**. +Therefore the `ingress.extraPaths` parameter needs to be updated to the new format. +See the [v1.22 API deprecations guide](https://kubernetes.io/docs/reference/using-api/deprecation-guide/#ingress-v122) for more information. + +For the same reason `service.port` was renamed to `service.portNumber`. + +### To 5.0.0 + +Version 5.0.0 introduces support for custom labels and refactor [Kubernetes recommended labels](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/). This is a breaking change because many labels of all resources need to be updated to stay consistent. + +In order to upgrade, delete the Deployment before upgrading: + +```bash +kubectl delete deployment my-release-oauth2-proxy +``` + +This will introduce a slight downtime. + +For users who don't want downtime, you can perform these actions: + +- Perform a non-cascading removal of the deployment that keeps the pods running +- Add new labels to pods +- Perform `helm upgrade` + +### To 6.0.0 + +Version 6.0.0 bumps the version of the redis subchart from ~10.6.0 to ~16.4.0. You probably need to adjust your redis config. See [here](https://github.com/bitnami/charts/tree/master/bitnami/redis#upgrading) for detailed upgrade instructions. + +## Configuration + +The following table lists the configurable parameters of the oauth2-proxy chart and their default values. + +Parameter | Description | Default +--- | --- | --- +`affinity` | node/pod affinities | None +`authenticatedEmailsFile.enabled` | Enables authorize individual email addresses | `false` +`authenticatedEmailsFile.persistence` | Defines how the email addresses file will be projected, via a configmap or secret | `configmap` +`authenticatedEmailsFile.template` | Name of the configmap or secret that is handled outside of that chart | `""` +`authenticatedEmailsFile.restrictedUserAccessKey` | The key of the configmap or secret that holds the email addresses list | `""` +`authenticatedEmailsFile.restricted_access` | [email addresses](https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider#email-authentication) list config | `""` +`authenticatedEmailsFile.annotations` | configmap or secret annotations | `nil` +`config.clientID` | oauth client ID | `""` +`config.clientSecret` | oauth client secret | `""` +`config.cookieSecret` | server specific cookie for the secret; create a new one with `openssl rand -base64 32 \| head -c 32 \| base64` | `""` +`config.existingSecret` | existing Kubernetes secret to use for OAuth2 credentials. See [oauth2-proxy.secrets helper](https://github.com/oauth2-proxy/manifests/blob/main/helm/oauth2-proxy/templates/_helpers.tpl#L157C13-L157C33) for the required values | `nil` +`config.configFile` | custom [oauth2_proxy.cfg](https://github.com/oauth2-proxy/oauth2-proxy/blob/master/contrib/oauth2-proxy.cfg.example) contents for settings not overridable via environment nor command line | `""` +`config.existingConfig` | existing Kubernetes configmap to use for the configuration file. See [config template](https://github.com/oauth2-proxy/manifests/blob/master/helm/oauth2-proxy/templates/configmap.yaml) for the required values | `nil` +`config.cookieName` | The name of the cookie that oauth2-proxy will create. | `""` +`alphaConfig.enabled` | Flag to toggle any alpha config related logic | `false` +`alphaConfig.annotations` | Configmap annotations | `{}` +`alphaConfig.serverConfigData` | Arbitrary configuration data to append to the server section | `{}` +`alphaConfig.metricsConfigData` | Arbitrary configuration data to append to the metrics section | `{}` +`alphaConfig.configData` | Arbitrary configuration data to append | `{}` +`alphaConfig.configFile` | Arbitrary configuration to append, treated as a Go template and rendered with the root context | `""` +`alphaConfig.existingConfig` | existing Kubernetes configmap to use for the alpha configuration file. See [config template](https://github.com/oauth2-proxy/manifests/blob/master/helm/oauth2-proxy/templates/secret-alpha.yaml) for the required values | `nil` +`alphaConfig.existingSecret` | existing Kubernetes secret to use for the alpha configuration file. See [config template](https://github.com/oauth2-proxy/manifests/blob/master/helm/oauth2-proxy/templates/secret-alpha.yaml) for the required values | `nil` +`customLabels` | Custom labels to add into metadata | `{}` | +`config.google.adminEmail` | user impersonated by the google service account | `""` +`config.google.useApplicationDefaultCredentials` | use the application-default credentials (i.e. Workload Identity on GKE) instead of providing a service account json | `false` +`config.google.targetPrincipal` | service account to use/impersonate | `""` +`config.google.serviceAccountJson` | google service account json contents | `""` +`config.google.existingConfig` | existing Kubernetes configmap to use for the service account file. See [google secret template](https://github.com/oauth2-proxy/manifests/blob/master/helm/oauth2-proxy/templates/google-secret.yaml) for the required values | `nil` +`config.google.groups` | restrict logins to members of these google groups | `[]` +`containerPort` | used to customise port on the deployment | `""` +`extraArgs` | Extra arguments to give the binary. Either as a map with key:value pairs or as a list type, which allows to configure the same flag multiple times. (e.g. `["--allowed-role=CLIENT_ID:CLIENT_ROLE_NAME_A", "--allowed-role=CLIENT_ID:CLIENT_ROLE_NAME_B"]`). | `{}` or `[]` +`extraContainers` | List of extra containers to be added to the pod | `[]` +`extraEnv` | key:value list of extra environment variables to give the binary | `[]` +`extraVolumes` | list of extra volumes | `[]` +`extraVolumeMounts` | list of extra volumeMounts | `[]` +`hostAliases` | hostAliases is a list of aliases to be added to /etc/hosts for network name resolution. +`htpasswdFile.enabled` | enable htpasswd-file option | `false` +`htpasswdFile.entries` | list of [encrypted user:passwords](https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview#command-line-options) | `{}` +`htpasswdFile.existingSecret` | existing Kubernetes secret to use for OAuth2 htpasswd file | `""` +`httpScheme` | `http` or `https`. `name` used for port on the deployment. `httpGet` port `name` and `scheme` used for `liveness`- and `readinessProbes`. `name` and `targetPort` used for the service. | `http` +`image.pullPolicy` | Image pull policy | `IfNotPresent` +`image.repository` | Image repository | `quay.io/oauth2-proxy/oauth2-proxy` +`image.tag` | Image tag | `""` (defaults to appVersion) +`imagePullSecrets` | Specify image pull secrets | `nil` (does not add image pull secrets to deployed pods) +`ingress.enabled` | Enable Ingress | `false` +`ingress.className` | name referencing IngressClass | `nil` +`ingress.path` | Ingress accepted path | `/` +`ingress.pathType` | Ingress [path type](https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types) | `ImplementationSpecific` +`ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions). | `[]` +`ingress.labels` | Ingress extra labels | `{}` +`ingress.annotations` | Ingress annotations | `nil` +`ingress.hosts` | Ingress accepted hostnames | `nil` +`ingress.tls` | Ingress TLS configuration | `nil` +`initContainers.waitForRedis.enabled` | if `redis.enabled` is true, use an init container to wait for the redis master pod to be ready. If `serviceAccount.enabled` is true, create additionally a role/binding to get, list and watch the redis master pod | `true` +`initContainers.waitForRedis.image.pullPolicy` | kubectl image pull policy | `IfNotPresent` +`initContainers.waitForRedis.image.repository` | kubectl image repository | `docker.io/bitnami/kubectl` +`initContainers.waitForRedis.kubectlVersion` | kubectl version to use for the init container | `printf "%s.%s" .Capabilities.KubeVersion.Major (.Capabilities.KubeVersion.Minor | replace "+" "")` +`initContainers.waitForRedis.securityContext.enabled` | enable Kubernetes security context on container | `true` +`initContainers.waitForRedis.timeout` | number of seconds | 180 +`initContainers.waitForRedis.resources` | pod resource requests & limits | `{}` +`livenessProbe.enabled` | enable Kubernetes livenessProbe. Disable to use oauth2-proxy with Istio mTLS. See [Istio FAQ](https://istio.io/help/faq/security/#k8s-health-checks) | `true` +`livenessProbe.initialDelaySeconds` | number of seconds | 0 +`livenessProbe.timeoutSeconds` | number of seconds | 1 +`namespaceOverride` | Override the deployment namespace | `""` +`nodeSelector` | node labels for pod assignment | `{}` +`deploymentAnnotations` | annotations to add to the deployment | `{}` +`podAnnotations` | annotations to add to each pod | `{}` +`podLabels` | additional labesl to add to each pod | `{}` +`podDisruptionBudget.enabled`| Enabled creation of PodDisruptionBudget (only if replicaCount > 1) | true +`podDisruptionBudget.minAvailable`| minAvailable parameter for PodDisruptionBudget | 1 +`podSecurityContext` | Kubernetes security context to apply to pod | `{}` +`priorityClassName` | priorityClassName | `nil` +`readinessProbe.enabled` | enable Kubernetes readinessProbe. Disable to use oauth2-proxy with Istio mTLS. See [Istio FAQ](https://istio.io/help/faq/security/#k8s-health-checks) | `true` +`readinessProbe.initialDelaySeconds` | number of seconds | 0 +`readinessProbe.timeoutSeconds` | number of seconds | 5 +`readinessProbe.periodSeconds` | number of seconds | 10 +`readinessProbe.successThreshold` | number of successes | 1 +`replicaCount` | desired number of pods | `1` +`resources` | pod resource requests & limits | `{}` +`revisionHistoryLimit` | maximum number of revisions maintained | 10 +`service.portNumber` | port number for the service | `80` +`service.appProtocol` | application protocol on the port of the service | `http` +`service.type` | type of service | `ClusterIP` +`service.clusterIP` | cluster ip address | `nil` +`service.loadBalancerIP` | ip of load balancer | `nil` +`service.loadBalancerSourceRanges` | allowed source ranges in load balancer | `nil` +`service.nodePort` | external port number for the service when service.type is `NodePort` | `nil` +`serviceAccount.enabled` | create a service account | `true` +`serviceAccount.name` | the service account name | `` +`serviceAccount.annotations` | (optional) annotations for the service account | `{}` +`strategy` | configure deployment strategy | `{}` +`tolerations` | list of node taints to tolerate | `[]` +`securityContext.enabled` | enable Kubernetes security context on container | `true` +`proxyVarsAsSecrets` | choose between environment values or secrets for setting up OAUTH2_PROXY variables. When set to false, remember to add the variables OAUTH2_PROXY_CLIENT_ID, OAUTH2_PROXY_CLIENT_SECRET, OAUTH2_PROXY_COOKIE_SECRET in extraEnv | `true` +`sessionStorage.type` | Session storage type which can be one of the following: cookie or redis | `cookie` +`sessionStorage.redis.existingSecret` | Name of the Kubernetes secret containing the redis & redis sentinel password values (see also `sessionStorage.redis.passwordKey`) | `""` +`sessionStorage.redis.password` | Redis password. Applicable for all Redis configurations. Taken from redis subchart secret if not set. sessionStorage.redis.existingSecret takes precedence | `nil` +`sessionStorage.redis.passwordKey` | Key of the Kubernetes secret data containing the redis password value | `redis-password` +`sessionStorage.redis.clientType` | Allows the user to select which type of client will be used for redis instance. Possible options are: `sentinel`, `cluster` or `standalone` | `standalone` +`sessionStorage.redis.standalone.connectionUrl` | URL of redis standalone server for redis session storage (e.g. `redis://HOST[:PORT]`). Automatically generated if not set. | `""` +`sessionStorage.redis.cluster.connectionUrls` | List of Redis cluster connection URLs (e.g. `["redis://127.0.0.1:8000", "redis://127.0.0.1:8000"]`) | `[]` +`sessionStorage.redis.sentinel.existingSecret` | Name of the Kubernetes secret containing the redis sentinel password value (see also `sessionStorage.redis.sentinel.passwordKey`). Default: `sessionStorage.redis.existingSecret` | `""` +`sessionStorage.redis.sentinel.password` | Redis sentinel password. Used only for sentinel connection; any redis node passwords need to use `sessionStorage.redis.password` | `nil` +`sessionStorage.redis.sentinel.passwordKey` | Key of the Kubernetes secret data containing the redis sentinel password value | `redis-sentinel-password` +`sessionStorage.redis.sentinel.masterName` | Redis sentinel master name | `nil` +`sessionStorage.redis.sentinel.connectionUrls` | List of Redis sentinel connection URLs (e.g. `["redis://127.0.0.1:8000", "redis://127.0.0.1:8000"]`) | `[]` +`topologySpreadConstraints` | List of pod topology spread constraints | `[]` +`redis.enabled` | Enable the redis subchart deployment | `false` +`checkDeprecation` | Enable deprecation checks | `true` +`metrics.enabled` | Enable Prometheus metrics endpoint | `true` +`metrics.port` | Serve Prometheus metrics on this port | `44180` +`metrics.nodePort` | External port for the metrics when service.type is `NodePort` | `nil` +`metrics.service.appProtocol` | application protocol of the metrics port in the service | `http` +`metrics.serviceMonitor.enabled` | Enable Prometheus Operator ServiceMonitor | `false` +`metrics.serviceMonitor.namespace` | Define the namespace where to deploy the ServiceMonitor resource | `""` +`metrics.serviceMonitor.prometheusInstance` | Prometheus Instance definition | `default` +`metrics.serviceMonitor.interval` | Prometheus scrape interval | `60s` +`metrics.serviceMonitor.scrapeTimeout` | Prometheus scrape timeout | `30s` +`metrics.serviceMonitor.labels` | Add custom labels to the ServiceMonitor resource| `{}` +`metrics.serviceMonitor.scheme` | HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS.| `""` +`metrics.serviceMonitor.tlsConfig` | TLS configuration to use when scraping the endpoint. For example if using istio mTLS.| `{}` +`metrics.serviceMonitor.bearerTokenFile` | Path to bearer token file.| `""` +`metrics.serviceMonitor.annotations` | Used to pass annotations that are used by the Prometheus installed in your cluster| `{}` +`metrics.serviceMonitor.metricRelabelings` | Metric relabel configs to apply to samples before ingestion.| `[]` +`metrics.serviceMonitor.relabelings` | Relabel configs to apply to samples before ingestion.| `[]` +`extraObjects` | Extra K8s manifests to deploy | `[]` + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install my-release oauth2-proxy/oauth2-proxy \ + --set=image.tag=v0.0.2,resources.limits.cpu=200m +``` + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +$ helm install my-release oauth2-proxy/oauth2-proxy -f values.yaml +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## TLS Configuration + +See: [TLS Configuration](https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/tls). +Use ```values.yaml``` like: + +```yaml +... +extraArgs: + tls-cert-file: /path/to/cert.pem + tls-key-file: /path/to/cert.key + +extraVolumes: + - name: ssl-cert + secret: + secretName: my-ssl-secret + +extraVolumeMounts: + - mountPath: /path/to/ + name: ssl-cert +... +``` + +With a secret called `my-ssl-secret`: + +```yaml +... +data: + cert.pem: AB..== + cert.key: CD..== +``` + +## Extra environment variable templating +The extraEnv value supports the tpl function which evaluate strings as templates inside the deployment template. +This is useful to pass a template string as a value to the chart's extra environment variables and to render external configuration environment values + + +```yaml +... +tplValue: "This is a test value for the tpl function" +extraEnv: + - name: TEST_ENV_VAR_1 + value: test_value_1 + - name: TEST_ENV_VAR_2 + value: '{{ .Values.tplValue }}' +``` + +## Custom templates configuration +You can replace the default template files using a Kubernetes `configMap` volume. The default templates are the two files [sign_in.html](https://github.com/oauth2-proxy/oauth2-proxy/blob/master/pkg/app/pagewriter/sign_in.html) and [error.html](https://github.com/oauth2-proxy/oauth2-proxy/blob/master/pkg/app/pagewriter/error.html). + +```yaml +config: + configFile: | + ... + custom_templates_dir = "/data/custom-templates" + +extraVolumes: + - name: custom-templates + configMap: + name: oauth2-proxy-custom-templates + +extraVolumeMounts: + - name: custom-templates + mountPath: "/data/custom-templates" + readOnly: true + +extraObjects: + - apiVersion: v1 + kind: ConfigMap + metadata: + name: oauth2-proxy-custom-templates + data: + sign_in.html: | + <!DOCTYPE html> + <html> + <body>sign_in</body> + </html> + error.html: | + <!DOCTYPE html> + <html> + <body> + <h1>error</h1> + <p>{{.StatusCode}}</p> + </body> + </html> +``` +## Multi whitelist-domain configuration +For using multi whitelist-domain configuration for one Oauth2-proxy instance, you have to use the config.configFile section. + +It will be overwriting the `/etc/oauth2_proxy/oauth2_proxy.cfg` configuration file. +In this example, Google provider is used, but you can find all other provider configuration here [oauth_provider](https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/oauth_provider/) + +```yaml +config: + ... + clientID="$YOUR_GOOGLE_CLIENT_ID" + clientSecret="$YOUR_GOOGLE_CLIENT_SECRET" + cookieSecret="$YOUR_COOKIE_SECRET" + configFile: | + ... + email_domains = [ "*" ] + upstreams = [ "file:///dev/null" ] + cookie_secure = "false" + cookie_domains = [ ".domain.com", ".otherdomain.io" ] + whitelist_domains = [ ".domain.com", ".otherdomain.io"] + provider = "google" +``` diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/default-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/default-values.yaml new file mode 100644 index 0000000000..fc2ba605ad --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/default-values.yaml @@ -0,0 +1 @@ +# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/extra-args-as-dict-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/extra-args-as-dict-values.yaml new file mode 100644 index 0000000000..92dc451807 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/extra-args-as-dict-values.yaml @@ -0,0 +1,4 @@ +extraArgs: + pass-authorization-header: "true" + request-logging: "true" + allowed-role: client_id:client_role diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/extra-args-as-list-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/extra-args-as-list-values.yaml new file mode 100644 index 0000000000..5f47a5f479 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/extra-args-as-list-values.yaml @@ -0,0 +1,5 @@ +extraArgs: + - "--pass-authorization-header=true" + - "--request-logging=true" + - --allowed-role=client_id:client_role_A + - --allowed-role=client_id_B:client_role_C diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/extra-env-tpl-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/extra-env-tpl-values.yaml new file mode 100644 index 0000000000..357dba9153 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/extra-env-tpl-values.yaml @@ -0,0 +1,6 @@ +tplValue: "This is a test value for the template function" +extraEnv: + - name: TEST_ENV_VAR_1 + value: test_value_1 + - name: TEST_ENV_VAR_2 + value: '{{ .Values.tplValue }}' diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/ingress-extra-paths-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/ingress-extra-paths-values.yaml new file mode 100644 index 0000000000..e74a393db0 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/ingress-extra-paths-values.yaml @@ -0,0 +1,14 @@ +ingress: + enabled: true + path: / + pathType: ImplementationSpecific + hosts: + - chart-example.local + extraPaths: + - path: /* + pathType: ImplementationSpecific + backend: + service: + name: ssl-redirect + port: + name: use-annotation diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/pdb-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/pdb-values.yaml new file mode 100644 index 0000000000..25b16272a7 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/pdb-values.yaml @@ -0,0 +1 @@ +replicaCount: 2 # Enables PodDisruptionBudget which is disabled when replicaCount is 1 diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/pod-security-context-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/pod-security-context-values.yaml new file mode 100644 index 0000000000..b7c8cea546 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/pod-security-context-values.yaml @@ -0,0 +1,4 @@ +# Allocate a FSGroup that owns the pod’s volumes via podSecurityContext +--- +podSecurityContext: + fsGroup: 2000 diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/redis-standalone-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/redis-standalone-values.yaml new file mode 100644 index 0000000000..e58c32cf0c --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/redis-standalone-values.yaml @@ -0,0 +1,15 @@ +sessionStorage: + type: redis + redis: + clientType: "standalone" + password: "foo" +redis: + # provision an instance of the redis sub-chart + enabled: true + architecture: standalone + global: + redis: + password: "foo" +initContainers: + waitForRedis: + enabled: true diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/servicemonitor-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/servicemonitor-values.yaml new file mode 100644 index 0000000000..0c232bf5c1 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/servicemonitor-values.yaml @@ -0,0 +1,18 @@ +metrics: + enabled: true + serviceMonitor: + enabled: true + annotations: + key: value + metricRelabelings: + - action: keep + regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + sourceLabels: [__name__] + + relabelings: + - sourceLabels: [__meta_kubernetes_pod_node_name] + separator: ; + regex: ^(.*)$ + targetLabel: nodename + replacement: $1 + action: replace diff --git a/kubernetes/authentication/components/oauth2-proxy/ci/tpl-values.yaml b/kubernetes/authentication/components/oauth2-proxy/ci/tpl-values.yaml new file mode 100644 index 0000000000..65977d921b --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/ci/tpl-values.yaml @@ -0,0 +1,21 @@ +extraEnv: + - name: TEST_ENV_VAR_2 + value: '{{ $.Release.Name }}' +ingress: + enabled: true + hosts: + - "{{ $.Release.Name }}.local" + tls: + - hosts: + - "{{ $.Release.Name }}.local" +oauth2-proxy: + checkDeprecation: false + config: + clientSecret: '{{ $.Release.Name }}' + configFile: | + oidc_issuer_url = "https://{{ $.Release.Name }}/dex" + +pass_authorization_header: "true" + +extraArgs: + pass-authorization-header: "{{ $.Values.pass_authorization_header }}" diff --git a/kubernetes/authentication/components/oauth2-proxy/scripts/check-redis.sh b/kubernetes/authentication/components/oauth2-proxy/scripts/check-redis.sh new file mode 100644 index 0000000000..24e628f426 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/scripts/check-redis.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +RETRY_INTERVAL=5 # Interval between retries in seconds +elapsed=0 # Elapsed time + +check_redis() { + host=$1 + port=$2 + while [ $elapsed -lt $TOTAL_RETRY_TIME ]; do + echo "Checking Redis at $host:$port... Elapsed time: ${elapsed}s" + if nc -z -w1 $TIMEOUT $host $port > /dev/null 2>&1; then + echo "Redis is up at $host:$port!" + return 0 + else + echo "Redis is down at $host:$port. Retrying in $RETRY_INTERVAL seconds." + sleep $RETRY_INTERVAL + elapsed=$((elapsed + RETRY_INTERVAL)) + fi + done + echo "Failed to connect to Redis at $host:$port after $TOTAL_RETRY_TIME seconds." + return 1 +} + +# For parsing and checking connections +parse_and_check() { + url=$1 + clean_url=${url#redis://} + host=$(echo $clean_url | cut -d':' -f1) + port=$(echo $clean_url | cut -d':' -f2) + check_redis $host $port +} + +# Main +if [ -n "$OAUTH2_PROXY_REDIS_CLUSTER_CONNECTION_URLS" ]; then + echo "Checking Redis in cluster mode..." + echo "$OAUTH2_PROXY_REDIS_CLUSTER_CONNECTION_URLS" | tr ',' '\n' | while read -r addr; do + parse_and_check $addr || exit 1 + done +elif [ -n "$OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS" ]; then + echo "Checking Redis in sentinel mode..." + echo "$OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS" | tr ',' '\n' | while read -r addr; do + parse_and_check $addr || exit 1 + done +elif [ -n "$OAUTH2_PROXY_REDIS_CONNECTION_URL" ]; then + echo "Checking standalone Redis..." + parse_and_check "$OAUTH2_PROXY_REDIS_CONNECTION_URL" || exit 1 +else + echo "Redis configuration not specified." + exit 1 +fi + +echo "Redis check completed." diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/NOTES.txt b/kubernetes/authentication/components/oauth2-proxy/templates/NOTES.txt new file mode 100644 index 0000000000..36ded35867 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/NOTES.txt @@ -0,0 +1,3 @@ +To verify that oauth2-proxy has started, run: + + kubectl --namespace={{ template "oauth2-proxy.namespace" $ }} get pods -l "app={{ template "oauth2-proxy.name" . }}" diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/_capabilities.tpl b/kubernetes/authentication/components/oauth2-proxy/templates/_capabilities.tpl new file mode 100644 index 0000000000..f959f10e49 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/_capabilities.tpl @@ -0,0 +1,23 @@ +{{/* +Returns the appropriate apiVersion for podDisruptionBudget object. +*/}} +{{- define "capabilities.podDisruptionBudget.apiVersion" -}} +{{- if semverCompare ">=1.21-0" ( .Values.kubeVersion | default .Capabilities.KubeVersion.Version ) -}} +{{- print "policy/v1" -}} +{{- else -}} +{{- print "policy/v1beta1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress object. +*/}} +{{- define "capabilities.ingress.apiVersion" -}} +{{- if semverCompare "<1.14-0" ( .Values.kubeVersion | default .Capabilities.KubeVersion.Version ) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" ( .Values.kubeVersion | default .Capabilities.KubeVersion.Version ) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/_helpers.tpl b/kubernetes/authentication/components/oauth2-proxy/templates/_helpers.tpl new file mode 100644 index 0000000000..6a9bbb320d --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/_helpers.tpl @@ -0,0 +1,161 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "oauth2-proxy.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 "oauth2-proxy.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 "oauth2-proxy.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Generate basic labels +*/}} +{{- define "oauth2-proxy.labels" }} +helm.sh/chart: {{ include "oauth2-proxy.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: authentication-proxy +app.kubernetes.io/part-of: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "oauth2-proxy.selectorLabels" }} +app.kubernetes.io/name: {{ include "oauth2-proxy.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Get the secret name. +*/}} +{{- define "oauth2-proxy.secretName" -}} +{{- if .Values.config.existingSecret -}} +{{- printf "%s" .Values.config.existingSecret -}} +{{- else -}} +{{- printf "%s" (include "oauth2-proxy.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "oauth2-proxy.serviceAccountName" -}} +{{- if .Values.serviceAccount.enabled -}} + {{ default (include "oauth2-proxy.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "oauth2-proxy.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Redis subcharts fullname +*/}} +{{- define "oauth2-proxy.redis.fullname" -}} +{{- if .Values.redis.enabled -}} +{{- include "common.names.fullname" (dict "Chart" (dict "Name" "redis") "Release" .Release "Values" .Values.redis) -}} +{{- else -}} +{{ fail "attempting to use redis subcharts fullname, even though the subchart is not enabled. This will lead to misconfiguration" }} +{{- end -}} +{{- end -}} + +{{/* +Compute the redis url if not set explicitly. +*/}} +{{- define "oauth2-proxy.redis.StandaloneUrl" -}} +{{- if .Values.sessionStorage.redis.standalone.connectionUrl -}} +{{ .Values.sessionStorage.redis.standalone.connectionUrl }} +{{- else if .Values.redis.enabled -}} +{{- printf "redis://%s-master:%.0f" (include "oauth2-proxy.redis.fullname" .) .Values.redis.master.service.ports.redis -}} +{{- else -}} +{{ fail "please set sessionStorage.redis.standalone.connectionUrl or enable the redis subchart via redis.enabled" }} +{{- end -}} +{{- end -}} + +{{/* +Returns the version +*/}} +{{- define "oauth2-proxy.version" -}} +{{ .Values.image.tag | default (printf "v%s" .Chart.AppVersion) }} +{{- end -}} + +{{/* +Returns the kubectl version +Workaround for EKS https://github.com/aws/eks-distro/issues/1128 +*/}} +{{- define "kubectl.version" -}} +{{- if .Values.initContainers.waitForRedis.kubectlVersion -}} +{{ .Values.initContainers.waitForRedis.kubectlVersion }} +{{- else -}} +{{- printf "%s.%s" .Capabilities.KubeVersion.Major (.Capabilities.KubeVersion.Minor | replace "+" "") -}} +{{- end -}} +{{- end -}} + +{{- define "oauth2-proxy.alpha-config" -}} +--- +server: + BindAddress: '0.0.0.0:4180' +{{- if .Values.alphaConfig.serverConfigData }} +{{- toYaml .Values.alphaConfig.serverConfigData | nindent 2 }} +{{- end }} +{{- if .Values.metrics.enabled }} +metricsServer: + BindAddress: '0.0.0.0:44180' +{{- if .Values.alphaConfig.metricsConfigData }} +{{- toYaml .Values.alphaConfig.metricsConfigData | nindent 2 }} +{{- end }} +{{- end }} +{{- if .Values.alphaConfig.configData }} +{{- toYaml .Values.alphaConfig.configData | nindent 0 }} +{{- end }} +{{- if .Values.alphaConfig.configFile }} +{{- tpl .Values.alphaConfig.configFile $ | nindent 0 }} +{{- end }} +{{- end -}} + +{{- define "oauth2-proxy.secrets" -}} +cookie-secret: {{ tpl .Values.config.cookieSecret $ | b64enc | quote }} +client-secret: {{ tpl .Values.config.clientSecret $ | b64enc | quote }} +client-id: {{ tpl .Values.config.clientID $ | b64enc | quote }} +{{- end -}} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/_ingress.tpl b/kubernetes/authentication/components/oauth2-proxy/templates/_ingress.tpl new file mode 100644 index 0000000000..f4a3cad0e4 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/_ingress.tpl @@ -0,0 +1,46 @@ +{{/* +Returns `true` if the API `ingressClassName` field is supported and `false` otherwise +*/}} +{{- define "ingress.supportsIngressClassName" -}} +{{- if ( semverCompare "<1.18-0" ( .Values.kubeVersion | default .Capabilities.KubeVersion.Version ) ) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns `true` if the API `pathType` field is supported and `false` otherwise +*/}} +{{- define "ingress.supportsPathType" -}} +{{- if ( semverCompare "<1.18-0" ( .Values.kubeVersion | default .Capabilities.KubeVersion.Version ) ) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns the appropriate ingress `backend` fields depending on the Kubernetes API version. +e.g.: `{{ include "common.ingress.backend" (dict "serviceName" "backendName" "servicePort" "backendPort" "context" $) }}` +Where the dict must contain the following entries: +- `serviceName` {String} - Name of an existing service backend +- `servicePort` {String|Number} - Port name or port number of the service. +- `context` {Dict} - (Parent) Context for the template evaluation required for the API version detection. +*/}} +{{- define "ingress.backend" -}} +{{- $apiVersion := ( include "capabilities.ingress.apiVersion" .context ) -}} +{{- if or ( eq $apiVersion "extensions/v1beta1" ) ( eq $apiVersion "networking.k8s.io/v1beta1" ) -}} +serviceName: {{ .serviceName }} +servicePort: {{ .servicePort }} +{{- else -}} +service: + name: {{ .serviceName }} + port: + {{- if typeIs "string" .servicePort }} + name: {{ .servicePort }} + {{- else if or ( typeIs "int" .servicePort ) ( typeIs "float64" .servicePort ) }} + number: {{ .servicePort }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/configmap-authenticated-emails-file.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/configmap-authenticated-emails-file.yaml new file mode 100644 index 0000000000..d9f9cffef7 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/configmap-authenticated-emails-file.yaml @@ -0,0 +1,18 @@ +{{- if .Values.authenticatedEmailsFile.enabled }} +{{- if and (.Values.authenticatedEmailsFile.restricted_access) (eq .Values.authenticatedEmailsFile.persistence "configmap") }} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} +{{- if .Values.authenticatedEmailsFile.annotations }} + annotations: +{{ toYaml .Values.authenticatedEmailsFile.annotations | indent 4 }} +{{- end }} + name: {{ template "oauth2-proxy.fullname" . }}-accesslist + namespace: {{ template "oauth2-proxy.namespace" $ }} +data: + {{ default "restricted_user_access" .Values.authenticatedEmailsFile.restrictedUserAccessKey }}: {{ .Values.authenticatedEmailsFile.restricted_access | quote }} +{{- end }} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/configmap-wait-for-redis.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/configmap-wait-for-redis.yaml new file mode 100644 index 0000000000..721048d786 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/configmap-wait-for-redis.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.redis.enabled .Values.initContainers.waitForRedis.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.fullname" . }}-wait-for-redis + namespace: {{ template "oauth2-proxy.namespace" $ }} +data: + check-redis.sh: | +{{ .Files.Get "scripts/check-redis.sh" | indent 4 }} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/configmap.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/configmap.yaml new file mode 100644 index 0000000000..94d7806d2e --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/configmap.yaml @@ -0,0 +1,18 @@ +{{- if not .Values.config.existingConfig }} +{{- if .Values.config.configFile }} +apiVersion: v1 +kind: ConfigMap +metadata: +{{- if .Values.config.annotations }} + annotations: +{{ toYaml .Values.config.annotations | indent 4 }} +{{- end }} + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.fullname" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +data: + oauth2_proxy.cfg: {{ tpl .Values.config.configFile $ | quote }} +{{- end }} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/deployment.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/deployment.yaml new file mode 100644 index 0000000000..1a626d1ab8 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/deployment.yaml @@ -0,0 +1,406 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + {{- if .Values.deploymentAnnotations }} + annotations: +{{ toYaml .Values.deploymentAnnotations | indent 8 }} + {{- end }} + name: {{ template "oauth2-proxy.fullname" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +spec: + replicas: {{ .Values.replicaCount }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- with .Values.strategy }} + strategy: + {{ toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "oauth2-proxy.selectorLabels" . | indent 6 }} + template: + metadata: + annotations: + checksum/config: {{ tpl .Values.config.configFile $ | sha256sum }} + {{- if .Values.alphaConfig.enabled }} + checksum/alpha-config: {{ include "oauth2-proxy.alpha-config" . | sha256sum }} + {{- end }} + {{- if .Values.authenticatedEmailsFile.enabled }} + checksum/config-emails: {{ include (print $.Template.BasePath "/configmap-authenticated-emails-file.yaml") . | sha256sum }} + {{- end }} + checksum/secret: {{ include "oauth2-proxy.secrets" . | sha256sum }} + checksum/google-secret: {{ include (print $.Template.BasePath "/google-secret.yaml") . | sha256sum }} + checksum/redis-secret: {{ include (print $.Template.BasePath "/redis-secret.yaml") . | sha256sum }} +{{- if .Values.htpasswdFile.enabled }} + checksum/htpasswd: {{ toYaml .Values.htpasswdFile.entries | sha256sum }} +{{- end }} + {{- if .Values.podAnnotations }} +{{ toYaml .Values.podAnnotations | indent 8 }} + {{- end }} + labels: + app: {{ template "oauth2-proxy.name" . }} + {{- include "oauth2-proxy.labels" . | indent 8 }} + {{- if .Values.podLabels }} +{{ toYaml .Values.podLabels | indent 8 }} + {{- end }} + spec: + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "oauth2-proxy.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{- if .Values.hostAliases }} + hostAliases: + {{ toYaml .Values.hostAliases | nindent 8}} + {{- end }} + {{- if and .Values.redis.enabled .Values.initContainers.waitForRedis.enabled }} + initContainers: + - name: wait-for-redis + #image: "{{ .Values.initContainers.waitForRedis.image.repository }}:{{ .Values.initContainers.waitForRedis.image.tag }}" + image: "{{ include "repositoryGenerator.dockerHubRepository" . }}/{{ .Values.initContainers.waitForRedis.image.repository }}:{{ .Values.initContainers.waitForRedis.image.tag }}" + imagePullPolicy: {{ .Values.initContainers.waitForRedis.image.pullPolicy }} + command: ["/bin/sh", "-c", "/scripts/check-redis.sh"] + env: + - name: TOTAL_RETRY_TIME + value: "{{ .Values.initContainers.waitForRedis.timeout }}" + {{- if eq (default "" .Values.sessionStorage.redis.clientType) "standalone" }} + - name: OAUTH2_PROXY_REDIS_CONNECTION_URL + value: {{ include "oauth2-proxy.redis.StandaloneUrl" . }} + {{- else if eq (default "" .Values.sessionStorage.redis.clientType) "cluster" }} + - name: OAUTH2_PROXY_REDIS_USE_CLUSTER + value: "true" + - name: OAUTH2_PROXY_REDIS_CLUSTER_CONNECTION_URLS + value: {{ .Values.sessionStorage.redis.cluster.connectionUrls }} + {{- else if eq (default "" .Values.sessionStorage.redis.clientType) "sentinel" }} + - name: OAUTH2_PROXY_REDIS_USE_SENTINEL + value: "true" + - name: OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS + value: {{ .Values.sessionStorage.redis.sentinel.connectionUrls }} + {{- end }} + {{- if .Values.initContainers.waitForRedis.securityContext.enabled }} + {{- $securityContext := unset .Values.initContainers.waitForRedis.securityContext "enabled" }} + securityContext: + {{- toYaml $securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.initContainers.waitForRedis.resources | nindent 10 }} + volumeMounts: + - name: redis-script + mountPath: /scripts + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ include "repositoryGenerator.quayRepository" . }}/{{ .Values.image.repository }}:{{ include "oauth2-proxy.version" . }}" + #image: "{{ .Values.image.repository }}:{{ include "oauth2-proxy.version" . }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + {{- if .Values.alphaConfig.enabled }} + - --alpha-config=/etc/oauth2_proxy/oauth2_proxy.yml + {{- else }} + - --http-address=0.0.0.0:4180 + - --https-address=0.0.0.0:4443 + {{- if .Values.metrics.enabled }} + - --metrics-address=0.0.0.0:44180 + {{- end }} + {{- end }} + {{- if .Values.config.cookieName }} + - --cookie-name={{ .Values.config.cookieName }} + {{- end }} + {{- if kindIs "map" .Values.extraArgs }} + {{- range $key, $value := .Values.extraArgs }} + {{- if not (kindIs "invalid" $value) }} + - --{{ $key }}={{ tpl ($value | toString) $ }} + {{- else }} + - --{{ $key }} + {{- end }} + {{- end }} + {{- end }} + {{- if kindIs "slice" .Values.extraArgs }} + {{- with .Values.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + {{- if or .Values.config.existingConfig .Values.config.configFile }} + - --config=/etc/oauth2_proxy/oauth2_proxy.cfg + {{- end }} + {{- if .Values.authenticatedEmailsFile.enabled }} + {{- if .Values.authenticatedEmailsFile.template }} + - --authenticated-emails-file=/etc/oauth2-proxy/{{ .Values.authenticatedEmailsFile.template }} + {{- else }} + - --authenticated-emails-file=/etc/oauth2-proxy/authenticated-emails-list + {{- end }} + {{- end }} + {{- with .Values.config.google }} + {{- if and .adminEmail (or .serviceAccountJson .existingSecret .useApplicationDefaultCredentials) }} + - --google-admin-email={{ .adminEmail }} + {{- if .useApplicationDefaultCredentials }} + - --google-use-application-default-credentials=true + {{- else }} + - --google-service-account-json=/google/service-account.json + {{- end }} + {{- if .targetPrincipal }} + - --google-target-principal={{ .targetPrincipal }} + {{- end }} + {{- end }} + {{- if .groups }} + {{- range $group := .groups }} + - --google-group={{ $group }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.htpasswdFile.enabled }} + - --htpasswd-file=/etc/oauth2_proxy/htpasswd/users.txt + {{- end }} +{{- if .Values.lifecycle }} + lifecycle: +{{ toYaml .Values.lifecycle | indent 10 }} +{{- end }} + env: + {{- if .Values.proxyVarsAsSecrets }} + - name: OAUTH2_PROXY_CLIENT_ID + valueFrom: + secretKeyRef: + name: {{ template "oauth2-proxy.secretName" . }} + key: client-id + - name: OAUTH2_PROXY_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ template "oauth2-proxy.secretName" . }} + key: client-secret + - name: OAUTH2_PROXY_COOKIE_SECRET + valueFrom: + secretKeyRef: + name: {{ template "oauth2-proxy.secretName" . }} + key: cookie-secret + {{- end }} + {{- if eq (default "cookie" .Values.sessionStorage.type) "redis" }} + - name: OAUTH2_PROXY_SESSION_STORE_TYPE + value: "redis" + {{- if or .Values.sessionStorage.redis.existingSecret .Values.sessionStorage.redis.password (and .Values.redis.enabled (.Values.redis.auth).enabled )}} + - name: OAUTH2_PROXY_REDIS_PASSWORD + valueFrom: + secretKeyRef: + {{- if .Values.sessionStorage.redis.existingSecret }} + name: {{ .Values.sessionStorage.redis.existingSecret }} + {{- else if .Values.sessionStorage.redis.password }} + name: {{ template "oauth2-proxy.fullname" . }}-redis-access + {{- else }} + name: {{ include "oauth2-proxy.redis.fullname" . }} + {{- end }} + key: {{ .Values.sessionStorage.redis.passwordKey }} + {{- end }} + {{- if eq (default "" .Values.sessionStorage.redis.clientType) "standalone" }} + - name: OAUTH2_PROXY_REDIS_CONNECTION_URL + value: {{ include "oauth2-proxy.redis.StandaloneUrl" . }} + {{- else if eq (default "" .Values.sessionStorage.redis.clientType) "cluster" }} + - name: OAUTH2_PROXY_REDIS_USE_CLUSTER + value: "true" + - name: OAUTH2_PROXY_REDIS_CLUSTER_CONNECTION_URLS + value: {{ .Values.sessionStorage.redis.cluster.connectionUrls }} + {{- else if eq (default "" .Values.sessionStorage.redis.clientType) "sentinel" }} + - name: OAUTH2_PROXY_REDIS_USE_SENTINEL + value: "true" + - name: OAUTH2_PROXY_REDIS_SENTINEL_MASTER_NAME + value: {{ .Values.sessionStorage.redis.sentinel.masterName }} + - name: OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS + value: {{ .Values.sessionStorage.redis.sentinel.connectionUrls }} + {{- if or .Values.sessionStorage.redis.sentinel.existingSecret .Values.sessionStorage.redis.existingSecret .Values.sessionStorage.redis.sentinel.password }} + - name: OAUTH2_PROXY_REDIS_SENTINEL_PASSWORD + valueFrom: + secretKeyRef: + {{- if or .Values.sessionStorage.redis.sentinel.existingSecret .Values.sessionStorage.redis.existingSecret }} + name: {{ .Values.sessionStorage.redis.sentinel.existingSecret | default .Values.sessionStorage.redis.existingSecret }} + {{- else }} + name: {{ template "oauth2-proxy.fullname" . }}-redis-access + {{- end }} + key: {{ .Values.sessionStorage.redis.sentinel.passwordKey }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.extraEnv }} +{{ tpl (toYaml .Values.extraEnv) . | indent 8 }} + {{- end }} + {{- if .Values.envFrom }} + envFrom: +{{ tpl (toYaml .Values.envFrom) . | indent 8 }} + {{- end }} + ports: + {{- if .Values.containerPort }} + - containerPort: {{ .Values.containerPort }} + {{- else if (and (eq .Values.httpScheme "http") (empty .Values.containerPort)) }} + - containerPort: 4180 + {{- else if (and (eq .Values.httpScheme "https") (empty .Values.containerPort)) }} + - containerPort: 4443 + {{- else }} + {{- end}} + name: {{ .Values.httpScheme }} + protocol: TCP +{{- if .Values.metrics.enabled }} + - containerPort: 44180 + protocol: TCP + name: metrics +{{- end }} +{{- if .Values.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /ping + port: {{ .Values.httpScheme }} + scheme: {{ .Values.httpScheme | upper }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} +{{- end }} +{{- if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ if gt (include "oauth2-proxy.version" .) "7.4.0" }}/ready{{ else }}/ping{{ end }} + port: {{ .Values.httpScheme }} + scheme: {{ .Values.httpScheme | upper }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} +{{- end }} + resources: +{{ toYaml .Values.resources | indent 10 }} + volumeMounts: +{{- with .Values.config.google }} +{{- if and .adminEmail (or .serviceAccountJson .existingSecret) }} + - name: google-secret + mountPath: /google + readOnly: true +{{- end }} +{{- end }} +{{- if or .Values.config.existingConfig .Values.config.configFile }} + - mountPath: /etc/oauth2_proxy/oauth2_proxy.cfg + name: configmain + subPath: oauth2_proxy.cfg +{{- end }} +{{- if .Values.alphaConfig.enabled }} + - mountPath: /etc/oauth2_proxy/oauth2_proxy.yml + name: configalpha + subPath: oauth2_proxy.yml +{{- end }} +{{- if .Values.authenticatedEmailsFile.enabled }} + - mountPath: /etc/oauth2-proxy + name: configaccesslist + readOnly: true +{{- end }} +{{- if .Values.htpasswdFile.enabled }} + - mountPath: /etc/oauth2_proxy/htpasswd + name: {{ template "oauth2-proxy.fullname" . }}-htpasswd-file + readOnly: true +{{- end }} +{{- if ne (len .Values.extraVolumeMounts) 0 }} +{{ toYaml .Values.extraVolumeMounts | indent 8 }} +{{- end }} +{{- if .Values.securityContext.enabled }} +{{- $securityContext := unset .Values.securityContext "enabled" }} + securityContext: + {{- toYaml $securityContext | nindent 10 }} +{{- end }} +{{- if .Values.extraContainers }} + {{- toYaml .Values.extraContainers | nindent 6 }} +{{- end }} + volumes: +{{- with .Values.config.google }} +{{- if and .adminEmail (or .serviceAccountJson .existingSecret) }} + - name: google-secret + secret: + secretName: {{ if .existingSecret }}{{ .existingSecret }}{{ else }} {{ template "oauth2-proxy.secretName" $ }}-google{{ end }} +{{- end }} +{{- end }} + +{{- if .Values.htpasswdFile.enabled }} + - name: {{ template "oauth2-proxy.fullname" . }}-htpasswd-file + secret: + secretName: {{ if .Values.htpasswdFile.existingSecret }}{{ .Values.htpasswdFile.existingSecret }}{{ else }} {{ template "oauth2-proxy.fullname" . }}-htpasswd-file {{ end }} +{{- end }} + +{{- if and (.Values.authenticatedEmailsFile.enabled) (eq .Values.authenticatedEmailsFile.persistence "secret") }} + - name: configaccesslist + secret: + items: + - key: {{ default "restricted_user_access" .Values.authenticatedEmailsFile.restrictedUserAccessKey }} +{{- if .Values.authenticatedEmailsFile.template }} + path: {{ .Values.authenticatedEmailsFile.template }} +{{- else }} + path: authenticated-emails-list +{{- end }} +{{- if .Values.authenticatedEmailsFile.template }} + secretName: {{ .Values.authenticatedEmailsFile.template }} +{{- else }} + secretName: {{ template "oauth2-proxy.fullname" . }}-accesslist +{{- end }} +{{- end }} +{{- if and .Values.redis.enabled .Values.initContainers.waitForRedis.enabled }} + - name: redis-script + configMap: + name: {{ template "oauth2-proxy.fullname" . }}-wait-for-redis + defaultMode: 0775 +{{- end }} +{{- if or .Values.config.existingConfig .Values.config.configFile }} + - configMap: + defaultMode: 420 + name: {{ if .Values.config.existingConfig }}{{ .Values.config.existingConfig }}{{ else }}{{ template "oauth2-proxy.fullname" . }}{{ end }} + name: configmain +{{- end }} +{{- if .Values.alphaConfig.enabled }} +{{- if .Values.alphaConfig.existingConfig }} + - configMap: + defaultMode: 420 + name: {{ .Values.alphaConfig.existingConfig }} + name: configalpha +{{- else }} + - secret: + defaultMode: 420 + secretName: {{ if .Values.alphaConfig.existingSecret }}{{ .Values.alphaConfig.existingSecret }}{{ else }}{{ template "oauth2-proxy.fullname" . }}-alpha{{ end }} + name: configalpha +{{- end }} +{{- end }} +{{- if ne (len .Values.extraVolumes) 0 }} +{{ toYaml .Values.extraVolumes | indent 6 }} +{{- end }} +{{- if and (.Values.authenticatedEmailsFile.enabled) (eq .Values.authenticatedEmailsFile.persistence "configmap") }} + - configMap: +{{- if .Values.authenticatedEmailsFile.template }} + name: {{ .Values.authenticatedEmailsFile.template }} +{{- else }} + name: {{ template "oauth2-proxy.fullname" . }}-accesslist +{{- end }} + items: + - key: {{ default "restricted_user_access" .Values.authenticatedEmailsFile.restrictedUserAccessKey }} +{{- if .Values.authenticatedEmailsFile.template }} + path: {{ .Values.authenticatedEmailsFile.template }} +{{- else }} + path: authenticated-emails-list +{{- end }} + name: configaccesslist +{{- end }} + + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/deprecation.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/deprecation.yaml new file mode 100644 index 0000000000..126d3e7a18 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/deprecation.yaml @@ -0,0 +1,12 @@ +{{- if .Values.checkDeprecation }} + {{- if .Values.service.port }} + {{ fail "`service.port` does no longer exist. It has been renamed to `service.portNumber`" }} + {{- end }} + {{- if eq ( include "capabilities.ingress.apiVersion" . ) "networking.k8s.io/v1" -}} + {{- range .Values.ingress.extraPaths }} + {{- if or (.backend.serviceName) (.backend.servicePort) }} + {{ fail "Please update the format of your `ingress.extraPaths` to the new ingress apiVersion `networking.k8s.io/v1` format" }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/extra-manifests.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/extra-manifests.yaml new file mode 100644 index 0000000000..a9bb3b6ba8 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/google-secret.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/google-secret.yaml new file mode 100644 index 0000000000..30a9ae1bb6 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/google-secret.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.config.google (and (not .Values.config.google.existingSecret) (not .Values.config.google.useApplicationDefaultCredentials)) }} +apiVersion: v1 +kind: Secret +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.fullname" . }}-google + namespace: {{ template "oauth2-proxy.namespace" $ }} +type: Opaque +data: + service-account.json: {{ .Values.config.google.serviceAccountJson | b64enc | quote }} +{{- end -}} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/ingress.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/ingress.yaml new file mode 100644 index 0000000000..5323820487 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/ingress.yaml @@ -0,0 +1,44 @@ +{{- if .Values.ingress.enabled -}} +{{- $serviceName := include "oauth2-proxy.fullname" . -}} +{{- $servicePort := .Values.service.portNumber -}} +{{- $ingressPath := .Values.ingress.path -}} +{{- $ingressPathType := .Values.ingress.pathType -}} +{{- $extraPaths := .Values.ingress.extraPaths -}} +apiVersion: {{ include "capabilities.ingress.apiVersion" . }} +kind: Ingress +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} + {{- include "oauth2-proxy.labels" . | indent 4 }} +{{- if .Values.ingress.labels }} +{{ toYaml .Values.ingress.labels | indent 4 }} +{{- end }} + name: {{ template "oauth2-proxy.fullname" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +{{- with .Values.ingress.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + {{- if and .Values.ingress.className ( eq "true" ( include "ingress.supportsIngressClassName" . ) ) }} + ingressClassName: {{ .Values.ingress.className | quote }} + {{- end }} + rules: + {{- range $host := .Values.ingress.hosts }} + - host: {{ tpl $host $ | quote }} + http: + paths: +{{- if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: {{ $ingressPath }} + {{- if eq "true" ( include "ingress.supportsPathType" $ ) }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: {{- include "ingress.backend" ( dict "serviceName" $serviceName "servicePort" $servicePort "context" $ ) | nindent 14 }} + {{- end -}} + {{- if .Values.ingress.tls }} + tls: +{{ tpl (toYaml .Values.ingress.tls) $ | indent 4 }} + {{- end -}} +{{- end -}} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/poddisruptionbudget.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000000..1fc8ecc005 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/poddisruptionbudget.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.podDisruptionBudget.enabled (gt (.Values.replicaCount | int) 1) }} +apiVersion: {{ include "capabilities.podDisruptionBudget.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.fullname" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +spec: + selector: + matchLabels: + {{- include "oauth2-proxy.selectorLabels" . | indent 6 }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/redis-secret.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/redis-secret.yaml new file mode 100644 index 0000000000..202e9243e3 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/redis-secret.yaml @@ -0,0 +1,23 @@ +{{- $name := include "oauth2-proxy.name" . -}} +{{- $fullName := include "oauth2-proxy.fullname" . -}} +{{- $labels := include "oauth2-proxy.labels" . -}} +{{- with .Values.sessionStorage }} +{{- if and (eq .type "redis") (not .redis.existingSecret) (or .redis.password .redis.sentinel.password) }} +apiVersion: v1 +kind: Secret +metadata: + labels: + app: {{ $name }} + {{- $labels | indent 4 }} + name: {{ $fullName }}-redis-access + namespace: {{ template "oauth2-proxy.namespace" $ }} +type: Opaque +data: + {{- if and .redis.password (not .redis.existingSecret) }} + {{ .redis.passwordKey }}: {{ .redis.password | b64enc | quote }} + {{- end }} + {{- if and .redis.sentinel.password (not .redis.sentinel.existingSecret) (ne .redis.sentinel.passwordKey .redis.passwordKey) }} + {{ .redis.sentinel.passwordKey }}: {{ .redis.sentinel.password | b64enc | quote }} + {{- end }} +{{- end }} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/secret-alpha.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/secret-alpha.yaml new file mode 100644 index 0000000000..15bb89338e --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/secret-alpha.yaml @@ -0,0 +1,20 @@ +{{- + if and + .Values.alphaConfig.enabled + (not .Values.alphaConfig.existingConfig) + (not .Values.alphaConfig.existingSecret) +}} +apiVersion: v1 +kind: Secret +metadata: +{{- if .Values.alphaConfig.annotations }} + annotations: {{- toYaml .Values.alphaConfig.annotations | nindent 4 }} +{{- end }} + labels: + app: {{ template "oauth2-proxy.name" . }} + {{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.fullname" . }}-alpha + namespace: {{ template "oauth2-proxy.namespace" $ }} +data: + oauth2_proxy.yml: {{ include "oauth2-proxy.alpha-config" . | b64enc | quote }} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/secret-authenticated-emails-file.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/secret-authenticated-emails-file.yaml new file mode 100644 index 0000000000..95f85a8006 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/secret-authenticated-emails-file.yaml @@ -0,0 +1,19 @@ +{{- if .Values.authenticatedEmailsFile.enabled }} +{{- if and (.Values.authenticatedEmailsFile.restricted_access) (eq .Values.authenticatedEmailsFile.persistence "secret") }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} +{{- if .Values.authenticatedEmailsFile.annotations }} + annotations: +{{ toYaml .Values.authenticatedEmailsFile.annotations | indent 4 }} +{{- end }} + name: {{ template "oauth2-proxy.fullname" . }}-accesslist + namespace: {{ template "oauth2-proxy.namespace" $ }} +data: + {{ default "restricted_user_access" .Values.authenticatedEmailsFile.restrictedUserAccessKey }}: {{ .Values.authenticatedEmailsFile.restricted_access | b64enc }} +{{- end }} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/secret-htpasswd-file.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/secret-htpasswd-file.yaml new file mode 100644 index 0000000000..c5ea330ff7 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/secret-htpasswd-file.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.htpasswdFile.enabled (not .Values.htpasswdFile.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.fullname" . }}-htpasswd-file + namespace: {{ template "oauth2-proxy.namespace" $ }} +type: Opaque +stringData: + users.txt: |- + {{- range $entries := .Values.htpasswdFile.entries }} + {{ $entries }} + {{- end -}} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/secret.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/secret.yaml new file mode 100644 index 0000000000..f3364e95a9 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/secret.yaml @@ -0,0 +1,17 @@ +{{- if and (not .Values.config.existingSecret) (.Values.proxyVarsAsSecrets) }} +apiVersion: v1 +kind: Secret +metadata: +{{- if .Values.config.annotations }} + annotations: +{{ toYaml .Values.config.annotations | indent 4 }} +{{- end }} + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.fullname" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +type: Opaque +data: +{{- include "oauth2-proxy.secrets" . | nindent 2 }} +{{- end -}} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/service.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/service.yaml new file mode 100644 index 0000000000..d16120ee91 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/service.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.fullname" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +{{- end }} +spec: +{{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} + type: ClusterIP + {{- if .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{end}} +{{- else if eq .Values.service.type "LoadBalancer" }} + type: {{ .Values.service.type }} + {{- if .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} + {{- end -}} +{{- else }} + type: {{ .Values.service.type }} +{{- end }} + ports: + - port: {{ .Values.service.portNumber }} + targetPort: {{ .Values.httpScheme }} + {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + protocol: TCP + {{- with .Values.service.appProtocol }} + appProtocol: {{ . }} + {{- end }} + name: {{ .Values.httpScheme }} + {{- if and .Values.metrics.enabled .Values.metrics.port }} + - port: {{ .Values.metrics.port }} + protocol: TCP + {{- with .Values.metrics.service.appProtocol }} + appProtocol: {{ . }} + {{- end }} + targetPort: metrics + {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.metrics.nodePort))) }} + nodePort: {{ .Values.metrics.nodePort }} + {{- end }} + name: metrics + {{- end }} + selector: + {{- include "oauth2-proxy.selectorLabels" . | indent 4 }} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/serviceaccount.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/serviceaccount.yaml new file mode 100644 index 0000000000..2a89c4b9e3 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/serviceaccount.yaml @@ -0,0 +1,60 @@ +{{- if or .Values.serviceAccount.enabled -}} +{{- $fullName := include "oauth2-proxy.fullname" . -}} +{{- $saName := include "oauth2-proxy.serviceAccountName" . -}} +{{- $name := include "oauth2-proxy.name" . -}} +{{- $namespace := include "oauth2-proxy.namespace" $ -}} +{{- $labels := include "oauth2-proxy.labels" . -}} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ $name }} +{{- $labels | indent 4 }} + name: {{ $saName }} + namespace: {{ $namespace }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- if and .Values.redis.enabled .Values.initContainers.waitForRedis.enabled }} +--- +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ $fullName }}-watch-redis + namespace: {{ $namespace }} + labels: + app: {{ $name }} + {{- $labels | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - pods + resourceNames: + - "{{ include "oauth2-proxy.redis.fullname" . }}-master-0" + verbs: + - get + - list + - watch +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ $saName }}-watch-redis + namespace: {{ $namespace }} + labels: + app: {{ $name }} + {{- $labels | nindent 4 }} +subjects: +- kind: ServiceAccount + name: {{ $saName }} + apiGroup: "" +roleRef: + kind: Role + name: {{ $fullName }}-watch-redis + apiGroup: "" +{{- end -}} +{{- end -}} diff --git a/kubernetes/authentication/components/oauth2-proxy/templates/servicemonitor.yaml b/kubernetes/authentication/components/oauth2-proxy/templates/servicemonitor.yaml new file mode 100644 index 0000000000..3802666be0 --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/templates/servicemonitor.yaml @@ -0,0 +1,57 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + {{- with .Values.metrics.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "oauth2-proxy.fullname" . }} +{{- if .Values.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.metrics.serviceMonitor.namespace }} +{{- else }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +{{- end }} + labels: + prometheus: {{ .Values.metrics.serviceMonitor.prometheusInstance }} + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} +{{- if .Values.metrics.serviceMonitor.labels }} +{{ toYaml .Values.metrics.serviceMonitor.labels | indent 4}} +{{- end }} +spec: + jobLabel: {{ template "oauth2-proxy.fullname" . }} + selector: + matchLabels: + {{- include "oauth2-proxy.selectorLabels" . | indent 6 }} + namespaceSelector: + matchNames: + - {{ template "oauth2-proxy.namespace" $ }} + endpoints: + - port: metrics + path: "/metrics" + {{- with .Values.metrics.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.bearerTokenFile }} + bearerTokenFile: {{ . }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml .| nindent 6 }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/kubernetes/authentication/components/oauth2-proxy/values.yaml b/kubernetes/authentication/components/oauth2-proxy/values.yaml new file mode 100644 index 0000000000..f49cb638fa --- /dev/null +++ b/kubernetes/authentication/components/oauth2-proxy/values.yaml @@ -0,0 +1,478 @@ +global: + quayRepository: quay.io + dockerHubRepository: docker.io + # Additions for Redis **************************** + # If dockerHubRepository is changes the following entry needs + # to be changed as well + imageRegistry: docker.io + imagePullSecrets: + - '{{ include "common.names.namespace" . }}-docker-registry-key' + # ************************************************* + +## Override the deployment namespace +## +namespaceOverride: "" + +# Force the target Kubernetes version (it uses Helm `.Capabilities` if not set). +# This is especially useful for `helm template` as capabilities are always empty +# due to the fact that it doesn't query an actual cluster +kubeVersion: + +# Oauth client configuration specifics +config: + # Add config annotations + annotations: {} + # OAuth client ID + clientID: "XXXXXXX" + # OAuth client secret + clientSecret: "XXXXXXXX" + # Create a new secret with the following command + # openssl rand -base64 32 | head -c 32 | base64 + # Use an existing secret for OAuth2 credentials (see secret.yaml for required fields) + # Example: + # existingSecret: secret + cookieSecret: "XXXXXXXXXXXXXXXX" + # The name of the cookie that oauth2-proxy will create + # If left empty, it will default to the release name + cookieName: "" + google: {} + # adminEmail: xxxx + # useApplicationDefaultCredentials: true + # targetPrincipal: xxxx + # serviceAccountJson: xxxx + # Alternatively, use an existing secret (see google-secret.yaml for required fields) + # Example: + # existingSecret: google-secret + # groups: [] + # Example: + # - group1@example.com + # - group2@example.com + # Default configuration, to be overridden + configFile: |- + email_domains = [ "*" ] + upstreams = [ "file:///dev/null" ] + # Custom configuration file: oauth2_proxy.cfg + # configFile: |- + # pass_basic_auth = false + # pass_access_token = true + # Use an existing config map (see configmap.yaml for required fields) + # Example: + # existingConfig: config + +alphaConfig: + enabled: false + # Add config annotations + annotations: {} + # Arbitrary configuration data to append to the server section + serverConfigData: {} + # Arbitrary configuration data to append to the metrics section + metricsConfigData: {} + # Arbitrary configuration data to append + configData: {} + # Arbitrary configuration to append + # This is treated as a Go template and rendered with the root context + configFile: "" + # Use an existing config map (see secret-alpha.yaml for required fields) + existingConfig: ~ + # Use an existing secret + existingSecret: ~ + +image: + #repository: "quay.io/oauth2-proxy/oauth2-proxy" + repository: "oauth2-proxy/oauth2-proxy" + # appVersion is used by default + tag: "" + pullPolicy: "IfNotPresent" + +# Optionally specify an array of imagePullSecrets. +# Secrets must be manually created in the namespace. +# ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod +# imagePullSecrets: + # - name: myRegistryKeySecretName + +# Set a custom containerPort if required. +# This will default to 4180 if this value is not set and the httpScheme set to http +# This will default to 4443 if this value is not set and the httpScheme set to https +# containerPort: 4180 + +extraArgs: {} +extraEnv: [] + +envFrom: [] +# Load environment variables from a ConfigMap(s) and/or Secret(s) +# that already exists (created and managed by you). +# ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables +# +# PS: Changes in these ConfigMaps or Secrets will not be automatically +# detected and you must manually restart the relevant Pods after changes. +# +# - configMapRef: +# name: special-config +# - secretRef: +# name: special-config-secret + +# -- Custom labels to add into metadata +customLabels: {} + +# To authorize individual email addresses +# That is part of extraArgs but since this needs special treatment we need to do a separate section +authenticatedEmailsFile: + enabled: false + # Defines how the email addresses file will be projected, via a configmap or secret + persistence: configmap + # template is the name of the configmap what contains the email user list but has been configured without this chart. + # It's a simpler way to maintain only one configmap (user list) instead changing it for each oauth2-proxy service. + # Be aware the value name in the extern config map in data needs to be named to "restricted_user_access" or to the + # provided value in restrictedUserAccessKey field. + template: "" + # The configmap/secret key under which the list of email access is stored + # Defaults to "restricted_user_access" if not filled-in, but can be overridden to allow flexibility + restrictedUserAccessKey: "" + # One email per line + # example: + # restricted_access: |- + # name1@domain + # name2@domain + # If you override the config with restricted_access it will configure a user list within this chart what takes care of the + # config map resource. + restricted_access: "" + annotations: {} + # helm.sh/resource-policy: keep + +service: + type: ClusterIP + # when service.type is ClusterIP ... + # clusterIP: 192.0.2.20 + # when service.type is LoadBalancer ... + # loadBalancerIP: 198.51.100.40 + # loadBalancerSourceRanges: 203.0.113.0/24 + # when service.type is NodePort ... + # nodePort: 80 + portNumber: 80 + # Protocol set on the service + appProtocol: http + annotations: {} + # foo.io/bar: "true" + +## Create or use ServiceAccount +serviceAccount: + ## Specifies whether a ServiceAccount should be created + enabled: true + ## The name of the ServiceAccount to use. + ## If not set and create is true, a name is generated using the fullname template + name: + automountServiceAccountToken: true + annotations: {} + +ingress: + enabled: false + # className: nginx + path: / + # Only used if API capabilities (networking.k8s.io/v1) allow it + pathType: ImplementationSpecific + # Used to create an Ingress record. + # hosts: + # - chart-example.local + # Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + # Warning! The configuration is dependant on your current k8s API version capabilities (networking.k8s.io/v1) + # extraPaths: + # - path: /* + # pathType: ImplementationSpecific + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + labels: {} + # annotations: + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # tls: + # Secrets must be manually created in the namespace. + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # limits: + # cpu: 100m + # memory: 300Mi + # requests: + # cpu: 100m + # memory: 300Mi + +extraVolumes: [] + # - name: ca-bundle-cert + # secret: + # secretName: <secret-name> + +extraVolumeMounts: [] + # - mountPath: /etc/ssl/certs/ + # name: ca-bundle-cert + +# Additional containers to be added to the pod. +extraContainers: [] + # - name: my-sidecar + # image: nginx:latest + +priorityClassName: "" + +# hostAliases is a list of aliases to be added to /etc/hosts for network name resolution +hostAliases: [] +# - ip: "10.xxx.xxx.xxx" +# hostnames: +# - "auth.example.com" +# - ip: 127.0.0.1 +# hostnames: +# - chart-example.local +# - example.local + +# [TopologySpreadConstraints](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/) configuration. +# Ref: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling +# topologySpreadConstraints: [] + +# Affinity for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +# affinity: {} + +# Tolerations for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +# Node labels for pod assignment +# Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +# Whether to use secrets instead of environment values for setting up OAUTH2_PROXY variables +proxyVarsAsSecrets: true + +# Configure Kubernetes liveness and readiness probes. +# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ +# Disable both when deploying with Istio 1.0 mTLS. https://istio.io/help/faq/security/#k8s-health-checks +livenessProbe: + enabled: true + initialDelaySeconds: 0 + timeoutSeconds: 1 + +readinessProbe: + enabled: true + initialDelaySeconds: 0 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + +# Configure Kubernetes security context for container +# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: + enabled: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 2000 + runAsGroup: 2000 + seccompProfile: + type: RuntimeDefault + +deploymentAnnotations: {} +podAnnotations: {} +podLabels: {} +replicaCount: 1 +revisionHistoryLimit: 10 +strategy: {} + +## PodDisruptionBudget settings +## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ +podDisruptionBudget: + enabled: true + minAvailable: 1 + +# Configure Kubernetes security context for pod +# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +podSecurityContext: {} + +# whether to use http or https +httpScheme: http + +initContainers: + # if the redis sub-chart is enabled, wait for it to be ready + # before starting the proxy + # creates a role binding to get, list, watch, the redis master pod + # if service account is enabled + waitForRedis: + enabled: true + image: + repository: "alpine" + tag: "latest" + pullPolicy: "IfNotPresent" + # uses the kubernetes version of the cluster + # the chart is deployed on, if not set + kubectlVersion: "" + securityContext: + enabled: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65534 + runAsGroup: 65534 + seccompProfile: + type: RuntimeDefault + timeout: 180 + resources: {} + # limits: + # cpu: 100m + # memory: 300Mi + # requests: + # cpu: 100m + # memory: 300Mi + +# Additionally authenticate against a htpasswd file. Entries must be created with "htpasswd -B" for bcrypt encryption. +# Alternatively supply an existing secret which contains the required information. +htpasswdFile: + enabled: false + existingSecret: "" + entries: [] + # One row for each user + # example: + # entries: + # - testuser:$2y$05$gY6dgXqjuzFhwdhsiFe7seM9q9Tile4Y3E.CBpAZJffkeiLaC21Gy + +# Configure the session storage type, between cookie and redis +sessionStorage: + # Can be one of the supported session storage cookie|redis + type: cookie + redis: + # Name of the Kubernetes secret containing the redis & redis sentinel password values (see also `sessionStorage.redis.passwordKey`) + existingSecret: "" + # Redis password value. Applicable for all Redis configurations. Taken from redis subchart secret if not set. `sessionStorage.redis.existingSecret` takes precedence + password: "" + # Key of the Kubernetes secret data containing the redis password value + passwordKey: "redis-password" + # Can be one of standalone|cluster|sentinel + clientType: "standalone" + standalone: + # URL of redis standalone server for redis session storage (e.g. `redis://HOST[:PORT]`). Automatically generated if not set + connectionUrl: "" + cluster: + # List of Redis cluster connection URLs (e.g. `["redis://127.0.0.1:8000", "redis://127.0.0.1:8000"]`) + connectionUrls: [] + sentinel: + # Name of the Kubernetes secret containing the redis sentinel password value (see also `sessionStorage.redis.sentinel.passwordKey`). Default: `sessionStorage.redis.existingSecret` + existingSecret: "" + # Redis sentinel password. Used only for sentinel connection; any redis node passwords need to use `sessionStorage.redis.password` + password: "" + # Key of the Kubernetes secret data containing the redis sentinel password value + passwordKey: "redis-sentinel-password" + # Redis sentinel master name + masterName: "" + # List of Redis sentinel connection URLs (e.g. `["redis://127.0.0.1:8000", "redis://127.0.0.1:8000"]`) + connectionUrls: [] + +# Enables and configure the automatic deployment of the redis subchart +redis: + # provision an instance of the redis sub-chart + enabled: false + # Redis specific helm chart settings, please see: + # https://github.com/bitnami/charts/tree/master/bitnami/redis#parameters + # redisPort: 6379 + # architecture: standalone + +# Enables apiVersion deprecation checks +checkDeprecation: true + +# Allows graceful shutdown +# terminationGracePeriodSeconds: 65 +# lifecycle: +# preStop: +# exec: +# command: [ "sh", "-c", "sleep 60" ] + +metrics: + # Enable Prometheus metrics endpoint + enabled: true + # Serve Prometheus metrics on this port + port: 44180 + # when service.type is NodePort ... + # nodePort: 44180 + # Protocol set on the service for the metrics port + service: + appProtocol: http + serviceMonitor: + # Enable Prometheus Operator ServiceMonitor + enabled: false + # Define the namespace where to deploy the ServiceMonitor resource + namespace: "" + # Prometheus Instance definition + prometheusInstance: default + # Prometheus scrape interval + interval: 60s + # Prometheus scrape timeout + scrapeTimeout: 30s + # Add custom labels to the ServiceMonitor resource + labels: {} + + ## scheme: HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS. + scheme: "" + + ## tlsConfig: TLS configuration to use when scraping the endpoint. For example if using istio mTLS. + ## Of type: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#tlsconfig + tlsConfig: {} + + ## bearerTokenFile: Path to bearer token file. + bearerTokenFile: "" + + ## Used to pass annotations that are used by the Prometheus installed in your cluster to select Service Monitors to work with + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec + annotations: {} + + ## Metric relabel configs to apply to samples before ingestion. + ## [Metric Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs) + metricRelabelings: [] + # - action: keep + # regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+' + # sourceLabels: [__name__] + + ## Relabel configs to apply to samples before ingestion. + ## [Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) + relabelings: [] + # - sourceLabels: [__meta_kubernetes_pod_node_name] + # separator: ; + # regex: ^(.*)$ + # targetLabel: nodename + # replacement: $1 + # action: replace + +# Extra K8s manifests to deploy +extraObjects: [] + # - apiVersion: secrets-store.csi.x-k8s.io/v1 + # kind: SecretProviderClass + # metadata: + # name: oauth2-proxy-secrets-store + # spec: + # provider: aws + # parameters: + # objects: | + # - objectName: "oauth2-proxy" + # objectType: "secretsmanager" + # jmesPath: + # - path: "client_id" + # objectAlias: "client-id" + # - path: "client_secret" + # objectAlias: "client-secret" + # - path: "cookie_secret" + # objectAlias: "cookie-secret" + # secretObjects: + # - data: + # - key: client-id + # objectName: client-id + # - key: client-secret + # objectName: client-secret + # - key: cookie-secret + # objectName: cookie-secret + # secretName: oauth2-proxy-secrets-store + # type: Opaque diff --git a/kubernetes/authentication/resources/oauth2_proxy.cfg b/kubernetes/authentication/resources/oauth2_proxy.cfg new file mode 100644 index 0000000000..60aaad4b52 --- /dev/null +++ b/kubernetes/authentication/resources/oauth2_proxy.cfg @@ -0,0 +1,38 @@ +provider = "oidc" +provider_display_name = "ONAPKeycloakID" +client_id = "{{ index .Values "onap-oauth2-proxy" "config" "clientId" }}" +client_secret = "{{ index .Values "onap-oauth2-proxy" "config" "clientSecret" }}" +oidc_issuer_url = 'https://{{ include "ingress.config.host" (dict "dot" . "baseaddr" "keycloak-ui") }}/realms/onap' +oidc_jwks_url = 'http://{{ include "common.namespace" . }}-authentication-keycloakx-http.{{ include "common.namespace" . }}/realms/onap/protocol/openid-connect/certs' +profile_url = 'https://{{ include "ingress.config.host" (dict "dot" . "baseaddr" "keycloak-ui") }}/realms/onap/protocol/openid-connect/userinfo' +validate_url = 'https://{{ include "ingress.config.host" (dict "dot" . "baseaddr" "keycloak-ui") }}/realms/onap/protocol/openid-connect/userinfo' +redeem_url = 'http://{{ include "common.namespace" . }}-authentication-keycloakx-http.{{ include "common.namespace" . }}/realms/onap/protocol/openid-connect/token' +scope = "openid email profile groups onap_roles" +skip_oidc_discovery = true +cookie_secure = false +cookie_secret = "{{ index .Values "onap-oauth2-proxy" "config" "cookieSecret" }}" +email_domains = [ "*" ] +auth_logging = true +request_logging = true +standard_logging = true +show_debug_on_error = true +cookie_domains = ".{{ .Values.global.ingress.virtualhost.baseurl }}" +cookie_samesite = "lax" +whitelist_domains = ".{{ .Values.global.ingress.virtualhost.baseurl }}" +login_url = 'https://{{ include "ingress.config.host" (dict "dot" . "baseaddr" "keycloak-ui") }}/realms/onap/protocol/openid-connect/auth' +pass_access_token = true +pass_authorization_header = true +pass_host_header = true +pass_user_headers = true +http_address = "0.0.0.0:4180" +oidc_email_claim = "email" +oidc_groups_claim = "groups" +insecure_oidc_skip_issuer_verification = true +insecure_oidc_allow_unverified_email = true +silence_ping_logging = true +upstreams = "static://200" +set_xauthrequest = true +set_authorization_header = true +skip_provider_button = true +skip_jwt_bearer_tokens = true +cookie_expire = "30m" diff --git a/kubernetes/authentication/templates/_utils.tpl b/kubernetes/authentication/templates/_utils.tpl new file mode 100644 index 0000000000..806f96164a --- /dev/null +++ b/kubernetes/authentication/templates/_utils.tpl @@ -0,0 +1,811 @@ +{{/* +# Copyright © 2024 Tata Communication Limited (TCL), Deutsche Telekom AG +# +# 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. +*/}} + +{{/* +Renders a value that contains template. +Usage: +{{ include "auth.realm" ( dict "dot" . "realm" .Values.path.to.realm) }} +*/}} +{{- define "auth.realm" -}} +{{- $dot := default . .dot -}} +{{- $realm := (required "'realm' param, set to the specific service, is required." .realm) -}} +realm: {{ $realm.name }} +{{ if $realm.displayName }}displayName: {{ $realm.displayName }}{{ end }} +id: {{ $realm.name }} +accessTokenLifespan: 1900 +registrationAllowed: false +resetPasswordAllowed: true +enabled: true +{{ if $realm.themes }} +{{ if $realm.themes.login }}loginTheme: {{ $realm.themes.login }}{{ end }} +{{ if $realm.themes.admin }}adminTheme: {{ $realm.themes.admin }}{{ end }} +{{ if $realm.themes.account }}accountTheme: {{ $realm.themes.account }}{{ end }} +{{ if $realm.themes.email }}emailTheme: {{ $realm.themes.email }}{{ end }} +{{- end }} +{{- if $realm.accessControl }} +{{ include "auth._roles" $realm }} +{{- end }} +{{ include "auth._clients" (dict "dot" $dot "realm" $realm) }} +{{ include "auth._clientScopes" $realm }} +{{ include "auth._defaultClientScopes" $realm }} +{{ include "auth._groups" $realm }} +{{ include "auth._users" $realm }} +{{ include "auth._identity" $realm }} +{{ include "auth._identityMapper" $realm }} +{{ include "auth._smtpServer" $realm }} +{{ include "auth._attributes" (dict "dot" $dot "realm" $realm) }} +{{- end -}} + +{{/* +Renders the roles section in a realm. +Usage: +{{ include "auth._roles" ( dict "dot" .Values) }} +*/}} +{{- define "auth._roles" -}} +{{- $realm := default . .dot -}} +roles: + realm: + {{- range $index, $role := $realm.accessControl.assignableRoles }} + - name: "{{ $role.name }}" + description: "{{ $role.description }}" + {{- if $role.associatedAccessRoles }} + composite: true + composites: + client: + {{- range $key, $accessRole := $realm.accessControl.accessRoles }} + {{ $client := index $realm.clients $key -}} + {{ $client.clientId }}: + {{- range $index2, $associatedRole := $role.associatedAccessRoles }} + - {{ $associatedRole }} + {{- end }} + {{- end }} + {{- else }} + composite: false + {{- end }} + clientRole: false + containerId: "{{ $realm.name }}" + attributes: {} + {{- end }} + - name: "user" + composite: false + clientRole: false + containerId: "{{ $realm.name }}" + attributes: {} + - name: "admin" + composite: false + clientRole: false + containerId: "{{ $realm.name }}" + attributes: {} + - name: "offline_access" + description: "${role_offline-access}" + composite: false + clientRole: false + containerId: "{{ $realm.name }}" + attributes: {} + - name: "uma_authorization" + description: "${role_uma_authorization}" + composite: false + clientRole: false + containerId: "{{ $realm.name }}" + attributes: {} + - name: "default-roles-{{ $realm.name }}" + description: "${role_default-roles}" + composite: true + composites: + realm: + - "offline_access" + - "uma_authorization" + client: + account: + - "view-profile" + - "manage-account" + clientRole: false + containerId: "{{ $realm.name }}" + attributes: {} + {{- if $realm.accessControl.accessRoles }} + client: + {{- range $key, $accessRole := $realm.accessControl.accessRoles }} + {{ $client := index $realm.clients $key -}} + {{ $client.clientId }}: + {{- range $index, $role := get $realm.accessControl.accessRoles $key }} + - name: "{{ $role.name }}" + description: "Allows to perform {{ $role.methodsAllowed }} operations for {{ $role.name }} component" + composite: false + clientRole: false + containerId: "{{ $client.clientId }}" + attributes: {} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{/* +Renders the clients section in a realm. +Usage: +{{ include "auth._clients" ( dict "dot" . "realm" $realm ) }} +*/}} +{{- define "auth._clients" -}} +{{- $dot := default . .dot -}} +{{- $realm := (required "'realm' param, set to the specific service, is required." .realm) -}} +clients: + {{- range $index, $client := $realm.clients }} + - clientId: "{{ $client.clientId }}" + {{- if $client.name }} + name: "{{ $client.name }}" + {{- end }} + {{- if $client.description }} + description: "{{ $client.description }}" + {{- end }} + {{- if $client.rootUrl }} + rootUrl: {{ tpl $client.rootUrl $dot }} + {{- end }} + {{- if $client.adminUrl }} + adminUrl: {{ tpl $client.adminUrl $dot }} + {{- end }} + {{- if $client.baseUrl }} + baseUrl: {{ tpl $client.baseUrl $dot }} + {{- end }} + surrogateAuthRequired: {{ default false $client.surrogateAuthRequired }} + enabled: true + alwaysDisplayInConsole: false + clientAuthenticatorType: {{ default "client-secret" $client.clientAuthenticatorType }} + {{- if $client.secret }} + secret: "{{ $client.secret }}" + {{- end }} + {{- if $client.redirectUris }} + redirectUris: + {{- range $index2, $url := $client.redirectUris }} + - {{ tpl $url $dot }} + {{- end }} + {{- else }} + redirectUris: [] + {{- end }} + {{- if $client.webOrigins }} + webOrigins: + {{- range $index3, $web := $client.webOrigins }} + - {{ $web | quote }} + {{- end }} + {{- else }} + webOrigins: [] + {{- end }} + notBefore: 0 + bearerOnly: {{ default false $client.bearerOnly }} + consentRequired: {{ default false $client.consentRequired }} + standardFlowEnabled: {{ default true $client.standardFlowEnabled }} + implicitFlowEnabled: {{ default false $client.implicitFlowEnabled }} + directAccessGrantsEnabled: {{ default true $client.directAccessGrantsEnabled }} + serviceAccountsEnabled: {{ default false $client.serviceAccountsEnabled }} + publicClient: {{ default false $client.publicClient }} + frontchannelLogout: {{ default false $client.frontchannelLogout }} + protocol: "{{ default "openid-connect" $client.protocol }}" + {{- if $client.attributes }} + attributes: + {{- range $key,$value := $client.attributes }} + {{ $key }}: {{ tpl $value $dot }} + {{- end }} + {{- end }} + authenticationFlowBindingOverrides: {} + fullScopeAllowed: true + nodeReRegistrationTimeout: -1 + protocolMappers: + {{- if $client.protocolMappers }} + {{- range $index2, $mapper := $client.protocolMappers }} + - name: {{ $mapper.name }} + protocol: "openid-connect" + protocolMapper: {{ $mapper.protocolMapper }} + consentRequired: false + config: + {{ toYaml $mapper.config | nindent 10 }} + {{- end }} + {{- end }} + defaultClientScopes: + {{- if $client.defaultClientScopes }} + {{- range $index2, $scope := $client.defaultClientScopes }} + - {{ $scope }} + {{- end }} + {{- else }} + - web-origins + - profile + - acr + - email + {{- end }} + optionalClientScopes: + {{- if $client.optionalClientScopes }} + {{- range $index2, $scope := $client.optionalClientScopes }} + - {{ $scope }} + {{- end }} + {{- else }} + - address + - phone + - offline_access + - microprofile-jwt + {{- end }} + {{- end }} +{{- end }} + +{{/* +Renders the defaulDefaultClientScopes section in a realm. +Usage: +{{ include "auth._defaultClientScopes" ( dict "dot" .Values) }} +*/}} +{{- define "auth._defaultClientScopes" -}} +{{- $dot := default . .dot -}} +{{- if $dot.defaultClientScopes }} +defaultDefaultClientScopes: + {{- range $index, $scope := $dot.defaultClientScopes }} + - {{ $scope }} + {{- end }} +{{- end }} +{{- end }} + +{{/* +Renders the clientScopes section in a realm. +Usage: +{{ include "auth._clientScopes" ( dict "dot" .Values) }} +*/}} +{{- define "auth._clientScopes" -}} +{{- $dot := default . .dot -}} +clientScopes: +{{- if $dot.additionalClientScopes }} +{{- range $index, $scope := $dot.additionalClientScopes }} +- name: {{ $scope.name }} + description: "{{ default "" $scope.description }}" + protocol: openid-connect + attributes: + include.in.token.scope: 'false' + display.on.consent.screen: 'true' + gui.order: '' + consent.screen.text: "${rolesScopeConsentText}" + protocolMappers: + {{- if $scope.protocolMappers }} + {{- range $index2, $mapper := $scope.protocolMappers }} + - name: {{ $mapper.name }} + protocol: "openid-connect" + protocolMapper: {{ $mapper.protocolMapper }} + consentRequired: false + config: + {{ toYaml $mapper.config | nindent 8 }} + {{- end }} + {{- end }} + +{{- end }} +{{- end }} +- name: roles + description: OpenID Connect scope for add user roles to the access token + protocol: openid-connect + attributes: + include.in.token.scope: 'false' + display.on.consent.screen: 'true' + consent.screen.text: "${rolesScopeConsentText}" + protocolMappers: + - name: audience resolve + protocol: openid-connect + protocolMapper: oidc-audience-resolve-mapper + consentRequired: false + config: {} + - name: realm roles + protocol: openid-connect + protocolMapper: oidc-usermodel-realm-role-mapper + consentRequired: false + config: + user.attribute: foo + access.token.claim: 'true' + claim.name: realm_access.roles + jsonType.label: String + multivalued: 'true' + - name: client roles + protocol: openid-connect + protocolMapper: oidc-usermodel-client-role-mapper + consentRequired: false + config: + user.attribute: foo + access.token.claim: 'true' + claim.name: resource_access.${client_id}.roles + jsonType.label: String + multivalued: 'true' +- name: groups + description: Membership to a group + protocol: openid-connect + attributes: + include.in.token.scope: 'true' + display.on.consent.screen: 'true' + gui.order: '' + consent.screen.text: '' + protocolMappers: + - name: groups + protocol: openid-connect + protocolMapper: oidc-group-membership-mapper + consentRequired: false + config: + full.path: 'false' + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: groups + userinfo.token.claim: 'true' +- name: acr + description: OpenID Connect scope for add acr (authentication context class reference) + to the token + protocol: openid-connect + attributes: + include.in.token.scope: 'false' + display.on.consent.screen: 'false' + protocolMappers: + - name: acr loa level + protocol: openid-connect + protocolMapper: oidc-acr-mapper + consentRequired: false + config: + id.token.claim: 'true' + access.token.claim: 'true' +- name: profile + description: 'OpenID Connect built-in scope: profile' + protocol: openid-connect + attributes: + include.in.token.scope: 'true' + display.on.consent.screen: 'true' + consent.screen.text: "${profileScopeConsentText}" + protocolMappers: + - name: profile + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: profile + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: profile + jsonType.label: String + - name: given name + protocol: openid-connect + protocolMapper: oidc-usermodel-property-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: firstName + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: given_name + jsonType.label: String + - name: website + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: website + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: website + jsonType.label: String + - name: zoneinfo + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: zoneinfo + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: zoneinfo + jsonType.label: String + - name: locale + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: locale + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: locale + jsonType.label: String + - name: gender + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: gender + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: gender + jsonType.label: String + - name: family name + protocol: openid-connect + protocolMapper: oidc-usermodel-property-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: lastName + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: family_name + jsonType.label: String + - name: username + protocol: openid-connect + protocolMapper: oidc-usermodel-property-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: username + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: preferred_username + jsonType.label: String + - name: middle name + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: middleName + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: middle_name + jsonType.label: String + - name: birthdate + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: birthdate + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: birthdate + jsonType.label: String + - name: updated at + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: updatedAt + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: updated_at + jsonType.label: long + - name: full name + protocol: openid-connect + protocolMapper: oidc-full-name-mapper + consentRequired: false + config: + id.token.claim: 'true' + access.token.claim: 'true' + userinfo.token.claim: 'true' + - name: nickname + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: nickname + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: nickname + jsonType.label: String + - name: picture + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: picture + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: picture + jsonType.label: String +- name: address + description: 'OpenID Connect built-in scope: address' + protocol: openid-connect + attributes: + include.in.token.scope: 'true' + display.on.consent.screen: 'true' + consent.screen.text: "${addressScopeConsentText}" + protocolMappers: + - name: address + protocol: openid-connect + protocolMapper: oidc-address-mapper + consentRequired: false + config: + user.attribute.formatted: formatted + user.attribute.country: country + user.attribute.postal_code: postal_code + userinfo.token.claim: 'true' + user.attribute.street: street + id.token.claim: 'true' + user.attribute.region: region + access.token.claim: 'true' + user.attribute.locality: locality +- name: web-origins + description: OpenID Connect scope for add allowed web origins to the access token + protocol: openid-connect + attributes: + include.in.token.scope: 'false' + display.on.consent.screen: 'false' + consent.screen.text: '' + protocolMappers: + - name: allowed web origins + protocol: openid-connect + protocolMapper: oidc-allowed-origins-mapper + consentRequired: false + config: {} +- name: phone + description: 'OpenID Connect built-in scope: phone' + protocol: openid-connect + attributes: + include.in.token.scope: 'true' + display.on.consent.screen: 'true' + consent.screen.text: "${phoneScopeConsentText}" + protocolMappers: + - name: phone number verified + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: phoneNumberVerified + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: phone_number_verified + jsonType.label: boolean + - name: phone number + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: phoneNumber + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: phone_number + jsonType.label: String +- name: offline_access + description: 'OpenID Connect built-in scope: offline_access' + protocol: openid-connect + attributes: + consent.screen.text: "${offlineAccessScopeConsentText}" + display.on.consent.screen: 'true' +- name: role_list + description: SAML role list + protocol: saml + attributes: + consent.screen.text: "${samlRoleListScopeConsentText}" + display.on.consent.screen: 'true' + protocolMappers: + - name: role list + protocol: saml + protocolMapper: saml-role-list-mapper + consentRequired: false + config: + single: 'false' + attribute.nameformat: Basic + attribute.name: Role +- name: microprofile-jwt + description: Microprofile - JWT built-in scope + protocol: openid-connect + attributes: + include.in.token.scope: 'true' + display.on.consent.screen: 'false' + protocolMappers: + - name: upn + protocol: openid-connect + protocolMapper: oidc-usermodel-property-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: username + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: upn + jsonType.label: String + - name: groups + protocol: openid-connect + protocolMapper: oidc-usermodel-realm-role-mapper + consentRequired: false + config: + multivalued: 'true' + user.attribute: foo + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: groups + jsonType.label: String +- name: email + description: 'OpenID Connect built-in scope: email' + protocol: openid-connect + attributes: + include.in.token.scope: 'true' + display.on.consent.screen: 'true' + consent.screen.text: "${emailScopeConsentText}" + protocolMappers: + - name: email + protocol: openid-connect + protocolMapper: oidc-usermodel-property-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: email + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: email + jsonType.label: String + - name: email verified + protocol: openid-connect + protocolMapper: oidc-usermodel-property-mapper + consentRequired: false + config: + userinfo.token.claim: 'true' + user.attribute: emailVerified + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: email_verified + jsonType.label: boolean +{{- end }} + +{{/* +Renders the groups section in a realm. +Usage: +{{ include "auth._groups" ( dict "dot" .Values) }} +*/}} +{{- define "auth._groups" -}} +{{- $dot := default . .dot -}} +{{- if $dot.groups }} +groups: +{{- range $index, $group := $dot.groups }} + - name: "{{ $group.name }}" + path: "{{ $group.path }}" + attributes: {} + {{- if $group.roles }} + realmRoles: + {{- range $index2, $groupRole := $group.roles }} + - "{{ $groupRole }}" + {{- end }} + {{- else }} + realmRoles: [] + {{- end }} + clientRoles: {} + subGroups: [] +{{- end }} +{{- else }} +groups: [] +{{- end }} +{{- end }} + +{{/* +Renders the users section in a realm. +Usage: +{{ include "auth._users" ( dict "dot" .Values) }} +*/}} +{{- define "auth._users" -}} +{{- $dot := default . .dot -}} +{{- if $dot.initialUsers }} +users: + {{- range $index, $user := $dot.initialUsers }} + - username: "{{ $user.username }}" + enabled: true + totp: false + email: "{{ default "" $user.email }}" + emailVerified: "{{ default true $user.emailVerified }}" + firstName: "{{ default "" $user.firstName }}" + lastName: "{{ default "" $user.lastName }}" + {{- if $user.attributes }} + attributes: + {{ toYaml $user.attributes | nindent 6 }} + {{- else }} + attributes: {} + {{- end }} + {{- if $user.password }} + credentials: + - type: "password" + temporary: false + value: "{{ $user.password }}" + {{- end }} + {{- if $user.credentials }} + credentials: + {{ toYaml $user.credentials | nindent 6 }} + {{- end }} + disableableCredentialTypes: [] + requiredActions: [] + {{- if $user.realmRoles }} + realmRoles: + {{- range $index2, $realmRole := $user.realmRoles }} + - "{{ $realmRole }}" + {{- end }} + {{- else }} + realmRoles: [ "default-roles-{{ $dot.name }}" ] + {{- end }} + {{- if $user.clientRoles }} + clientRoles: + {{ toYaml $user.clientRoles | nindent 6 }} + {{- end }} + notBefore: 0 + groups: {{ $user.groups | toJson }} + {{- end }} +{{- end }} +{{- end }} + +{{/* +Renders the identityProviders section in a realm. +Usage: +{{ include "auth._identity" ( dict "dot" .Values) }} +*/}} +{{- define "auth._identity" -}} +{{- $dot := default . .dot -}} +{{- if $dot.identityProviders }} +identityProviders: +{{- range $index, $provider := $dot.identityProviders }} + - alias: {{ $provider.name }} + displayName: {{ $provider.displayName }} + providerId: oidc + enabled: true + updateProfileFirstLoginMode: "on" + trustEmail: true + storeToken: true + addReadTokenRoleOnCreate: true + authenticateByDefault: false + linkOnly: false + firstBrokerLoginFlowAlias: "first broker login" + config: + {{ toYaml $provider.config | nindent 6 }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Renders the identityProviderMappers section in a realm. +Usage: +{{ include "auth._identityMapper" ( dict "dot" .Values) }} +*/}} +{{- define "auth._identityMapper" -}} +{{- $dot := default . .dot -}} +{{- if $dot.identityProviderMappers }} +identityProviderMappers: +{{- range $index, $mapper := $dot.identityProviderMappers }} + - name: {{ $mapper.name }} + identityProviderAlias: {{ $mapper.identityProviderAlias }} + identityProviderMapper: {{ $mapper.identityProviderMapper }} + config: + {{ toYaml $mapper.config | nindent 6 }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Renders the smtpServer section in a realm. +Usage: +{{ include "auth._smtpServer" ( dict "dot" .Values) }} +*/}} +{{- define "auth._smtpServer" -}} +{{- $dot := default . .dot -}} +{{- if $dot.smtpServer }} +smtpServer: + {{ toYaml $dot.smtpServer | nindent 2 }} +{{- end }} +{{- end }} + +{{/* +Renders the attributes section in a realm. +Usage: +{{ include "auth._attributes" ( dict "dot" . "realm" $realm ) }} +*/}} +{{- define "auth._attributes" -}} +{{- $dot := default . .dot -}} +{{- $realm := (required "'realm' param, set to the specific service, is required." .realm) -}} +attributes: + frontendUrl: {{ tpl $realm.attributes.frontendUrl $dot }} + acr.loa.map: "{\"ABC\":\"5\"}" +{{- end }} diff --git a/kubernetes/authentication/templates/authorizationpolicy.yaml b/kubernetes/authentication/templates/authorizationpolicy.yaml new file mode 100644 index 0000000000..abd40725da --- /dev/null +++ b/kubernetes/authentication/templates/authorizationpolicy.yaml @@ -0,0 +1,90 @@ +{{/* +# Copyright © 2024 Tata Communication Limited (TCL), Deutsche Telekom AG +# +# 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.ingressAuthentication.enabled }} +--- +{{- $dot := . }} +{{- range $index, $realm := .Values.realmSettings }} +{{- range $key, $accessRole := $realm.accessControl.accessRoles }} +{{- range $index, $role := get $realm.accessControl.accessRoles $key }} +apiVersion: security.istio.io/v1 +kind: AuthorizationPolicy +metadata: + name: {{ $key }}-{{ $role.name }}-jwt + namespace: istio-ingress +spec: + action: ALLOW + rules: + - to: + - operation: + hosts: + - {{ include "ingress.config.host" (dict "dot" $dot "baseaddr" $role.servicePrefix) }} + methods: + {{- range $role.methodsAllowed }} + - {{ . }} + {{- end }} + when: + - key: request.auth.claims[onap_roles] + values: + - {{ $role.name }} + selector: + matchLabels: + istio: ingress +--- +{{- end }} +{{- end }} +{{- end }} +apiVersion: security.istio.io/v1 +kind: AuthorizationPolicy +metadata: + name: {{ .Release.Name }}-custom-action + namespace: istio-ingress +spec: + action: CUSTOM + provider: + name: oauth2-proxy + rules: + - to: + - operation: + notHosts: + {{- if .Values.ingressAuthentication.exceptions }} + {{- range $index, $url := .Values.ingressAuthentication.exceptions }} + - {{ tpl $url $dot }} + {{- end }} + {{- end }} + selector: + matchLabels: + istio: ingress +--- +apiVersion: security.istio.io/v1 +kind: AuthorizationPolicy +metadata: + name: {{ .Release.Name }}-allowed-exceptions + namespace: istio-ingress +spec: + action: ALLOW + rules: + - to: + - operation: + hosts: + {{- if .Values.ingressAuthentication.exceptions }} + {{- range $index, $url := .Values.ingressAuthentication.exceptions }} + - {{ tpl $url $dot }} + {{- end }} + {{- end }} + selector: + matchLabels: + istio: ingress +{{- end }} diff --git a/kubernetes/authentication/templates/configmap.yaml b/kubernetes/authentication/templates/configmap.yaml new file mode 100644 index 0000000000..f373754379 --- /dev/null +++ b/kubernetes/authentication/templates/configmap.yaml @@ -0,0 +1,23 @@ +{{/* +# Copyright © 2024 Tata Communication Limited (TCL), Deutsche Telekom AG +# +# 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: v1 +kind: ConfigMap +metadata: + name: oauth2-onap-config + namespace: {{ include "common.namespace" . }} +data: +{{ tpl (.Files.Glob "resources/oauth2_proxy.cfg").AsConfig . | indent 2 }} diff --git a/kubernetes/authentication/templates/requestauthentication.yaml b/kubernetes/authentication/templates/requestauthentication.yaml new file mode 100644 index 0000000000..92bea9f48e --- /dev/null +++ b/kubernetes/authentication/templates/requestauthentication.yaml @@ -0,0 +1,36 @@ +{{/* +# Copyright © 2024 Tata Communication Limited (TCL), Deutsche Telekom AG +# +# 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.ingressAuthentication.enabled }} +--- +apiVersion: security.istio.io/v1beta1 +kind: RequestAuthentication +metadata: + name: {{ .Release.Name }}-request-auth + namespace: istio-ingress +spec: + selector: + matchLabels: + istio: ingress + jwtRules: + {{- $dot := . }} + {{- range $index, $realm := .Values.realmSettings }} + - issuer: "https://{{ include "ingress.config.host" (dict "dot" $dot "baseaddr" "keycloak-ui") }}/{{ $dot.Values.keycloak.relativePath }}realms/{{ $realm.name }}" + jwksUri: {{ $dot.Values.keycloak.intURL }}realms/{{ $realm.name }}/protocol/openid-connect/certs + {{- end }} + - issuer: "https://{{ include "ingress.config.host" (dict "dot" $dot "baseaddr" "keycloak-ui") }}/{{ .Values.keycloak.relativePath }}realms/master" + jwksUri: {{ .Values.keycloak.intURL }}realms/master/protocol/openid-connect/certs + forwardOriginalToken: true +{{- end }} diff --git a/kubernetes/authentication/templates/secret.yaml b/kubernetes/authentication/templates/secret.yaml new file mode 100644 index 0000000000..1488be6969 --- /dev/null +++ b/kubernetes/authentication/templates/secret.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: keycloak-config-cli-config-realms + namespace: {{ include "common.namespace" . }} + labels: + app: {{ include "common.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ include "common.release" . }} + heritage: {{ .Release.Service }} +data: +{{- $dot := . }} +{{- range $realm := .Values.realmSettings }} + {{ $realm.name }}: {{ include "auth.realm" (dict "dot" $dot "realm" $realm) | fromYaml | toPrettyJson | indent 2 | b64enc | quote }} +{{- end -}} diff --git a/kubernetes/authentication/values.yaml b/kubernetes/authentication/values.yaml new file mode 100644 index 0000000000..ba99879e87 --- /dev/null +++ b/kubernetes/authentication/values.yaml @@ -0,0 +1,648 @@ +# Copyright © 2024, 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" + # prefix for baseaddr + # can be overwritten in component by setting ingress.preaddrOverride + preaddr: "" + # postfix for baseaddr + # can be overwritten in component by setting ingress.postaddrOverride + postaddr: "" + +keycloak: + intURL: "http://keycloak-keycloakx-http.keycloak.svc.cluster.local/" + relativePath: "auth/" +ingressAuthentication: + enabled: false + exceptions: + - '{{ include "ingress.config.host" (dict "dot" . "baseaddr" "keycloak-ui") }}' + - '{{ include "ingress.config.host" (dict "dot" . "baseaddr" "portal-ui") }}' + - '{{ include "ingress.config.host" (dict "dot" . "baseaddr" "minio-console") }}' + - '{{ include "ingress.config.host" (dict "dot" . "baseaddr" "uui-server") }}' + +onap-keycloak-config-cli: + image: + pullSecrets: + - name: onap-docker-registry-key + #existingSecret: "keycloak-keycloakx-admin-creds" + env: + # internal KC URL plus relative path + KEYCLOAK_URL: "http://keycloak-keycloakx-http.keycloak.svc.cluster.local/auth/" + KEYCLOAK_SSLVERIFY: "false" + KEYCLOAK_AVAILABILITYCHECK_ENABLED: "true" + secrets: + KEYCLOAK_PASSWORD: secret + existingConfigSecret: "keycloak-config-cli-config-realms" + securityContext: + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + seccompProfile: + type: RuntimeDefault + containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + - CAP_NET_RAW + readOnlyRootFilesystem: true + resources: + limits: + cpu: "1" + memory: 500Mi + requests: + cpu: 100m + memory: 10Mi + +onap-oauth2-proxy: + securityContext: + capabilities: + drop: + - ALL + - CAP_NET_RAW + + resources: + limits: + cpu: 500m + memory: 500Mi + requests: + cpu: 500m + memory: 500Mi + + initContainers: + waitForRedis: + #image: + # repository: "dockerhub.devops.telekom.de/alpine" + # tag: "3.20" + securityContext: + capabilities: + drop: + - ALL + - CAP_NET_RAW + resources: + limits: + cpu: 100m + memory: 300Mi + requests: + cpu: 100m + memory: 300Mi + + # Oauth client configuration specifics + config: + # Create a new secret with the following command + # openssl rand -base64 32 | head -c 32 | base64 + cookieSecret: "CbgXFXDJ16laaCfChtFBpKy1trNEmJZDIjaiaIMLyRA=" + clientID: &clientID "oauth2-proxy-onap" + # To be set in helmfile + clientSecret: &clientSecret "5YSOkJz99WHv8enDZPknzJuGqVSerELp" + # To be set in helmfile + cookieName: "onap-cookie" + # settings see https://github.com/oauth2-proxy/oauth2-proxy/blob/master/docs/docs/configuration/overview.md + existingConfig: "oauth2-onap-config" + + # Configure the session storage type, between cookie and redis + sessionStorage: + # Can be one of the supported session storage cookie|redis + type: redis + redis: + # Name of the Kubernetes secret containing the redis & redis sentinel password values (see also `sessionStorage.redis.passwordKey`) + existingSecret: "onap-authentication-redis" + # Redis password value. Applicable for all Redis configurations. Taken from redis subchart secret if not set. `sessionStorage.redis.existingSecret` takes precedence + password: "" + # Key of the Kubernetes secret data containing the redis password value + passwordKey: "redis-password" + # Can be one of standalone|cluster|sentinel + clientType: "sentinel" + standalone: + # URL of redis standalone server for redis session storage (e.g. `redis://HOST[:PORT]`). Automatically generated if not set + connectionUrl: "" + cluster: + # List of Redis cluster connection URLs (e.g. `["redis://127.0.0.1:8000", "redis://127.0.0.1:8000"]`) + connectionUrls: [] + sentinel: + # Name of the Kubernetes secret containing the redis sentinel password value (see also `sessionStorage.redis.sentinel.passwordKey`). Default: `sessionStorage.redis.existingSecret` + existingSecret: "" + # Redis sentinel password. Used only for sentinel connection; any redis node passwords need to use `sessionStorage.redis.password` + password: "" + # Key of the Kubernetes secret data containing the redis sentinel password value + passwordKey: "redis-password" + # Redis sentinel master name + masterName: "mymaster" + # List of Redis sentinel connection URLs (e.g. `["redis://127.0.0.1:8000", "redis://127.0.0.1:8000"]`) + connectionUrls: "redis://onap-authentication-redis-node-0.onap-authentication-redis-headless.onap:26379,redis://onap-authentication-redis-node-1.onap-authentication-redis-headless.onap:26379,redis://onap-authentication-redis-node-2.onap-authentication-redis-headless.onap:26379" + + # Enables and configure the automatic deployment of the redis subchart + redis: + # provision an instance of the redis sub-chart + enabled: true + master: + containerSecurityContext: + capabilities: + drop: ["ALL", "CAP_NET_RAW"] + replica: + containerSecurityContext: + capabilities: + drop: ["ALL", "CAP_NET_RAW"] + sentinel: + enabled: true + containerSecurityContext: + capabilities: + drop: ["ALL", "CAP_NET_RAW"] + +serviceAccount: + nameOverride: keycloak-init + roles: + - read + +realmSettings: + - name: onap + displayName: "ONAP Realm" + attributes: + frontendUrl: 'https://{{ include "ingress.config.host" (dict "dot" . "baseaddr" "keycloak-ui") }}/{{ .Values.keycloak.relativePath }}' + themes: + login: "base" + admin: "base" + account: "base" + email: "base" + groups: + - name: admins + path: /admins + roles: [ "platform-all-full" ] + - name: contributors + path: /contributors + roles: [ "platform-all-write" ] + - name: readers + path: /readers + roles: [ "platform-all-read" ] + initialUsers: + - username: "onap-admin" + credentials: + - type: password + secretData: "{\"value\":\"nD4K4x8HEgk6xlWIAgzZOE+EOjdbovJfEa7N3WXwIMCWCfdXpn7Riys7hZhI1NbKcc9QPI9j8LQB/JSuZVcXKA==\",\"salt\":\"T8X9A9tT2cyLvEjHFo+zuQ==\",\"additionalParameters\":{}}" + credentialData : "{\"hashIterations\":27500,\"algorithm\":\"pbkdf2-sha256\",\"additionalParameters\":{}}" + attributes: + sdc_user: + - "cs0008" + realmRoles: + - default-roles-onap + - portal_admin + groups: [] + - username: "onap-designer" + credentials: [] + attributes: + sdc_user: + - "cs0008" + realmRoles: + - default-roles-onap + - portal_designer + groups: [] + - username: "onap-operator" + credentials: [] + attributes: + sdc_user: + - "cs0008" + realmRoles: + - default-roles-onap + - portal_operator + groups: [] + - username: "service-account-portal-bff" + serviceAccountClientId: "portal-bff" + credentials: [] + clientRoles: + realm-management: + - manage-realm + - manage-users + groups: [] + - username: adminek + password: Adminek + email: "onap-admin@amartus.com" + groups: + - admins + - username: onapadmin + password: ONAPAdmin + email: "onap-admin1@amartus.com" + groups: + - admins + - username: contributor + password: Contributor + email: "onap-contributor@amartus.com" + groups: + - contributors + - username: reader + password: Reader + email: "onap-reader@amartus.com" + groups: + - readers + clients: + oauth2_proxy: + clientId: *clientID + name: "Oauth2 Proxy" + secret: *clientSecret + protocol: openid-connect + protocolMappers: + - name: "Audience for Oauth2Proxy" + protocolMapper: "oidc-audience-mapper" + config: + included.client.audience: "oauth2-proxy-onap" + id.token.claim: "false" + access.token.claim: "true" + included.custom.audience: "oauth2-proxy-onap" + - name: "SDC-User" + protocolMapper: "oidc-usermodel-attribute-mapper" + config: + multivalued: "false" + userinfo.token.claim: "true" + user.attribute: "sdc_user" + id.token.claim: "true" + access.token.claim: "true" + claim.name: "sdc_user" + jsonType.label: "String" + additionalDefaultScopes: + - "onap_roles" + portal_app: + clientId: "portal-app" + redirectUris: + - 'https://{{ include "ingress.config.host" (dict "dot" . "baseaddr" "portal-ng-ui") }}/*' + - 'http://localhost/*' + protocol: openid-connect + additionalAttributes: + post.logout.redirect.uris: 'https://{{ include "ingress.config.host" (dict "dot" . "baseaddr" "portal-ng-ui") }}/*' + protocolMappers: + - name: "User-Roles" + protocolMapper: "oidc-usermodel-attribute-mapper" + config: + userinfo.token.claim: "true" + id.token.claim: "true" + access.token.claim: "true" + claim.name: "roles" + multivalued: "true" + - name: "SDC-User" + protocolMapper: "oidc-usermodel-attribute-mapper" + config: + userinfo.token.claim: "true" + user.attribute: "sdc_user" + id.token.claim: "true" + access.token.claim: "true" + claim.name: "sdc_user" + jsonType.label: "String" + portal_bff: + clientId: "portal-bff" + protocol: openid-connect + secret : pKOuVH1bwRZoNzp5P5t4GV8CqcCJYVtr + protocolMappers: + - name: "Client Host" + protocolMapper: "oidc-usersessionmodel-note-mapper" + config: + user.session.note : "clientHost" + id.token.claim : "true" + access.token.claim : "true" + claim.name : "clientHost" + jsonType.label : "String" + - name: "Client IP Address" + protocolMapper: "oidc-usersessionmodel-note-mapper" + config: + user.session.note : "clientAddress" + id.token.claim : "true" + access.token.claim : "true" + claim.name : "clientAddress" + jsonType.label : "String" + defaultClientScopes: + - "onap_roles" + additionalClientScopes: + - name: onap_roles + description: OpenID Connect scope for add user onap roles to the access token + protocolMappers: + - name: aud + protocol: openid-connect + protocolMapper: oidc-audience-mapper + consentRequired: false + config: + included.client.audience: oauth2-proxy + id.token.claim: 'false' + access.token.claim: 'true' + - name: client roles + protocol: openid-connect + protocolMapper: oidc-usermodel-client-role-mapper + consentRequired: false + config: + multivalued: 'true' + userinfo.token.claim: 'false' + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: onap_roles + jsonType.label: String + usermodel.clientRoleMapping.clientId: oauth2-proxy + accessControl: + assignableRoles: + - name: portal_admin + description: "User role for administration tasks in the portal." + - name: portal_designer + description: "User role for designer tasks in the portal." + - name: portal_operator + description: "User role for operator tasks in the portal." + - name: onap-operator-read + description: "Allows to perform GET operations for all ONAP components" + associatedAccessRoles: [ "dmaap-bc-api-read", "dmaap-dr-node-api-read", "dmaap-dr-prov-api-read", "dmaap-mr-api-read", "msb-consul-api-read", "msb-discovery-api-read", "msb-eag-ui-read", "msb-iag-ui-read", "nbi-api-read", "aai-api-read", "aai-babel-api-read", "aai-sparkybe-api-read", "cds-blueprintsprocessor-api-read", "cds-ui-read", "cps-core-api-read", "cps-ncmp-dmi-plugin-api-read", "cps-temporal-api-read", "reaper-dc1-read", "sdc-be-api-read", "sdc-fe-ui-read", "sdc-wfd-be-api-read", "sdc-wfd-fe-ui-read", "so-admin-cockpit-ui-read", "so-api-read", "usecase-ui-read", "uui-server-read" ] + - name: onap-operator-write + description: "Allows to perform GET, POST, PUT, PATCH operations for all ONAP components" + associatedAccessRoles: [ "dmaap-bc-api-write", "dmaap-dr-node-api-write", "dmaap-dr-prov-api-write", "dmaap-mr-api-write", "msb-consul-api-write", "msb-discovery-api-write", "msb-eag-ui-write", "msb-iag-ui-write", "nbi-api-write", "aai-api-write", "aai-babel-api-write", "aai-sparkybe-api-write", "cds-blueprintsprocessor-api-write", "cds-ui-write", "cps-core-api-write", "cps-ncmp-dmi-plugin-api-write", "cps-temporal-api-write", "reaper-dc1-write", "sdc-be-api-write", "sdc-fe-ui-write", "sdc-wfd-be-api-write", "sdc-wfd-fe-ui-write", "so-admin-cockpit-ui-write", "so-api-write", "usecase-ui-write", "uui-server-write" ] + - name: onap-operator-full + description: "Allows to perform GET, POST, PUT, PATCH, DELETE operations for all ONAP components" + associatedAccessRoles: [ "dmaap-bc-api-full", "dmaap-dr-node-api-full", "dmaap-dr-prov-api-full", "dmaap-mr-api-full", "msb-consul-api-full", "msb-discovery-api-full", "msb-eag-ui-full", "msb-iag-ui-full", "nbi-api-full", "aai-api-full", "aai-babel-api-full", "aai-sparkybe-api-full", "cds-blueprintsprocessor-api-full", "cds-ui-full", "cps-core-api-full", "cps-ncmp-dmi-plugin-api-full", "cps-temporal-api-full", "reaper-dc1-full", "sdc-be-api-full", "sdc-fe-ui-full", "sdc-wfd-be-api-full", "sdc-wfd-fe-ui-full", "so-admin-cockpit-ui-full", "so-api-full", "usecase-ui-full", "uui-server-full" ] + - name: platform-operator-read + description: "Allows to perform GET operations for all ONAP components" + associatedAccessRoles: [ "grafana-read", "kibana-read" ] + - name: platform-operator-write + description: "Allows to perform GET, POST, PUT, PATCH operations for all ONAP components" + associatedAccessRoles: [ "grafana-write", "kibana-write" ] + - name: platform-operator-full + description: "Allows to perform GET, POST, PUT, PATCH, DELETE operations for all ONAP components" + associatedAccessRoles: [ "grafana-full", "kibana-full" ] + - name: platform-all-read + description: "Allows to perform GET operations for all PLATFORM components" + associatedAccessRoles: [ "dmaap-bc-api-read", "dmaap-dr-node-api-read", "dmaap-dr-prov-api-read", "dmaap-mr-api-read", "msb-consul-api-read", "msb-discovery-api-read", "msb-eag-ui-read", "msb-iag-ui-read", "nbi-api-read", "aai-api-read", "aai-babel-api-read", "aai-sparkybe-api-read", "cds-blueprintsprocessor-api-read", "cds-ui-read", "cps-core-api-read", "cps-ncmp-dmi-plugin-api-read", "cps-temporal-api-read", "grafana-read", "kibana-read", "reaper-dc1-read", "sdc-be-api-read", "sdc-fe-ui-read", "sdc-wfd-be-api-read", "sdc-wfd-fe-ui-read", "so-admin-cockpit-ui-read", "so-api-read", "usecase-ui-read", "uui-server-read" ] + - name: platform-all-write + description: "Allows to perform GET, POST, PUT, PATCH operations for all PLATFORM components" + associatedAccessRoles: [ "dmaap-bc-api-write", "dmaap-dr-node-api-write", "dmaap-dr-prov-api-write", "dmaap-mr-api-write", "msb-consul-api-write", "msb-discovery-api-write", "msb-eag-ui-write", "msb-iag-ui-write", "nbi-api-write", "aai-api-write", "aai-babel-api-write", "aai-sparkybe-api-write", "cds-blueprintsprocessor-api-write", "cds-ui-write", "cps-core-api-write", "cps-ncmp-dmi-plugin-api-write", "cps-temporal-api-write", "grafana-write", "kibana-write", "reaper-dc1-write", "sdc-be-api-write", "sdc-fe-ui-write", "sdc-wfd-be-api-write", "sdc-wfd-fe-ui-write", "so-admin-cockpit-ui-write", "so-api-write", "usecase-ui-write", "uui-server-write" ] + - name: platform-all-full + description: "Allows to perform GET, POST, PUT, PATCH, DELETE operations for all PLATFORM components" + associatedAccessRoles: [ "dmaap-bc-api-full", "dmaap-dr-node-api-full", "dmaap-dr-prov-api-full", "dmaap-mr-api-full", "msb-consul-api-full", "msb-discovery-api-full", "msb-eag-ui-full", "msb-iag-ui-full", "nbi-api-full", "aai-api-full", "aai-babel-api-full", "aai-sparkybe-api-full", "cds-blueprintsprocessor-api-full", "cds-ui-full", "cps-core-api-full", "cps-ncmp-dmi-plugin-api-full", "cps-temporal-api-full", "grafana-full", "kibana-full", "reaper-dc1-full", "sdc-be-api-full", "sdc-fe-ui-full", "sdc-wfd-be-api-full", "sdc-wfd-fe-ui-full", "so-admin-cockpit-ui-full", "so-api-full", "usecase-ui-full", "uui-server-full" ] + accessRoles: + "oauth2_proxy": + - name: dmaap-bc-api-read + methodsAllowed: ["GET"] + servicePrefix: dmaap-bc-api + - name: dmaap-bc-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: dmaap-bc-api + - name: dmaap-bc-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: dmaap-bc-api + - name: dmaap-dr-node-api-read + methodsAllowed: ["GET"] + servicePrefix: dmaap-dr-node-api + - name: dmaap-dr-node-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: dmaap-dr-node-api + - name: dmaap-dr-node-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: dmaap-dr-node-api + - name: dmaap-dr-prov-api-read + methodsAllowed: ["GET"] + servicePrefix: dmaap-dr-prov-api + - name: dmaap-dr-prov-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: dmaap-dr-prov-api + - name: dmaap-dr-prov-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: dmaap-dr-prov-api + - name: dmaap-mr-api-read + methodsAllowed: ["GET"] + servicePrefix: dmaap-mr-api + - name: dmaap-mr-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: dmaap-mr-api + - name: dmaap-mr-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: dmaap-mr-api + - name: msb-consul-api-read + methodsAllowed: ["GET"] + servicePrefix: msb-consul-api + - name: msb-consul-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: msb-consul-api + - name: msb-consul-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: msb-consul-api + - name: msb-discovery-api-read + methodsAllowed: ["GET"] + servicePrefix: msb-discovery-api + - name: msb-discovery-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: msb-discovery-api + - name: msb-discovery-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: msb-discovery-api + - name: msb-eag-ui-read + methodsAllowed: ["GET"] + servicePrefix: msb-eag-ui + - name: msb-eag-ui-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: msb-eag-ui + - name: msb-eag-ui-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: msb-eag-ui + - name: msb-iag-ui-read + methodsAllowed: ["GET"] + servicePrefix: msb-iag-ui + - name: msb-iag-ui-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: msb-iag-ui + - name: msb-iag-ui-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: msb-iag-ui + - name: nbi-api-read + methodsAllowed: ["GET"] + servicePrefix: nbi-api + - name: nbi-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: nbi-api + - name: nbi-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: nbi-api + - name: aai-api-read + methodsAllowed: ["GET"] + servicePrefix: aai-api + - name: aai-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: aai-api + - name: aai-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: aai-api + - name: aai-babel-api-read + methodsAllowed: ["GET"] + servicePrefix: aai-babel-api + - name: aai-babel-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: aai-babel-api + - name: aai-babel-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: aai-babel-api + - name: aai-sparkybe-api-read + methodsAllowed: ["GET"] + servicePrefix: aai-sparkybe-api + - name: aai-sparkybe-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: aai-sparkybe-api + - name: aai-sparkybe-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: aai-sparkybe-api + - name: cds-blueprintsprocessor-api-read + methodsAllowed: ["GET"] + servicePrefix: cds-blueprintsprocessor-api + - name: cds-blueprintsprocessor-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: cds-blueprintsprocessor-api + - name: cds-blueprintsprocessor-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: cds-blueprintsprocessor-api + - name: cds-ui-read + methodsAllowed: ["GET"] + servicePrefix: cds-ui + - name: cds-ui-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: cds-ui + - name: cds-ui-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: cds-ui + - name: cps-core-api-read + methodsAllowed: ["GET"] + servicePrefix: cps-core-api + - name: cps-core-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: cps-core-api + - name: cps-core-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: cps-core-api + - name: cps-ncmp-dmi-plugin-api-read + methodsAllowed: ["GET"] + servicePrefix: cps-ncmp-dmi-plugin-api + - name: cps-ncmp-dmi-plugin-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: cps-ncmp-dmi-plugin-api + - name: cps-ncmp-dmi-plugin-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: cps-ncmp-dmi-plugin-api + - name: cps-temporal-api-read + methodsAllowed: ["GET"] + servicePrefix: cps-temporal-api + - name: cps-temporal-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: cps-temporal-api + - name: cps-temporal-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: cps-temporal-api + - name: grafana-read + methodsAllowed: ["GET"] + servicePrefix: grafana + - name: grafana-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: grafana + - name: grafana-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: grafana + - name: kibana-read + methodsAllowed: ["GET"] + servicePrefix: kibana + - name: kibana-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: kibana + - name: kibana-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: kibana + - name: minio-read + methodsAllowed: ["GET"] + servicePrefix: minio-console + - name: minio-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: minio-console + - name: minio-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: minio-console + - name: reaper-dc1-read + methodsAllowed: ["GET"] + servicePrefix: reaper-dc1 + - name: reaper-dc1-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: reaper-dc1 + - name: reaper-dc1-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: reaper-dc1 + - name: sdc-be-api-read + methodsAllowed: ["GET"] + servicePrefix: sdc-be-api + - name: sdc-be-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: sdc-be-api + - name: sdc-be-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: sdc-be-api + - name: sdc-fe-ui-read + methodsAllowed: ["GET"] + servicePrefix: sdc-fe-ui + - name: sdc-fe-ui-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: sdc-fe-ui + - name: sdc-fe-ui-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: sdc-fe-ui + - name: sdc-wfd-be-api-read + methodsAllowed: ["GET"] + servicePrefix: sdc-wfd-be-api + - name: sdc-wfd-be-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: sdc-wfd-be-api + - name: sdc-wfd-be-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: sdc-wfd-be-api + - name: sdc-wfd-fe-ui-read + methodsAllowed: ["GET"] + servicePrefix: sdc-wfd-fe-ui + - name: sdc-wfd-fe-ui-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: sdc-wfd-fe-ui + - name: sdc-wfd-fe-ui-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: sdc-wfd-fe-ui + - name: so-admin-cockpit-ui-read + methodsAllowed: ["GET"] + servicePrefix: so-admin-cockpit-ui + - name: so-admin-cockpit-ui-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: so-admin-cockpit-ui + - name: so-admin-cockpit-ui-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: so-admin-cockpit-ui + - name: so-api-read + methodsAllowed: ["GET"] + servicePrefix: so-api + - name: so-api-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: so-api + - name: so-api-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: so-api + - name: usecase-ui-read + methodsAllowed: ["GET"] + servicePrefix: usecase-ui + - name: usecase-ui-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: usecase-ui + - name: usecase-ui-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: usecase-ui + - name: uui-server-read + methodsAllowed: ["GET"] + servicePrefix: uui-server + - name: uui-server-write + methodsAllowed: ["GET", "POST", "PUT", "PATCH"] + servicePrefix: uui-server + - name: uui-server-full + methodsAllowed: ["GET", "POST", "PUT", "PATCH", "DELETE"] + servicePrefix: uui-server |