From afbeb60f455081feb79d1212d1c164da2fbdcba3 Mon Sep 17 00:00:00 2001 From: Andrew Block Date: Sun, 10 Mar 2024 22:59:44 -0500 Subject: [PATCH 1/2] Introduction of Red Hat Build of Keycloak Signed-off-by: Andrew Block --- charts/keycloak-operator/.helmignore | 23 ++ charts/keycloak-operator/Chart.yaml | 27 ++ .../keycloak-operator/templates/_helpers.tpl | 59 +++ .../templates/operatorgroup.yaml | 20 + .../templates/subscription.yaml | 21 ++ charts/keycloak-operator/values.yaml | 16 + charts/keycloak/.helmignore | 23 ++ charts/keycloak/Chart.yaml | 28 ++ charts/keycloak/templates/_helpers.tpl | 141 +++++++ .../templates/keycloak/keycloak-ingress.yaml | 32 ++ .../templates/keycloak/keycloak-service.yaml | 24 ++ .../keycloak/templates/keycloak/keycloak.yaml | 33 ++ .../keycloak/keycloakrealmimport.yaml | 348 ++++++++++++++++++ .../postgresql/postgresql-secret.yaml | 12 + .../postgresql/postgresql-service.yaml | 18 + .../postgresql/postgresql-serviceaccount.yaml | 14 + .../postgresql/postgresql-statefulset.yaml | 83 +++++ charts/keycloak/values.yaml | 65 ++++ charts/trusted-artifact-signer/Chart.yaml | 2 +- charts/trusted-artifact-signer/README.md | 2 +- .../trusted-artifact-signer/ci/ci-values.yaml | 6 +- docs/sign-verify.md | 2 +- examples/values-kind-byodb.yaml | 6 +- examples/values-kind-sigstore.yaml | 4 +- ...es-sigstore-openshift-byo-fulcio-root.yaml | 6 +- ...lues-sigstore-openshift-byo-rekor-key.yaml | 6 +- examples/values-sigstore-openshift.yaml | 6 +- examples/values.yaml | 6 +- tas-easy-install.sh | 65 +++- tas-env-variables.sh | 4 +- 30 files changed, 1068 insertions(+), 34 deletions(-) create mode 100644 charts/keycloak-operator/.helmignore create mode 100644 charts/keycloak-operator/Chart.yaml create mode 100644 charts/keycloak-operator/templates/_helpers.tpl create mode 100644 charts/keycloak-operator/templates/operatorgroup.yaml create mode 100644 charts/keycloak-operator/templates/subscription.yaml create mode 100644 charts/keycloak-operator/values.yaml create mode 100644 charts/keycloak/.helmignore create mode 100644 charts/keycloak/Chart.yaml create mode 100644 charts/keycloak/templates/_helpers.tpl create mode 100644 charts/keycloak/templates/keycloak/keycloak-ingress.yaml create mode 100644 charts/keycloak/templates/keycloak/keycloak-service.yaml create mode 100644 charts/keycloak/templates/keycloak/keycloak.yaml create mode 100644 charts/keycloak/templates/keycloak/keycloakrealmimport.yaml create mode 100644 charts/keycloak/templates/postgresql/postgresql-secret.yaml create mode 100644 charts/keycloak/templates/postgresql/postgresql-service.yaml create mode 100644 charts/keycloak/templates/postgresql/postgresql-serviceaccount.yaml create mode 100644 charts/keycloak/templates/postgresql/postgresql-statefulset.yaml create mode 100644 charts/keycloak/values.yaml diff --git a/charts/keycloak-operator/.helmignore b/charts/keycloak-operator/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/charts/keycloak-operator/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/keycloak-operator/Chart.yaml b/charts/keycloak-operator/Chart.yaml new file mode 100644 index 00000000..7efcaf4b --- /dev/null +++ b/charts/keycloak-operator/Chart.yaml @@ -0,0 +1,27 @@ +annotations: + artifacthub.io/category: integration-delivery + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: support + url: https://github.com/securesign/sigstore-ocp/issues + - name: Chart Source + url: https://github.com/securesign/sigstore-ocp + - name: Default Image Source + url: "" + charts.openshift.io/name: KeycloakOperator + charts.openshift.io/provider: TrustedArtifactSigner + charts.openshift.io/supportURL: https://github.com/securesign/sigstore-ocp/issues +apiVersion: v2 +name: keycloak-operator +description: A Helm chart for deploying the Keycloak Operator Using the Operator Lifecycle Manager (OLM) +type: application +keywords: + - operator + - keycloak +kubeVersion: ">= 1.19.0-0" +maintainers: + - name: TrustedArtifactSigner + url: "" +sources: + - https://github.com/securesign/sigstore-ocp +version: 0.1.0 diff --git a/charts/keycloak-operator/templates/_helpers.tpl b/charts/keycloak-operator/templates/_helpers.tpl new file mode 100644 index 00000000..8c0482c9 --- /dev/null +++ b/charts/keycloak-operator/templates/_helpers.tpl @@ -0,0 +1,59 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "keycloak-operator.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-operator.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 the chart namespace. +*/}} +{{- define "keycloak-operator.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "keycloak-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "keycloak-operator.labels" -}} +helm.sh/chart: {{ include "keycloak-operator.chart" . }} +{{ include "keycloak-operator.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "keycloak-operator.selectorLabels" -}} +app.kubernetes.io/name: {{ include "keycloak-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/keycloak-operator/templates/operatorgroup.yaml b/charts/keycloak-operator/templates/operatorgroup.yaml new file mode 100644 index 00000000..48bbe70d --- /dev/null +++ b/charts/keycloak-operator/templates/operatorgroup.yaml @@ -0,0 +1,20 @@ +{{- if .Values.operatorgroup.create }} +apiVersion: operators.coreos.com/v1 +kind: OperatorGroup +metadata: + name: {{ include "keycloak-operator.fullname" . }} + generateName: {{ include "keycloak-operator.fullname" . }}- + namespace: {{ include "keycloak-operator.namespace" . }} + labels: + {{- include "keycloak-operator.labels" . | nindent 4 }} + {{- if .Values.operatorgroup.annotations }} + annotations: + {{- tpl (toYaml .Values.operatorgroup.annotations) $ | nindent 4 }} + {{- end }} +spec: + {{- if not .Values.operatorgroup.allNamespaces }} + targetNamespaces: + {{ tpl (toYaml (list (include "keycloak-operator.namespace" .))) $ }} + {{- end }} + upgradeStrategy: {{ tpl .Values.operatorgroup.upgradeStrategy $ }} +{{- end }} \ No newline at end of file diff --git a/charts/keycloak-operator/templates/subscription.yaml b/charts/keycloak-operator/templates/subscription.yaml new file mode 100644 index 00000000..a74970dc --- /dev/null +++ b/charts/keycloak-operator/templates/subscription.yaml @@ -0,0 +1,21 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: {{ include "keycloak-operator.fullname" . }} + namespace: {{ default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" }} + labels: + {{- include "keycloak-operator.labels" . | nindent 4 }} + {{- if .Values.subscription.annotations }} + annotations: + {{- tpl (toYaml .Values.subscription.annotations) $ | nindent 4 }} + {{- end }} +spec: + channel: {{ required "Operator channel is required!" .Values.subscription.channel }} + installPlanApproval: {{ default "Automatic" .Values.subscription.installPlanApproval }} + name: {{ required "Operator name is required!" .Values.subscription.name }} + source: {{ required "Operator source is required!" .Values.subscription.source }} + sourceNamespace: {{ required "Operator source namespace is required!" .Values.subscription.sourceNamespace }} +{{- if .Values.subscription.config }} + config: + {{- tpl (toYaml .Values.subscription.config) $ | nindent 4 }} +{{- end }} \ No newline at end of file diff --git a/charts/keycloak-operator/values.yaml b/charts/keycloak-operator/values.yaml new file mode 100644 index 00000000..3d11ace4 --- /dev/null +++ b/charts/keycloak-operator/values.yaml @@ -0,0 +1,16 @@ +--- + +subscription: + channel: "stable-v22" + installPlanApproval: Automatic + name: "rhbk-operator" + source: "redhat-operators" + sourceNamespace: "openshift-marketplace" + config: {} + +operatorgroup: + create: true + allNamespaces: false + upgradeStrategy: Default + +namespaceOverride: "" diff --git a/charts/keycloak/.helmignore b/charts/keycloak/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/charts/keycloak/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/keycloak/Chart.yaml b/charts/keycloak/Chart.yaml new file mode 100644 index 00000000..af911449 --- /dev/null +++ b/charts/keycloak/Chart.yaml @@ -0,0 +1,28 @@ +annotations: + artifacthub.io/category: integration-delivery + artifacthub.io/license: Apache-2.0 + artifacthub.io/links: | + - name: support + url: https://github.com/securesign/sigstore-ocp/issues + - name: Chart Source + url: https://github.com/securesign/sigstore-ocp + - name: Default Image Source + url: "" + charts.openshift.io/name: Keycloak + charts.openshift.io/provider: TrustedArtifactSigner + charts.openshift.io/supportURL: https://github.com/securesign/sigstore-ocp/issues +apiVersion: v2 +name: keycloak +description: A Helm chart for deploying the Keycloak +type: application +keywords: + - sso + - keycloak + - identity +kubeVersion: ">= 1.19.0-0" +maintainers: + - name: TrustedArtifactSigner + url: "" +sources: + - https://github.com/securesign/sigstore-ocp +version: 0.1.0 diff --git a/charts/keycloak/templates/_helpers.tpl b/charts/keycloak/templates/_helpers.tpl new file mode 100644 index 00000000..3330369e --- /dev/null +++ b/charts/keycloak/templates/_helpers.tpl @@ -0,0 +1,141 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "keycloak.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.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 the chart namespace. +*/}} +{{- define "keycloak.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "keycloak.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "keycloak.labels" -}} +helm.sh/chart: {{ include "keycloak.chart" . }} +{{ include "keycloak.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Common PostgreSQL labels +*/}} +{{- define "keycloak.postgresql.labels" -}} +helm.sh/chart: {{ include "keycloak.chart" . }} +{{ include "keycloak.postgresql.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "keycloak.selectorLabels" -}} +app.kubernetes.io/name: {{ include "keycloak.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "keycloak.postgresql.selectorLabels" -}} +app.kubernetes.io/name: {{ include "keycloak.postgresql.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "keycloak.serviceAccountName" -}} +{{- if .serviceAccount.create }} +{{- default .name .serviceAccount.name }} +{{- else }} +{{- default "default" .serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Create the image path for the passed in image field +*/}} +{{- define "keycloak.image" -}} +{{- if eq (substr 0 7 .version) "sha256:" -}} +{{- printf "%s/%s@%s" .registry .repository .version -}} +{{- else -}} +{{- printf "%s/%s:%s" .registry .repository .version -}} +{{- end -}} +{{- end -}} + +{{/* +Name of the PostgreSQL instance +*/}} +{{- define "keycloak.postgresql.name" -}} +{{- (printf "%s-%s" (include "keycloak.name" $) "postgresql") | trunc 63 | trimSuffix "-" -}} +{{- end }} + +{{/* +Full Name of the PostgreSQL instance +*/}} +{{- define "keycloak.postgresql.fullname" -}} +{{- (printf "%s-%s" (include "keycloak.fullname" $) "postgresql") | trunc 63 | trimSuffix "-" -}} +{{- end }} + +{{/* +Name of the PostgreSQL Secret +*/}} +{{- define "keycloak.postgresql.secret.name" -}} +{{ default (include "keycloak.postgresql.fullname" .) (.Values.postgresql.secret.existingSecret) }} +{{- end }} + +{{/* +Name of the Keycloak Service +*/}} +{{- define "keycloak.service.name" -}} +{{ .Values.openshift | ternary (printf "%s-trusted" (include "keycloak.fullname" .)) (include "keycloak.fullname" .) }} +{{- end }} + +{{/* +Name of the TLS Secret +*/}} +{{- define "keycloak.tls.secret.name" -}} +{{- $defaultTls := printf "%s-tls" (include "keycloak.fullname" .) }} +{{- if .Values.openshift -}} +{{- default $defaultTls .Values.keycloak.tls.secret -}} +{{- else -}} +{{ len .Values.keycloak.tls.secret }} +{{- end }} +{{- end }} diff --git a/charts/keycloak/templates/keycloak/keycloak-ingress.yaml b/charts/keycloak/templates/keycloak/keycloak-ingress.yaml new file mode 100644 index 00000000..806b7a43 --- /dev/null +++ b/charts/keycloak/templates/keycloak/keycloak-ingress.yaml @@ -0,0 +1,32 @@ +{{- $keycloakName := include "keycloak.fullname" . }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + {{- if .Values.keycloak.service.annotations }} + {{- tpl (toYaml .Values.keycloak.ingress.annotations) $ | nindent 4 }} + {{- end }} + {{- if .Values.openshift }} + route.openshift.io/termination: {{ .Values.keycloak.ingress.termination }} + route.openshift.io/destination-ca-certificate-secret: {{ $keycloakName }}-tls + {{- end }} + labels: + {{- include "keycloak.labels" . | nindent 4 }} + name: {{ include "keycloak.fullname" . }} + namespace: {{ include "keycloak.namespace" . }} +spec: + defaultBackend: + service: + name: {{ include "keycloak.service.name" . }} + port: + number: {{ .Values.keycloak.service.port }} + rules: + - host: {{ required "A valid hostname must be provided" (tpl .Values.keycloak.ingress.host $) }} + http: + paths: + - backend: + service: + name: {{ include "keycloak.service.name" . }} + port: + number: {{ .Values.keycloak.service.port }} + pathType: ImplementationSpecific diff --git a/charts/keycloak/templates/keycloak/keycloak-service.yaml b/charts/keycloak/templates/keycloak/keycloak-service.yaml new file mode 100644 index 00000000..08a3b7d4 --- /dev/null +++ b/charts/keycloak/templates/keycloak/keycloak-service.yaml @@ -0,0 +1,24 @@ +{{- if .Values.openshift -}} +{{- $keycloakName := include "keycloak.fullname" . }} +apiVersion: v1 +kind: Service +metadata: + labels: + {{- include "keycloak.labels" . | nindent 4 }} + annotations: + {{- if .Values.keycloak.service.annotations }} + {{- tpl (toYaml .Values.keycloak.service.annotations) $ | nindent 4 }} + {{- end }} + {{- if .Values.openshift }} + service.beta.openshift.io/serving-cert-secret-name: {{ include "keycloak.tls.secret.name" . }} + {{- end }} + name: {{ include "keycloak.service.name" . }} + namespace: {{ include "keycloak.namespace" . }} +spec: + ports: + - name: {{ .Values.keycloak.service.name }} + port: {{ .Values.keycloak.service.port }} + selector: + app: {{ $keycloakName }} + app.kubernetes.io/instance: {{ $keycloakName }} +{{- end }} diff --git a/charts/keycloak/templates/keycloak/keycloak.yaml b/charts/keycloak/templates/keycloak/keycloak.yaml new file mode 100644 index 00000000..73c6e5e9 --- /dev/null +++ b/charts/keycloak/templates/keycloak/keycloak.yaml @@ -0,0 +1,33 @@ +apiVersion: k8s.keycloak.org/v2alpha1 +kind: Keycloak +metadata: + labels: + {{- include "keycloak.labels" . | nindent 4 }} + name: {{ include "keycloak.fullname" . }} + namespace: {{ include "keycloak.namespace" . }} +spec: + db: + database: {{ .Values.keycloak.postgresql }} + host: {{ include "keycloak.postgresql.fullname" . }} + passwordSecret: + key: {{ .Values.postgresql.secret.passwordKey }} + name: {{ include "keycloak.postgresql.secret.name" . }} + usernameSecret: + key: {{ .Values.postgresql.secret.usernameKey }} + name: {{ include "keycloak.postgresql.secret.name" . }} + vendor: postgres + hostname: + strict: false + strictBackchannel: false + http: + {{- if .Values.keycloak.tls.enabled }} + tlsSecret: keycloak-tls + {{- else }} + httpEnabled: true + {{- end }} + ingress: + enabled: false + hostname: + hostname: {{ tpl .Values.keycloak.ingress.host $ }} + strictBackchannel: {{ not .Values.keycloak.tls.enabled }} + instances: 1 diff --git a/charts/keycloak/templates/keycloak/keycloakrealmimport.yaml b/charts/keycloak/templates/keycloak/keycloakrealmimport.yaml new file mode 100644 index 00000000..ad9f2259 --- /dev/null +++ b/charts/keycloak/templates/keycloak/keycloakrealmimport.yaml @@ -0,0 +1,348 @@ +{{- if .Values.keycloak.importRealm -}} +apiVersion: k8s.keycloak.org/v2alpha1 +kind: KeycloakRealmImport +metadata: + name: trusted-artifact-signer + namespace: {{ include "keycloak.namespace" . }} +spec: + keycloakCRName: {{ include "keycloak.fullname" . }} + realm: + realm: trusted-artifact-signer + displayName: Red Hat Trusted Artifact Signer + displayNameHtml: Red Hat Trusted Artifact Signer + enabled: true + users: + - username: jdoe + enabled: true + totp: false + emailVerified: true + firstName: Jane + lastName: Doe + email: jdoe@redhat.com + credentials: + - type: password + value: secure + disableableCredentialTypes: [] + requiredActions: [] + realmRoles: + - default-roles-trusted-artifact-signer + notBefore: 0 + groups: [] + clients: + - clientId: trusted-artifact-signer + name: trusted-artifact-signer + description: Client for Red Hat Trusted Artifact Signer authentication + surrogateAuthRequired: false + enabled: true + alwaysDisplayInConsole: false + clientAuthenticatorType: client-secret + redirectUris: + - "*" + webOrigins: [] + notBefore: 0 + bearerOnly: false + consentRequired: false + standardFlowEnabled: true + implicitFlowEnabled: false + directAccessGrantsEnabled: true + serviceAccountsEnabled: false + publicClient: true + frontchannelLogout: true + protocol: openid-connect + attributes: + oidc.ciba.grant.enabled: 'false' + oauth2.device.authorization.grant.enabled: 'false' + backchannel.logout.session.required: 'true' + backchannel.logout.revoke.offline.tokens: 'false' + authenticationFlowBindingOverrides: {} + fullScopeAllowed: true + nodeReRegistrationTimeout: -1 + defaultClientScopes: + - web-origins + - acr + - audience + - profile + - roles + - email + optionalClientScopes: [] + clientScopes: + - 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: 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: + - id: 1250283e-42b4-40aa-a56a-e9e583ee364d + 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: family name + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-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: 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: 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: 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: 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: given name + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-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: 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: 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: 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: 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: 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: 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: username + protocol: openid-connect + protocolMapper: oidc-usermodel-attribute-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: 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: 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: 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: 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-attribute-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 + - 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: audience + description: Audience for Red Hat Trusted Artifact Signer + protocol: openid-connect + attributes: + include.in.token.scope: 'true' + display.on.consent.screen: 'true' + gui.order: '' + consent.screen.text: '' + protocolMappers: + - name: audience + protocol: openid-connect + protocolMapper: oidc-hardcoded-claim-mapper + consentRequired: false + config: + claim.value: trusted-artifact-signer + userinfo.token.claim: 'true' + id.token.claim: 'true' + access.token.claim: 'true' + claim.name: aud + jsonType.label: String + access.tokenResponse.claim: 'false' + defaultDefaultClientScopes: + - role_list + - profile + - email + - roles + - web-origins + - acr +{{- end -}} diff --git a/charts/keycloak/templates/postgresql/postgresql-secret.yaml b/charts/keycloak/templates/postgresql/postgresql-secret.yaml new file mode 100644 index 00000000..e7cf234c --- /dev/null +++ b/charts/keycloak/templates/postgresql/postgresql-secret.yaml @@ -0,0 +1,12 @@ +{{- if not .Values.postgresql.secret.existingSecret -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "keycloak.postgresql.fullname" . }} + namespace: {{ include "keycloak.namespace" . }} + labels: + {{- include "keycloak.postgresql.labels" . | nindent 4 }} +data: + password: {{ (tpl .Values.postgresql.secret.password $) | b64enc }} + username: {{ (tpl .Values.postgresql.secret.username $) | b64enc }} +{{- end }} diff --git a/charts/keycloak/templates/postgresql/postgresql-service.yaml b/charts/keycloak/templates/postgresql/postgresql-service.yaml new file mode 100644 index 00000000..b018f867 --- /dev/null +++ b/charts/keycloak/templates/postgresql/postgresql-service.yaml @@ -0,0 +1,18 @@ +{{- $postgresqlName := include "keycloak.postgresql.fullname" . }} +apiVersion: v1 +kind: Service +metadata: + name: {{ $postgresqlName }} + namespace: {{ include "keycloak.namespace" . }} + labels: + {{- include "keycloak.postgresql.labels" . | nindent 4 }} + {{- if .Values.postgresql.service.annotations }} + annotations: + {{- tpl (toYaml .Values.postgresql.service.annotations) $ | nindent 4 }} + {{- end }} +spec: + ports: + - port: {{ .Values.postgresql.service.port }} + targetPort: {{ .Values.postgresql.service.port }} + selector: + {{- include "keycloak.postgresql.selectorLabels" . | nindent 4 }} diff --git a/charts/keycloak/templates/postgresql/postgresql-serviceaccount.yaml b/charts/keycloak/templates/postgresql/postgresql-serviceaccount.yaml new file mode 100644 index 00000000..450d59fa --- /dev/null +++ b/charts/keycloak/templates/postgresql/postgresql-serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if .Values.postgresql.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "keycloak.serviceAccountName" (dict "serviceAccount" .Values.postgresql.serviceAccount "name" (include "keycloak.postgresql.fullname" .)) }} + labels: + {{- include "keycloak.postgresql.labels" . | nindent 4 }} + {{- with .Values.postgresql.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + namespace: {{ include "keycloak.namespace" . }} +automountServiceAccountToken: {{ .Values.postgresql.serviceAccount.automount }} +{{- end }} diff --git a/charts/keycloak/templates/postgresql/postgresql-statefulset.yaml b/charts/keycloak/templates/postgresql/postgresql-statefulset.yaml new file mode 100644 index 00000000..9e4b452f --- /dev/null +++ b/charts/keycloak/templates/postgresql/postgresql-statefulset.yaml @@ -0,0 +1,83 @@ +--- +{{- $postgresqlName := include "keycloak.postgresql.fullname" . }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ $postgresqlName }} + namespace: {{ include "keycloak.namespace" . }} +spec: + {{- if .Values.postgresql.persistentVolumeClaimRetentionPolicy.enabled }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.postgresql.persistentVolumeClaimRetentionPolicy.whenDeleted }} + whenScaled: {{ .Values.postgresql.persistentVolumeClaimRetentionPolicy.whenScaled }} + {{- end }} + podManagementPolicy: {{ .Values.postgresql.podManagementPolicy }} + replicas: 1 + selector: + matchLabels: + {{- include "keycloak.postgresql.selectorLabels" . | nindent 6 }} + serviceName: {{ $postgresqlName }} + template: + metadata: + labels: + {{- include "keycloak.postgresql.labels" . | nindent 8 }} + spec: + containers: + - env: + - name: POSTGRESQL_USER + valueFrom: + secretKeyRef: + key: {{ .Values.postgresql.secret.usernameKey }} + name: {{ include "keycloak.postgresql.secret.name" . }} + - name: POSTGRESQL_PASSWORD + valueFrom: + secretKeyRef: + key: {{ .Values.postgresql.secret.passwordKey }} + name: {{ include "keycloak.postgresql.secret.name" . }} + - name: POSTGRESQL_DATABASE + value: {{ .Values.postgresql.database }} + image: "{{ template "keycloak.image" .Values.postgresql.image }}" + imagePullPolicy: {{ .Values.postgresql.image.pullPolicy }} + livenessProbe: {{ tpl (toYaml .Values.postgresql.livenessProbe) $ | nindent 10 }} + name: {{ $postgresqlName }} + readinessProbe: {{ tpl (toYaml .Values.postgresql.readinessProbe) $ | nindent 10 }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + volumeMounts: + - mountPath: {{ .Values.postgresql.persistence.mountPath }} + name: data + serviceAccountName: {{ include "keycloak.serviceAccountName" (dict "serviceAccount" .Values.postgresql.serviceAccount "name" (include "keycloak.postgresql.fullname" .)) }} + {{- if .Values.postgresql.image.pullSecrets }} + imagePullSecrets: + {{ tpl (toYaml .Values.postgresql.image.pullSecrets) $ | indent 8 }} + {{- end }} + securityContext: + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + terminationGracePeriodSeconds: 30 + updateStrategy: + {{- if .Values.postgresql.updateStrategy }} + rollingUpdate: {{- tpl (toYaml .Values.postgresql.updateStrategy) . | nindent 6 }} + {{- end }} + type: RollingUpdate + volumeClaimTemplates: + - apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + name: data + spec: + accessModes: + {{- if .Values.postgresql.storageClass }} + storageClassName: {{ .Values.postgresql.persistence.storageClass }} + {{- end }} + {{- range .Values.postgresql.persistence.accessModes }} + - {{ . | quote | indent 12 }} + {{- end }} + resources: + requests: + storage: {{ .Values.postgresql.persistence.size }} + volumeMode: Filesystem diff --git a/charts/keycloak/values.yaml b/charts/keycloak/values.yaml new file mode 100644 index 00000000..071fc599 --- /dev/null +++ b/charts/keycloak/values.yaml @@ -0,0 +1,65 @@ +keycloak: + service: + annotations: {} + port: 8443 + name: https + ingress: + host: "" + annotations: {} + termination: reencrypt + importRealm: true + tls: + enabled: true + secret: "" + +postgresql: + image: + registry: registry.redhat.io + repository: rhel9/postgresql-15 + pullPolicy: IfNotPresent + pullSecrets: [] + version: latest + service: + annotations: {} + port: 5432 + replicas: 1 + serviceAccount: + create: true + automount: true + annotations: {} + name: "" + secret: + existingSecret: "" + username: keycloak + password: keycloakRHTAS123 + usernameKey: username + passwordKey: password + persistentVolumeClaimRetentionPolicy: + enabled: false + whenDeleted: Retain + whenScaled: Retain + podManagementPolicy: OrderedReady + database: keycloak + livenessProbe: + exec: + command: + - /usr/libexec/check-container + - --live + readinessProbe: + exec: + command: + - /usr/libexec/check-container + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + persistence: + size: 5Gi + accessModes: + - ReadWriteOnce + mountPath: /var/lib/pgsql/data + storageClass: "" + updateStrategy: {} + +openshift: true diff --git a/charts/trusted-artifact-signer/Chart.yaml b/charts/trusted-artifact-signer/Chart.yaml index dcae92fb..4d5f26b5 100644 --- a/charts/trusted-artifact-signer/Chart.yaml +++ b/charts/trusted-artifact-signer/Chart.yaml @@ -33,4 +33,4 @@ sources: # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.52 +version: 0.1.53 diff --git a/charts/trusted-artifact-signer/README.md b/charts/trusted-artifact-signer/README.md index 9213d73e..8ed242ef 100644 --- a/charts/trusted-artifact-signer/README.md +++ b/charts/trusted-artifact-signer/README.md @@ -3,7 +3,7 @@ A Helm chart for deploying Sigstore scaffold chart that is opinionated for OpenShift -![Version: 0.1.47](https://img.shields.io/badge/Version-0.1.47-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) +![Version: 0.1.53](https://img.shields.io/badge/Version-0.1.53-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ## Overview diff --git a/charts/trusted-artifact-signer/ci/ci-values.yaml b/charts/trusted-artifact-signer/ci/ci-values.yaml index a4a4a3e8..71fd75b7 100644 --- a/charts/trusted-artifact-signer/ci/ci-values.yaml +++ b/charts/trusted-artifact-signer/ci/ci-values.yaml @@ -74,9 +74,9 @@ scaffold: config: contents: OIDCIssuers: - # https://../auth/realms/trusted-artifact-signer - ? http://keycloak-internal.keycloak-system.svc/auth/realms/trusted-artifact-signer - : IssuerURL: http://keycloak-internal.keycloak-system.svc/auth/realms/trusted-artifact-signer + # https://../realms/trusted-artifact-signer + ? http://keycloak-internal.keycloak-system.svc/realms/trusted-artifact-signer + : IssuerURL: http://keycloak-internal.keycloak-system.svc/realms/trusted-artifact-signer ClientID: trusted-artifact-signer Type: email rekor: diff --git a/docs/sign-verify.md b/docs/sign-verify.md index dae76c40..d804becc 100644 --- a/docs/sign-verify.md +++ b/docs/sign-verify.md @@ -55,7 +55,7 @@ Authenticate with the OIDC provider (Keycloak, here) using the desired credenti 4. Verify the signed image -This example that verifies an image signed with email identity `sigstore-user@email.com` and issuer `https://keycloak-keycloak.apps.com/auth/realms/trusted-artifact-signer`. +This example that verifies an image signed with email identity `sigstore-user@email.com` and issuer `https://keycloak-keycloak.apps.com/realms/trusted-artifact-signer`. ```shell cosign verify \ diff --git a/examples/values-kind-byodb.yaml b/examples/values-kind-byodb.yaml index f1ed0093..28857627 100644 --- a/examples/values-kind-byodb.yaml +++ b/examples/values-kind-byodb.yaml @@ -51,9 +51,9 @@ scaffold: config: contents: OIDCIssuers: - # https://../auth/realms/trusted-artifact-signer - ? http://keycloak-internal.keycloak-system.svc/auth/realms/trusted-artifact-signer - : IssuerURL: http://keycloak-internal.keycloak-system.svc/auth/realms/trusted-artifact-signer + # https://../realms/trusted-artifact-signer + ? http://keycloak-internal.keycloak-system.svc/realms/trusted-artifact-signer + : IssuerURL: http://keycloak-internal.keycloak-system.svc/realms/trusted-artifact-signer ClientID: trusted-artifact-signer Type: email rekor: diff --git a/examples/values-kind-sigstore.yaml b/examples/values-kind-sigstore.yaml index 841b95d3..1c2930d0 100644 --- a/examples/values-kind-sigstore.yaml +++ b/examples/values-kind-sigstore.yaml @@ -35,8 +35,8 @@ scaffold: config: contents: OIDCIssuers: - ? http://keycloak-internal.keycloak-system.svc/auth/realms/trusted-artifact-signer - : IssuerURL: http://keycloak-internal.keycloak-system.svc/auth/realms/trusted-artifact-signer + ? http://keycloak-internal.keycloak-system.svc/realms/trusted-artifact-signer + : IssuerURL: http://keycloak-internal.keycloak-system.svc/realms/trusted-artifact-signer ClientID: trusted-artifact-signer Type: email rekor: diff --git a/examples/values-sigstore-openshift-byo-fulcio-root.yaml b/examples/values-sigstore-openshift-byo-fulcio-root.yaml index 75a4cb4b..34ef8180 100644 --- a/examples/values-sigstore-openshift-byo-fulcio-root.yaml +++ b/examples/values-sigstore-openshift-byo-fulcio-root.yaml @@ -55,9 +55,9 @@ scaffold: config: contents: OIDCIssuers: - # https://../auth/realms/trusted-artifact-signer - ? https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/trusted-artifact-signer - : IssuerURL: https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/trusted-artifact-signer + # https://../realms/trusted-artifact-signer + ? https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/realms/trusted-artifact-signer + : IssuerURL: https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/realms/trusted-artifact-signer ClientID: trusted-artifact-signer Type: email rekor: diff --git a/examples/values-sigstore-openshift-byo-rekor-key.yaml b/examples/values-sigstore-openshift-byo-rekor-key.yaml index 322e2b7b..6af6f81f 100644 --- a/examples/values-sigstore-openshift-byo-rekor-key.yaml +++ b/examples/values-sigstore-openshift-byo-rekor-key.yaml @@ -43,9 +43,9 @@ scaffold: config: contents: OIDCIssuers: - # https://../auth/realms/trusted-artifact-signer - ? https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/trusted-artifact-signer - : IssuerURL: https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/trusted-artifact-signer + # https://../realms/trusted-artifact-signer + ? https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/realms/trusted-artifact-signer + : IssuerURL: https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/realms/trusted-artifact-signer ClientID: trusted-artifact-signer Type: email rekor: diff --git a/examples/values-sigstore-openshift.yaml b/examples/values-sigstore-openshift.yaml index 047a026f..130d8742 100644 --- a/examples/values-sigstore-openshift.yaml +++ b/examples/values-sigstore-openshift.yaml @@ -31,9 +31,9 @@ scaffold: config: contents: OIDCIssuers: - # https://../auth/realms/trusted-artifact-signer - ? https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/trusted-artifact-signer - : IssuerURL: https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/trusted-artifact-signer + # https://../realms/trusted-artifact-signer + ? https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/realms/trusted-artifact-signer + : IssuerURL: https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/realms/trusted-artifact-signer ClientID: trusted-artifact-signer Type: email rekor: diff --git a/examples/values.yaml b/examples/values.yaml index b22bda5a..6a27bc72 100644 --- a/examples/values.yaml +++ b/examples/values.yaml @@ -48,9 +48,9 @@ scaffold: config: contents: OIDCIssuers: - # https://../auth/realms/trusted-artifact-signer - ? https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/trusted-artifact-signer - : IssuerURL: https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/auth/realms/trusted-artifact-signer + # https://../realms/trusted-artifact-signer + ? https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/realms/trusted-artifact-signer + : IssuerURL: https://keycloak-keycloak-system.$OPENSHIFT_APPS_SUBDOMAIN/realms/trusted-artifact-signer ClientID: trusted-artifact-signer Type: email rekor: diff --git a/tas-easy-install.sh b/tas-easy-install.sh index 55316b81..d1e911a0 100755 --- a/tas-easy-install.sh +++ b/tas-easy-install.sh @@ -32,27 +32,75 @@ check_pod_status() { return 1 } -# Install SSO Operator and Keycloak service -install_sso_keycloak() { - oc apply --kustomize keycloak/operator/base - check_pod_status "keycloak-system" "rhsso-operator" +# Function to check Realm Import Status status +check_rhbk_import_status() { + local namespace="$1" + local realm_import_name="$2" + local attempts=0 + + while [[ $attempts -lt $max_attempts ]]; do + realm_import=$(oc get keycloakrealmimport "$realm_import_name" -n "$namespace" --ignore-not-found=true) + if [ -n "$realm_import" ]; then + realm_import_complete_status=$(oc get keycloakrealmimport "$realm_import_name" -n "$namespace" -o jsonpath='{.status.conditions[?(@.type=="Done")].status}') + if [ "$realm_import_complete_status" == "True" ]; then + echo "$realm_import_name Keycloak Realm Import in namespace $namespace is complete." + return 0 + fi + fi + + sleep $sleep_interval + attempts=$((attempts + 1)) + done + + echo "Timed out. Keycloak Realm Import '$realm_import_name' completed within the specified time." + return 1 +} + +# Install Red Hat Build of Keycloak +install_rhbk() { + + # Create keycloak-system namespace + oc create namespace keycloak-system --dry-run=client -o yaml | oc apply -f- + + # Create PostgreSQL secret if it does not already exist + if [[ ! -n $(oc get secret -n keycloak-system keycloak-postgresql --ignore-not-found=true) ]]; then + oc create secret generic -n keycloak-system keycloak-postgresql --from-literal=username=keycloak --from-literal=password=$(echo $(date +%s%N) | sha256sum | head -c 20) --dry-run=client -o yaml | oc apply -f- + fi + + # Install Keycloak Operator + helm upgrade -i keycloak-operator charts/keycloak-operator -n keycloak-system + + check_pod_status "keycloak-system" "rhbk-operator" # Check the return value from the function if [ $? -ne 0 ]; then echo "Pod status check failed. Exiting the script." exit 1 fi - oc apply --kustomize keycloak/resources/base - check_pod_status "keycloak-system" "keycloak-postgresql" + # Install Keycloak + helm upgrade -i keycloak charts/keycloak -n keycloak-system --set keycloak.ingress.host=keycloak-keycloak-system.$common_name --set postgresql.secret.existingSecret=keycloak-postgresql + + check_pod_status "keycloak-system" "keycloak-postgresql-0" # Check the return value from the function if [ $? -ne 0 ]; then echo "Pod status check failed. Exiting the script." exit 1 fi + + check_pod_status "keycloak-system" "keycloak-0" + # Check the return value from the function + if [ $? -ne 0 ]; then + echo "Pod status check failed. Exiting the script." + exit 1 + fi + + check_rhbk_import_status "keycloak-system" "trusted-artifact-signer" } -# Install Red Hat SSO Operator and setup Keycloak service -install_sso_keycloak +common_name=apps.$(oc get dns cluster -o jsonpath='{ .spec.baseDomain }') + +# Install Red Hat Build of Keycloak +install_rhbk mkdir -p keys-cert pushd keys-cert > /dev/null @@ -64,7 +112,6 @@ else generate_certs=false fi -common_name=apps.$(oc get dns cluster -o jsonpath='{ .spec.baseDomain }') if [ "$generate_certs" = true ]; then # Prompt for the organizationName read -p "Enter the organization name for the certificate: " organization_name diff --git a/tas-env-variables.sh b/tas-env-variables.sh index cdec2c1d..019bc1ff 100755 --- a/tas-env-variables.sh +++ b/tas-env-variables.sh @@ -9,8 +9,8 @@ export KEYCLOAK_NAMESPACE="${KEYCLOAK_NAMESPACE:=keycloak-system}" export KEYCLOAK_CLIENT_ID="${KEYCLOAK_CLIENT_ID:=trusted-artifact-signer}" export KEYCLOAK_REALM="${KEYCLOAK_REALM:=trusted-artifact-signer}" -export KEYCLOAK_HOSTNAME="${KEYCLOAK_HOSTNAME:=$(kubectl get keycloak -n ${KEYCLOAK_NAMESPACE} -o jsonpath='{.items[*].status.externalURL}')}" -export OIDC_ISSUER_URL="${OIDC_ISSUER_URL:=${KEYCLOAK_HOSTNAME}/auth/realms/${KEYCLOAK_REALM}}" +export KEYCLOAK_HOSTNAME="${KEYCLOAK_HOSTNAME:=https://$(kubectl get keycloak -n ${KEYCLOAK_NAMESPACE} -o jsonpath='{.items[*].spec.hostname.hostname}')}" +export OIDC_ISSUER_URL="${OIDC_ISSUER_URL:=${KEYCLOAK_HOSTNAME}/realms/${KEYCLOAK_REALM}}" if [[ `kubectl api-resources -o name | grep securesigns.rhtas.redhat.com` ]]; then CURRENT_NAMESPACE="${RHTAS_NAMESPACE:=$(kubectl config view --minify -o jsonpath='{..namespace}')}" From 8d82e4130d5f469de2b2acdf4fed6728909e5b5e Mon Sep 17 00:00:00 2001 From: Andrew Block Date: Tue, 12 Mar 2024 10:22:54 -0500 Subject: [PATCH 2/2] KIND testing Signed-off-by: Andrew Block --- .github/workflows/test.yaml | 7 ++++--- charts/keycloak/ci/ct-values.yaml | 5 +++++ charts/keycloak/templates/_helpers.tpl | 10 ++++++++++ .../templates/keycloak/keycloak-ingress.yaml | 5 ++++- .../keycloak/templates/keycloak/keycloak.yaml | 16 +++++++++++---- .../postgresql/postgresql-statefulset.yaml | 2 +- charts/keycloak/values.yaml | 4 ++++ kind/values-keycloak-operator.yaml | 7 +++++++ kind/values-keycloak.yaml | 20 +++++++++++++++++++ 9 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 charts/keycloak/ci/ct-values.yaml create mode 100644 kind/values-keycloak-operator.yaml create mode 100644 kind/values-keycloak.yaml diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 2bd245b2..78ce720f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -100,15 +100,16 @@ jobs: # wait for a while to be sure CRDs are installed sleep 1 kubectl create -f https://github.com/operator-framework/operator-lifecycle-manager/releases/download/v0.25.0/olm.yaml - kubectl create --kustomize keycloak/operator/overlay/kind + oc create namespace keycloak-system --dry-run=client -o yaml | oc apply -f- + helm upgrade -i -n keycloak-system charts/keycloak-operator -f kind/values/values-keycloak-operator.yaml until [ ! -z "$(kubectl get pod -l name=keycloak-operator -n keycloak-system 2>/dev/null)" ] do echo "Waiting for keycloak operator. Pods in keycloak-system namespace:" kubectl get pods -n keycloak-system sleep 10 done - kubectl create --kustomize keycloak/resources/overlay/kind - until [[ $( oc get keycloak keycloak -o jsonpath='{.status.ready}' -n keycloak-system 2>/dev/null) == "true" ]] + helm upgrade -i -n keycloak-system charts/keycloak -f kind/values/values-keycloak.yaml + until [[ $( oc get keycloak keycloak -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' -n keycloak-system 2>/dev/null) == "True" ]] do printf "Waiting for keycloak deployment. \n Keycloak ready: %s\n" $(oc get keycloak keycloak -o jsonpath='{.status.ready}' -n keycloak-system) sleep 10 diff --git a/charts/keycloak/ci/ct-values.yaml b/charts/keycloak/ci/ct-values.yaml new file mode 100644 index 00000000..bf2d36a5 --- /dev/null +++ b/charts/keycloak/ci/ct-values.yaml @@ -0,0 +1,5 @@ +--- + +keycloak: + ingress: + host: foo diff --git a/charts/keycloak/templates/_helpers.tpl b/charts/keycloak/templates/_helpers.tpl index 3330369e..12601913 100644 --- a/charts/keycloak/templates/_helpers.tpl +++ b/charts/keycloak/templates/_helpers.tpl @@ -139,3 +139,13 @@ Name of the TLS Secret {{ len .Values.keycloak.tls.secret }} {{- end }} {{- end }} + +{{/* +Keycloak hostname +*/}} +{{- define "keycloak.hostname" -}} +{{- if .Values.keycloak.strictHostname -}} +{{ required "A valid hostname must be provided" (tpl .Values.keycloak.ingress.host $) }} +{{- else -}} +{{- end -}} +{{- end }} diff --git a/charts/keycloak/templates/keycloak/keycloak-ingress.yaml b/charts/keycloak/templates/keycloak/keycloak-ingress.yaml index 806b7a43..a5467110 100644 --- a/charts/keycloak/templates/keycloak/keycloak-ingress.yaml +++ b/charts/keycloak/templates/keycloak/keycloak-ingress.yaml @@ -1,4 +1,6 @@ {{- $keycloakName := include "keycloak.fullname" . }} +{{- $keycloakHostname := include "keycloak.hostname" . }} +{{- if $keycloakHostname -}} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: @@ -21,7 +23,7 @@ spec: port: number: {{ .Values.keycloak.service.port }} rules: - - host: {{ required "A valid hostname must be provided" (tpl .Values.keycloak.ingress.host $) }} + - host: {{ $keycloakHostname }} http: paths: - backend: @@ -30,3 +32,4 @@ spec: port: number: {{ .Values.keycloak.service.port }} pathType: ImplementationSpecific +{{- end -}} diff --git a/charts/keycloak/templates/keycloak/keycloak.yaml b/charts/keycloak/templates/keycloak/keycloak.yaml index 73c6e5e9..6ba1953c 100644 --- a/charts/keycloak/templates/keycloak/keycloak.yaml +++ b/charts/keycloak/templates/keycloak/keycloak.yaml @@ -1,3 +1,4 @@ +{{- $keycloakHostname := include "keycloak.hostname" . }} apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: @@ -16,9 +17,6 @@ spec: key: {{ .Values.postgresql.secret.usernameKey }} name: {{ include "keycloak.postgresql.secret.name" . }} vendor: postgres - hostname: - strict: false - strictBackchannel: false http: {{- if .Values.keycloak.tls.enabled }} tlsSecret: keycloak-tls @@ -28,6 +26,16 @@ spec: ingress: enabled: false hostname: - hostname: {{ tpl .Values.keycloak.ingress.host $ }} + strict: {{ .Values.keycloak.strictHostname }} + {{- if $keycloakHostname }} + hostname: {{ $keycloakHostname }} + {{- end }} strictBackchannel: {{ not .Values.keycloak.tls.enabled }} instances: 1 + {{- if .Values.keycloak.resources }} + unsupported: + podTemplate: + spec: + containers: + - resources: {{- tpl (toYaml .Values.keycloak.resources) $ | nindent 14 }} + {{- end }} diff --git a/charts/keycloak/templates/postgresql/postgresql-statefulset.yaml b/charts/keycloak/templates/postgresql/postgresql-statefulset.yaml index 9e4b452f..aeadbf7e 100644 --- a/charts/keycloak/templates/postgresql/postgresql-statefulset.yaml +++ b/charts/keycloak/templates/postgresql/postgresql-statefulset.yaml @@ -55,7 +55,7 @@ spec: {{ tpl (toYaml .Values.postgresql.image.pullSecrets) $ | indent 8 }} {{- end }} securityContext: - runAsNonRoot: true + runAsNonRoot: {{ .Values.postgresql.securityContext.runAsNonRoot }} seccompProfile: type: RuntimeDefault terminationGracePeriodSeconds: 30 diff --git a/charts/keycloak/values.yaml b/charts/keycloak/values.yaml index 071fc599..7853c3b8 100644 --- a/charts/keycloak/values.yaml +++ b/charts/keycloak/values.yaml @@ -11,6 +11,8 @@ keycloak: tls: enabled: true secret: "" + resources: {} + strictHostname: true postgresql: image: @@ -54,6 +56,8 @@ postgresql: periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 + securityContext: + runAsNonRoot: true persistence: size: 5Gi accessModes: diff --git a/kind/values-keycloak-operator.yaml b/kind/values-keycloak-operator.yaml new file mode 100644 index 00000000..cd0454b4 --- /dev/null +++ b/kind/values-keycloak-operator.yaml @@ -0,0 +1,7 @@ +--- + +subscription: + channel: "fast" + name: "keycloak-operator" + source: "operatorhubio-catalog" + sourceNamespace: "olm" \ No newline at end of file diff --git a/kind/values-keycloak.yaml b/kind/values-keycloak.yaml new file mode 100644 index 00000000..fc8ddf75 --- /dev/null +++ b/kind/values-keycloak.yaml @@ -0,0 +1,20 @@ +--- + +openshift: false + +keycloak: + strictHostname: false + tls: + enabled: false + resources: + requests: + memory: 512Mi + +postgresql: + image: + registry: quay.io + repository: sclorg/postgresql-15-c9s + version: latest + + + \ No newline at end of file