diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6d6f79e44c8..f33fe6fac22 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -245,3 +245,13 @@ updates: directory: /jans-linux-setup/jans_setup/templates/jans-keycloak-link/idp-broker-api schedule: interval: daily + + - package-ecosystem: docker + directory: /docker-jans-kc-scheduler + schedule: + interval: daily + + - package-ecosystem: pip + directory: /docker-jans-kc-scheduler + schedule: + interval: daily diff --git a/.github/workflows/docker_build_image.yml b/.github/workflows/docker_build_image.yml index 58eddd8e0d7..d8b8504fa3f 100644 --- a/.github/workflows/docker_build_image.yml +++ b/.github/workflows/docker_build_image.yml @@ -26,9 +26,9 @@ on: workflow_dispatch: inputs: services: - description: 'One or set of the docker images. Format as following: "docker-jans-auth-server docker-jans-certmanager docker-jans-config-api docker-jans-configurator docker-jans-fido2 docker-jans-persistence-loader docker-jans-scim docker-jans-monolith docker-jans-loadtesting-jmeter docker-jans-link docker-jans-casa docker-jans-all-in-one docker-jans-saml docker-jans-keycloak-link"' + description: 'One or set of the docker images. Format as following: "docker-jans-auth-server docker-jans-certmanager docker-jans-config-api docker-jans-configurator docker-jans-fido2 docker-jans-persistence-loader docker-jans-scim docker-jans-monolith docker-jans-loadtesting-jmeter docker-jans-link docker-jans-casa docker-jans-all-in-one docker-jans-saml docker-jans-keycloak-link docker-jans-kc-scheduler"' required: true - default: 'docker-jans-auth-server docker-jans-certmanager docker-jans-config-api docker-jans-configurator docker-jans-fido2 docker-jans-persistence-loader docker-jans-scim docker-jans-monolith docker-jans-loadtesting-jmeter docker-jans-link docker-jans-casa docker-jans-all-in-one docker-jans-saml docker-jans-keycloak-link' + default: 'docker-jans-auth-server docker-jans-certmanager docker-jans-config-api docker-jans-configurator docker-jans-fido2 docker-jans-persistence-loader docker-jans-scim docker-jans-monolith docker-jans-loadtesting-jmeter docker-jans-link docker-jans-casa docker-jans-all-in-one docker-jans-saml docker-jans-keycloak-link docker-jans-kc-scheduler' cn_version: description: 'The war version to build the image off' required: false @@ -53,7 +53,7 @@ jobs: strategy: max-parallel: 8 matrix: - docker-images: ["auth-server", "certmanager", "config-api", "configurator", "fido2", "persistence-loader", "scim", "monolith", "loadtesting-jmeter", "link", "casa", "all-in-one", "saml", "keycloak-link"] + docker-images: ["auth-server", "certmanager", "config-api", "configurator", "fido2", "persistence-loader", "scim", "monolith", "loadtesting-jmeter", "link", "casa", "all-in-one", "saml", "keycloak-link", "kc-scheduler"] steps: - name: Harden Runner uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1 @@ -78,7 +78,7 @@ jobs: DEFAULT_ALL=${{ github.event.inputs.services }} if [ -z "$DEFAULT_ALL" ] then - DEFAULT_ALL="docker-jans-auth-server docker-jans-certmanager docker-jans-config-api docker-jans-configurator docker-jans-fido2 docker-jans-persistence-loader docker-jans-scim docker-jans-monolith docker-jans-loadtesting-jmeter docker-jans-link docker-jans-casa docker-jans-all-in-one docker-jans-saml docker-jans-keycloak-link" + DEFAULT_ALL="docker-jans-auth-server docker-jans-certmanager docker-jans-config-api docker-jans-configurator docker-jans-fido2 docker-jans-persistence-loader docker-jans-scim docker-jans-monolith docker-jans-loadtesting-jmeter docker-jans-link docker-jans-casa docker-jans-all-in-one docker-jans-saml docker-jans-keycloak-link docker-jans-kc-scheduler" else echo "$DEFAULT_ALL" fi @@ -148,7 +148,7 @@ jobs: # wait for all images in DEFAULT_ALL to be built before building the all-in-one image as it depends on all other images if [[ "docker-jans-all-in-one" =~ "${{ matrix.docker-images }}" ]]; then if [[ ${{ github.event_name != 'pull_request' }} ]]; then - TEMP_IMG="auth-server certmanager config-api configurator fido2 persistence-loader scim monolith loadtesting-jmeter link casa saml keycloak-link" + TEMP_IMG="auth-server certmanager config-api configurator fido2 persistence-loader scim monolith loadtesting-jmeter link casa saml keycloak-link kc-scheduler" for i in $TEMP_IMG; do echo "Waiting for $i to be built" sleep 30 diff --git a/charts/janssen-all-in-one/README.md b/charts/janssen-all-in-one/README.md index ac185bf947f..14ed0199857 100644 --- a/charts/janssen-all-in-one/README.md +++ b/charts/janssen-all-in-one/README.md @@ -234,6 +234,28 @@ Kubernetes: `>=v1.22.0-0` | istio.ingress | bool | `false` | Boolean flag that enables using istio gateway for Janssen. This assumes istio ingress is installed and hence the LB is available. | | istio.namespace | string | `"istio-system"` | The namespace istio is deployed in. The is normally istio-system. | | istio.tlsSecretName | string | `"istio-tls-certificate"` | | +| kc-scheduler | object | `{"additionalAnnotations":{},"additionalLabels":{},"customScripts":[],"dnsConfig":{},"dnsPolicy":"","enabled":false,"image":{"pullPolicy":"IfNotPresent","pullSecrets":[],"repository":"ghcr.io/janssenproject/jans/kc-scheduler","tag":"1.1.2_dev"},"interval":10,"lifecycle":{},"resources":{"limits":{"cpu":"300m","memory":"300Mi"},"requests":{"cpu":"300m","memory":"300Mi"}},"usrEnvs":{"normal":{},"secret":{}},"volumeMounts":[],"volumes":[]}` | Responsible for synchronizing Keycloak SAML clients | +| kc-scheduler.additionalAnnotations | object | `{}` | Additional annotations that will be added across the gateway in the format of {cert-manager.io/issuer: "letsencrypt-prod"} | +| kc-scheduler.additionalLabels | object | `{}` | Additional labels that will be added across the gateway in the format of {mylabel: "myapp"} | +| kc-scheduler.customScripts | list | `[]` | Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh | +| kc-scheduler.dnsConfig | object | `{}` | Add custom dns config | +| kc-scheduler.dnsPolicy | string | `""` | Add custom dns policy | +| kc-scheduler.enabled | bool | `false` | Boolean flag to enable/disable the kc-scheduler cronjob chart. | +| kc-scheduler.image.pullPolicy | string | `"IfNotPresent"` | Image pullPolicy to use for deploying. | +| kc-scheduler.image.pullSecrets | list | `[]` | Image Pull Secrets | +| kc-scheduler.image.repository | string | `"ghcr.io/janssenproject/jans/kc-scheduler"` | Image to use for deploying. | +| kc-scheduler.image.tag | string | `"1.1.2_dev"` | Image tag to use for deploying. | +| kc-scheduler.interval | int | `10` | Interval of running the scheduler (in minutes) | +| kc-scheduler.resources | object | `{"limits":{"cpu":"300m","memory":"300Mi"},"requests":{"cpu":"300m","memory":"300Mi"}}` | Resource specs. | +| kc-scheduler.resources.limits.cpu | string | `"300m"` | CPU limit. | +| kc-scheduler.resources.limits.memory | string | `"300Mi"` | Memory limit. | +| kc-scheduler.resources.requests.cpu | string | `"300m"` | CPU request. | +| kc-scheduler.resources.requests.memory | string | `"300Mi"` | Memory request. | +| kc-scheduler.usrEnvs | object | `{"normal":{},"secret":{}}` | Add custom normal and secret envs to the service | +| kc-scheduler.usrEnvs.normal | object | `{}` | Add custom normal envs to the service variable1: value1 | +| kc-scheduler.usrEnvs.secret | object | `{}` | Add custom secret envs to the service variable1: value1 | +| kc-scheduler.volumeMounts | list | `[]` | Configure any additional volumesMounts that need to be attached to the containers | +| kc-scheduler.volumes | list | `[]` | Configure any additional volumes that need to be attached to the pod | | kcAdminCredentialsFile | string | `"/etc/jans/conf/kc_admin_creds"` | Path to file contains Keycloak admin credentials (username and password) | | kcDbPasswordFile | string | `"/etc/jans/conf/kc_db_password"` | Path to file contains password for database access | | lbIp | string | `"22.22.22.22"` | The Loadbalancer IP created by nginx or istio on clouds that provide static IPs. This is not needed if `fqdn` is globally resolvable. | diff --git a/charts/janssen-all-in-one/templates/cronjobs.yaml b/charts/janssen-all-in-one/templates/cronjobs.yaml index 32e046257f5..9d19b7223b8 100644 --- a/charts/janssen-all-in-one/templates/cronjobs.yaml +++ b/charts/janssen-all-in-one/templates/cronjobs.yaml @@ -166,3 +166,177 @@ spec: {{- end }} restartPolicy: Never {{- end }} + +{{ if and (index .Values "kc-scheduler" "enabled") (.Values.saml.enabled) -}} +kind: CronJob +apiVersion: batch/v1 +metadata: + name: {{ include "janssen-all-in-one.fullname" . }}-kc-scheduler + namespace: {{ .Release.Namespace }} + labels: + app: {{ .Release.Name }}-{{ include "janssen-all-in-one.name" . }}-kc-scheduler +{{ include "janssen-all-in-one.labels" . | indent 4 }} +{{- if (index .Values "kc-scheduler" "additionalLabels") }} +{{ toYaml (index .Values "kc-scheduler" "additionalLabels") | indent 4 }} +{{- end }} +{{- if (index .Values "kc-scheduler" "additionalAnnotations") }} + annotations: +{{ toYaml (index .Values "kc-scheduler" "additionalAnnotations") | indent 4 }} +{{- end }} +spec: + schedule: "@every {{ index .Values "kc-scheduler" "interval" }}m" + concurrencyPolicy: Forbid + jobTemplate: + spec: + template: + metadata: + annotations: + sidecar.istio.io/inject: "false" + spec: + {{- with (index .Values "kc-scheduler" "image" "pullSecrets") }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + dnsPolicy: {{ index .Values "kc-scheduler" "dnsPolicy" | quote }} + {{- with (index .Values "kc-scheduler" "dnsConfig") }} + dnsConfig: +{{ toYaml . | indent 12 }} + {{- end }} + containers: + - name: {{ include "janssen-all-in-one.name" . }}-kc-scheduler + {{- if (index .Values "kc-scheduler" "customScripts") }} + command: + - /bin/sh + - -c + - | + {{- with (index .Values "kc-scheduler" "customScripts") }} + {{- toYaml . | replace "- " "" | nindent 20}} + {{- end }} + /app/bin/entrypoint.sh + {{- end}} + image: "{{ index .Values "kc-scheduler" "image" "repository" }}:{{ index .Values "kc-scheduler" "image" "tag" }}" + env: + {{- include "janssen-all-in-one.usr-envs" . | indent 16 }} + {{- include "janssen-all-in-one.usr-secret-envs" . | indent 16 }} + imagePullPolicy: {{ index .Values "kc-scheduler" "image" "pullPolicy" }} + lifecycle: +{{- toYaml (index .Values "kc-scheduler" "lifecycle") | nindent 16 }} + volumeMounts: + {{ if or (eq .Values.configSecretAdapter "aws") (eq .Values.configAdapterName "aws") }} + - mountPath: {{ .Values.cnAwsSharedCredentialsFile }} + name: aws-shared-credential-file + subPath: aws_shared_credential_file + - mountPath: {{ .Values.cnAwsConfigFile }} + name: aws-config-file + subPath: aws_config_file + - mountPath: {{ .Values.cnAwsSecretsReplicaRegionsFile }} + name: aws-secrets-replica-regions + subPath: aws_secrets_replica_regions + {{- end }} + {{ if or (eq .Values.configSecretAdapter "google") (eq .Values.cnPersistenceType "spanner") }} + - mountPath: {{ .Values.cnGoogleApplicationCredentials }} + name: google-sa + subPath: google-credentials.json + {{- end }} + {{ if eq .Values.configSecretAdapter "vault" }} + - name: vault + mountPath: /etc/certs/vault_role_id + subPath: vault_role_id + - name: vault + mountPath: /etc/certs/vault_secret_id + subPath: vault_secret_id + {{- end }} + {{- with (index .Values "kc-scheduler" "volumeMounts") }} +{{- toYaml . | nindent 16 }} + {{- end }} + {{- if or (eq .Values.cnPersistenceType "couchbase") (eq .Values.cnPersistenceType "hybrid") }} + {{- if not .Values.istio.enabled }} + - name: cb-crt + mountPath: "/etc/certs/couchbase.crt" + subPath: couchbase.crt + {{- end }} + - name: cb-pass + mountPath: {{ .Values.cnCouchbasePasswordFile }} + subPath: couchbase_password + {{- end }} + {{- if or (eq .Values.cnPersistenceType "sql") (eq .Values.cnPersistenceType "hybrid") }} + - name: sql-pass + mountPath: {{ .Values.cnSqlPasswordFile }} + subPath: sql_password + {{- end }} + envFrom: + - configMapRef: + name: {{ .Release.Name }}-config-cm + {{ if .Values.usrEnvs.secret }} + - secretRef: + name: {{ .Release.Name }}-global-user-custom-envs + {{- end }} + {{ if .Values.usrEnvs.normal }} + - configMapRef: + name: {{ .Release.Name }}-global-user-custom-envs + {{- end }} + {{- if .Values.testEnviroment }} + resources: {} + {{- else }} + resources: +{{- toYaml (index .Values "kc-scheduler" "resources") | nindent 16 }} + {{- end }} + volumes: + {{- with (index .Values "kc-scheduler" "volumes") }} +{{- toYaml . | nindent 12 }} + {{- end }} + {{ if or (eq .Values.configSecretAdapter "aws") (eq .Values.configAdapterName "aws") }} + - name: aws-shared-credential-file + secret: + secretName: {{ .Release.Name }}-aws-config-creds + items: + - key: aws_shared_credential_file + path: aws_shared_credential_file + - name: aws-config-file + secret: + secretName: {{ .Release.Name }}-aws-config-creds + items: + - key: aws_config_file + path: aws_config_file + - name: aws-secrets-replica-regions + secret: + secretName: {{ .Release.Name }}-aws-config-creds + items: + - key: aws_secrets_replica_regions + path: aws_secrets_replica_regions + {{- end }} + {{ if or (eq .Values.configSecretAdapter "google") (eq .Values.cnPersistenceType "spanner") }} + - name: google-sa + secret: + secretName: {{ .Release.Name }}-google-sa + {{- end }} + {{ if eq .Values.configSecretAdapter "vault" }} + - name: vault + secret: + secretName: {{ .Release.Name }}-vault + items: + - key: vault_role_id + path: vault_role_id + - key: vault_secret_id + path: vault_secret_id + {{- end }} + {{- if or (eq .Values.cnPersistenceType "couchbase") (eq .Values.cnPersistenceType "hybrid") }} + {{- if not .Values.istio.enabled }} + - name: cb-crt + secret: + secretName: {{ .Release.Name }}-cb-crt + {{- end }} + {{- end }} + {{- if or (eq .Values.cnPersistenceType "sql") (eq .Values.cnPersistenceType "hybrid") }} + - name: sql-pass + secret: + secretName: {{ .Release.Name }}-sql-pass + {{- end }} + restartPolicy: Never + {{- if not .Values.isFqdnRegistered }} + hostAliases: + - ip: {{ .Values.lbIp }} + hostnames: + - {{ .Values.fqdn }} + {{- end }} +{{- end }} diff --git a/charts/janssen-all-in-one/values.yaml b/charts/janssen-all-in-one/values.yaml index e0869979937..3f2ce6c8646 100644 --- a/charts/janssen-all-in-one/values.yaml +++ b/charts/janssen-all-in-one/values.yaml @@ -732,3 +732,62 @@ additionalAnnotations: { } # - /tmp/custom.sh # - /tmp/custom2.sh customScripts: [ ] + +# -- Responsible for synchronizing Keycloak SAML clients +kc-scheduler: + # -- Add custom normal and secret envs to the service + usrEnvs: + # -- Add custom normal envs to the service + # variable1: value1 + normal: {} + # -- Add custom secret envs to the service + # variable1: value1 + secret: {} + # -- Add custom dns policy + dnsPolicy: "" + # -- Add custom dns config + dnsConfig: {} + image: + # -- Image pullPolicy to use for deploying. + pullPolicy: IfNotPresent + # -- Image to use for deploying. + repository: ghcr.io/janssenproject/jans/kc-scheduler + # -- Image tag to use for deploying. + tag: 1.1.2_dev + # -- Image Pull Secrets + pullSecrets: [ ] + # -- Resource specs. + resources: + limits: + # -- CPU limit. + cpu: 300m + # -- Memory limit. + memory: 300Mi + requests: + # -- CPU request. + cpu: 300m + # -- Memory request. + memory: 300Mi + # -- Interval of running the scheduler (in minutes) + interval: 10 + # -- Configure any additional volumes that need to be attached to the pod + volumes: [] + # -- Configure any additional volumesMounts that need to be attached to the containers + volumeMounts: [] + # Actions on lifecycle events such as postStart and preStop + # Example + # lifecycle: + # postStart: + # exec: + # command: ["sh", "-c", "mkdir /opt/jans/jetty/jans-auth/custom/static/stylesheet/"] + lifecycle: {} + # -- Additional labels that will be added across the gateway in the format of {mylabel: "myapp"} + additionalLabels: { } + # -- Additional annotations that will be added across the gateway in the format of {cert-manager.io/issuer: "letsencrypt-prod"} + additionalAnnotations: {} + # -- Add custom scripts that have been mounted to run before the entrypoint. + # - /tmp/custom.sh + # - /tmp/custom2.sh + customScripts: [] + # -- Boolean flag to enable/disable the kc-scheduler cronjob chart. + enabled: false diff --git a/charts/janssen/Chart.yaml b/charts/janssen/Chart.yaml index 08f0d9edeb5..7f30da9406a 100644 --- a/charts/janssen/Chart.yaml +++ b/charts/janssen/Chart.yaml @@ -24,6 +24,8 @@ annotations: image: ghcr.io/janssenproject/jans/link:1.1.2_dev - name: saml image: ghcr.io/janssenproject/jans/saml:1.1.2_dev + - name: kc-scheduler + image: ghcr.io/janssenproject/jans/kc-scheduler:1.1.2_dev artifacthub.io/license: Apache-2.0 artifacthub.io/prerelease: 'true' catalog.cattle.io/certified: partner @@ -95,3 +97,7 @@ dependencies: - name: cn-istio-ingress condition: global.istio.ingress version: 1.1.2-dev + + - name: kc-scheduler + condition: global.kc-scheduler.enabled + version: 1.1.2-dev diff --git a/charts/janssen/README.md b/charts/janssen/README.md index 7886279140c..4dfc96dc173 100644 --- a/charts/janssen/README.md +++ b/charts/janssen/README.md @@ -30,6 +30,7 @@ Kubernetes: `>=v1.22.0-0` | | config | 1.1.2-dev | | | config-api | 1.1.2-dev | | | fido2 | 1.1.2-dev | +| | kc-scheduler | 1.1.2-dev | | | link | 1.1.2-dev | | | nginx-ingress | 1.1.2-dev | | | opendj | 1.1.2-dev | @@ -273,7 +274,7 @@ Kubernetes: `>=v1.22.0-0` | fido2.usrEnvs.secret | object | `{}` | Add custom secret envs to the service variable1: value1 | | fido2.volumeMounts | list | `[]` | Configure any additional volumesMounts that need to be attached to the containers | | fido2.volumes | list | `[]` | Configure any additional volumes that need to be attached to the pod | -| global | object | `{"alb":{"ingress":false},"auth-server":{"appLoggers":{"auditStatsLogLevel":"INFO","auditStatsLogTarget":"FILE","authLogLevel":"INFO","authLogTarget":"STDOUT","enableStdoutLogPrefix":"true","httpLogLevel":"INFO","httpLogTarget":"FILE","ldapStatsLogLevel":"INFO","ldapStatsLogTarget":"FILE","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"authEncKeys":"RSA1_5 RSA-OAEP","authServerServiceName":"auth-server","authSigKeys":"RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512","cnCustomJavaOptions":"","enabled":true,"ingress":{"authServerEnabled":true,"deviceCodeEnabled":true,"firebaseMessagingEnabled":true,"openidConfigEnabled":true,"u2fConfigEnabled":true,"uma2ConfigEnabled":true,"webdiscoveryEnabled":true,"webfingerEnabled":true},"lockEnabled":false},"auth-server-key-rotation":{"enabled":true,"initKeysLife":48},"awsStorageType":"io1","azureStorageAccountType":"Standard_LRS","azureStorageKind":"Managed","casa":{"appLoggers":{"casaLogLevel":"INFO","casaLogTarget":"STDOUT","enableStdoutLogPrefix":"true","timerLogLevel":"INFO","timerLogTarget":"FILE"},"casaServiceName":"casa","cnCustomJavaOptions":"","enabled":true,"ingress":{"casaEnabled":false}},"cloud":{"testEnviroment":false},"cnAwsConfigFile":"/etc/jans/conf/aws_config_file","cnAwsSecretsReplicaRegionsFile":"/etc/jans/conf/aws_secrets_replica_regions","cnAwsSharedCredentialsFile":"/etc/jans/conf/aws_shared_credential_file","cnCouchbasePasswordFile":"/etc/jans/conf/couchbase_password","cnCouchbaseSuperuserPasswordFile":"/etc/jans/conf/couchbase_superuser_password","cnDocumentStoreType":"DB","cnGoogleApplicationCredentials":"/etc/jans/conf/google-credentials.json","cnLdapCacertFile":"/etc/certs/opendj.pem","cnLdapCertFile":"/etc/certs/opendj.crt","cnLdapKeyFile":"/etc/certs/opendj.key","cnLdapPasswordFile":"/etc/jans/conf/ldap_password","cnLdapTruststoreFile":"/etc/certs/opendj.pkcs12","cnLdapTruststorePasswordFile":"/etc/jans/conf/ldap_truststore_password","cnPersistenceType":"sql","cnPrometheusPort":"","cnSqlPasswordFile":"/etc/jans/conf/sql_password","config":{"enabled":true},"config-api":{"appLoggers":{"configApiLogLevel":"INFO","configApiLogTarget":"STDOUT","enableStdoutLogPrefix":"true","ldapStatsLogLevel":"INFO","ldapStatsLogTarget":"FILE","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"cnCustomJavaOptions":"","configApiServerServiceName":"config-api","enabled":true,"ingress":{"configApiEnabled":true},"plugins":"fido2,scim,user-mgt"},"configAdapterName":"kubernetes","configSecretAdapter":"kubernetes","fido2":{"appLoggers":{"enableStdoutLogPrefix":"true","fido2LogLevel":"INFO","fido2LogTarget":"STDOUT","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"cnCustomJavaOptions":"","enabled":true,"fido2ServiceName":"fido2","ingress":{"fido2ConfigEnabled":false,"fido2Enabled":false}},"fqdn":"demoexample.jans.io","gcePdStorageType":"pd-standard","isFqdnRegistered":false,"istio":{"additionalAnnotations":{},"additionalLabels":{},"enabled":false,"gateways":[],"ingress":false,"namespace":"istio-system"},"jobTtlSecondsAfterFinished":300,"kcAdminCredentialsFile":"/etc/jans/conf/kc_admin_creds","kcDbPasswordFile":"/etc/jans/conf/kc_db_password","lbIp":"22.22.22.22","link":{"appLoggers":{"enableStdoutLogPrefix":"true","ldapStatsLogLevel":"INFO","ldapStatsLogTarget":"FILE","linkLogLevel":"INFO","linkLogTarget":"STDOUT","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"cnCustomJavaOptions":"","enabled":false,"ingress":{"linkEnabled":true},"linkServiceName":"link"},"nginx-ingress":{"enabled":true},"opendj":{"enabled":false,"ldapServiceName":"opendj"},"persistence":{"enabled":true},"saml":{"cnCustomJavaOptions":"","enabled":false,"ingress":{"samlEnabled":false},"samlServiceName":"saml"},"scim":{"appLoggers":{"enableStdoutLogPrefix":"true","ldapStatsLogLevel":"INFO","ldapStatsLogTarget":"FILE","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scimLogLevel":"INFO","scimLogTarget":"STDOUT","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"cnCustomJavaOptions":"","enabled":true,"ingress":{"scimConfigEnabled":false,"scimEnabled":false},"scimServiceName":"scim"},"storageClass":{"allowVolumeExpansion":true,"allowedTopologies":[],"mountOptions":["debug"],"parameters":{},"provisioner":"microk8s.io/hostpath","reclaimPolicy":"Retain","volumeBindingMode":"WaitForFirstConsumer"},"usrEnvs":{"normal":{},"secret":{}}}` | Parameters used globally across all services helm charts. | +| global | object | `{"alb":{"ingress":false},"auth-server":{"appLoggers":{"auditStatsLogLevel":"INFO","auditStatsLogTarget":"FILE","authLogLevel":"INFO","authLogTarget":"STDOUT","enableStdoutLogPrefix":"true","httpLogLevel":"INFO","httpLogTarget":"FILE","ldapStatsLogLevel":"INFO","ldapStatsLogTarget":"FILE","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"authEncKeys":"RSA1_5 RSA-OAEP","authServerServiceName":"auth-server","authSigKeys":"RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512","cnCustomJavaOptions":"","enabled":true,"ingress":{"authServerEnabled":true,"deviceCodeEnabled":true,"firebaseMessagingEnabled":true,"openidConfigEnabled":true,"u2fConfigEnabled":true,"uma2ConfigEnabled":true,"webdiscoveryEnabled":true,"webfingerEnabled":true},"lockEnabled":false},"auth-server-key-rotation":{"enabled":true,"initKeysLife":48},"awsStorageType":"io1","azureStorageAccountType":"Standard_LRS","azureStorageKind":"Managed","casa":{"appLoggers":{"casaLogLevel":"INFO","casaLogTarget":"STDOUT","enableStdoutLogPrefix":"true","timerLogLevel":"INFO","timerLogTarget":"FILE"},"casaServiceName":"casa","cnCustomJavaOptions":"","enabled":true,"ingress":{"casaEnabled":false}},"cloud":{"testEnviroment":false},"cnAwsConfigFile":"/etc/jans/conf/aws_config_file","cnAwsSecretsReplicaRegionsFile":"/etc/jans/conf/aws_secrets_replica_regions","cnAwsSharedCredentialsFile":"/etc/jans/conf/aws_shared_credential_file","cnCouchbasePasswordFile":"/etc/jans/conf/couchbase_password","cnCouchbaseSuperuserPasswordFile":"/etc/jans/conf/couchbase_superuser_password","cnDocumentStoreType":"DB","cnGoogleApplicationCredentials":"/etc/jans/conf/google-credentials.json","cnLdapCacertFile":"/etc/certs/opendj.pem","cnLdapCertFile":"/etc/certs/opendj.crt","cnLdapKeyFile":"/etc/certs/opendj.key","cnLdapPasswordFile":"/etc/jans/conf/ldap_password","cnLdapTruststoreFile":"/etc/certs/opendj.pkcs12","cnLdapTruststorePasswordFile":"/etc/jans/conf/ldap_truststore_password","cnPersistenceType":"sql","cnPrometheusPort":"","cnSqlPasswordFile":"/etc/jans/conf/sql_password","config":{"enabled":true},"config-api":{"appLoggers":{"configApiLogLevel":"INFO","configApiLogTarget":"STDOUT","enableStdoutLogPrefix":"true","ldapStatsLogLevel":"INFO","ldapStatsLogTarget":"FILE","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"cnCustomJavaOptions":"","configApiServerServiceName":"config-api","enabled":true,"ingress":{"configApiEnabled":true},"plugins":"fido2,scim,user-mgt"},"configAdapterName":"kubernetes","configSecretAdapter":"kubernetes","fido2":{"appLoggers":{"enableStdoutLogPrefix":"true","fido2LogLevel":"INFO","fido2LogTarget":"STDOUT","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"cnCustomJavaOptions":"","enabled":true,"fido2ServiceName":"fido2","ingress":{"fido2ConfigEnabled":false,"fido2Enabled":false}},"fqdn":"demoexample.jans.io","gcePdStorageType":"pd-standard","isFqdnRegistered":false,"istio":{"additionalAnnotations":{},"additionalLabels":{},"enabled":false,"gateways":[],"ingress":false,"namespace":"istio-system"},"jobTtlSecondsAfterFinished":300,"kc-scheduler":{"enabled":false},"kcAdminCredentialsFile":"/etc/jans/conf/kc_admin_creds","kcDbPasswordFile":"/etc/jans/conf/kc_db_password","lbIp":"22.22.22.22","link":{"appLoggers":{"enableStdoutLogPrefix":"true","ldapStatsLogLevel":"INFO","ldapStatsLogTarget":"FILE","linkLogLevel":"INFO","linkLogTarget":"STDOUT","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"cnCustomJavaOptions":"","enabled":false,"ingress":{"linkEnabled":true},"linkServiceName":"link"},"nginx-ingress":{"enabled":true},"opendj":{"enabled":false,"ldapServiceName":"opendj"},"persistence":{"enabled":true},"saml":{"cnCustomJavaOptions":"","enabled":false,"ingress":{"samlEnabled":false},"samlServiceName":"saml"},"scim":{"appLoggers":{"enableStdoutLogPrefix":"true","ldapStatsLogLevel":"INFO","ldapStatsLogTarget":"FILE","persistenceDurationLogLevel":"INFO","persistenceDurationLogTarget":"FILE","persistenceLogLevel":"INFO","persistenceLogTarget":"FILE","scimLogLevel":"INFO","scimLogTarget":"STDOUT","scriptLogLevel":"INFO","scriptLogTarget":"FILE"},"cnCustomJavaOptions":"","enabled":true,"ingress":{"scimConfigEnabled":false,"scimEnabled":false},"scimServiceName":"scim"},"storageClass":{"allowVolumeExpansion":true,"allowedTopologies":[],"mountOptions":["debug"],"parameters":{},"provisioner":"microk8s.io/hostpath","reclaimPolicy":"Retain","volumeBindingMode":"WaitForFirstConsumer"},"usrEnvs":{"normal":{},"secret":{}}}` | Parameters used globally across all services helm charts. | | global.alb.ingress | bool | `false` | Activates ALB ingress | | global.auth-server-key-rotation.enabled | bool | `true` | Boolean flag to enable/disable the auth-server-key rotation cronjob chart. | | global.auth-server-key-rotation.initKeysLife | int | `48` | The initial auth server key rotation keys life in hours | @@ -382,6 +383,7 @@ Kubernetes: `>=v1.22.0-0` | global.istio.ingress | bool | `false` | Boolean flag that enables using istio gateway for Janssen. This assumes istio ingress is installed and hence the LB is available. | | global.istio.namespace | string | `"istio-system"` | The namespace istio is deployed in. The is normally istio-system. | | global.jobTtlSecondsAfterFinished | int | `300` | https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ | +| global.kc-scheduler.enabled | bool | `false` | Boolean flag to enable/disable the kc-scheduler cronjob chart. | | global.kcAdminCredentialsFile | string | `"/etc/jans/conf/kc_admin_creds"` | Path to file contains Keycloak admin credentials (username and password) | | global.kcDbPasswordFile | string | `"/etc/jans/conf/kc_db_password"` | Path to file contains password for database access | | global.lbIp | string | `"22.22.22.22"` | The Loadbalancer IP created by nginx or istio on clouds that provide static IPs. This is not needed if `global.fqdn` is globally resolvable. | @@ -432,6 +434,27 @@ Kubernetes: `>=v1.22.0-0` | global.usrEnvs | object | `{"normal":{},"secret":{}}` | Add custom normal and secret envs to the service. Envs defined in global.userEnvs will be globally available to all services | | global.usrEnvs.normal | object | `{}` | Add custom normal envs to the service. variable1: value1 | | global.usrEnvs.secret | object | `{}` | Add custom secret envs to the service. variable1: value1 | +| kc-scheduler | object | `{"additionalAnnotations":{},"additionalLabels":{},"customScripts":[],"dnsConfig":{},"dnsPolicy":"","image":{"pullPolicy":"IfNotPresent","pullSecrets":[],"repository":"ghcr.io/janssenproject/jans/kc-scheduler","tag":"1.1.2_dev"},"interval":10,"lifecycle":{},"resources":{"limits":{"cpu":"300m","memory":"300Mi"},"requests":{"cpu":"300m","memory":"300Mi"}},"usrEnvs":{"normal":{},"secret":{}},"volumeMounts":[],"volumes":[]}` | Responsible for synchronizing Keycloak SAML clients | +| kc-scheduler.additionalAnnotations | object | `{}` | Additional annotations that will be added across the gateway in the format of {cert-manager.io/issuer: "letsencrypt-prod"} | +| kc-scheduler.additionalLabels | object | `{}` | Additional labels that will be added across the gateway in the format of {mylabel: "myapp"} | +| kc-scheduler.customScripts | list | `[]` | Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh | +| kc-scheduler.dnsConfig | object | `{}` | Add custom dns config | +| kc-scheduler.dnsPolicy | string | `""` | Add custom dns policy | +| kc-scheduler.image.pullPolicy | string | `"IfNotPresent"` | Image pullPolicy to use for deploying. | +| kc-scheduler.image.pullSecrets | list | `[]` | Image Pull Secrets | +| kc-scheduler.image.repository | string | `"ghcr.io/janssenproject/jans/kc-scheduler"` | Image to use for deploying. | +| kc-scheduler.image.tag | string | `"1.1.2_dev"` | Image tag to use for deploying. | +| kc-scheduler.interval | int | `10` | Interval of running the scheduler (in minutes) | +| kc-scheduler.resources | object | `{"limits":{"cpu":"300m","memory":"300Mi"},"requests":{"cpu":"300m","memory":"300Mi"}}` | Resource specs. | +| kc-scheduler.resources.limits.cpu | string | `"300m"` | CPU limit. | +| kc-scheduler.resources.limits.memory | string | `"300Mi"` | Memory limit. | +| kc-scheduler.resources.requests.cpu | string | `"300m"` | CPU request. | +| kc-scheduler.resources.requests.memory | string | `"300Mi"` | Memory request. | +| kc-scheduler.usrEnvs | object | `{"normal":{},"secret":{}}` | Add custom normal and secret envs to the service | +| kc-scheduler.usrEnvs.normal | object | `{}` | Add custom normal envs to the service variable1: value1 | +| kc-scheduler.usrEnvs.secret | object | `{}` | Add custom secret envs to the service variable1: value1 | +| kc-scheduler.volumeMounts | list | `[]` | Configure any additional volumesMounts that need to be attached to the containers | +| kc-scheduler.volumes | list | `[]` | Configure any additional volumes that need to be attached to the pod | | link | object | `{"additionalAnnotations":{},"additionalLabels":{},"customScripts":[],"dnsConfig":{},"dnsPolicy":"","hpa":{"behavior":{},"enabled":true,"maxReplicas":10,"metrics":[],"minReplicas":1,"targetCPUUtilizationPercentage":50},"image":{"pullPolicy":"IfNotPresent","pullSecrets":[],"repository":"ghcr.io/janssenproject/jans/link","tag":"1.1.2_dev"},"lifecycle":{},"livenessProbe":{"exec":{"command":["python3","/app/scripts/healthcheck.py"]},"initialDelaySeconds":30,"periodSeconds":30,"timeoutSeconds":5},"pdb":{"enabled":true,"maxUnavailable":"90%"},"readinessProbe":{"exec":{"command":["python3","/app/scripts/healthcheck.py"]},"initialDelaySeconds":25,"periodSeconds":25,"timeoutSeconds":5},"replicas":1,"resources":{"limits":{"cpu":"500m","memory":"1000Mi"},"requests":{"cpu":"500m","memory":"1000Mi"}},"topologySpreadConstraints":{},"usrEnvs":{"normal":{},"secret":{}},"volumeMounts":[],"volumes":[]}` | Link. | | link.additionalAnnotations | object | `{}` | Additional annotations that will be added across the gateway in the format of {cert-manager.io/issuer: "letsencrypt-prod"} | | link.additionalLabels | object | `{}` | Additional labels that will be added across the gateway in the format of {mylabel: "myapp"} | diff --git a/charts/janssen/charts/kc-scheduler/.helmignore b/charts/janssen/charts/kc-scheduler/.helmignore new file mode 100644 index 00000000000..f0c13194444 --- /dev/null +++ b/charts/janssen/charts/kc-scheduler/.helmignore @@ -0,0 +1,21 @@ +# 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 diff --git a/charts/janssen/charts/kc-scheduler/Chart.yaml b/charts/janssen/charts/kc-scheduler/Chart.yaml new file mode 100644 index 00000000000..b97a4a150ef --- /dev/null +++ b/charts/janssen/charts/kc-scheduler/Chart.yaml @@ -0,0 +1,19 @@ + +apiVersion: v2 +name: kc-scheduler +version: 1.1.2-dev +kubeVersion: ">=v1.22.0-0" +description: Responsible for synchronizing Keycloak SAML clients +type: application +keywords: + - Keycloak + - SAML +home: https://jans.io +sources: + - https://github.com/JanssenProject/jans/docker-jans-kc-scheduler +maintainers: + - name: Mohammad Abudayyeh + email: support@jans.io + url: https://github.com/moabu +icon: https://github.com/JanssenProject/jans/raw/main/docs/assets/logo/janssen_project_favicon_transparent_50px_50px.png +appVersion: "1.1.2-dev" diff --git a/charts/janssen/charts/kc-scheduler/README.md b/charts/janssen/charts/kc-scheduler/README.md new file mode 100644 index 00000000000..29de06b8aa7 --- /dev/null +++ b/charts/janssen/charts/kc-scheduler/README.md @@ -0,0 +1,50 @@ +# kc-scheduler + +![Version: 1.1.2-dev](https://img.shields.io/badge/Version-1.1.2--dev-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.1.2-dev](https://img.shields.io/badge/AppVersion-1.1.2--dev-informational?style=flat-square) + +Responsible for synchronizing Keycloak SAML clients + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| Mohammad Abudayyeh | | | + +## Source Code + +* + +## Requirements + +Kubernetes: `>=v1.22.0-0` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| additionalAnnotations | object | `{}` | Additional annotations that will be added across the gateway in the format of {cert-manager.io/issuer: "letsencrypt-prod"} | +| additionalLabels | object | `{}` | Additional labels that will be added across the gateway in the format of {mylabel: "myapp"} | +| customScripts | list | `[]` | Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh | +| dnsConfig | object | `{}` | Add custom dns config | +| dnsPolicy | string | `""` | Add custom dns policy | +| image.pullPolicy | string | `"IfNotPresent"` | Image pullPolicy to use for deploying. | +| image.pullSecrets | list | `[]` | Image Pull Secrets | +| image.repository | string | `"ghcr.io/janssenproject/jans/kc-scheduler"` | Image to use for deploying. | +| image.tag | string | `"1.1.2_dev"` | Image tag to use for deploying. | +| interval | int | `10` | Interval of running the scheduler (in minutes) | +| lifecycle | object | `{}` | | +| resources | object | `{"limits":{"cpu":"300m","memory":"300Mi"},"requests":{"cpu":"300m","memory":"300Mi"}}` | Resource specs. | +| resources.limits.cpu | string | `"300m"` | CPU limit. | +| resources.limits.memory | string | `"300Mi"` | Memory limit. | +| resources.requests.cpu | string | `"300m"` | CPU request. | +| resources.requests.memory | string | `"300Mi"` | Memory request. | +| usrEnvs | object | `{"normal":{},"secret":{}}` | Add custom normal and secret envs to the service | +| usrEnvs.normal | object | `{}` | Add custom normal envs to the service variable1: value1 | +| usrEnvs.secret | object | `{}` | Add custom secret envs to the service variable1: value1 | +| volumeMounts | list | `[]` | Configure any additional volumesMounts that need to be attached to the containers | +| volumes | list | `[]` | Configure any additional volumes that need to be attached to the pod | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/charts/janssen/charts/kc-scheduler/templates/_helpers.tpl b/charts/janssen/charts/kc-scheduler/templates/_helpers.tpl new file mode 100644 index 00000000000..5cf07a22fe2 --- /dev/null +++ b/charts/janssen/charts/kc-scheduler/templates/_helpers.tpl @@ -0,0 +1,68 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "kc-scheduler.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 "kc-scheduler.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 "kc-scheduler.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* + Common labels +*/}} +{{- define "kc-scheduler.labels" -}} +app: {{ .Release.Name }}-{{ include "kc-scheduler.name" . }} +helm.sh/chart: {{ include "kc-scheduler.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Create user custom defined envs +*/}} +{{- define "kc-scheduler.usr-envs"}} +{{- range $key, $val := .Values.usrEnvs.normal }} +- name: {{ $key }} + value: {{ $val | quote }} +{{- end }} +{{- end }} + +{{/* +Create user custom defined secret envs +*/}} +{{- define "kc-scheduler.usr-secret-envs"}} +{{- range $key, $val := .Values.usrEnvs.secret }} +- name: {{ $key }} + valueFrom: + secretKeyRef: + name: {{ $.Release.Name }}-{{ $.Chart.Name }}-user-custom-envs + key: {{ $key | quote }} +{{- end }} +{{- end }} diff --git a/charts/janssen/charts/kc-scheduler/templates/cronjobs.yaml b/charts/janssen/charts/kc-scheduler/templates/cronjobs.yaml new file mode 100644 index 00000000000..35ac223984f --- /dev/null +++ b/charts/janssen/charts/kc-scheduler/templates/cronjobs.yaml @@ -0,0 +1,196 @@ +{{ if and (index .Values "global" "kc-scheduler" "enabled") (.Values.global.saml.enabled) -}} +kind: CronJob +apiVersion: batch/v1 +metadata: + name: {{ include "kc-scheduler.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + APP_NAME: kc-scheduler + release: {{ .Release.Name }} +{{ include "kc-scheduler.labels" . | indent 4 }} +{{- if .Values.additionalLabels }} +{{ toYaml .Values.additionalLabels | indent 4 }} +{{- end }} +{{- if .Values.additionalAnnotations }} + annotations: +{{ toYaml .Values.additionalAnnotations | indent 4 }} +{{- end }} +spec: + schedule: "@every {{ .Values.interval }}m" + concurrencyPolicy: Forbid + jobTemplate: + spec: + template: + metadata: + annotations: + sidecar.istio.io/inject: "false" + spec: + {{- with .Values.image.pullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.dnsPolicy | quote }} + {{- with .Values.dnsConfig }} + dnsConfig: +{{ toYaml . | indent 12 }} + {{- end }} + containers: + - name: {{ include "kc-scheduler.name" . }} + {{- if .Values.customScripts }} + command: + - /bin/sh + - -c + - | + {{- with .Values.customScripts }} + {{- toYaml . | replace "- " "" | nindent 20}} + {{- end }} + /app/scripts/entrypoint.sh + {{- end}} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + env: + {{- include "kc-scheduler.usr-envs" . | indent 16 }} + {{- include "kc-scheduler.usr-secret-envs" . | indent 16 }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + lifecycle: +{{- toYaml .Values.lifecycle | nindent 16 }} + volumeMounts: + {{ if or (eq .Values.global.configSecretAdapter "aws") (eq .Values.global.configAdapterName "aws") }} + - mountPath: {{ .Values.global.cnAwsSharedCredentialsFile }} + name: aws-shared-credential-file + subPath: aws_shared_credential_file + - mountPath: {{ .Values.global.cnAwsConfigFile }} + name: aws-config-file + subPath: aws_config_file + - mountPath: {{ .Values.global.cnAwsSecretsReplicaRegionsFile }} + name: aws-secrets-replica-regions + subPath: aws_secrets_replica_regions + {{- end }} + {{ if or (eq .Values.global.configSecretAdapter "google") (eq .Values.global.cnPersistenceType "spanner") }} + - mountPath: {{ .Values.global.cnGoogleApplicationCredentials }} + name: google-sa + subPath: google-credentials.json + {{- end }} + {{ if eq .Values.global.configSecretAdapter "vault" }} + - name: vault + mountPath: /etc/certs/vault_role_id + subPath: vault_role_id + - name: vault + mountPath: /etc/certs/vault_secret_id + subPath: vault_secret_id + {{- end }} + {{- with .Values.volumeMounts }} +{{- toYaml . | nindent 16 }} + {{- end }} + {{- if or (eq .Values.global.cnPersistenceType "couchbase") (eq .Values.global.cnPersistenceType "hybrid") }} + {{- if not .Values.global.istio.enabled }} + - name: cb-crt + mountPath: "/etc/certs/couchbase.crt" + subPath: couchbase.crt + {{- end }} + - name: cb-pass + mountPath: {{ .Values.global.cnCouchbasePasswordFile }} + subPath: couchbase_password + {{- end }} + {{- if or (eq .Values.global.cnPersistenceType "sql") (eq .Values.global.cnPersistenceType "hybrid") }} + - name: sql-pass + mountPath: {{ .Values.global.cnSqlPasswordFile }} + subPath: sql_password + {{- end }} + {{- if or (eq .Values.global.cnPersistenceType "ldap") (eq .Values.global.cnPersistenceType "hybrid") }} + - name: ldap-pass + mountPath: {{ .Values.global.cnLdapPasswordFile }} + subPath: ldap_password + {{- end }} + envFrom: + - configMapRef: + name: {{ .Release.Name }}-config-cm + {{ if .Values.global.usrEnvs.secret }} + - secretRef: + name: {{ .Release.Name }}-global-user-custom-envs + {{- end }} + {{ if .Values.global.usrEnvs.normal }} + - configMapRef: + name: {{ .Release.Name }}-global-user-custom-envs + {{- end }} + {{- if and ( .Values.global.opendj.enabled ) (or (eq .Values.global.storageClass.provisioner "microk8s.io/hostpath" ) (eq .Values.global.storageClass.provisioner "k8s.io/minikube-hostpath")) }} + resources: {} + {{- else if .Values.global.cloud.testEnviroment }} + resources: {} + {{- else }} + resources: +{{- toYaml .Values.resources | nindent 16 }} + {{- end }} + volumes: + {{- with .Values.volumes }} +{{- toYaml . | nindent 12 }} + {{- end }} + {{ if or (eq .Values.global.configSecretAdapter "aws") (eq .Values.global.configAdapterName "aws") }} + - name: aws-shared-credential-file + secret: + secretName: {{ .Release.Name }}-aws-config-creds + items: + - key: aws_shared_credential_file + path: aws_shared_credential_file + - name: aws-config-file + secret: + secretName: {{ .Release.Name }}-aws-config-creds + items: + - key: aws_config_file + path: aws_config_file + - name: aws-secrets-replica-regions + secret: + secretName: {{ .Release.Name }}-aws-config-creds + items: + - key: aws_secrets_replica_regions + path: aws_secrets_replica_regions + {{- end }} + {{ if or (eq .Values.global.configSecretAdapter "google") (eq .Values.global.cnPersistenceType "spanner") }} + - name: google-sa + secret: + secretName: {{ .Release.Name }}-google-sa + {{- end }} + {{ if eq .Values.global.configSecretAdapter "vault" }} + - name: vault + secret: + secretName: {{ .Release.Name }}-vault + items: + - key: vault_role_id + path: vault_role_id + - key: vault_secret_id + path: vault_secret_id + {{- end }} + {{- if or (eq .Values.global.cnPersistenceType "couchbase") (eq .Values.global.cnPersistenceType "hybrid") }} + {{- if not .Values.global.istio.enabled }} + - name: cb-crt + secret: + secretName: {{ .Release.Name }}-cb-crt + {{- end }} + - name: cb-pass + secret: + secretName: {{ .Release.Name }}-cb-pass + items: + # we are mostly need non-superuser couchbase password file here + - key: couchbase_password + path: couchbase_password + {{- end }} + {{- if or (eq .Values.global.cnPersistenceType "sql") (eq .Values.global.cnPersistenceType "hybrid") }} + - name: sql-pass + secret: + secretName: {{ .Release.Name }}-sql-pass + {{- end }} + {{- if or (eq .Values.global.cnPersistenceType "ldap") (eq .Values.global.cnPersistenceType "hybrid") }} + - name: ldap-pass + secret: + secretName: {{ .Release.Name }}-ldap-pass + items: + - key: ldap_password + path: ldap_password + {{- end }} + restartPolicy: Never + {{- if not .Values.global.isFqdnRegistered }} + hostAliases: + - ip: {{ .Values.global.lbIp }} + hostnames: + - {{ .Values.global.fqdn }} + {{- end }} +{{- end }} diff --git a/charts/janssen/charts/kc-scheduler/templates/service.yaml b/charts/janssen/charts/kc-scheduler/templates/service.yaml new file mode 100644 index 00000000000..e32662e04ad --- /dev/null +++ b/charts/janssen/charts/kc-scheduler/templates/service.yaml @@ -0,0 +1,25 @@ +{{- if .Values.global.istio.enabled }} +# License terms and conditions: +# https://www.apache.org/licenses/LICENSE-2.0 +apiVersion: v1 +kind: Service +metadata: + name: {{ include "kc-scheduler.fullname" . }} + labels: +{{ include "kc-scheduler.labels" . | indent 4 }} +{{- if .Values.additionalLabels }} +{{ toYaml .Values.additionalLabels | indent 4 }} +{{- end }} +{{- if .Values.additionalAnnotations }} + annotations: +{{ toYaml .Values.additionalAnnotations | indent 4 }} +{{- end }} +spec: + ports: + - name: http + port: 80 + targetPort: 8080 + selector: + app: {{ .Release.Name }}-{{ include "kc-scheduler.name" . }} + type: ClusterIP +{{- end }} diff --git a/charts/janssen/charts/kc-scheduler/templates/user-custom-secret-envs.yaml b/charts/janssen/charts/kc-scheduler/templates/user-custom-secret-envs.yaml new file mode 100644 index 00000000000..8c6cb6075af --- /dev/null +++ b/charts/janssen/charts/kc-scheduler/templates/user-custom-secret-envs.yaml @@ -0,0 +1,20 @@ +{{ if .Values.usrEnvs.secret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-{{ .Chart.Name }}-user-custom-envs + labels: +{{ include "kc-scheduler.labels" . | indent 4 }} +{{- if .Values.additionalLabels }} +{{ toYaml .Values.additionalLabels | indent 4 }} +{{- end }} +{{- if .Values.additionalAnnotations }} + annotations: +{{ toYaml .Values.additionalAnnotations | indent 4 }} +{{- end }} +type: Opaque +data: + {{- range $key, $val := .Values.usrEnvs.secret }} + {{ $key }}: {{ $val | b64enc }} + {{- end}} +{{- end}} diff --git a/charts/janssen/charts/kc-scheduler/values.yaml b/charts/janssen/charts/kc-scheduler/values.yaml new file mode 100644 index 00000000000..a5457fa5cb7 --- /dev/null +++ b/charts/janssen/charts/kc-scheduler/values.yaml @@ -0,0 +1,54 @@ +# -- Add custom normal and secret envs to the service +usrEnvs: + # -- Add custom normal envs to the service + # variable1: value1 + normal: {} + # -- Add custom secret envs to the service + # variable1: value1 + secret: {} +# -- Add custom dns policy +dnsPolicy: "" +# -- Add custom dns config +dnsConfig: {} +image: + # -- Image pullPolicy to use for deploying. + pullPolicy: IfNotPresent + # -- Image to use for deploying. + repository: ghcr.io/janssenproject/jans/kc-scheduler + # -- Image tag to use for deploying. + tag: 1.1.2_dev + # -- Image Pull Secrets + pullSecrets: [ ] +# -- Resource specs. +resources: + limits: + # -- CPU limit. + cpu: 300m + # -- Memory limit. + memory: 300Mi + requests: + # -- CPU request. + cpu: 300m + # -- Memory request. + memory: 300Mi +# -- Interval of running the scheduler (in minutes) +interval: 10 +# -- Configure any additional volumes that need to be attached to the pod +volumes: [] +# -- Configure any additional volumesMounts that need to be attached to the containers +volumeMounts: [] +# Actions on lifecycle events such as postStart and preStop +# Example +# lifecycle: +# postStart: +# exec: +# command: ["sh", "-c", "mkdir /opt/jans/jetty/jans-auth/custom/static/stylesheet/"] +lifecycle: {} +# -- Additional labels that will be added across the gateway in the format of {mylabel: "myapp"} +additionalLabels: { } +# -- Additional annotations that will be added across the gateway in the format of {cert-manager.io/issuer: "letsencrypt-prod"} +additionalAnnotations: {} +# -- Add custom scripts that have been mounted to run before the entrypoint. +# - /tmp/custom.sh +# - /tmp/custom2.sh +customScripts: [] diff --git a/charts/janssen/values.schema.json b/charts/janssen/values.schema.json index 45b2cd28158..59cfc96ac81 100644 --- a/charts/janssen/values.schema.json +++ b/charts/janssen/values.schema.json @@ -918,6 +918,11 @@ , "type": "object", "properties": {} + }, + "kc-scheduler": { + "description": "Responsible for synchronizing Keycloak SAML clients", + "type": "object", + "properties": {} } }, "allOf": [ @@ -950,6 +955,9 @@ }, { "$ref": "#/definitions/saml-enabled" + }, + { + "$ref": "#/definitions/kc-scheduler-enabled" } ], "definitions": { @@ -2459,6 +2467,119 @@ } }, "else": true + }, + "kc-scheduler-enabled": { + "if": { + "properties": { + "global": { + "properties": { + "kc-scheduler": { + "properties": { + "enabled": { + "const": "true" + } + } + } + } + } + } + }, + "then": { + "properties": { + "kc-scheduler": { + "properties": { + "usrEnvs": { + "description": "Add custom normal and secret envs to the service", + "type": "object", + "properties": { + "normal": { + "description": "Add custom normal envs to the service", + "type": "object" + }, + "secret": { + "description": "Add custom secret envs to the service", + "type": "object" + } + } + }, + "dnsPolicy": { + "description": "Add custom dns policy", + "type": "string", + "pattern": "^(Default|ClusterFirst|ClusterFirstWithHostNet|None|)$" + }, + "dnsConfig": { + "description": "Add custom dns config", + "type": "object" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "description": "Image pullPolicy to use for deploying.", + "type": "string", + "pattern": "^(Always|Never|IfNotPresent)$" + }, + "repository": { + "description": "Image to use for deploying", + "type": "string" + }, + "tag": { + "description": "Image tag to use for deploying.", + "type": "string", + "pattern": "^[a-z0-9-_.]+$" + } + } + }, + "interval": { + "description": "Interval of running the scheduler (in minutes)", + "type": "integer" + }, + "resources": { + "description": "Resource specs.", + "type": "object", + "properties": { + "limits": { + "type": "object", + "properties": { + "cpu": { + "description": "CPU limit.", + "type": "string", + "pattern": "^[0-9m]+$" + }, + "memory": { + "description": "Memory limit.", + "type": "string", + "pattern": "^[0-9Mi]+$" + } + } + }, + "requests": { + "type": "object", + "properties": { + "cpu": { + "description": "CPU request.", + "type": "string", + "pattern": "^[0-9m]+$" + }, + "memory": { + "description": "Memory request.", + "type": "string", + "pattern": "^[0-9Mi]+$" + } + } + } + } + } + }, + "required": [ + "image", + "resources", + "interval" + ] + } + } + }, + "else": true } } } diff --git a/charts/janssen/values.yaml b/charts/janssen/values.yaml index 76953639bea..8a30adb40f4 100644 --- a/charts/janssen/values.yaml +++ b/charts/janssen/values.yaml @@ -1049,7 +1049,7 @@ global: # Enable saml endpoints /kc samlEnabled: false # -- passing custom java options to saml. DO NOT PASS JAVA_OPTIONS in envs. - cnCustomJavaOptions: "" + cnCustomJavaOptions: "" # -- Path to SQL password file cnSqlPasswordFile: /etc/jans/conf/sql_password # -- Path to Couchbase password file @@ -1072,6 +1072,9 @@ global: kcDbPasswordFile: /etc/jans/conf/kc_db_password # -- Path to file contains Keycloak admin credentials (username and password) kcAdminCredentialsFile: /etc/jans/conf/kc_admin_creds + kc-scheduler: + # -- Boolean flag to enable/disable the kc-scheduler cronjob chart. + enabled: false # -- Nginx ingress definitions chart nginx-ingress: @@ -1679,3 +1682,60 @@ saml: # - /tmp/custom.sh # - /tmp/custom2.sh customScripts: [ ] + +# -- Responsible for synchronizing Keycloak SAML clients +kc-scheduler: + # -- Add custom normal and secret envs to the service + usrEnvs: + # -- Add custom normal envs to the service + # variable1: value1 + normal: {} + # -- Add custom secret envs to the service + # variable1: value1 + secret: {} + # -- Add custom dns policy + dnsPolicy: "" + # -- Add custom dns config + dnsConfig: {} + image: + # -- Image pullPolicy to use for deploying. + pullPolicy: IfNotPresent + # -- Image to use for deploying. + repository: ghcr.io/janssenproject/jans/kc-scheduler + # -- Image tag to use for deploying. + tag: 1.1.2_dev + # -- Image Pull Secrets + pullSecrets: [ ] + # -- Resource specs. + resources: + limits: + # -- CPU limit. + cpu: 300m + # -- Memory limit. + memory: 300Mi + requests: + # -- CPU request. + cpu: 300m + # -- Memory request. + memory: 300Mi + # -- Interval of running the scheduler (in minutes) + interval: 10 + # -- Configure any additional volumes that need to be attached to the pod + volumes: [] + # -- Configure any additional volumesMounts that need to be attached to the containers + volumeMounts: [] + # Actions on lifecycle events such as postStart and preStop + # Example + # lifecycle: + # postStart: + # exec: + # command: ["sh", "-c", "mkdir /opt/jans/jetty/jans-auth/custom/static/stylesheet/"] + lifecycle: {} + # -- Additional labels that will be added across the gateway in the format of {mylabel: "myapp"} + additionalLabels: { } + # -- Additional annotations that will be added across the gateway in the format of {cert-manager.io/issuer: "letsencrypt-prod"} + additionalAnnotations: {} + # -- Add custom scripts that have been mounted to run before the entrypoint. + # - /tmp/custom.sh + # - /tmp/custom2.sh + customScripts: [] diff --git a/docker-jans-kc-scheduler/.dockerignore b/docker-jans-kc-scheduler/.dockerignore new file mode 100644 index 00000000000..9bc4efd4324 --- /dev/null +++ b/docker-jans-kc-scheduler/.dockerignore @@ -0,0 +1,13 @@ +# exclude everything +* + +# include required files/directories +!certs +!conf +!jetty +!libs +!scripts +!LICENSE +!static +!requirements.txt +!templates diff --git a/docker-jans-kc-scheduler/.hadolint.yaml b/docker-jans-kc-scheduler/.hadolint.yaml new file mode 100644 index 00000000000..428f8174ee2 --- /dev/null +++ b/docker-jans-kc-scheduler/.hadolint.yaml @@ -0,0 +1,4 @@ +ignored: + - DL3018 # Pin versions in apk add + - DL3013 # Pin versions in pip + - DL3003 # Use WORKDIR to switch to a directory diff --git a/docker-jans-kc-scheduler/CHANGELOG.md b/docker-jans-kc-scheduler/CHANGELOG.md new file mode 100644 index 00000000000..825c32f0d03 --- /dev/null +++ b/docker-jans-kc-scheduler/CHANGELOG.md @@ -0,0 +1 @@ +# Changelog diff --git a/docker-jans-kc-scheduler/Dockerfile b/docker-jans-kc-scheduler/Dockerfile new file mode 100644 index 00000000000..79c3c7451a6 --- /dev/null +++ b/docker-jans-kc-scheduler/Dockerfile @@ -0,0 +1,152 @@ +FROM bellsoft/liberica-openjre-alpine:17.0.9@sha256:7c9948b1e267037b7cadfe448e732b9cb719bfd38d8c5811f2f2d33cc0c05123 + +# =============== +# Alpine packages +# =============== + +RUN apk update \ + && apk upgrade --available \ + && apk add --no-cache openssl python3 tini curl py3-cryptography py3-psycopg2 py3-grpcio bash \ + && apk add --no-cache --virtual .build-deps wget git zip + +# ============ +# KC scheduler +# ============ + +ENV CN_VERSION=1.1.2-SNAPSHOT +ENV CN_BUILD_DATE='2024-05-07 13:32' +ENV SCHEDULER_HOME=/opt/kc-scheduler + +RUN mkdir -p ${SCHEDULER_HOME}/bin \ + ${SCHEDULER_HOME}/conf \ + ${SCHEDULER_HOME}/lib \ + ${SCHEDULER_HOME}/logs + +RUN wget -q https://jenkins.jans.io/maven/io/jans/kc-jans-scheduler/${CN_VERSION}/kc-jans-scheduler-${CN_VERSION}-deps.zip -O /tmp/kc-scheduler.zip \ + && unzip /tmp/kc-scheduler.zip -d ${SCHEDULER_HOME}/lib \ + && rm -rf /tmp/kc-scheduler.zip \ + && wget -q https://jenkins.jans.io/maven/io/jans/kc-jans-scheduler/${CN_VERSION}/kc-jans-scheduler-${CN_VERSION}.jar -P ${SCHEDULER_HOME}/lib + +# ================== +# Logback extra libs +# ================== + +RUN wget -q https://repo1.maven.org/maven2/org/codehaus/janino/janino/3.1.9/janino-3.1.9.jar -P ${SCHEDULER_HOME}/lib \ + && wget -q https://repo1.maven.org/maven2/org/codehaus/janino/commons-compiler/3.1.9/commons-compiler-3.1.9.jar -P ${SCHEDULER_HOME}/lib + +# ====== +# Python +# ====== + +COPY requirements.txt /app/requirements.txt +RUN python3 -m ensurepip \ + && pip3 install --no-cache-dir -U pip wheel setuptools \ + && pip3 install --no-cache-dir -r /app/requirements.txt \ + && pip3 uninstall -y pip wheel + +# ======= +# Cleanup +# ======= + +RUN apk del .build-deps \ + && rm -rf /var/cache/apk/* + +# ======= +# License +# ======= + +COPY LICENSE /licenses/LICENSE + +# ========== +# Config ENV +# ========== + +ENV CN_CONFIG_ADAPTER=consul \ + CN_CONFIG_CONSUL_HOST=localhost \ + CN_CONFIG_CONSUL_PORT=8500 \ + CN_CONFIG_CONSUL_CONSISTENCY=stale \ + CN_CONFIG_CONSUL_SCHEME=http \ + CN_CONFIG_CONSUL_VERIFY=false \ + CN_CONFIG_CONSUL_CACERT_FILE=/etc/certs/consul_ca.crt \ + CN_CONFIG_CONSUL_CERT_FILE=/etc/certs/consul_client.crt \ + CN_CONFIG_CONSUL_KEY_FILE=/etc/certs/consul_client.key \ + CN_CONFIG_CONSUL_TOKEN_FILE=/etc/certs/consul_token \ + CN_CONFIG_CONSUL_NAMESPACE=jans \ + CN_CONFIG_KUBERNETES_NAMESPACE=default \ + CN_CONFIG_KUBERNETES_CONFIGMAP=jans \ + CN_CONFIG_KUBERNETES_USE_KUBE_CONFIG=false + +# ========== +# Secret ENV +# ========== + +ENV CN_SECRET_ADAPTER=vault \ + CN_SECRET_VAULT_VERIFY=false \ + CN_SECRET_VAULT_ROLE_ID_FILE=/etc/certs/vault_role_id \ + CN_SECRET_VAULT_SECRET_ID_FILE=/etc/certs/vault_secret_id \ + CN_SECRET_VAULT_CERT_FILE=/etc/certs/vault_client.crt \ + CN_SECRET_VAULT_KEY_FILE=/etc/certs/vault_client.key \ + CN_SECRET_VAULT_CACERT_FILE=/etc/certs/vault_ca.crt \ + CN_SECRET_VAULT_NAMESPACE="" \ + CN_SECRET_VAULT_ADDR=http://localhost:8200 \ + CN_SECRET_VAULT_KV_PATH=secret \ + CN_SECRET_VAULT_PREFIX=jans \ + CN_SECRET_VAULT_APPROLE_PATH=approle \ + CN_SECRET_KUBERNETES_NAMESPACE=default \ + CN_SECRET_KUBERNETES_SECRET=jans \ + CN_SECRET_KUBERNETES_USE_KUBE_CONFIG=false + +# =========== +# Generic ENV +# =========== + +ENV CN_MAX_RAM_PERCENTAGE=75.0 \ + CN_WAIT_MAX_TIME=300 \ + CN_WAIT_SLEEP_DURATION=10 \ + GOOGLE_PROJECT_ID="" \ + CN_GOOGLE_SECRET_MANAGER_PASSPHRASE=secret \ + CN_GOOGLE_SECRET_VERSION_ID=latest \ + CN_GOOGLE_SECRET_NAME_PREFIX=jans \ + CN_AWS_SECRETS_ENDPOINT_URL="" \ + CN_AWS_SECRETS_PREFIX=jans \ + CN_AWS_SECRETS_REPLICA_FILE="" \ + CN_SSL_CERT_FROM_SECRETS=true + +# ========== +# misc stuff +# ========== + +EXPOSE $CN_SAML_HTTP_PORT + +LABEL org.opencontainers.image.url="ghcr.io/janssenproject/jans/kc-scheduler" \ + org.opencontainers.image.authors="Janssen Project " \ + org.opencontainers.image.vendor="Janssen Project" \ + org.opencontainers.image.version="1.1.2" \ + org.opencontainers.image.title="Janssen KC scheduler" \ + org.opencontainers.image.description="" + +RUN mkdir -p /etc/certs \ + /etc/jans/conf + +COPY templates /app/templates/ +COPY scripts /app/scripts +RUN chmod +x /app/scripts/entrypoint.sh \ + && ln -sf /app/scripts/entrypoint.sh ${SCHEDULER_HOME}/bin/kc-scheduler.sh + +RUN ln -sf /usr/lib/jvm/jre /opt/java + +# create non-root user +RUN adduser -s /bin/sh -h /home/1000 -D -G root -u 1000 jans + +# adjust ownership and permission +RUN chmod -R g=u /etc/certs \ + && chmod -R g=u /etc/jans \ + && chmod 664 /opt/java/lib/security/cacerts \ + && chown -R 1000:0 /opt/kc-scheduler + +USER 1000 + +RUN mkdir -p $HOME/.config/gcloud + +ENTRYPOINT ["tini", "-e", "143", "-g", "--"] +CMD ["sh", "/opt/kc-scheduler/bin/kc-scheduler.sh"] diff --git a/docker-jans-kc-scheduler/LICENSE b/docker-jans-kc-scheduler/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/docker-jans-kc-scheduler/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/docker-jans-kc-scheduler/Makefile b/docker-jans-kc-scheduler/Makefile new file mode 100644 index 00000000000..131f9c7cef3 --- /dev/null +++ b/docker-jans-kc-scheduler/Makefile @@ -0,0 +1,25 @@ +IMAGE_VERSION?=$(shell grep -Po 'org.opencontainers.image.version="\K.*?(?=")' Dockerfile)_dev +IMAGE_URL=$(shell grep -Po 'org.opencontainers.image.url="\K.*?(?=")' Dockerfile) +IMAGE?=${IMAGE_URL}:${IMAGE_VERSION} + +# pass extra args to the targets, for example: +# +# - `make build-dev ARGS="--no-cache"` +# - `make trivy-scan TRIVY_ARGS="-f json"` +# - `make grype-scan GRYPE_ARGS="-o json"` +ARGS?= + +.PHONY: test clean all build-dev trivy-scan grype-scan +.DEFAULT_GOAL := build-dev + +build-dev: + @echo "[I] Building OCI image ${IMAGE}" + @docker build --rm --force-rm ${ARGS} -t ${IMAGE} . + +trivy-scan: + @echo "[I] Scanning OCI image ${IMAGE} using trivy" + @trivy image --scanners vuln ${ARGS} ${IMAGE} + +grype-scan: + @echo "[I] Scanning OCI image ${IMAGE} using grype" + @grype -v ${ARGS} ${IMAGE} diff --git a/docker-jans-kc-scheduler/README.md b/docker-jans-kc-scheduler/README.md new file mode 100644 index 00000000000..d1729837535 --- /dev/null +++ b/docker-jans-kc-scheduler/README.md @@ -0,0 +1,97 @@ +--- +tags: +- administration +- reference +- kubernetes +- docker image +--- + +# Overview + +Docker image packaging for jans-kc-scheduler + +## Versions + +See [Packages](https://github.com/orgs/JanssenProject/packages/container/package/jans%2Fkc%2Fscheduler) for available versions. + +## Environment Variables + +The following environment variables are supported by the container: + +- `CN_CONFIG_ADAPTER`: The config backend adapter, can be `consul` (default) or `kubernetes`. +- `CN_CONFIG_CONSUL_HOST`: hostname or IP of Consul (default to `localhost`). +- `CN_CONFIG_CONSUL_PORT`: port of Consul (default to `8500`). +- `CN_CONFIG_CONSUL_CONSISTENCY`: Consul consistency mode (choose one of `default`, `consistent`, or `stale`). Default to `stale` mode. +- `CN_CONFIG_CONSUL_SCHEME`: supported Consul scheme (`http` or `https`). +- `CN_CONFIG_CONSUL_VERIFY`: whether to verify cert or not (default to `false`). +- `CN_CONFIG_CONSUL_CACERT_FILE`: path to Consul CA cert file (default to `/etc/certs/consul_ca.crt`). This file will be used if it exists and `CN_CONFIG_CONSUL_VERIFY` set to `true`. +- `CN_CONFIG_CONSUL_CERT_FILE`: path to Consul cert file (default to `/etc/certs/consul_client.crt`). +- `CN_CONFIG_CONSUL_KEY_FILE`: path to Consul key file (default to `/etc/certs/consul_client.key`). +- `CN_CONFIG_CONSUL_TOKEN_FILE`: path to file contains ACL token (default to `/etc/certs/consul_token`). +- `CN_CONFIG_KUBERNETES_NAMESPACE`: Kubernetes namespace (default to `default`). +- `CN_CONFIG_KUBERNETES_CONFIGMAP`: Kubernetes configmaps name (default to `jans`). +- `CN_CONFIG_KUBERNETES_USE_KUBE_CONFIG`: Load credentials from `$HOME/.kube/config`, only useful for non-container environment (default to `false`). +- `CN_SECRET_ADAPTER`: The secrets' adapter, can be `vault` (default), `kubernetes`, or `google`. +- `CN_SECRET_VAULT_VERIFY`: whether to verify cert or not (default to `false`). +- `CN_SECRET_VAULT_ROLE_ID_FILE`: path to file contains Vault AppRole role ID (default to `/etc/certs/vault_role_id`). +- `CN_SECRET_VAULT_SECRET_ID_FILE`: path to file contains Vault AppRole secret ID (default to `/etc/certs/vault_secret_id`). +- `CN_SECRET_VAULT_CERT_FILE`: path to Vault cert file (default to `/etc/certs/vault_client.crt`). +- `CN_SECRET_VAULT_KEY_FILE`: path to Vault key file (default to `/etc/certs/vault_client.key`). +- `CN_SECRET_VAULT_CACERT_FILE`: path to Vault CA cert file (default to `/etc/certs/vault_ca.crt`). This file will be used if it exists and `CN_SECRET_VAULT_VERIFY` set to `true`. +- `CN_SECRET_VAULT_ADDR`: URL of Vault (default to `http://localhost:8200`). +- `CN_SECRET_VAULT_NAMESPACE`: Namespace used to access secrets (default to empty string). +- `CN_SECRET_VAULT_KV_PATH`: Path to KV secrets engine (default to `secret`). +- `CN_SECRET_VAULT_PREFIX`: Base prefix name used to build secret path (default to `jans`). +- `CN_SECRET_VAULT_APPROLE_PATH`: Path to AppRole (default to `approle`). +- `CN_SECRET_KUBERNETES_NAMESPACE`: Kubernetes namespace (default to `default`). +- `CN_SECRET_KUBERNETES_SECRET`: Kubernetes secrets name (default to `jans`). +- `CN_SECRET_KUBERNETES_USE_KUBE_CONFIG`: Load credentials from `$HOME/.kube/config`, only useful for non-container environment (default to `false`). +- `CN_WAIT_MAX_TIME`: How long the startup "health checks" should run (default to `300` seconds). +- `CN_WAIT_SLEEP_DURATION`: Delay between startup "health checks" (default to `10` seconds). +- `CN_MAX_RAM_PERCENTAGE`: Value passed to Java option `-XX:MaxRAMPercentage`. +- `GOOGLE_APPLICATION_CREDENTIALS`: Optional JSON file (contains Google credentials) that can be injected into container for authentication. Refer to https://cloud.google.com/docs/authentication/provide-credentials-adc#how-to for supported credentials. +- `GOOGLE_PROJECT_ID`: ID of Google project. +- `CN_GOOGLE_SECRET_VERSION_ID`: Janssen secret version ID in Google Secret Manager. Defaults to `latest`, which is recommended. +- `CN_GOOGLE_SECRET_NAME_PREFIX`: Prefix for Janssen secret in Google Secret Manager. Defaults to `jans`. If left `jans-secret` secret will be created. +- `CN_GOOGLE_SECRET_MANAGER_PASSPHRASE`: Passphrase for Janssen secret in Google Secret Manager. This is recommended to be changed and defaults to `secret`. +- `CN_AWS_SECRETS_ENDPOINT_URL`: The URL of AWS secretsmanager service (if omitted, will use the one in specified region). +- `CN_AWS_SECRETS_PREFIX`: The prefix name of the secrets (default to `jans`). +- `CN_AWS_SECRETS_REPLICA_FILE`: The location of file contains replica regions definition (if any). This file is mostly used in primary region. Example of contents of the file: `[{"Region": "us-west-1"}]`. +- `AWS_DEFAULT_REGION`: The default AWS Region to use, for example, `us-west-1` or `us-west-2`. +- `AWS_SHARED_CREDENTIALS_FILE`: The location of the shared credentials file used by the client (see https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). +- `AWS_CONFIG_FILE`: The location of the config file used by the client (see https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). +- `AWS_PROFILE`: The default profile to use, if any. +- `CN_SSL_CERT_FROM_SECRETS`: Determine whether to get SSL cert from secrets backend (default to `true`). Note that the flag will take effect only if there's no mounted `/etc/certs/web_https.crt` file. + +### Configure app loggers + +There are logging levels that can be customized via Java system property, as listed below: + +| Name | Default value | +|-------------------------------------------|---------------| +| `app.logging.level.root` | `INFO` | +| `app.logging.level.apache.http.client` | `INFO` | +| `app.logging.level.apache.http.wire` | `INFO` | +| `app.logging.level.apache.http.header` | `INFO` | +| `app.logging.target` | `STDOUT` | + +To change the value, pass Java system property via `CN_KC_SCHEDULER_JAVA_OPTIONS` environment variable into the container/pod. + +Example: + +``` +CN_KC_SCHEDULER_JAVA_OPTIONS=-Dapp.logging.level.root=DEBUG -Dapp.logging.level.apache.http.client=DEBUG +``` + +Supported logging level: + +- `ERROR` +- `WARN` +- `INFO` +- `DEBUG` +- `TRACE` + +Supported logging target: + +- `STDOUT` +- `FILE` diff --git a/docker-jans-kc-scheduler/requirements.txt b/docker-jans-kc-scheduler/requirements.txt new file mode 100644 index 00000000000..130b8ff796e --- /dev/null +++ b/docker-jans-kc-scheduler/requirements.txt @@ -0,0 +1,3 @@ +# pinned to py3-grpcio version to avoid failure on native extension build +grpcio==1.54.2 +git+https://github.com/JanssenProject/jans@19f0deb368617c344df24abeff0b913bbbfdd6b9#egg=jans-pycloudlib&subdirectory=jans-pycloudlib \ No newline at end of file diff --git a/docker-jans-kc-scheduler/scripts/bootstrap.py b/docker-jans-kc-scheduler/scripts/bootstrap.py new file mode 100644 index 00000000000..04c5a6fd31d --- /dev/null +++ b/docker-jans-kc-scheduler/scripts/bootstrap.py @@ -0,0 +1,74 @@ +import logging.config +import os +import shutil +from string import Template + +from jans.pycloudlib import get_manager +from jans.pycloudlib.utils import cert_to_truststore +from jans.pycloudlib.utils import as_boolean +from jans.pycloudlib.utils import get_server_certificate + + +from settings import LOGGING_CONFIG + +logging.config.dictConfig(LOGGING_CONFIG) +logger = logging.getLogger("jans-kc-scheduler") + +manager = get_manager() + + +def render_config_props(): + hostname = manager.config.get("hostname") + + ctx = { + # config-api + "api_url": f"https://{hostname}/jans-config-api", + "token_endpoint": f"https://{hostname}/jans-auth/restv1/token", + "client_id": manager.config.get("kc_scheduler_api_client_id"), + "client_secret": manager.secret.get("kc_scheduler_api_client_pw"), + "scopes": "", + "auth_method": "basic", + + # keycloak-api + "keycloak_admin_url": f"https://{hostname}/kc", + "keycloak_admin_realm": "master", + "keycloak_admin_username": manager.config.get("kc_admin_username"), + "keycloak_admin_password": manager.secret.get("kc_admin_password"), + "keycloak_client_id": "admin-cli", + } + + with open("/app/templates/kc-scheduler/config.properties") as f: + tmpl = Template(f.read()) + + with open("/opt/kc-scheduler/conf/config.properties", "w") as f: + f.write(tmpl.safe_substitute(ctx)) + + +def render_logback_config(): + src = "/app/templates/kc-scheduler/logback.xml" + dst = "/opt/kc-scheduler/conf/logback.xml" + shutil.copyfile(src, dst) + + +def main(): + if not os.path.isfile("/etc/certs/web_https.crt"): + if as_boolean(os.environ.get("CN_SSL_CERT_FROM_SECRETS", "true")): + manager.secret.to_file("ssl_cert", "/etc/certs/web_https.crt") + else: + hostname = manager.config.get("hostname") + logger.info(f"Pulling SSL certificate from {hostname}") + get_server_certificate(hostname, 443, "/etc/certs/web_https.crt") + + cert_to_truststore( + "web_https", + "/etc/certs/web_https.crt", + "/opt/java/lib/security/cacerts", + "changeit", + ) + + render_config_props() + render_logback_config() + + +if __name__ == "__main__": + main() diff --git a/docker-jans-kc-scheduler/scripts/entrypoint.sh b/docker-jans-kc-scheduler/scripts/entrypoint.sh new file mode 100644 index 00000000000..cf201bc4ae3 --- /dev/null +++ b/docker-jans-kc-scheduler/scripts/entrypoint.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +set -e + +# get script directory +basedir=$(dirname "$(readlink -f -- "$0")") + +app_config_file=${SCHEDULER_HOME}/conf/config.properties +log_config_file=${SCHEDULER_HOME}/conf/logback.xml +scheduler_version=${CN_VERSION} + +get_java_options() { + if [ -n "${CN_KC_SCHEDULER_JAVA_OPTIONS}" ]; then + echo " ${CN_KC_SCHEDULER_JAVA_OPTIONS} " + else + # backward-compat + echo " ${CN_JAVA_OPTIONS} " + fi +} + +get_max_ram_percentage() { + if [ -n "${CN_MAX_RAM_PERCENTAGE}" ]; then + echo " -XX:MaxRAMPercentage=$CN_MAX_RAM_PERCENTAGE " + fi +} + +python3 "$basedir/wait.py" +python3 "$basedir/bootstrap.py" + +# shellcheck disable=SC2046 +exec java \ + -Dapp.config="${app_config_file}" \ + -Dlogback.configurationFile="${log_config_file}" \ + -Dapp.version="${scheduler_version}" \ + -Dapp.home="${SCHEDULER_HOME}" \ + $(get_max_ram_percentage) \ + $(get_java_options) \ + -cp "${SCHEDULER_HOME}/lib/*" \ + io.jans.kc.scheduler.App diff --git a/docker-jans-kc-scheduler/scripts/settings.py b/docker-jans-kc-scheduler/scripts/settings.py new file mode 100644 index 00000000000..0d35be05b64 --- /dev/null +++ b/docker-jans-kc-scheduler/scripts/settings.py @@ -0,0 +1,26 @@ +LOGGING_CONFIG = { + "version": 1, + "formatters": { + "default": { + "format": "%(levelname)s - %(name)s - %(asctime)s - %(message)s", + }, + }, + "handlers": { + "console": { + "class": "logging.StreamHandler", + "formatter": "default", + }, + }, + "loggers": { + "jans.pycloudlib": { + "handlers": ["console"], + "level": "INFO", + "propagate": True, + }, + "jans-kc-scheduler": { + "handlers": ["console"], + "level": "INFO", + "propagate": False, + }, + }, +} diff --git a/docker-jans-kc-scheduler/scripts/wait.py b/docker-jans-kc-scheduler/scripts/wait.py new file mode 100644 index 00000000000..566f108fa21 --- /dev/null +++ b/docker-jans-kc-scheduler/scripts/wait.py @@ -0,0 +1,18 @@ +import logging.config + +from jans.pycloudlib import get_manager +from jans.pycloudlib import wait_for + +from settings import LOGGING_CONFIG + +logging.config.dictConfig(LOGGING_CONFIG) + + +def main(): + manager = get_manager() + deps = ["config", "secret"] + wait_for(manager, deps) + + +if __name__ == "__main__": + main() diff --git a/docker-jans-kc-scheduler/templates/kc-scheduler/config.properties b/docker-jans-kc-scheduler/templates/kc-scheduler/config.properties new file mode 100644 index 00000000000..73e16955711 --- /dev/null +++ b/docker-jans-kc-scheduler/templates/kc-scheduler/config.properties @@ -0,0 +1,30 @@ +# scheduler configuration file + +# quartz scheduler configuration +app.scheduler.quartz.name=kc-jans-scheduler +app.scheduler.quartz.instanceid=AUTO +app.scheduler.quartz.threadpoolsize=3 + +# config api configuration +app.config-api.url=${api_url} +app.config-api.auth.url=${token_endpoint} +app.config-api.auth.client.id=${client_id} +app.config-api.auth.client.secret=${client_secret} +app.config-api.auth.client.scopes=${scopes} +app.config-api.auth.method=${auth_method} + +# keycloak api configuration +app.keycloak-admin.url=${keycloak_admin_url} +app.keycloak-admin.realm=${keycloak_admin_realm} +app.keycloak-admin.username=${keycloak_admin_username} +app.keycloak-admin.password=${keycloak_admin_password} +app.keycloak-admin.client.id=${keycloak_client_id} +app.keycloak-admin.conn.poolsize=10 + +# trust relationship sync job configuration +app.job.trustrelationship-sync.schedule-interval=PT10M + +# keycloak resources configuration +app.keycloak.resources.realm=jans +app.keycloak.resources.authn.browser.flow-alias=janssen login +app.keycloak.resources.saml.user-attribute-mapper=saml-user-attribute-mapper diff --git a/docker-jans-kc-scheduler/templates/kc-scheduler/logback.xml b/docker-jans-kc-scheduler/templates/kc-scheduler/logback.xml new file mode 100644 index 00000000000..0c64e379836 --- /dev/null +++ b/docker-jans-kc-scheduler/templates/kc-scheduler/logback.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + ${app.logdir}/scheduler.log + true + + ${app.logdir}/scheduler-%d{yyyy-mm-dd}.log.gz + ${app.logging.loghistory:-180} + + + + UTF-8 + %date{ISO8601}:%-5level [%logger:%line] - %msg%n%ex{short} + + + + + + + + + UTF-8 + jans-kc-scheduler - %date{ISO8601}:%-5level [%logger:%line] - %msg%n%ex{short} + + + + + + + + + + + + + + + + + + + + diff --git a/docker-jans-kc-scheduler/version.txt b/docker-jans-kc-scheduler/version.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/docs/admin/reference/kubernetes/docker-jans-kc-scheduler.md b/docs/admin/reference/kubernetes/docker-jans-kc-scheduler.md new file mode 100644 index 00000000000..d1729837535 --- /dev/null +++ b/docs/admin/reference/kubernetes/docker-jans-kc-scheduler.md @@ -0,0 +1,97 @@ +--- +tags: +- administration +- reference +- kubernetes +- docker image +--- + +# Overview + +Docker image packaging for jans-kc-scheduler + +## Versions + +See [Packages](https://github.com/orgs/JanssenProject/packages/container/package/jans%2Fkc%2Fscheduler) for available versions. + +## Environment Variables + +The following environment variables are supported by the container: + +- `CN_CONFIG_ADAPTER`: The config backend adapter, can be `consul` (default) or `kubernetes`. +- `CN_CONFIG_CONSUL_HOST`: hostname or IP of Consul (default to `localhost`). +- `CN_CONFIG_CONSUL_PORT`: port of Consul (default to `8500`). +- `CN_CONFIG_CONSUL_CONSISTENCY`: Consul consistency mode (choose one of `default`, `consistent`, or `stale`). Default to `stale` mode. +- `CN_CONFIG_CONSUL_SCHEME`: supported Consul scheme (`http` or `https`). +- `CN_CONFIG_CONSUL_VERIFY`: whether to verify cert or not (default to `false`). +- `CN_CONFIG_CONSUL_CACERT_FILE`: path to Consul CA cert file (default to `/etc/certs/consul_ca.crt`). This file will be used if it exists and `CN_CONFIG_CONSUL_VERIFY` set to `true`. +- `CN_CONFIG_CONSUL_CERT_FILE`: path to Consul cert file (default to `/etc/certs/consul_client.crt`). +- `CN_CONFIG_CONSUL_KEY_FILE`: path to Consul key file (default to `/etc/certs/consul_client.key`). +- `CN_CONFIG_CONSUL_TOKEN_FILE`: path to file contains ACL token (default to `/etc/certs/consul_token`). +- `CN_CONFIG_KUBERNETES_NAMESPACE`: Kubernetes namespace (default to `default`). +- `CN_CONFIG_KUBERNETES_CONFIGMAP`: Kubernetes configmaps name (default to `jans`). +- `CN_CONFIG_KUBERNETES_USE_KUBE_CONFIG`: Load credentials from `$HOME/.kube/config`, only useful for non-container environment (default to `false`). +- `CN_SECRET_ADAPTER`: The secrets' adapter, can be `vault` (default), `kubernetes`, or `google`. +- `CN_SECRET_VAULT_VERIFY`: whether to verify cert or not (default to `false`). +- `CN_SECRET_VAULT_ROLE_ID_FILE`: path to file contains Vault AppRole role ID (default to `/etc/certs/vault_role_id`). +- `CN_SECRET_VAULT_SECRET_ID_FILE`: path to file contains Vault AppRole secret ID (default to `/etc/certs/vault_secret_id`). +- `CN_SECRET_VAULT_CERT_FILE`: path to Vault cert file (default to `/etc/certs/vault_client.crt`). +- `CN_SECRET_VAULT_KEY_FILE`: path to Vault key file (default to `/etc/certs/vault_client.key`). +- `CN_SECRET_VAULT_CACERT_FILE`: path to Vault CA cert file (default to `/etc/certs/vault_ca.crt`). This file will be used if it exists and `CN_SECRET_VAULT_VERIFY` set to `true`. +- `CN_SECRET_VAULT_ADDR`: URL of Vault (default to `http://localhost:8200`). +- `CN_SECRET_VAULT_NAMESPACE`: Namespace used to access secrets (default to empty string). +- `CN_SECRET_VAULT_KV_PATH`: Path to KV secrets engine (default to `secret`). +- `CN_SECRET_VAULT_PREFIX`: Base prefix name used to build secret path (default to `jans`). +- `CN_SECRET_VAULT_APPROLE_PATH`: Path to AppRole (default to `approle`). +- `CN_SECRET_KUBERNETES_NAMESPACE`: Kubernetes namespace (default to `default`). +- `CN_SECRET_KUBERNETES_SECRET`: Kubernetes secrets name (default to `jans`). +- `CN_SECRET_KUBERNETES_USE_KUBE_CONFIG`: Load credentials from `$HOME/.kube/config`, only useful for non-container environment (default to `false`). +- `CN_WAIT_MAX_TIME`: How long the startup "health checks" should run (default to `300` seconds). +- `CN_WAIT_SLEEP_DURATION`: Delay between startup "health checks" (default to `10` seconds). +- `CN_MAX_RAM_PERCENTAGE`: Value passed to Java option `-XX:MaxRAMPercentage`. +- `GOOGLE_APPLICATION_CREDENTIALS`: Optional JSON file (contains Google credentials) that can be injected into container for authentication. Refer to https://cloud.google.com/docs/authentication/provide-credentials-adc#how-to for supported credentials. +- `GOOGLE_PROJECT_ID`: ID of Google project. +- `CN_GOOGLE_SECRET_VERSION_ID`: Janssen secret version ID in Google Secret Manager. Defaults to `latest`, which is recommended. +- `CN_GOOGLE_SECRET_NAME_PREFIX`: Prefix for Janssen secret in Google Secret Manager. Defaults to `jans`. If left `jans-secret` secret will be created. +- `CN_GOOGLE_SECRET_MANAGER_PASSPHRASE`: Passphrase for Janssen secret in Google Secret Manager. This is recommended to be changed and defaults to `secret`. +- `CN_AWS_SECRETS_ENDPOINT_URL`: The URL of AWS secretsmanager service (if omitted, will use the one in specified region). +- `CN_AWS_SECRETS_PREFIX`: The prefix name of the secrets (default to `jans`). +- `CN_AWS_SECRETS_REPLICA_FILE`: The location of file contains replica regions definition (if any). This file is mostly used in primary region. Example of contents of the file: `[{"Region": "us-west-1"}]`. +- `AWS_DEFAULT_REGION`: The default AWS Region to use, for example, `us-west-1` or `us-west-2`. +- `AWS_SHARED_CREDENTIALS_FILE`: The location of the shared credentials file used by the client (see https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). +- `AWS_CONFIG_FILE`: The location of the config file used by the client (see https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). +- `AWS_PROFILE`: The default profile to use, if any. +- `CN_SSL_CERT_FROM_SECRETS`: Determine whether to get SSL cert from secrets backend (default to `true`). Note that the flag will take effect only if there's no mounted `/etc/certs/web_https.crt` file. + +### Configure app loggers + +There are logging levels that can be customized via Java system property, as listed below: + +| Name | Default value | +|-------------------------------------------|---------------| +| `app.logging.level.root` | `INFO` | +| `app.logging.level.apache.http.client` | `INFO` | +| `app.logging.level.apache.http.wire` | `INFO` | +| `app.logging.level.apache.http.header` | `INFO` | +| `app.logging.target` | `STDOUT` | + +To change the value, pass Java system property via `CN_KC_SCHEDULER_JAVA_OPTIONS` environment variable into the container/pod. + +Example: + +``` +CN_KC_SCHEDULER_JAVA_OPTIONS=-Dapp.logging.level.root=DEBUG -Dapp.logging.level.apache.http.client=DEBUG +``` + +Supported logging level: + +- `ERROR` +- `WARN` +- `INFO` +- `DEBUG` +- `TRACE` + +Supported logging target: + +- `STDOUT` +- `FILE`