diff --git a/docker-compose.yml b/docker-compose.yml index 7b74252..383be4e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,6 +9,7 @@ services: - '8080:8080' environment: - AUTH_SERVER_URL=http://keycloak:8080 + restart: on-failure keycloak: image: quay.io/keycloak/keycloak:22.0.5 container_name: keycloak diff --git a/helm/charts/identity-manager/.helmignore b/helm/charts/identity-manager/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/charts/identity-manager/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/charts/identity-manager/Chart.yaml b/helm/charts/identity-manager/Chart.yaml new file mode 100644 index 0000000..004dfbc --- /dev/null +++ b/helm/charts/identity-manager/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: identity-manager +description: A helm chart for Identity Manager +version: 1.0.0 +#appVersion: "1.0" +appVersion: "develop" \ No newline at end of file diff --git a/helm/charts/identity-manager/templates/_helpers.tpl b/helm/charts/identity-manager/templates/_helpers.tpl new file mode 100644 index 0000000..a103d10 --- /dev/null +++ b/helm/charts/identity-manager/templates/_helpers.tpl @@ -0,0 +1,76 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "identity-manager.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 "identity-manager.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 }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "identity-manager.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "identity-manager.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + + + + +{{/* +Common labels +*/}} +{{- define "identity-manager.labels" -}} +helm.sh/chart: {{ include "identity-manager.chart" . }} +{{ include "identity-manager.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "identity-manager.selectorLabels" -}} +app.kubernetes.io/name: {{ include "identity-manager.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "identity-manager.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "identity-manager.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/helm/charts/identity-manager/templates/deployment.yaml b/helm/charts/identity-manager/templates/deployment.yaml new file mode 100644 index 0000000..7c94678 --- /dev/null +++ b/helm/charts/identity-manager/templates/deployment.yaml @@ -0,0 +1,78 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "identity-manager.name" . }} + labels: + {{- include "identity-manager.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.deployment.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "identity-manager.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.deployment.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "identity-manager.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.deployment.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "identity-manager.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.deployment.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.deployment.securityContext | nindent 12 }} + image: "{{ .Values.deployment.image.repository }}:{{ .Values.deployment.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.deployment.image.pullPolicy }} + args: + {{- toYaml .Values.deployment.args | nindent 12 }} + env: + {{- with .Values.deployment.extraEnv }} + {{- tpl . $ | nindent 12 }} + {{- end }} + envFrom: + {{- with .Values.deployment.extraEnvFrom }} + {{- tpl . $ | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.deployment.containerPort }} + protocol: TCP + # + {{- with .Values.deployment.livenessProbe }} + livenessProbe: + {{- tpl . $ | nindent 12 }} + {{- end }} + # + {{- with .Values.deployment.readinessProbe }} + readinessProbe: + {{- tpl . $ | nindent 12 }} + {{- end }} + # + {{- with .Values.deployment.startupProbe }} + startupProbe: + {{- tpl . $ | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.deployment.resources | nindent 12 }} + {{- with .Values.deployment.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.deployment.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.deployment.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm/charts/identity-manager/templates/hpa.yaml b/helm/charts/identity-manager/templates/hpa.yaml new file mode 100644 index 0000000..4ee2716 --- /dev/null +++ b/helm/charts/identity-manager/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "identity-manager.name" . }} + labels: + {{- include "identity-manager.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "identity-manager.name" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/charts/identity-manager/templates/ingress.yaml b/helm/charts/identity-manager/templates/ingress.yaml new file mode 100644 index 0000000..0541494 --- /dev/null +++ b/helm/charts/identity-manager/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "identity-manager.name" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "identity-manager.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/charts/identity-manager/templates/service.yaml b/helm/charts/identity-manager/templates/service.yaml new file mode 100644 index 0000000..b355879 --- /dev/null +++ b/helm/charts/identity-manager/templates/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "identity-manager.name" . }} + labels: + {{- include "identity-manager.labels" . | nindent 4 }} + namespace: {{ template "identity-manager.namespace" $ }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "identity-manager.selectorLabels" . | nindent 4 }} diff --git a/helm/charts/identity-manager/templates/serviceaccount.yaml b/helm/charts/identity-manager/templates/serviceaccount.yaml new file mode 100644 index 0000000..6b44b23 --- /dev/null +++ b/helm/charts/identity-manager/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "identity-manager.serviceAccountName" . }} + labels: + {{- include "identity-manager.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/charts/identity-manager/values.yaml b/helm/charts/identity-manager/values.yaml new file mode 100644 index 0000000..16fd41f --- /dev/null +++ b/helm/charts/identity-manager/values.yaml @@ -0,0 +1,117 @@ +# Default values for identity-manager. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# --------------------------------------- +# Global variables +# --------------------------------------- +nameOverride: "" +namespaceOverride: "" +fullnameOverride: "" +restartPolicy: Always + +# --------------------------------------------- +# Variable used in hpa template and deployment +# --------------------------------------------- +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 3 + targetCPUUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 80 + +# --------------------------------------- +# Variable used in Deployment template +# --------------------------------------- +deployment: + replicaCount: 1 + # Additional Pod annotations + podAnnotations: {} + # Image pull secrets for the Pod + imagePullSecrets: [] + # - name: myRegistrKeySecretName + # SecurityContext for the entire Pod. Every container running in the Pod will inherit this SecurityContext. This might be relevant when other components of the environment inject additional containers into running Pods (service meshes are the most prominent example for this) + podSecurityContext: + fsGroup: 1000 + # SecurityContext for the identity-manager container + securityContext: + runAsUser: 1000 + runAsNonRoot: true + image: + repository: ghcr.io/eoepca/um-identity-manager + pullPolicy: Always + + # Define which port will be used in the containers + containerPort: 8080 + # Liveness probe configuration + livenessProbe: | + httpGet: + path: / + port: 8080 + initialDelaySeconds: 0 + timeoutSeconds: 5 + # Readiness probe configuration + readinessProbe: | + httpGet: + path: / + port: 8080 + initialDelaySeconds: 30 + timeoutSeconds: 1 + # Startup probe configuration + startupProbe: | + httpGet: + path: / + port: http + initialDelaySeconds: 30 + timeoutSeconds: 1 + failureThreshold: 60 + periodSeconds: 5 + # Pod resource requests and limits + resources: {} + # requests: + # cpu: "500m" + # memory: "1024Mi" + # limits: + # cpu: "500m" + # memory: "1024Mi" + # Node labels for Pod assignment + nodeSelector: {} + # Pod affinity + affinity: {} + # Node taints to tolerate + tolerations: [] + +# --------------------------------------- +# Variable group used in ingress template +# --------------------------------------- +ingress: + enabled: true + className: "" + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web, websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: selfsigned-issuer + hosts: + - host: identity.manager.local.eoepca.org + paths: + - path: / + pathType: Prefix + tls: + - secretName: identity-manager-tls-certificate + hosts: + - identity.manager.local.eoepca.org +# --------------------------------------- +# Variable group used in ingress template +# --------------------------------------- +service: + type: ClusterIP + port: 8080 + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" \ No newline at end of file diff --git a/helm/charts/identity-nginx/.helmignore b/helm/charts/identity-nginx/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/charts/identity-nginx/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/charts/identity-nginx/Chart.yaml b/helm/charts/identity-nginx/Chart.yaml new file mode 100644 index 0000000..5ab129a --- /dev/null +++ b/helm/charts/identity-nginx/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: identity-nginx +description: A helm chart for Identity NGINX +version: 1.0.0 +appVersion: "alpine" \ No newline at end of file diff --git a/helm/charts/identity-nginx/templates/_helpers.tpl b/helm/charts/identity-nginx/templates/_helpers.tpl new file mode 100644 index 0000000..3747354 --- /dev/null +++ b/helm/charts/identity-nginx/templates/_helpers.tpl @@ -0,0 +1,110 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "nginx.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 "nginx.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 }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "nginx.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "nginx.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + + +{{/* +Common labels +*/}} +{{- define "nginx.labels" -}} +helm.sh/chart: {{ include "nginx.chart" . }} +{{ include "nginx.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "nginx.selectorLabels" -}} +app.kubernetes.io/name: {{ include "nginx.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "nginx.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "nginx.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + + +{{/* +Return true if a static site should be mounted in the NGINX container +*/}} +{{- define "nginx.useStaticSite" -}} +{{- if or (and .Values.cloneStaticSiteFromGit .Values.cloneStaticSiteFromGit.enabled) .Values.staticSiteConfigmap .Values.staticSitePVC }} + {- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the custom NGINX server block configmap. +*/}} +{{- define "nginx.serversConfigmapName" -}} +{{- if .Values.existingServerBlockConfigmap -}} + {{- printf "%s" (tpl .Values.existingServerBlockConfigmap $) -}} +{{- else -}} + {{- printf "%s-server-block" (include "nginx.name" . ) -}} +{{- end -}} +{{- end -}} + +{{/* +Return the volume to use to mount the static site in the NGINX container +*/}} +{{- define "nginx.staticSiteVolume" -}} +{{- if .Values.cloneStaticSiteFromGit.enabled }} +emptyDir: {} +{{- else if .Values.staticSiteConfigmap }} +configMap: + name: {{ printf "%s" (tpl .Values.staticSiteConfigmap $) -}} +{{- else if .Values.staticSitePVC }} +persistentVolumeClaim: + claimName: {{ printf "%s" (tpl .Values.staticSitePVC $) -}} +{{- end }} +{{- end -}} \ No newline at end of file diff --git a/helm/charts/identity-nginx/templates/deployment.yaml b/helm/charts/identity-nginx/templates/deployment.yaml new file mode 100644 index 0000000..338d819 --- /dev/null +++ b/helm/charts/identity-nginx/templates/deployment.yaml @@ -0,0 +1,101 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "nginx.name" . }} + labels: + {{- include "nginx.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.deployment.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "nginx.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.deployment.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "nginx.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.deployment.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "nginx.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.deployment.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.deployment.securityContext | nindent 12 }} + image: "{{ .Values.deployment.image.repository }}:{{ .Values.deployment.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.deployment.image.pullPolicy }} + {{- if .Values.servers.enable }} + command: + - nginx + - -c /opt/nginx_agent/conf/nginx.conf + - -g daemon off; + {{- end }} + env: + {{- with .Values.deployment.extraEnv }} + {{- tpl . $ | nindent 12 }} + {{- end }} + envFrom: + {{- with .Values.deployment.extraEnvFrom }} + {{- tpl . $ | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.deployment.containerPort }} + protocol: TCP + # + {{- with .Values.deployment.livenessProbe }} + livenessProbe: + {{- tpl . $ | nindent 12 }} + {{- end }} + # + {{- with .Values.deployment.readinessProbe }} + readinessProbe: + {{- tpl . $ | nindent 12 }} + {{- end }} + # + {{- with .Values.deployment.startupProbe }} + startupProbe: + {{- tpl . $ | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.deployment.resources | nindent 12 }} + volumeMounts: + {{- if .Values.servers }} + - name: nginx-server-block + mountPath: /opt/nginx_agent/conf + {{- end }} + {{- if (include "nginx.useStaticSite" .) }} + - name: staticsite + mountPath: /app + {{- end }} + volumes: + {{- if .Values.servers }} + - name: nginx-server-block + configMap: + name: {{ include "nginx.serversConfigmapName" . }} + {{- end }} + {{- if include "nginx.useStaticSite" . }} + - name: staticsite + {{- include "nginx.staticSiteVolume" . | nindent 10 }} + {{- end }} + {{- with .Values.deployment.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.deployment.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.deployment.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} \ No newline at end of file diff --git a/helm/charts/identity-nginx/templates/hpa.yaml b/helm/charts/identity-nginx/templates/hpa.yaml new file mode 100644 index 0000000..b5be550 --- /dev/null +++ b/helm/charts/identity-nginx/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "nginx.name" . }} + labels: + {{- include "nginx.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "nginx.name" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/charts/identity-nginx/templates/ingress.yaml b/helm/charts/identity-nginx/templates/ingress.yaml new file mode 100644 index 0000000..501b7bc --- /dev/null +++ b/helm/charts/identity-nginx/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "nginx.name" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "nginx.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/charts/identity-nginx/templates/server-block-configmap.yaml b/helm/charts/identity-nginx/templates/server-block-configmap.yaml new file mode 100644 index 0000000..6a375b0 --- /dev/null +++ b/helm/charts/identity-nginx/templates/server-block-configmap.yaml @@ -0,0 +1,11 @@ +{{- if .Values.servers.enable }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "nginx.name" . }}-server-block + namespace: {{ include "nginx.namespace" . | quote }} + labels: + {{- include "nginx.labels" . | nindent 4 }} +data: + nginx.conf: {{ tpl .Values.servers.data $ | quote }} +{{- end }} \ No newline at end of file diff --git a/helm/charts/identity-nginx/templates/service.yaml b/helm/charts/identity-nginx/templates/service.yaml new file mode 100644 index 0000000..1511275 --- /dev/null +++ b/helm/charts/identity-nginx/templates/service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "nginx.name" . }} + labels: + {{- include "nginx.labels" . | nindent 4 }} + namespace: {{ template "nginx.namespace" $ }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "nginx.selectorLabels" . | nindent 4 }} diff --git a/helm/charts/identity-nginx/templates/serviceaccount.yaml b/helm/charts/identity-nginx/templates/serviceaccount.yaml new file mode 100644 index 0000000..3650603 --- /dev/null +++ b/helm/charts/identity-nginx/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "nginx.serviceAccountName" . }} + labels: + {{- include "nginx.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/charts/identity-nginx/values.yaml b/helm/charts/identity-nginx/values.yaml new file mode 100644 index 0000000..14ac51e --- /dev/null +++ b/helm/charts/identity-nginx/values.yaml @@ -0,0 +1,252 @@ +# Default values for identity-api. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# --------------------------------------- +# Global variables +# --------------------------------------- +nameOverride: "" +namespaceOverride: "" +fullnameOverride: "" +restartPolicy: Always + +# --------------------------------------------- +# Variable used in hpa template and deployment +# --------------------------------------------- +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 3 + targetCPUUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 80 + +# --------------------------------------- +# Variable used in Deployment template +# --------------------------------------- +deployment: + replicaCount: 1 + # Additional Pod annotations + podAnnotations: {} + # Image pull secrets for the Pod + imagePullSecrets: [] + # - name: myRegistrKeySecretName + # SecurityContext for the entire Pod. Every container running in the Pod will inherit this SecurityContext. This might be relevant when other components of the environment inject additional containers into running Pods (service meshes are the most prominent example for this) + podSecurityContext: + fsGroup: 1000 + # SecurityContext for the identity-api container + securityContext: + runAsUser: 1000 + runAsNonRoot: true + image: + repository: ghcr.io/eoepca/um-identity-nginx + pullPolicy: Always + + # Define which port will be used in the containers + containerPort: 8080 + # Liveness probe configuration + livenessProbe: | + httpGet: + path: / + port: http + initialDelaySeconds: 0 + timeoutSeconds: 5 + # Readiness probe configuration + readinessProbe: | + httpGet: + path: / + port: http + initialDelaySeconds: 30 + timeoutSeconds: 1 + # Startup probe configuration + startupProbe: | + httpGet: + path: / + port: http + initialDelaySeconds: 30 + timeoutSeconds: 1 + failureThreshold: 60 + periodSeconds: 5 + # Pod resource requests and limits + resources: {} + # requests: + # cpu: "500m" + # memory: "1024Mi" + # limits: + # cpu: "500m" + # memory: "1024Mi" + # Node labels for Pod assignment + nodeSelector: {} + # Pod affinity + affinity: {} + # Node taints to tolerate + tolerations: [] + +# --------------------------------------- +# Variable group used in ingress template +# --------------------------------------- +ingress: + enabled: true + className: "" + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web, websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: selfsigned-issuer + hosts: + - host: identity.nginx.local.eoepca.org + paths: + - path: / + pathType: Prefix + tls: + - secretName: identity-nginx-tls-certificate + hosts: + - identity.nginx.local.eoepca.org + +# --------------------------------------- +# Variable group used in ingress template +# --------------------------------------- +service: + type: ClusterIP + port: 8080 + +serviceAccount: + # Specifies whether a service account should be created + create: false + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +servers: + enable: true + data: |- + # server { + # listen 8080 default_server; + # server_name _; + # return 301 https://$host$request_uri; + # } + server { + #listen 443 default ssl; + listen 8080; + server_name oauth2-proxy; + #ssl_certificate /etc/letsencrypt/live/auth.proxy.develop.eoepca.org/fullchain.pem; + #ssl_certificate_key /etc/letsencrypt/live/auth.proxy.develop.eoepca.org/privkey.pem; + add_header Strict-Transport-Security max-age=2592000; + + location /oauth2/ { + expires -1; + proxy_pass http://oauth2-proxy:4443; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Auth-Request-Redirect $request_uri; + proxy_set_header X-Forwarded-Proto $scheme; + # or, if you are handling multiple domains: + # proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri; + } + + + location = /oauth2/auth { + internal; + proxy_pass http://oauth2-proxy:4443; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + # nginx auth_request includes headers but not body + proxy_set_header Content-Length ""; + proxy_pass_request_body off; + } + + location = /oauth2/sign_out { + # Sign-out mutates the session, only allow POST requests + if ($request_method != POST) { + return 405; + } + expires -1; + proxy_pass http://oauth2-proxy:4443; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Auth-Request-Redirect /oauth2/sign_in; + } + + location /auth/realms { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Auth-Request-Redirect $request_uri; + proxy_pass http://keycloak:8080; + } + + location /auth/resources { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Auth-Request-Redirect $request_uri; + proxy_pass http://keycloak:8080; + } + + location /auth/js { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Auth-Request-Redirect $request_uri; + proxy_pass http://keycloak:8080; + } + + location / { + root /data/www; + #proxy_pass http://open-springboot-demo:7071; + proxy_pass http://keycloak-springboot-demo:7070; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + proxy_set_header X-Forwarded-Host $host:8080; + proxy_set_header X-Forwarded-Port 8080; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_connect_timeout 1; + proxy_send_timeout 30; + proxy_read_timeout 30; + proxy_http_version 1.1; + + auth_request /oauth2/auth; + error_page 401 = /oauth2/sign_in?rd=$scheme://$host$request_uri; + + # pass information via X-User and X-Email headers to backend, + # requires running with --set-xauthrequest flag + auth_request_set $user $upstream_http_x_auth_request_user; + auth_request_set $email $upstream_http_x_auth_request_email; + proxy_set_header X-User $user; + proxy_set_header X-Email $email; + + # if you enabled --pass-access-token, this will pass the token to the backend + auth_request_set $token $upstream_http_x_auth_request_access_token; + proxy_set_header X-Access-Token $token; + + # if you enabled --cookie-refresh, this is needed for it to work with auth_request + auth_request_set $auth_cookie $upstream_http_set_cookie; + add_header Set-Cookie $auth_cookie; + + # When using the --set-authorization-header flag, some provider's cookies can exceed the 4kb + # limit and so the OAuth2 Proxy splits these into multiple parts. + # Nginx normally only copies the first `Set-Cookie` header from the auth_request to the response, + # so if your cookies are larger than 4kb, you will need to extract additional cookies manually. + auth_request_set $auth_cookie_name_upstream_1 $upstream_cookie_auth_cookie_name_1; + + # Extract the Cookie attributes from the first Set-Cookie header and append them + # to the second part ($upstream_cookie_* variables only contain the raw cookie content) + if ($auth_cookie ~* "(; .*)") { + set $auth_cookie_name_0 $auth_cookie; + set $auth_cookie_name_1 "auth_cookie_name_1=$auth_cookie_name_upstream_1$1"; + } + + # Send both Set-Cookie headers now if there was a second part + if ($auth_cookie_name_upstream_1) { + add_header Set-Cookie $auth_cookie_name_0; + add_header Set-Cookie $auth_cookie_name_1; + } + } + } \ No newline at end of file diff --git a/helm/charts/identity-oauth2-proxy/.helmignore b/helm/charts/identity-oauth2-proxy/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/charts/identity-oauth2-proxy/Chart.yaml b/helm/charts/identity-oauth2-proxy/Chart.yaml new file mode 100644 index 0000000..57f8509 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: identity-oauth2-proxy +description: A OAuth2-Proxy helm chart +version: 1.0.0 +appVersion: "v7.4.0" \ No newline at end of file diff --git a/helm/charts/identity-oauth2-proxy/templates/_capabilities.tpl b/helm/charts/identity-oauth2-proxy/templates/_capabilities.tpl new file mode 100644 index 0000000..f959f10 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/_capabilities.tpl @@ -0,0 +1,23 @@ +{{/* +Returns the appropriate apiVersion for podDisruptionBudget object. +*/}} +{{- define "capabilities.podDisruptionBudget.apiVersion" -}} +{{- if semverCompare ">=1.21-0" ( .Values.kubeVersion | default .Capabilities.KubeVersion.Version ) -}} +{{- print "policy/v1" -}} +{{- else -}} +{{- print "policy/v1beta1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress object. +*/}} +{{- define "capabilities.ingress.apiVersion" -}} +{{- if semverCompare "<1.14-0" ( .Values.kubeVersion | default .Capabilities.KubeVersion.Version ) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" ( .Values.kubeVersion | default .Capabilities.KubeVersion.Version ) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} diff --git a/helm/charts/identity-oauth2-proxy/templates/_helpers.tpl b/helm/charts/identity-oauth2-proxy/templates/_helpers.tpl new file mode 100644 index 0000000..5a281c1 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/_helpers.tpl @@ -0,0 +1,114 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "oauth2-proxy.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "oauth2-proxy.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "oauth2-proxy.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Generate basic labels +*/}} +{{- define "oauth2-proxy.labels" }} +helm.sh/chart: {{ include "oauth2-proxy.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: authentication-proxy +app.kubernetes.io/part-of: {{ include "oauth2-proxy.name" . }} +{{ include "oauth2-proxy.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "oauth2-proxy.selectorLabels" -}} +app.kubernetes.io/name: {{ include "oauth2-proxy.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + + +{{/* +Get the secret name. +*/}} +{{- define "oauth2-proxy.secretName" -}} +{{- if .Values.config.existingSecret -}} +{{- printf "%s" .Values.config.existingSecret -}} +{{- else -}} +{{- printf "%s" (include "oauth2-proxy.name" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "oauth2-proxy.serviceAccountName" -}} +{{- if .Values.serviceAccount.enabled -}} + {{ default (include "oauth2-proxy.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "oauth2-proxy.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Redis subcharts fullname +*/}} +{{- define "oauth2-proxy.redis.fullname" -}} +{{- if .Values.redis.enabled -}} +{{- include "common.names.fullname" (dict "Chart" (dict "Name" "redis") "Release" .Release "Values" .Values.redis) -}} +{{- else -}} +{{ fail "attempting to use redis subcharts fullname, even though the subchart is not enabled. This will lead to misconfiguration" }} +{{- end -}} +{{- end -}} + +{{/* +Compute the redis url if not set explicitly. +*/}} +{{- define "oauth2-proxy.redis.StandaloneUrl" -}} +{{- if .Values.sessionStorage.redis.standalone.connectionUrl -}} +{{ .Values.sessionStorage.redis.standalone.connectionUrl }} +{{- else if .Values.redis.enabled -}} +{{- printf "redis://%s-master:%.0f" (include "oauth2-proxy.redis.fullname" .) .Values.redis.master.service.ports.redis -}} +{{- else -}} +{{ fail "please set sessionStorage.redis.standalone.connectionUrl or enable the redis subchart via redis.enabled" }} +{{- end -}} +{{- end -}} diff --git a/helm/charts/identity-oauth2-proxy/templates/configmap-alpha.yaml b/helm/charts/identity-oauth2-proxy/templates/configmap-alpha.yaml new file mode 100644 index 0000000..af95be1 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/configmap-alpha.yaml @@ -0,0 +1,36 @@ +{{- if .Values.alphaConfig.enabled }} +{{- if not .Values.alphaConfig.existingConfig }} +apiVersion: v1 +kind: ConfigMap +metadata: +{{- if .Values.alphaConfig.annotations }} + annotations: {{- toYaml .Values.alphaConfig.annotations | nindent 4 }} +{{- end }} + labels: + app: {{ template "oauth2-proxy.name" . }} + {{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.name" . }}-alpha + namespace: {{ template "oauth2-proxy.namespace" $ }} +data: + oauth2_proxy.yml: | + --- + server: + BindAddress: '0.0.0.0:4180' + {{- if .Values.alphaConfig.serverConfigData }} + {{- toYaml .Values.alphaConfig.serverConfigData | nindent 6 }} + {{- end }} + {{- if .Values.metrics.enabled }} + metricsServer: + BindAddress: '0.0.0.0:44180' + {{- if .Values.alphaConfig.metricsConfigData }} + {{- toYaml .Values.alphaConfig.metricsConfigData | nindent 6 }} + {{- end }} + {{- end }} + {{- if .Values.alphaConfig.configData }} + {{- toYaml .Values.alphaConfig.configData | nindent 4 }} + {{- end }} + {{- if .Values.alphaConfig.configFile }} + {{- tpl .Values.alphaConfig.configFile $ | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/configmap-authenticated-emails-file.yaml b/helm/charts/identity-oauth2-proxy/templates/configmap-authenticated-emails-file.yaml new file mode 100644 index 0000000..f0ae9e8 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/configmap-authenticated-emails-file.yaml @@ -0,0 +1,18 @@ +{{- if .Values.authenticatedEmailsFile.enabled }} +{{- if and (.Values.authenticatedEmailsFile.restricted_access) (eq .Values.authenticatedEmailsFile.persistence "configmap") }} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} +{{- if .Values.authenticatedEmailsFile.annotations }} + annotations: +{{ toYaml .Values.authenticatedEmailsFile.annotations | indent 4 }} +{{- end }} + name: {{ template "oauth2-proxy.name" . }}-accesslist + namespace: {{ template "oauth2-proxy.namespace" $ }} +data: + {{ default "restricted_user_access" .Values.authenticatedEmailsFile.restrictedUserAccessKey }}: {{ .Values.authenticatedEmailsFile.restricted_access | quote }} +{{- end }} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/configmap.yaml b/helm/charts/identity-oauth2-proxy/templates/configmap.yaml new file mode 100644 index 0000000..5cf0dd4 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/configmap.yaml @@ -0,0 +1,18 @@ +{{- if not .Values.config.existingConfig }} +{{- if .Values.config.configFile }} +apiVersion: v1 +kind: ConfigMap +metadata: +{{- if .Values.config.annotations }} + annotations: +{{ toYaml .Values.config.annotations | indent 2 }} +{{- end }} + labels: + app: {{ include "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.name" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +data: + oauth2_proxy.cfg: {{ tpl .Values.config.configFile $ | quote }} +{{- end }} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/deployment.yaml b/helm/charts/identity-oauth2-proxy/templates/deployment.yaml new file mode 100644 index 0000000..3c4dac2 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/deployment.yaml @@ -0,0 +1,333 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "oauth2-proxy.name" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} + labels: + app: {{ include "oauth2-proxy.name" . -}} +{{- include "oauth2-proxy.labels" . | indent 4 }} + {{- if .Values.annotations }} + annotations: +{{ toYaml .Values.annotations | indent 8 }} + {{- end }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "oauth2-proxy.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- if .Values.alphaConfig.enabled }} + checksum/alpha-config: {{ include (print $.Template.BasePath "/configmap-alpha.yaml") . | sha256sum }} + {{- end }} + checksum/config-emails: {{ include (print $.Template.BasePath "/configmap-authenticated-emails-file.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + checksum/google-secret: {{ include (print $.Template.BasePath "/google-secret.yaml") . | sha256sum }} + checksum/redis-secret: {{ include (print $.Template.BasePath "/redis-secret.yaml") . | sha256sum }} + {{- if .Values.htpasswdFile.enabled }} + checksum/htpasswd: {{ include (print $.Template.BasePath "/secret-htpasswd-file.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.podAnnotations }} +{{ toYaml .Values.podAnnotations | indent 8 }} + {{- end }} + labels: + {{- include "oauth2-proxy.selectorLabels" . | nindent 8 }} + {{- if .Values.podLabels }} +{{ toYaml .Values.podLabels | indent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} + serviceAccountName: {{ include "oauth2-proxy.serviceAccountName" . }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{- if .Values.hostAlias.enabled }} + hostAliases: + - ip: {{ .Values.hostAlias.ip }} + hostnames: + - {{ .Values.hostAlias.hostname }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + {{- if .Values.alphaConfig.enabled }} + - --alpha-config=/etc/oauth2_proxy/oauth2_proxy.yml + {{- else }} + - --http-address=0.0.0.0:4180 + - --https-address=0.0.0.0:4443 + {{- if .Values.metrics.enabled }} + - --metrics-address=0.0.0.0:44180 + {{- end }} + {{- end }} + {{- if .Values.config.cookieName }} + - --cookie-name={{ .Values.config.cookieName }} + {{- end }} + {{- if kindIs "map" .Values.extraArgs }} + {{- range $key, $value := .Values.extraArgs }} + {{- if not (kindIs "invalid" $value) }} + - --{{ $key }}={{ tpl ($value | toString) $ }} + {{- else }} + - --{{ $key }} + {{- end }} + {{- end }} + {{- end }} + {{- if kindIs "slice" .Values.extraArgs }} + {{- with .Values.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + {{- if or .Values.config.existingConfig .Values.config.configFile }} + - --config=/etc/oauth2_proxy/oauth2_proxy.cfg + {{- end }} + {{- if .Values.authenticatedEmailsFile.enabled }} + {{- if .Values.authenticatedEmailsFile.emailUserListTemplate }} + - --authenticated-emails-file=/etc/oauth2-proxy/{{ .Values.authenticatedEmailsFile.emailUserListTemplate }} + {{- else }} + - --authenticated-emails-file=/etc/oauth2-proxy/authenticated-emails-list + {{- end }} + {{- end }} + {{- with .Values.config.google }} + {{- if and .adminEmail (or .serviceAccountJson .existingSecret .useApplicationDefaultCredentials) }} + - --google-admin-email={{ .adminEmail }} + {{- if .useApplicationDefaultCredentials }} + - --google-use-application-default-credentials=true + {{- else }} + - --google-service-account-json=/google/service-account.json + {{- end }} + {{- if .targetPrincipal }} + - --google-target-principal={{ .targetPrincipal }} + {{- end }} + {{- end }} + {{- if .groups }} + {{- range $group := .groups }} + - --google-group={{ $group }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.htpasswdFile.enabled }} + - --htpasswd-file=/etc/oauth2_proxy/htpasswd/users.txt + {{- end }} + env: + {{- if .Values.proxyVarsAsSecrets }} + - name: OAUTH2_PROXY_CLIENT_ID + valueFrom: + secretKeyRef: + name: {{ template "oauth2-proxy.secretName" . }} + key: client-id + - name: OAUTH2_PROXY_CLIENT_SECRET + valueFrom: + secretKeyRef: + name: {{ template "oauth2-proxy.secretName" . }} + key: client-secret + - name: OAUTH2_PROXY_COOKIE_SECRET + valueFrom: + secretKeyRef: + name: {{ template "oauth2-proxy.secretName" . }} + key: cookie-secret + {{- end }} + {{- if eq (default "cookie" .Values.sessionStorage.type) "redis" }} + - name: OAUTH2_PROXY_SESSION_STORE_TYPE + value: "redis" + {{- if or .Values.sessionStorage.redis.existingSecret .Values.sessionStorage.redis.password (and .Values.redis.enabled (.Values.redis.auth).enabled )}} + - name: OAUTH2_PROXY_REDIS_PASSWORD + valueFrom: + secretKeyRef: + {{- if .Values.sessionStorage.redis.existingSecret }} + name: {{ .Values.sessionStorage.redis.existingSecret }} + {{- else if .Values.sessionStorage.redis.password }} + name: {{ template "oauth2-proxy.name" . }}-redis-access + {{- else }} + name: {{ include "oauth2-proxy.redis.fullname" . }} + {{- end }} + key: {{ .Values.sessionStorage.redis.passwordKey }} + {{- end }} + {{- if eq (default "" .Values.sessionStorage.redis.clientType) "standalone" }} + - name: OAUTH2_PROXY_REDIS_CONNECTION_URL + value: {{ include "oauth2-proxy.redis.StandaloneUrl" . }} + {{- else if eq (default "" .Values.sessionStorage.redis.clientType) "cluster" }} + - name: OAUTH2_PROXY_REDIS_USE_CLUSTER + value: "true" + - name: OAUTH2_PROXY_REDIS_CLUSTER_CONNECTION_URLS + value: {{ .Values.sessionStorage.redis.cluster.connectionUrls }} + {{- else if eq (default "" .Values.sessionStorage.redis.clientType) "sentinel" }} + - name: OAUTH2_PROXY_REDIS_USE_SENTINEL + value: "true" + - name: OAUTH2_PROXY_REDIS_SENTINEL_MASTER_NAME + value: {{ .Values.sessionStorage.redis.sentinel.masterName }} + - name: OAUTH2_PROXY_REDIS_SENTINEL_CONNECTION_URLS + value: {{ .Values.sessionStorage.redis.sentinel.connectionUrls }} + {{- if or .Values.sessionStorage.redis.sentinel.existingSecret .Values.sessionStorage.redis.existingSecret .Values.sessionStorage.redis.sentinel.password }} + - name: OAUTH2_PROXY_REDIS_SENTINEL_PASSWORD + valueFrom: + secretKeyRef: + {{- if or .Values.sessionStorage.redis.sentinel.existingSecret .Values.sessionStorage.redis.existingSecret }} + name: {{ .Values.sessionStorage.redis.sentinel.existingSecret | default .Values.sessionStorage.redis.existingSecret }} + {{- else }} + name: {{ template "oauth2-proxy.name" . }}-redis-access + {{- end }} + key: {{ .Values.sessionStorage.redis.sentinel.passwordKey }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.extraEnv }} +{{ tpl (toYaml .Values.extraEnv) . | indent 8 }} + {{- end }} + ports: + {{- if .Values.containerPort }} + - containerPort: {{ .Values.containerPort }} + {{- else if (and (eq .Values.httpScheme "http") (empty .Values.containerPort)) }} + - containerPort: 4180 + {{- else if (and (eq .Values.httpScheme "https") (empty .Values.containerPort)) }} + - containerPort: 4443 + {{- else }} + {{- end }} + name: {{ .Values.httpScheme }} + protocol: TCP + {{- if .Values.metrics.enabled }} + - containerPort: 44180 + protocol: TCP + name: metrics + {{- end }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.livenessProbe.path }} + port: {{ .Values.httpScheme }} + scheme: {{ .Values.httpScheme | upper }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.readinessProbe.path }} + port: {{ .Values.httpScheme }} + scheme: {{ .Values.httpScheme | upper }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + {{- end }} + resources: +{{- toYaml .Values.resources | nindent 12 }} + volumeMounts: + {{- with .Values.config.google }} + {{- if and .adminEmail (or .serviceAccountJson .existingSecret) }} + - name: google-secret + mountPath: /google + readOnly: true + {{- end }} + {{- end }} + {{- if or .Values.config.existingConfig .Values.config.configFile }} + - mountPath: /etc/oauth2_proxy/oauth2_proxy.cfg + name: configmain + subPath: oauth2_proxy.cfg + {{- end }} + {{- if .Values.alphaConfig.enabled }} + - mountPath: /etc/oauth2_proxy/oauth2_proxy.yml + name: configalpha + subPath: oauth2_proxy.yml + {{- end }} + {{- if .Values.authenticatedEmailsFile.enabled }} + - mountPath: /etc/oauth2-proxy + name: configaccesslist + readOnly: true + {{- end }} + {{- if .Values.htpasswdFile.enabled }} + - mountPath: /etc/oauth2_proxy/htpasswd + name: {{ template "oauth2-proxy.name" . }}-htpasswd-file + readOnly: true + {{- end }} + {{- if ne (len .Values.extraVolumeMounts) 0 }} +{{ toYaml .Values.extraVolumeMounts | indent 8 }} + {{- end }} + {{- if .Values.securityContext.enabled }} + {{- $securityContext := unset .Values.securityContext "enabled" }} + securityContext: +{{- toYaml $securityContext | nindent 12 }} + {{- end }} + {{- if .Values.extraContainers }} +{{- toYaml .Values.extraContainers | nindent 6 }} + {{- end }} + volumes: + {{- with .Values.config.google }} + {{- if and .adminEmail (or .serviceAccountJson .existingSecret) }} + - name: google-secret + secret: + secretName: {{ if .existingSecret }}{{ .existingSecret }}{{ else }} {{ template "oauth2-proxy.secretName" $ }}-google{{ end }} + {{- end }} + {{- end }} + {{- if .Values.htpasswdFile.enabled }} + - name: {{ template "oauth2-proxy.name" . }}-htpasswd-file + secret: + secretName: {{ if .Values.htpasswdFile.existingSecret }}{{ .Values.htpasswdFile.existingSecret }}{{ else }} {{ template "oauth2-proxy.name" . }}-htpasswd-file {{ end }} + {{- end }} + {{- if and (.Values.authenticatedEmailsFile.enabled) (eq .Values.authenticatedEmailsFile.persistence "secret") }} + - name: configaccesslist + secret: + items: + - key: {{ default "restricted_user_access" .Values.authenticatedEmailsFile.restrictedUserAccessKey }} + {{- if .Values.authenticatedEmailsFile.emailUserListTemplate }} + path: {{ .Values.authenticatedEmailsFile.emailUserListTemplate }} + {{- else }} + path: authenticated-emails-list + {{- end }} + {{- if .Values.authenticatedEmailsFile.emailUserListTemplate }} + secretName: {{ .Values.authenticatedEmailsFile.emailUserListTemplate }} + {{- else }} + secretName: {{ template "oauth2-proxy.name" . }}-accesslist + {{- end }} + {{- end }} + {{- if or .Values.config.existingConfig .Values.config.configFile }} + - configMap: + defaultMode: 420 + name: {{ if .Values.config.existingConfig }}{{ .Values.config.existingConfig }}{{ else }}{{ template "oauth2-proxy.name" . }}{{ end }} + name: configmain + {{- end }} + {{- if .Values.alphaConfig.enabled }} + - configMap: + defaultMode: 420 + name: {{ if .Values.alphaConfig.existingConfig }}{{ .Values.alphaConfig.existingConfig }}{{ else }}{{ template "oauth2-proxy.name" . }}-alpha{{ end }} + name: configalpha + {{- end }} + {{- if ne (len .Values.extraVolumes) 0 }} +{{ toYaml .Values.extraVolumes | indent 6 }} + {{- end }} + {{- if and (.Values.authenticatedEmailsFile.enabled) (eq .Values.authenticatedEmailsFile.persistence "configmap") }} + - configMap: + {{- if .Values.authenticatedEmailsFile.emailUserListTemplate }} + name: {{ .Values.authenticatedEmailsFile.emailUserListTemplate }} + {{- else }} + name: {{ template "oauth2-proxy.name" . }}-accesslist + {{- end }} + items: + - key: {{ default "restricted_user_access" .Values.authenticatedEmailsFile.restrictedUserAccessKey }} + {{- if .Values.authenticatedEmailsFile.emailUserListTemplate }} + path: {{ .Values.authenticatedEmailsFile.emailUserListTemplate }} + {{- else }} + path: authenticated-emails-list + {{- end }} + name: configaccesslist + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} \ No newline at end of file diff --git a/helm/charts/identity-oauth2-proxy/templates/extra-manifests.yaml b/helm/charts/identity-oauth2-proxy/templates/extra-manifests.yaml new file mode 100644 index 0000000..ba38128 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/extra-manifests.yaml @@ -0,0 +1,16 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }}{{- if and .Values.config.google (and (not .Values.config.google.existingSecret) (not .Values.config.google.useApplicationDefaultCredentials)) }} +apiVersion: v1 +kind: Secret +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.name" . }}-google + namespace: {{ template "oauth2-proxy.namespace" $ }} +type: Opaque +data: + service-account.json: {{ .Values.config.google.serviceAccountJson | b64enc | quote }} +{{- end -}} diff --git a/helm/charts/identity-oauth2-proxy/templates/google-secret.yaml b/helm/charts/identity-oauth2-proxy/templates/google-secret.yaml new file mode 100644 index 0000000..7397d27 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/google-secret.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.config.google (and (not .Values.config.google.existingSecret) (not .Values.config.google.useApplicationDefaultCredentials)) }} +apiVersion: v1 +kind: Secret +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.name" . }}-google + namespace: {{ template "oauth2-proxy.namespace" $ }} +type: Opaque +data: + service-account.json: {{ .Values.config.google.serviceAccountJson | b64enc | quote }} +{{- end -}} diff --git a/helm/charts/identity-oauth2-proxy/templates/hpa.yaml b/helm/charts/identity-oauth2-proxy/templates/hpa.yaml new file mode 100644 index 0000000..3d80dee --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "oauth2-proxy.name" . }} + labels: + {{- include "oauth2-proxy.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "oauth2-proxy.name" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/ingress.yaml b/helm/charts/identity-oauth2-proxy/templates/ingress.yaml new file mode 100644 index 0000000..df62bd2 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "oauth2-proxy.name" . -}} +{{- $svcPort := .Values.service.portNumber -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "oauth2-proxy.labels" . | nindent 4 -}} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/poddisruptionbudget.yaml b/helm/charts/identity-oauth2-proxy/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000..4fcb2c1 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/poddisruptionbudget.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.podDisruptionBudget.enabled (gt (.Values.replicaCount | int) 1) }} +apiVersion: {{ include "capabilities.podDisruptionBudget.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.name" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +spec: + selector: + matchLabels: + {{- include "oauth2-proxy.selectorLabels" . | indent 6 }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/redis-secret.yaml b/helm/charts/identity-oauth2-proxy/templates/redis-secret.yaml new file mode 100644 index 0000000..0df2511 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/redis-secret.yaml @@ -0,0 +1,23 @@ +{{- $name := include "oauth2-proxy.name" . -}} +{{- $fullName := include "oauth2-proxy.name" . -}} +{{- $labels := include "oauth2-proxy.labels" . -}} +{{- with .Values.sessionStorage }} +{{- if and (eq .type "redis") (not .redis.existingSecret) (or .redis.password .redis.sentinel.password) }} +apiVersion: v1 +kind: Secret +metadata: + labels: + app: {{ $name }} + {{- $labels | indent 4 }} + name: {{ $fullName }}-redis-access + namespace: {{ template "oauth2-proxy.namespace" $ }} +type: Opaque +data: + {{- if and .redis.password (not .redis.existingSecret) }} + {{ .redis.passwordKey }}: {{ .redis.password | b64enc | quote }} + {{- end }} + {{- if and .redis.sentinel.password (not .redis.sentinel.existingSecret) (ne .redis.sentinel.passwordKey .redis.passwordKey) }} + {{ .redis.sentinel.passwordKey }}: {{ .redis.sentinel.password | b64enc | quote }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/secret-authenticated-emails-file.yaml b/helm/charts/identity-oauth2-proxy/templates/secret-authenticated-emails-file.yaml new file mode 100644 index 0000000..1a9098c --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/secret-authenticated-emails-file.yaml @@ -0,0 +1,19 @@ +{{- if .Values.authenticatedEmailsFile.enabled }} +{{- if and (.Values.authenticatedEmailsFile.restricted_access) (eq .Values.authenticatedEmailsFile.persistence "secret") }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} +{{- if .Values.authenticatedEmailsFile.annotations }} + annotations: +{{ toYaml .Values.authenticatedEmailsFile.annotations | indent 4 }} +{{- end }} + name: {{ template "oauth2-proxy.name" . }}-accesslist + namespace: {{ template "oauth2-proxy.namespace" $ }} +data: + {{ default "restricted_user_access" .Values.authenticatedEmailsFile.restrictedUserAccessKey }}: {{ .Values.authenticatedEmailsFile.restricted_access | b64enc }} +{{- end }} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/secret-htpasswd-file.yam b/helm/charts/identity-oauth2-proxy/templates/secret-htpasswd-file.yam new file mode 100644 index 0000000..0975b3e --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/secret-htpasswd-file.yam @@ -0,0 +1,16 @@ +{{- if and .Values.htpasswdFile.enabled (not .Values.htpasswdFile.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.name" . }}-htpasswd-file + namespace: {{ template "oauth2-proxy.namespace" $ }} +type: Opaque +stringData: + users.txt: |- + {{- range $entries := .Values.htpasswdFile.entries }} + {{ $entries }} + {{- end -}} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/secret.yaml b/helm/charts/identity-oauth2-proxy/templates/secret.yaml new file mode 100644 index 0000000..fd7c7b9 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/secret.yaml @@ -0,0 +1,19 @@ +{{- if and (not .Values.config.existingSecret) (.Values.proxyVarsAsSecrets) }} +apiVersion: v1 +kind: Secret +metadata: +{{- if .Values.config.annotations }} + annotations: +{{ toYaml .Values.config.annotations | indent 4 }} +{{- end }} + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.name" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +type: Opaque +data: + cookie-secret: {{ tpl .Values.config.cookieSecret $ | b64enc | quote }} + client-secret: {{ tpl .Values.config.clientSecret $ | b64enc | quote }} + client-id: {{ tpl .Values.config.clientID $ | b64enc | quote }} +{{- end -}} diff --git a/helm/charts/identity-oauth2-proxy/templates/service.yaml b/helm/charts/identity-oauth2-proxy/templates/service.yaml new file mode 100644 index 0000000..7f49f2e --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/service.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.name" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +{{- end }} +spec: +{{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} + type: ClusterIP + {{- if .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{end}} +{{- else if eq .Values.service.type "LoadBalancer" }} + type: {{ .Values.service.type }} + {{- if .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} + {{- end -}} +{{- else }} + type: {{ .Values.service.type }} +{{- end }} + ports: + - port: {{ .Values.service.portNumber }} + targetPort: {{ .Values.httpScheme }} + {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + protocol: TCP + {{- with .Values.service.appProtocol }} + appProtocol: {{ . }} + {{- end }} + name: {{ .Values.httpScheme }} + {{- if and .Values.metrics.enabled .Values.metrics.port }} + - port: {{ .Values.metrics.port }} + protocol: TCP + {{- with .Values.metrics.service.appProtocol }} + appProtocol: {{ . }} + {{- end }} + targetPort: metrics + {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.metrics.nodePort))) }} + nodePort: {{ .Values.metrics.nodePort }} + {{- end }} + name: metrics + {{- end }} + selector: +{{ include "oauth2-proxy.selectorLabels" . | indent 4 }} diff --git a/helm/charts/identity-oauth2-proxy/templates/serviceaccount.yaml b/helm/charts/identity-oauth2-proxy/templates/serviceaccount.yaml new file mode 100644 index 0000000..fe6281b --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if or .Values.serviceAccount.enabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} + name: {{ template "oauth2-proxy.serviceAccountName" . }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end -}} \ No newline at end of file diff --git a/helm/charts/identity-oauth2-proxy/templates/servicemonitor.yaml b/helm/charts/identity-oauth2-proxy/templates/servicemonitor.yaml new file mode 100644 index 0000000..ac8c011 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/servicemonitor.yaml @@ -0,0 +1,31 @@ +{{- if and .Values.metrics.enabled .Values.metrics.servicemonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "oauth2-proxy.name" . }} +{{- if .Values.metrics.servicemonitor.namespace }} + namespace: {{ .Values.metrics.servicemonitor.namespace }} +{{- else }} + namespace: {{ template "oauth2-proxy.namespace" $ }} +{{- end }} + labels: + prometheus: {{ .Values.metrics.servicemonitor.prometheusInstance }} + app: {{ template "oauth2-proxy.name" . }} +{{- include "oauth2-proxy.labels" . | indent 4 }} +{{- if .Values.metrics.servicemonitor.labels }} +{{ toYaml .Values.metrics.servicemonitor.labels | indent 4}} +{{- end }} +spec: + jobLabel: {{ template "oauth2-proxy.name" . }} + selector: + matchLabels: + {{- include "oauth2-proxy.selectorLabels" . | indent 6 }} + namespaceSelector: + matchNames: + - {{ template "oauth2-proxy.namespace" $ }} + endpoints: + - port: metrics + path: "/metrics" + interval: {{ .Values.metrics.servicemonitor.interval }} + scrapeTimeout: {{ .Values.metrics.servicemonitor.scrapeTimeout }} +{{- end }} diff --git a/helm/charts/identity-oauth2-proxy/templates/tests/test-connection.yaml b/helm/charts/identity-oauth2-proxy/templates/tests/test-connection.yaml new file mode 100644 index 0000000..42e48d5 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/templates/tests/test-connection.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "oauth2-proxy.name" . }}-test-connection" + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "oauth2-proxy.name" . }}:{{ .Values.service.portNumber }}'] + restartPolicy: Never diff --git a/helm/charts/identity-oauth2-proxy/values.yaml b/helm/charts/identity-oauth2-proxy/values.yaml new file mode 100644 index 0000000..34fd0a2 --- /dev/null +++ b/helm/charts/identity-oauth2-proxy/values.yaml @@ -0,0 +1,373 @@ +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# --------------------------------------- +# Global variables +# --------------------------------------- +nameOverride: "" +namespaceOverride: "" +fullnameOverride: "" +restartPolicy: Always + +# --------------------------------------------- +# Variable used in hpa template and deployment +# --------------------------------------------- +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 3 + targetCPUUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 80 + +# Force the target Kubernetes version (it uses Helm `.Capabilities` if not set). +# This is especially useful for `helm template` as capabilities are always empty +# due to the fact that it doesn't query an actual cluster +kubeVersion: + +# --------------------------------------- +# Variable used in Deployment template +# --------------------------------------- + +replicaCount: 1 +# Additional Pod annotations +podAnnotations: {} +# Additional Pod labels +podLabels: {} +deploymentAnnotations: {} +revisionHistoryLimit: 10 +# Image pull secrets for the Pod +imagePullSecrets: [] +# SecurityContext for the entire Pod. Every container running in the Pod will inherit this SecurityContext. This might be relevant when other components of the environment inject additional containers into running Pods (service meshes are the most prominent example for this) +podSecurityContext: + fsGroup: 1000 +# Configure Kubernetes security context for container +# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: + enabled: true + runAsUser: 1000 + # runAsNonRoot: true + # allowPrivilegeEscalation: false + +## PodDisruptionBudget settings +## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ +podDisruptionBudget: + enabled: true + minAvailable: 1 +# whether to use http or https +httpScheme: http + + +image: + repository: "quay.io/oauth2-proxy/oauth2-proxy" + pullPolicy: IfNotPresent + # Optionally specify an array of imagePullSecrets. + # Secrets must be manually created in the namespace. + # ref: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + # imagePullSecrets: + # - name: myRegistryKeySecretName + # Set a custom containerPort if required. + # This will default to 4180 if this value is not set and the httpScheme set to http + # This will default to 4443 if this value is not set and the httpScheme set to https + # containerPort: 4180 + +extraArgs: {} +extraEnv: [] +# -- Custom labels to add into metadata +customLabels: {} +service: + type: ClusterIP + # when service.type is ClusterIP ... + # clusterIP: 192.0.2.20 + # when service.type is LoadBalancer ... + # loadBalancerIP: 198.51.100.40 + # loadBalancerSourceRanges: 203.0.113.0/24 + # when service.type is NodePort ... + # nodePort: 80 + portNumber: 4180 + # Protocol set on the service + appProtocol: http + annotations: {} + # foo.io/bar: "true" + +extraVolumes: [] +# - name: ca-bundle-cert +# secret: +# secretName: + +extraVolumeMounts: [] +# - mountPath: /etc/ssl/certs/ +# name: ca-bundle-cert + +# Additional containers to be added to the pod. +extraContainers: [] +# - name: my-sidecar +# image: nginx:latest + +# Whether to use secrets instead of environment values for setting up OAUTH2_PROXY variables +proxyVarsAsSecrets: true + +# Additionally authenticate against a htpasswd file. Entries must be created with "htpasswd -B" for bcrypt encryption. +# Alternatively supply an existing secret which contains the required information. +htpasswdFile: + enabled: false + existingSecret: "" + entries: [] + # One row for each user + # example: + # entries: + # - testuser:$2y$05$gY6dgXqjuzFhwdhsiFe7seM9q9Tile4Y3E.CBpAZJffkeiLaC21Gy + + +# Configure the session storage type, between cookie and redis +sessionStorage: + # Can be one of the supported session storage cookie|redis + type: cookie + redis: + # Name of the Kubernetes secret containing the redis & redis sentinel password values (see also `sessionStorage.redis.passwordKey`) + existingSecret: "" + # Redis password value. Applicable for all Redis configurations. Taken from redis subchart secret if not set. `sessionStorage.redis.existingSecret` takes precedence + password: "" + # Key of the Kubernetes secret data containing the redis password value + passwordKey: "redis-password" + # Can be one of standalone|cluster|sentinel + clientType: "standalone" + standalone: + # URL of redis standalone server for redis session storage (e.g. `redis://HOST[:PORT]`). Automatically generated if not set + connectionUrl: "" + cluster: + # List of Redis cluster connection URLs (e.g. `["redis://127.0.0.1:8000", "redis://127.0.0.1:8000"]`) + connectionUrls: [] + sentinel: + # Name of the Kubernetes secret containing the redis sentinel password value (see also `sessionStorage.redis.sentinel.passwordKey`). Default: `sessionStorage.redis.existingSecret` + existingSecret: "" + # Redis sentinel password. Used only for sentinel connection; any redis node passwords need to use `sessionStorage.redis.password` + password: "" + # Key of the Kubernetes secret data containing the redis sentinel password value + passwordKey: "redis-sentinel-password" + # Redis sentinel master name + masterName: "" + # List of Redis sentinel connection URLs (e.g. `["redis://127.0.0.1:8000", "redis://127.0.0.1:8000"]`) + connectionUrls: [] +# Enables and configure the automatic deployment of the redis subchart +redis: + # provision an instance of the redis sub-chart + enabled: false + # Redis specific helm chart settings, please see: + # https://github.com/bitnami/charts/tree/master/bitnami/redis#parameters + # redisPort: 6379 + # cluster: + # enabled: false + # slaveCount: 1 + +# Enables apiVersion deprecation checks +checkDeprecation: true + +metrics: + # Enable Prometheus metrics endpoint + enabled: true + # Serve Prometheus metrics on this port + port: 44180 + # when service.type is NodePort ... + # nodePort: 44180 + # Protocol set on the service for the metrics port + service: + appProtocol: http + servicemonitor: + # Enable Prometheus Operator ServiceMonitor + enabled: false + # Define the namespace where to deploy the ServiceMonitor resource + namespace: "" + # Prometheus Instance definition + prometheusInstance: default + # Prometheus scrape interval + interval: 60s + # Prometheus scrape timeout + scrapeTimeout: 30s + # Add custom labels to the ServiceMonitor resource + labels: {} + +# Extra K8s manifests to deploy +extraObjects: [] + # - apiVersion: secrets-store.csi.x-k8s.io/v1 + # kind: SecretProviderClass + # metadata: + # name: oauth2-proxy-secrets-store + # spec: + # provider: aws + # parameters: + # objects: | + # - objectName: "oauth2-proxy" + # objectType: "secretsmanager" + # jmesPath: + # - path: "client_id" + # objectAlias: "client-id" + # - path: "client_secret" + # objectAlias: "client-secret" + # - path: "cookie_secret" + # objectAlias: "cookie-secret" + # secretObjects: + # - data: + # - key: client-id + # objectName: client-id + # - key: client-secret + # objectName: client-secret + # - key: cookie-secret + # objectName: cookie-secret + # secretName: oauth2-proxy-secrets-store +# type: Opaque + +priorityClassName: "" + +# Host aliases, useful when working "on premise" where (public) DNS resolver does not know about my hosts. +hostAlias: + enabled: false + # ip: "10.xxx.xxx.xxx" + # hostname: "auth.example.com" + +# Define which port will be used in the containers +containerPort: 4180 +# Configure Kubernetes liveness and readiness probes. +# Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ +# Disable both when deploying with Istio 1.0 mTLS. https://istio.io/help/faq/security/#k8s-health-checks +livenessProbe: + enabled: true + initialDelaySeconds: 0 + timeoutSeconds: 1 + path: /ping +readinessProbe: + enabled: true + initialDelaySeconds: 0 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + path: /ping +# Pod resource requests and limits +resources: {} + # requests: + # cpu: "500m" + # memory: "1024Mi" + # limits: + # cpu: "500m" +# memory: "1024Mi" +# Node labels for Pod assignment +nodeSelector: {} +# Pod affinity +affinity: {} +# Node taints to tolerate +tolerations: [] + +# --------------------------------------- +# Variable group used in ingress template +# --------------------------------------- +ingress: + enabled: true + className: "" + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: web, websecure + traefik.ingress.kubernetes.io/router.tls: "true" + cert-manager.io/cluster-issuer: selfsigned-issuer + hosts: + - host: identity.proxy.local.eoepca.org + paths: + - path: / + pathType: Prefix + tls: + - secretName: identity-proxy-tls-certificate + hosts: + - identity.proxy.local.eoepca.org + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: + automountServiceAccountToken: true + + + +alphaConfig: + enabled: false + # Add config annotations + annotations: {} + # Arbitrary configuration data to append to the server section + serverConfigData: {} + # Arbitrary configuration data to append to the metrics section + metricsConfigData: {} + # Arbitrary configuration data to append + configData: {} + # Arbitrary configuration to append + # This is treated as a Go template and rendered with the root context + configFile: "" + # Use an existing config map (see configmap-alpha.yaml for required fields) + existingConfig: ~ + + + +# To authorize individual email addresses +# That is part of extraArgs but since this needs special treatment we need to do a separate section +authenticatedEmailsFile: + enabled: false + # Defines how the email addresses file will be projected, via a configmap or secret + persistence: configmap + # template is the name of the configmap what contains the email user list but has been configured without this chart. + # It's a simpler way to maintain only one configmap (user list) instead changing it for each oauth2-proxy service. + # Be aware the value name in the extern config map in data needs to be named to "restricted_user_access" or to the + # provided value in restrictedUserAccessKey field. + emailUserListTemplate: "" + # The configmap/secret key under which the list of email access is stored + # Defaults to "restricted_user_access" if not filled-in, but can be overridden to allow flexibility + restrictedUserAccessKey: "" + # One email per line + # example: + # restricted_access: |- + # name1@domain + # name2@domain + # If you override the config with restricted_access it will configure a user list within this chart what takes care of the + # config map resource. + restricted_access: "" + annotations: {} + # helm.sh/resource-policy: keep + + +config: + # Add config annotations + annotations: {} + clientID: "oauth2-proxy" + clientSecret: "secret" + cookieSecret: "JxJZrvNo4z1VJIiDMDGJe3q4TjmpVxMNHziW97J9UAo=" + # The name of the cookie that oauth2-proxy will create + # If left empty, it will default to the release name + cookieName: "" + google: {} + # Use an existing config map (see configmap.yaml for required fields) + existingConfig: ~ + configFile: |- + http_address = "0.0.0.0:4180" + cookie_secure = true + cookie_secret = "JxJZrvNo4z1VJIiDMDGJe3q4TjmpVxMNHziW97J9UAo=" + upstreams = ["https://dummy-service.develop.eoepca.org"] + cookie_domains = [".eoepca.org", "localhost"] # Required so cookie can be read on all subdomains. + whitelist_domains = [".eoepca.org", "localhost"] # Required to allow redirection back to original requested target. + pass_access_token = true + set_xauthrequest = true + # allow accounts to sign-in with empty emails + # https://github.com/oauth2-proxy/oauth2-proxy/issues/769#issuecomment-808916298 + email_domains = ["*"] + insecure_oidc_allow_unverified_email = true + oidc_email_claim = "sub" + # keycloak provider + client_id = "oauth2-proxy" + client_secret = "secret" + redirect_url = "https://identity.proxy.local.eoepca.org/oauth2/callback" + # in this case oauth2-proxy is going to visit + # https://identity.keycloak.local.eoepca.org/realms/demo/.well-known/openid-configuration for configuration + oidc_issuer_url = "https://identity.keycloak.local.eoepca.org/realms/demo" + provider = "oidc" + provider_display_name = "Keycloak" + skip_provider_button = true + skip_jwt_bearer_tokens = true + pass_host_header = false + pass_authorization_header = true \ No newline at end of file