From ac5f79c81e277f8e3631b6cce4197f82f726f027 Mon Sep 17 00:00:00 2001 From: Vladimir Antropov Date: Tue, 15 Oct 2024 13:57:22 +0200 Subject: [PATCH] feat: inital release of glauth and platforma --- .gitignore | 3 + artifacthub-repo.yml | 0 charts/glauth/.helmignore | 23 + charts/glauth/Chart.yaml | 11 + charts/glauth/README.md | 61 ++ charts/glauth/templates/_helpers.tpl | 69 +++ charts/glauth/templates/app-deployment.yaml | 159 ++++++ .../glauth/templates/app-isito-gateway.yaml | 25 + .../templates/app-isito-virtualservice.yaml | 28 + charts/glauth/templates/app-pvc.yaml | 35 ++ .../glauth/templates/app-secret-config.yaml | 10 + charts/glauth/templates/app-service.yaml | 48 ++ charts/glauth/templates/role.yaml | 17 + charts/glauth/templates/rolebinding.yaml | 24 + charts/glauth/templates/serviceaccount.yaml | 16 + charts/glauth/values.yaml | 257 +++++++++ charts/platforma/.helmignore | 23 + charts/platforma/Chart.yaml | 11 + charts/platforma/README.md | 129 +++++ charts/platforma/templates/_helpers.tpl | 123 ++++ .../templates/app-configuration.yaml | 10 + .../platforma/templates/app-deployment.yaml | 200 +++++++ .../templates/app-externalsecret.yaml | 30 + charts/platforma/templates/app-hpa.yaml | 21 + charts/platforma/templates/app-htpasswd.yaml | 12 + .../templates/app-ingress-debug.yaml | 55 ++ charts/platforma/templates/app-ingress.yaml | 77 +++ .../templates/app-isito-gateway.yaml | 25 + .../templates/app-isito-virtualservice.yaml | 29 + charts/platforma/templates/app-pdb.yaml | 22 + charts/platforma/templates/app-pvc.yaml | 107 ++++ .../platforma/templates/app-secretstore.yaml | 28 + .../templates/app-service-debug.yaml | 48 ++ charts/platforma/templates/app-service.yaml | 48 ++ charts/platforma/templates/role.yaml | 17 + charts/platforma/templates/rolebinding.yaml | 24 + .../platforma/templates/serviceaccount.yaml | 16 + charts/platforma/values.yaml | 528 ++++++++++++++++++ 38 files changed, 2369 insertions(+) create mode 100644 .gitignore create mode 100644 artifacthub-repo.yml create mode 100644 charts/glauth/.helmignore create mode 100644 charts/glauth/Chart.yaml create mode 100644 charts/glauth/README.md create mode 100644 charts/glauth/templates/_helpers.tpl create mode 100644 charts/glauth/templates/app-deployment.yaml create mode 100644 charts/glauth/templates/app-isito-gateway.yaml create mode 100644 charts/glauth/templates/app-isito-virtualservice.yaml create mode 100644 charts/glauth/templates/app-pvc.yaml create mode 100644 charts/glauth/templates/app-secret-config.yaml create mode 100644 charts/glauth/templates/app-service.yaml create mode 100644 charts/glauth/templates/role.yaml create mode 100644 charts/glauth/templates/rolebinding.yaml create mode 100644 charts/glauth/templates/serviceaccount.yaml create mode 100644 charts/glauth/values.yaml create mode 100644 charts/platforma/.helmignore create mode 100644 charts/platforma/Chart.yaml create mode 100644 charts/platforma/README.md create mode 100644 charts/platforma/templates/_helpers.tpl create mode 100644 charts/platforma/templates/app-configuration.yaml create mode 100644 charts/platforma/templates/app-deployment.yaml create mode 100644 charts/platforma/templates/app-externalsecret.yaml create mode 100644 charts/platforma/templates/app-hpa.yaml create mode 100644 charts/platforma/templates/app-htpasswd.yaml create mode 100644 charts/platforma/templates/app-ingress-debug.yaml create mode 100644 charts/platforma/templates/app-ingress.yaml create mode 100644 charts/platforma/templates/app-isito-gateway.yaml create mode 100644 charts/platforma/templates/app-isito-virtualservice.yaml create mode 100644 charts/platforma/templates/app-pdb.yaml create mode 100644 charts/platforma/templates/app-pvc.yaml create mode 100644 charts/platforma/templates/app-secretstore.yaml create mode 100644 charts/platforma/templates/app-service-debug.yaml create mode 100644 charts/platforma/templates/app-service.yaml create mode 100644 charts/platforma/templates/role.yaml create mode 100644 charts/platforma/templates/rolebinding.yaml create mode 100644 charts/platforma/templates/serviceaccount.yaml create mode 100644 charts/platforma/values.yaml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7cbf49d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Helm resources +charts/*/charts/*.tgz +charts/*/Chart.lock diff --git a/artifacthub-repo.yml b/artifacthub-repo.yml new file mode 100644 index 0000000..e69de29 diff --git a/charts/glauth/.helmignore b/charts/glauth/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/glauth/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/glauth/Chart.yaml b/charts/glauth/Chart.yaml new file mode 100644 index 0000000..275cb2f --- /dev/null +++ b/charts/glauth/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: glauth +description: GLAuth LDAP authentication server Helm Chart +type: application +appVersion: 2.3.2 +version: 1.0.1 +sources: + - https://github.com/milaboratory/public-helm-charts/charts/glauth +maintainers: + - name: Vladimir Antropov + email: vladimir.antropov@milaboratories.com diff --git a/charts/glauth/README.md b/charts/glauth/README.md new file mode 100644 index 0000000..1fc2fff --- /dev/null +++ b/charts/glauth/README.md @@ -0,0 +1,61 @@ +GLAuth: LDAP authentication server +============== + +For me information please visit the official github repository [GLAuth](https://github.com/glauth/glauth). + +## Prerequisites + +- Kubernetes 1.20+ +- Helm 3.0+ + +## Installing + +Add the desired configuration under `app.config` in the Helm `values.yaml`. +Here's a sample config with hardcoded users and groups: +```toml +[backend] + datastore = "config" + nameformat = "cn" + groupformat = "ou" + baseDN = "dc=demo,dc=io" + +[behaviors] + IgnoreCapabilities = false + LimitFailedBinds = false + +[ldap] + enabled = true + listen = "0.0.0.0:3893" +[ldaps] + enabled = false + listen = "0.0.0.0:3894" + cert = "/app/config/ssl/glauth-ca-cert.pem" + key = "/app/config/ssl/glauth-ca-key.pem" +[api] + enabled = false + internals = true + listen = "0.0.0.0:5555" + +[[groups]] + name = "users" + gidnumber = 4401 + +[[users]] + name = "testuser1" + uidnumber = 4001 + primarygroup = 4401 + passsha256 = "00a082620a12245988ee6ef6d61a561c009e0bbd033b40604b96c199f28c42b6" +[[users.capabilities]] + action = "search" + object = "ou=users,dc=demo,dc=io" +``` + +Here is how you can generate a SHA256 password hash. +```bash +#!/bin/bash +password=$(pwgen -n1 32) +echo "Passwd: ${password}" +# Generate SHA-256 hash of the password +pass_sha256=$(echo -n "${password}" | openssl dgst -sha256 | sed 's/^.* //') +echo "Sha256 ${pass_sha256}" +``` diff --git a/charts/glauth/templates/_helpers.tpl b/charts/glauth/templates/_helpers.tpl new file mode 100644 index 0000000..11cc317 --- /dev/null +++ b/charts/glauth/templates/_helpers.tpl @@ -0,0 +1,69 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "glauth.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 "glauth.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 "glauth.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "glauth.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} + {{- default (include "glauth.fullname" .) .Values.serviceAccount.name }} +{{- else }} + {{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Get the correct image tag name +*/}} +{{- define "glauth.imageTag" -}} +{{- .Values.app.image.tag | default (printf "v%s" .Chart.AppVersion) -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "glauth.labels" -}} +helm.sh/chart: {{ include "glauth.chart" . }} +{{ include "glauth.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "glauth.selectorLabels" -}} +app.kubernetes.io/name: {{ include "glauth.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/charts/glauth/templates/app-deployment.yaml b/charts/glauth/templates/app-deployment.yaml new file mode 100644 index 0000000..a65d00f --- /dev/null +++ b/charts/glauth/templates/app-deployment.yaml @@ -0,0 +1,159 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with .Values.app.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "glauth.labels" . | nindent 4 }} + {{- with .Values.app.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "glauth.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + {{- include "glauth.selectorLabels" . | nindent 6 }} + replicas: {{ .Values.app.replicaCount }} + {{- with .Values.app.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + annotations: + checksum/config: {{ include (print .Template.BasePath "/app-secret-config.yaml") . | sha256sum }} + {{- with .Values.app.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "glauth.labels" . | nindent 8 }} + {{- with .Values.app.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.app.priorityClassName }} + priorityClassName: {{ .Values.app.priorityClassName | toString }} + {{- end }} + {{- if .Values.app.schedulerName }} + schedulerName: {{ .Values.app.schedulerName }} + {{- end }} + {{- if .Values.app.enableServiceLinks }} + enableServiceLinks: {{ .Values.app.enableServiceLinks }} + {{- end }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{- with .Values.app.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.app.terminationGracePeriodSeconds }} + containers: + - name: {{ template "glauth.name" . }}-{{ .Values.app.name }} + image: "{{ .Values.app.image.repository }}:{{ include "glauth.imageTag" . }}" + imagePullPolicy: {{ .Values.app.image.pullPolicy }} + {{- if .Values.app.containerWorkingDir }} + workingDir: {{ .Values.app.containerWorkingDir }} + {{- end }} + {{- with .Values.app.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.app.image.command }} + command: [{{ .Values.app.image.command | quote }}] + {{- end }} + {{- if .Values.app.image.args }} + args: + {{- range .Values.app.image.args }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- if .Values.app.env }} + env: + {{- range $key, $value := .Values.app.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.app.envValueFrom }} + {{- range $key, $value := .Values.app.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 16 }} + {{- end }} + {{- end }} + ports: + - name: {{ .Values.app.service.portName }} + containerPort: {{ .Values.app.service.targetPort }} + {{- with .Values.app.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.app.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.app.startupProbe }} + startupProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.app.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /app/config/config.cfg + subPath: config.cfg + readOnly: true + - name: database-volume + mountPath: {{ .Values.app.persistentVolume.mountPath }} + {{- with .Values.app.podSecurityContext }} + securityContext: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.hostAliases }} + hostAliases: +{{ toYaml . | indent 8 }} + {{- end }} + serviceAccountName: {{ template "glauth.serviceAccountName" . }} + {{- with .Values.app.imagePullSecrets }} + imagePullSecrets: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml . | indent 8 }} + {{- end }} + hostNetwork: {{ .Values.app.hostNetwork }} + {{- if .Values.app.dnsPolicy }} + dnsPolicy: {{ .Values.app.dnsPolicy | toString }} + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: +{{- toYaml . | indent 8 }} + {{- end }} + volumes: + - name: config + secret: + secretName: {{ template "glauth.fullname" . }}-secret-config + - name: database-volume + {{- if .Values.app.persistentVolume.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.app.persistentVolume.existingClaim }}{{ .Values.app.persistentVolume.existingClaim }}{{- else }}{{ template "glauth.fullname" . }}{{- end }} + {{- else }} + emptyDir: {} + {{- end }} diff --git a/charts/glauth/templates/app-isito-gateway.yaml b/charts/glauth/templates/app-isito-gateway.yaml new file mode 100644 index 0000000..8ba50ef --- /dev/null +++ b/charts/glauth/templates/app-isito-gateway.yaml @@ -0,0 +1,25 @@ +{{- if .Values.app.istio.enabled }} +{{- $istioHosts := .Values.app.istio.hosts }} +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: {{ template "glauth.fullname" . }}-gateway + namespace: {{ .Release.Namespace }} + labels: + {{- include "glauth.labels" . | nindent 4 }} + {{- with .Values.app.istio.gateway.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + istio: {{ .Values.app.istio.gateway.ingressGatewayName }} + servers: + - port: + number: {{ .Values.app.istio.gateway.port }} + name: {{ .Values.app.istio.gateway.portName }} + protocol: {{ .Values.app.istio.gateway.protocol }} + hosts: + {{- range $istioHosts }} + - {{ tpl . $ | quote }} + {{- end }} +{{- end }} diff --git a/charts/glauth/templates/app-isito-virtualservice.yaml b/charts/glauth/templates/app-isito-virtualservice.yaml new file mode 100644 index 0000000..1ee75bc --- /dev/null +++ b/charts/glauth/templates/app-isito-virtualservice.yaml @@ -0,0 +1,28 @@ +{{- if .Values.app.istio.enabled }} +{{- $istioHosts := .Values.app.istio.hosts }} +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: {{ template "glauth.fullname" . }}-virtual-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "glauth.labels" . | nindent 4 }} + {{- with .Values.app.istio.virtualService.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + hosts: + {{- range $istioHosts }} + - {{ tpl . $ | quote }} + {{- end }} + gateways: + - {{ template "glauth.fullname" . }}-gateway + tcp: + - match: + - port: {{ .Values.app.istio.gateway.port }} + route: + - destination: + host: {{ template "glauth.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local + port: + number: {{ .Values.app.istio.gateway.port }} +{{- end }} diff --git a/charts/glauth/templates/app-pvc.yaml b/charts/glauth/templates/app-pvc.yaml new file mode 100644 index 0000000..3ec41fb --- /dev/null +++ b/charts/glauth/templates/app-pvc.yaml @@ -0,0 +1,35 @@ +{{- if and .Values.app.persistentVolume.enabled (not .Values.app.persistentVolume.existingClaim) .Values.app.enabled }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "glauth.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "glauth.labels" . | nindent 4 }} + {{- with .Values.app.persistentVolume.extraLabels }} + {{- toYaml . | nindent 4 }} + {{ end }} + {{- with .Values.app.persistentVolume.annotations }} + annotations: + {{- toYaml . | indent 4 }} + {{- end }} +spec: + {{- with .Values.app.persistentVolume.accessModes }} + accessModes: +{{ toYaml . | indent 4 }} + {{- end }} + resources: + requests: + storage: {{ .Values.app.persistentVolume.size | quote }} + {{- if .Values.app.persistentVolume.reclaimPolicy }} + persistentVolumeReclaimPolicy: {{ .Values.app.persistentVolume.reclaimPolicy }} + {{- end }} + {{- if .Values.app.persistentVolume.storageClass }} + storageClassName: {{ .Values.app.persistentVolume.storageClass | quote }} + {{- end }} + {{- with .Values.app.persistentVolume.matchLabels }} + selector: + matchLabels: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/glauth/templates/app-secret-config.yaml b/charts/glauth/templates/app-secret-config.yaml new file mode 100644 index 0000000..5619532 --- /dev/null +++ b/charts/glauth/templates/app-secret-config.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "glauth.fullname" . }}-secret-config + namespace: {{ .Release.Namespace }} + labels: + {{- include "glauth.labels" . | nindent 4 }} +type: Opaque +data: + config.cfg: {{ .Values.app.config | b64enc | quote }} diff --git a/charts/glauth/templates/app-service.yaml b/charts/glauth/templates/app-service.yaml new file mode 100644 index 0000000..4576010 --- /dev/null +++ b/charts/glauth/templates/app-service.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "glauth.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "glauth.labels" . | nindent 4 }} + {{- with .Values.app.service.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.app.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: +{{- if .Values.app.service.clusterIP }} + clusterIP: {{ .Values.app.service.clusterIP }} +{{- end }} +{{- if .Values.app.service.externalIPs }} + externalIPs: +{{ toYaml .Values.app.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.app.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.app.service.loadBalancerIP }} +{{- end }} +{{- if .Values.app.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.app.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: {{ .Values.app.service.portName }} + port: {{ .Values.app.service.port }} + protocol: TCP + targetPort: {{ .Values.app.service.targetPort }} + {{- if (and (eq .Values.app.service.type "NodePort") (not (empty .Values.app.service.nodePort))) }} + nodePort: {{ .Values.app.service.nodePort }} + {{- end }} + selector: + {{- include "glauth.selectorLabels" . | nindent 4 }} + type: {{ .Values.app.service.type }} + {{- with .Values.app.service.healthCheckNodePort }} + healthCheckNodePort: {{ . }} + {{- end }} + {{- with .Values.app.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ . }} + {{- end }} diff --git a/charts/glauth/templates/role.yaml b/charts/glauth/templates/role.yaml new file mode 100644 index 0000000..30f34a2 --- /dev/null +++ b/charts/glauth/templates/role.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "glauth.fullname" . }}-role + namespace: {{ .Release.Namespace }} + labels: + {{- include "glauth.labels" . | nindent 4 }} + {{- with .Values.rbac.extraLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: [] +{{- end }} diff --git a/charts/glauth/templates/rolebinding.yaml b/charts/glauth/templates/rolebinding.yaml new file mode 100644 index 0000000..d017d9a --- /dev/null +++ b/charts/glauth/templates/rolebinding.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "glauth.fullname" . }}-rolebinding + namespace: {{ .Release.Namespace }} + labels: + {{- include "glauth.labels" . | nindent 4 }} + {{- with .Values.rbac.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "glauth.fullname" . }}-role +subjects: + - kind: ServiceAccount + name: {{ template "glauth.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/charts/glauth/templates/serviceaccount.yaml b/charts/glauth/templates/serviceaccount.yaml new file mode 100644 index 0000000..a8d4277 --- /dev/null +++ b/charts/glauth/templates/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "glauth.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "glauth.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- end }} diff --git a/charts/glauth/values.yaml b/charts/glauth/values.yaml new file mode 100644 index 0000000..98a4873 --- /dev/null +++ b/charts/glauth/values.yaml @@ -0,0 +1,257 @@ +# Default values for generic-application. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +# +nameOverride: "" +fullnameOverride: "" +# +rbac: + create: true + annotations: {} + extraLabels: {} +serviceAccount: + # -- Create service account. + create: true + # name: + extraLabels: {} + 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 +app: + enabled: true + # -- Server container name + name: glauth + image: + # -- Image repository + repository: glauth/glauth-plugins + # -- Image tag + #tag: "" + # -- Image pull policy + pullPolicy: IfNotPresent + # -- Override command for the container + command: "" + # -- Argument list for the command + args: [] + # -- Deployment additional labels + extraLabels: {} + #-- Deployment annotations + annotations: {} + # -- Name of Priority Class + priorityClassName: "" + # Use an alternate scheduler, e.g. "stork". + # ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + schedulerName: "" + # -- Only Pod's additional labels + podLabels: {} + # -- Only Pod's annotations + podAnnotations: {} + # -- Pod's management policy + podManagementPolicy: OrderedReady + # Deployment strategy ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + type: RollingUpdate + #type: Recreate + # -- Depoyment's (continer level) security context + securityContext: [] + # runAsUser: 0 + # runAsGroup: 0 + # runAsNonRoot: false + # readOnlyRootFilesystem: false + # allowPrivilegeEscalation: false + # capabilities: + # drop: ["ALL"] + # -- Pod's security context. + # ref: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + podSecurityContext: [] + # fsGroup: 0 + # Number of old ReplicaSets to retain + # + replicaCount: 1 + # + containerWorkingDir: "" + # -- Deployment init containers + initContainers: [] + # Inject Kubernetes services as environment variables. + # See https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#environment-variables + enableServiceLinks: true + # -- Image pull secrets. + # ref. https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # -- Node tolerations for server scheduling to nodes with taints. + # ref: [https://kubernetes.io/docs/concepts/configuration/assign-pod-node/](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) + tolerations: [] + # -- Pod's node selector. + # ref: [https://kubernetes.io/docs/user-guide/node-selection/](https://kubernetes.io/docs/user-guide/node-selection/) + nodeSelector: {} + # -- Pod affinity + affinity: {} + # -- Topology Spread Constraints ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + topologySpreadConstraints: [] + # -- Env variables + # -- Additional environment variables (ex.: secret tokens, flags) + env: {} + envValueFrom: {} + # -- GLAuth config + config: | + [backend] + datastore = "config" + nameformat = "cn" + groupformat = "ou" + baseDN = "dc=demo,dc=io" + + [behaviors] + IgnoreCapabilities = false + LimitFailedBinds = false + + [ldap] + enabled = true + listen = "0.0.0.0:3893" + [ldaps] + enabled = false + listen = "0.0.0.0:3894" + cert = "/app/config/ssl/glauth-ca-cert.pem" + key = "/app/config/ssl/glauth-ca-key.pem" + [api] + enabled = false + internals = true + listen = "0.0.0.0:5555" + + [[groups]] + name = "users" + gidnumber = 5501 + + [[users]] + name = "testuser1" + uidnumber = 5001 + primarygroup = 5501 + passsha256 = "00a082620a12245988ee6ef6d61a561c009e0bbd033b40604b96c199f28c42b6" + [[users.capabilities]] + action = "search" + object = "ou=users,dc=demo,dc=io" + + # -- Persistent volume + persistentVolume: + # -- Create/use Persistent Volume Claim for server component. Empty dir if false + enabled: false + type: "pvc" + # -- Mount path + mountPath: "/app/data" + # -- Array of access modes. Must match those of existing PV or dynamic provisioner. + # ref: [http://kubernetes.io/docs/user-guide/persistent-volumes/](http://kubernetes.io/docs/user-guide/persistent-volumes/) + accessModes: + - ReadWriteOnce + # -- Persistant volume annotations + annotations: {} + # -- Persistant volume extraLabels + extraLabels: {} + # -- persistentVolumeReclaimPolicy. The reclaim policy for a PersistentVolume tells the cluster what to do with the volume after it has been released of its claim. + reclaimPolicy: "" + # -- StorageClass to use for persistent volume. Requires server.persistentVolume.enabled: true. If defined, PVC created automatically + storageClass: local-path + # -- Existing Claim name. If defined, PVC must be created manually before volume will be bound + # -- This helm chart is generic, so if the existing claim is set, the default PVC with the name release-name-generic-application won't be created. + # -- Don't forget to add value as clameName in the volumes section + existingClaim: "" + # -- Bind Persistent Volume by labels. Must match all labels of targeted PV. + matchLabels: {} + # -- Mount path. Server data Persistent Volume mount root path. + size: 10Gi + # -- Resource object. + # ref: [http://kubernetes.io/docs/user-guide/compute-resources/](http://kubernetes.io/docs/user-guide/compute-resources/ + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 100m + memory: 128Mi + # Indicates whether the Container is ready to service requests. If the readiness probe fails, the endpoints controller removes the Pod's IP address from the endpoints of all Services that match the Pod. The default state of readiness before the initial delay is Failure. If a Container does not provide a readiness probe, the default state is Success. + readinessProbe: + tcpSocket: + port: glauth + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + failureThreshold: 3 + # Indicates whether the Container is running. If the liveness probe fails, the kubelet kills the Container, and the Container is subjected to its restart policy. If a Container does not provide a liveness probe, the default state is Success. + livenessProbe: + tcpSocket: + port: glauth + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 5 + failureThreshold: 10 + # Indicates whether the Container is done with potentially costly initialization. If set it is executed first. If it fails Container is restarted. If it succeeds liveness and readiness probes takes over. + startupProbe: {} + #startupProbe: + # tcpSocket: + # port: http + # failureThreshold: 30 + # periodSeconds: 15 + # successThreshold: 1 + # timeoutSeconds: 5 + # + # Istio + istio: + enabled: false + gateway: + ingressGatewayName: ingressgateway-internal-nlb + port: 3893 + portName: tcp-istio + protocol: TCP + extraLabels: {} + virtualService: + extraLabels: {} + hosts: + - "*" + service: + # -- Service annotations + annotations: {} + # -- Service labels + extraLabels: {} + # -- Service ClusterIP + clusterIP: "" + # -- Service External IPs. ref: [https://kubernetes.io/docs/user-guide/services/#external-ips]( https://kubernetes.io/docs/user-guide/services/#external-ips) + externalIPs: [] + # -- Service load balacner IP + loadBalancerIP: "" + # -- Load balancer source range + loadBalancerSourceRanges: [] + # -- Service port + port: 3893 + # -- Container port name + portName: glauth + # -- Container port + targetPort: 3893 + # -- Node port + # nodePort: 30000 + # -- Service type + type: ClusterIP + # Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + # externalTrafficPolicy: "local" + # healthCheckNodePort: 0 + + # Container Lifecycle Hooks. Execute a specific bash command or make an HTTP request + lifecycleHooks: {} + # postStart: + # exec: + # command: [] + # -- Pod's termination grace period in seconds + terminationGracePeriodSeconds: 30 + # Overrides pod.spec.hostAliases in the generic-application deployment's pods + hostAliases: [] + # - ip: "1.2.3.4" + # hostnames: + # - "my.host.com" + + # Enable direct access to the network interfaces of the host machine where the pod was started + hostNetwork: false + # dnsPolicy and dnsConfig for Deployments if you want non-default settings. + # These will be passed directly to the PodSpec of same. + dnsPolicy: "" + dnsConfig: "" diff --git a/charts/platforma/.helmignore b/charts/platforma/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/platforma/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/platforma/Chart.yaml b/charts/platforma/Chart.yaml new file mode 100644 index 0000000..5205165 --- /dev/null +++ b/charts/platforma/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: platforma +description: MiLaboratories Platforma Helm Chart +type: application +appVersion: 1.14.8 +version: 1.0.1 +sources: + - https://github.com/milaboratory/public-helm-charts/charts/platforma +maintainers: + - name: Vladimir Antropov + email: vladimir.antropov@milaboratories.com diff --git a/charts/platforma/README.md b/charts/platforma/README.md new file mode 100644 index 0000000..b348e3e --- /dev/null +++ b/charts/platforma/README.md @@ -0,0 +1,129 @@ +Platfroma Backend +============== + +For me information please visit the official documentation page [Platforma Backend](https://docs.platforma.bio/deployment/getting-started). + +## Prerequisites + +- Kubernetes 1.20+ +- Helm 3.0+ + +## Installing + +### Setting Up Secrets for `PL_LICENSE` and `MI_LICENSE` + +#### Create the Secret Resource: +You need to create Kubernetes secrets that hold the license keys for `PL_LICENSE` and `MI_LICENSE`. You can do this using kubectl or include them in your Helm chart configurations. + +Using kubectl: + +```bash +kubectl create secret generic pl-license-secret --from-literal=pl-license-key='your_pl_license_key_here' +kubectl create secret generic mi-license-secret --from-literal=mi-license-key='your_mi_license_key_here' +``` + +Reference the Secrets in the Application: +Modify your application's deployment configuration to use these secrets. This is usually done in the envValueFrom section of the values.yaml file or directly in your application's configuration. + +```toml +app: + envValueFrom: + PL_LICENSE: + secretKeyRef: + name: pl-license-secret + key: pl-license-key + MI_LICENSE: + secretKeyRef: + name: mi-license-secret + key: mi-license-key +``` +You can also use the [External Secrets Operator](https://external-secrets.io), which is compatible with various secret management systems. For AWS environments, refer to the relevant configuration block in `values.yaml`: + +```toml +externalSecret: + enabled: false + awsRegion: eu-central-1 + # -- ExternalSecret annotations + annotations: {} + # -- ExternalSecret extra labels + extraLabels: {} + # -- SecretsStore target + secretRefreshInterval: 24h + secretStoreTarget: general-application-secrets + secretDataFrom: {} +``` +For this setup to function correctly on AWS, don’t forget to assign a role ARN with sufficient privileges to the service account managing the secrets. + +### Configuring Access to an AWS S3 Bucket + +When integrating an AWS S3 bucket with your application, you have two primary methods for managing access credentials: +œ +IAM Role: +Role-Based Access: Attach an IAM role to your service account or Kubernetes node. This role should have policies granting the necessary permissions to interact with the specified S3 bucket. This method is preferred in AWS as it does not require hard-coding credentials and offers more dynamic access control. +Example of assigning an IAM role to a service account: + +```toml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: my-service-account + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/my-s3-access-role" +``` + +Static Secrets: + +Secrets Management: You can store AWS access and secret keys in Kubernetes secrets and reference them in your deployment configuration. This approach is less secure and generally recommended only when IAM roles cannot be used. +Example of creating a secret for S3 access: + +```bash +kubectl create secret generic s3-credentials --from-literal=access-key-id='AKLLA.....FRRG' --from-literal=secret-access-key='wJalrX....hdkjfghk' +``` + +Referencing the secret in your deployment: + +```toml +env: + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: s3-credentials + key: access-key-id + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: s3-credentials + key: secret-access-key +``` + +### Configuring authentication +For the Platforma application, you have the option to use either htpasswd or LDAP for authentication. Below are the details on how to configure each method using the values.yaml file. + +#### Using htpasswd for Authentication + +If you choose to use htpasswd for authentication, you need to specify a list of users directly in the values.yaml file under the htpasswdConfig parameter. This method involves creating a hashed password for each user, which is then stored and referenced within the application. + +Configure htpasswd in values.yaml: +Add user credentials in the htpasswdConfig parameter. Each user's password must be hashed, typically using bcrypt, MD5, or SHA. + +```tomal +htpasswdConfig: | + testuser:$apr1$0eub5f9s$QfkUyJqNcTj3TcbO3dcEI1 +``` + +To generate a hashed password, you can use tools like htpasswd available in Apache HTTP Server or online bcrypt generators. + +#### Using LDAP for Authentication +LDAP is a popular choice for centralized authentication, allowing users to log in with their credentials managed by an organization's directory services. + +Configure LDAP in `values.yaml`: +Set the LDAP configuration parameters such as the server URL, bind DN, password, search base e.t.c + +```tomal +config: | + core: + auth: + - driver: ldap + serverUrl: "ldap://ldap.chart-exmaple.local:3894" + defaultDN: "cn=%u,ou=users,ou=users,dc=chart-example,dc=local" +``` diff --git a/charts/platforma/templates/_helpers.tpl b/charts/platforma/templates/_helpers.tpl new file mode 100644 index 0000000..caa06ae --- /dev/null +++ b/charts/platforma/templates/_helpers.tpl @@ -0,0 +1,123 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "platforma.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 "platforma.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 "platforma.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "platforma.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} + {{- default (include "platforma.fullname" .) .Values.serviceAccount.name }} +{{- else }} + {{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Get the correct image tag name +*/}} +{{- define "platforma.imageTag" -}} +{{- .Values.app.image.tag | default (printf "%s" .Chart.AppVersion) -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "platforma.labels" -}} +helm.sh/chart: {{ include "platforma.chart" . }} +{{ include "platforma.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "platforma.selectorLabels" -}} +app.kubernetes.io/name: {{ include "platforma.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Return the appropriate apiVersion for podDisruptionBudget. +*/}} +{{- define "platforma.podDisruptionBudget.apiVersion" -}} + {{- if $.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} + {{- print "policy/v1" }} + {{- else }} + {{- print "policy/v1beta1" }} + {{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "platforma.ingress.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") -}} + {{- print "networking.k8s.io/v1" -}} + {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "extensions/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return if ingress is stable. +*/}} +{{- define "platforma.ingress.isStable" -}} + {{- eq (include "platforma.ingress.apiVersion" .) "networking.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "platforma.ingress.supportsIngressClassName" -}} + {{- or (eq (include "platforma.ingress.isStable" .) "true") (and (eq (include "platforma.ingress.apiVersion" .) "networking.k8s.io/v1beta1")) -}} +{{- end -}} + +{{/* +Return if ingress supports pathType. +*/}} +{{- define "platforma.ingress.supportsPathType" -}} + {{- or (eq (include "platforma.ingress.isStable" .) "true") (and (eq (include "platforma.ingress.apiVersion" .) "networking.k8s.io/v1beta1")) -}} +{{- end -}} + +{{/* +Calculate the config from structured and unstructred text input +*/}} +{{- define "platforma.calculatedConfig" -}} +{{ tpl (mergeOverwrite (tpl .Values.app.config . | fromYaml) .Values.app.structuredConfig | toYaml) . }} +{{- end }} + diff --git a/charts/platforma/templates/app-configuration.yaml b/charts/platforma/templates/app-configuration.yaml new file mode 100644 index 0000000..86f9760 --- /dev/null +++ b/charts/platforma/templates/app-configuration.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "platforma.fullname" . }}-config + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} +data: + platforma.yaml: | + {{ include "platforma.calculatedConfig" . | nindent 4 }} diff --git a/charts/platforma/templates/app-deployment.yaml b/charts/platforma/templates/app-deployment.yaml new file mode 100644 index 0000000..6ee5181 --- /dev/null +++ b/charts/platforma/templates/app-deployment.yaml @@ -0,0 +1,200 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with .Values.app.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "platforma.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + {{- include "platforma.selectorLabels" . | nindent 6 }} + {{- if not .Values.app.horizontalPodAutoscaler.enabled }} + replicas: {{ .Values.app.replicaCount }} + {{- end }} + {{- with .Values.app.strategy }} + strategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + checksum/config: {{ include (print .Template.BasePath "/app-htpasswd.yaml") . | sha256sum }} + {{- with .Values.app.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "platforma.labels" . | nindent 8 }} + {{- with .Values.app.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.app.priorityClassName }} + priorityClassName: {{ .Values.app.priorityClassName | toString }} + {{- end }} + {{- if .Values.app.schedulerName }} + schedulerName: {{ .Values.app.schedulerName }} + {{- end }} + {{- if .Values.app.enableServiceLinks }} + enableServiceLinks: {{ .Values.app.enableServiceLinks }} + {{- end }} + automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} + {{- with .Values.app.initContainers }} + initContainers: + {{- toYaml . | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.app.terminationGracePeriodSeconds }} + containers: + - name: {{ template "platforma.name" . }}-{{ .Values.app.name }} + image: "{{ .Values.app.image.repository }}:{{ include "platforma.imageTag" . }}" + imagePullPolicy: {{ .Values.app.image.pullPolicy }} + {{- if .Values.app.containerWorkingDir }} + workingDir: {{ .Values.app.containerWorkingDir }} + {{- end }} + securityContext: + {{- toYaml .Values.app.securityContext | nindent 12 }} + {{- if .Values.app.image.command }} + command: [{{ .Values.app.image.command | quote }}] + {{- end }} + {{- if .Values.app.image.args }} + args: + {{- range .Values.app.image.args }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- if .Values.app.env }} + env: + {{- range $key, $value := .Values.app.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.app.envValueFrom }} + {{- range $key, $value := .Values.app.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 16 }} + {{- end }} + {{- end }} + ports: + - name: {{ .Values.app.service.portName }} + containerPort: {{ .Values.app.service.targetPort }} + - name: {{ .Values.app.debug.service.portName }} + containerPort: {{ .Values.app.debug.service.targetPort }} + {{- if .Values.app.metrics.enabled }} + - name: {{ .Values.app.metrics.portName }} + containerPort: {{ .Values.app.metrics.targetPort }} + {{- end }} + {{- with .Values.app.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.app.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.app.startupProbe }} + startupProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/platforma/platforma.yaml + subPath: platforma.yaml + readOnly: true + {{- if eq .Values.app.coreConfig.auth.type "htpasswd" }} + - name: htpasswd + mountPath: /etc/platforma/users.htpasswd + subPath: users.htpasswd + readOnly: true + {{- end }} + - name: database-volume + mountPath: {{ .Values.app.persistentVolume.database.mountPath }} + - name: work-volume + mountPath: {{ .Values.app.persistentVolume.work.mountPath }} + - name: software-loader + mountPath: {{ .Values.app.persistentVolume.softwareloader.mountPath }} + {{- with .Values.app.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.app.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.app.podSecurityContext }} + securityContext: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.hostAliases }} + hostAliases: +{{ toYaml . | indent 8 }} + {{- end }} + serviceAccountName: {{ template "platforma.serviceAccountName" . }} + {{- with .Values.app.imagePullSecrets }} + imagePullSecrets: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.app.topologySpreadConstraints }} + topologySpreadConstraints: +{{ toYaml . | indent 8 }} + {{- end }} + hostNetwork: {{ .Values.app.hostNetwork }} + {{- if .Values.app.dnsPolicy }} + dnsPolicy: {{ .Values.app.dnsPolicy | toString }} + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: +{{- toYaml . | indent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "platforma.fullname" . }}-config + {{- if eq .Values.app.coreConfig.auth.type "htpasswd" }} + - name: htpasswd + secret: + secretName: {{ template "platforma.fullname" . }}-htpasswd-config + {{- end }} + - name: work-volume + {{- if .Values.app.persistentVolume.work.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.app.persistentVolume.work.existingClaim }}{{ .Values.app.persistentVolume.work.existingClaim }}{{- else }}{{ template "platforma.fullname" . }}-work{{- end }} + {{- else }} + emptyDir: {} + {{- end }} + - name: database-volume + {{- if .Values.app.persistentVolume.database.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.app.persistentVolume.database.existingClaim }}{{ .Values.app.persistentVolume.database.existingClaim }}{{- else }}{{ template "platforma.fullname" . }}-database{{- end }} + {{- else }} + emptyDir: {} + {{- end }} + - name: software-loader + {{- if .Values.app.persistentVolume.softwareloader.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.app.persistentVolume.softwareloader.existingClaim }}{{ .Values.app.persistentVolume.softwareloader.existingClaim }}{{- else }}{{ template "platforma.fullname" . }}-softwareloader{{- end }} + {{- else }} + emptyDir: {} + {{- end -}} + {{- with .Values.app.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/platforma/templates/app-externalsecret.yaml b/charts/platforma/templates/app-externalsecret.yaml new file mode 100644 index 0000000..c755b2f --- /dev/null +++ b/charts/platforma/templates/app-externalsecret.yaml @@ -0,0 +1,30 @@ +{{- if .Values.app.externalSecret.enabled }} +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + {{- with .Values.app.externalSecret.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.externalSecret.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "platforma.fullname" . }}-externalsecret + namespace: {{ .Release.Namespace }} +spec: + refreshInterval: {{ .Values.app.externalSecret.secretRefreshInterval }} + secretStoreRef: + name: {{ template "platforma.fullname" . }}-secretstore + kind: SecretStore + target: + name: {{ .Values.app.externalSecret.secretStoreTarget }} + creationPolicy: Owner + data: + {{- range $key, $value := .Values.app.externalSecret.secretDataFrom }} + - secretKey: {{ $key }} + remoteRef: + {{- tpl (toYaml $value) $ | nindent 8 }} + {{- end }} +{{- end }} diff --git a/charts/platforma/templates/app-hpa.yaml b/charts/platforma/templates/app-hpa.yaml new file mode 100644 index 0000000..1b40afd --- /dev/null +++ b/charts/platforma/templates/app-hpa.yaml @@ -0,0 +1,21 @@ +{{- if .Values.app.horizontalPodAutoscaler.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ template "platforma.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "platforma.fullname" . }} + minReplicas: {{ .Values.app.horizontalPodAutoscaler.minReplicas }} + maxReplicas: {{ .Values.app.horizontalPodAutoscaler.maxReplicas }} + metrics: +{{ toYaml .Values.app.horizontalPodAutoscaler.metrics | indent 4 }} +{{- end }} diff --git a/charts/platforma/templates/app-htpasswd.yaml b/charts/platforma/templates/app-htpasswd.yaml new file mode 100644 index 0000000..4bff8f3 --- /dev/null +++ b/charts/platforma/templates/app-htpasswd.yaml @@ -0,0 +1,12 @@ +{{- if eq .Values.app.coreConfig.auth.type "htpasswd" }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "platforma.fullname" . }}-htpasswd-config + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} +type: Opaque +data: + users.htpasswd: {{ .Values.app.htpasswdConfig | b64enc | quote }} +{{- end }} diff --git a/charts/platforma/templates/app-ingress-debug.yaml b/charts/platforma/templates/app-ingress-debug.yaml new file mode 100644 index 0000000..24653f6 --- /dev/null +++ b/charts/platforma/templates/app-ingress-debug.yaml @@ -0,0 +1,55 @@ +{{- if .Values.app.debug.ingress.enabled }} +{{- $ingressApiIsStable := eq (include "platforma.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "platforma.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "platforma.ingress.supportsPathType" .) "true" -}} +{{- $servicePort := .Values.app.debug.service.port -}} +{{- $ingressPath := .Values.app.debug.ingress.path -}} +{{- $ingressPathType := .Values.app.debug.ingress.pathType -}} +{{- $extraPaths := .Values.app.ingress.extraPaths -}} +{{- $serviceName := include "platforma.fullname" . -}} +apiVersion: {{ include "platforma.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ template "platforma.fullname" . }}-debug + namespace: {{ .Release.Namespace }} + {{- with .Values.app.debug.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.app.debug.ingress.ingressClassName }} + ingressClassName: {{ .Values.app.debug.ingress.ingressClassName }} + {{- end -}} + {{- with .Values.app.debug.ingress.tls }} + tls: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + rules: + {{- range .Values.app.debug.ingress.hosts }} + - host: {{ tpl . $ }} + http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $serviceName }}-debug + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $serviceName }}-debug + servicePort: {{ $servicePort }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/platforma/templates/app-ingress.yaml b/charts/platforma/templates/app-ingress.yaml new file mode 100644 index 0000000..7c3ae6d --- /dev/null +++ b/charts/platforma/templates/app-ingress.yaml @@ -0,0 +1,77 @@ +{{- if .Values.app.ingress.enabled }} +{{- $ingressApiIsStable := eq (include "platforma.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "platforma.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "platforma.ingress.supportsPathType" .) "true" -}} +{{- $servicePort := .Values.app.service.port -}} +{{- $ingressPath := .Values.app.ingress.path -}} +{{- $ingressPathType := .Values.app.ingress.pathType -}} +{{- $extraPaths := .Values.app.ingress.extraPaths -}} +{{- $istioIngressGateway := .Values.app.istio.ingressGateway.backends }} +{{- $serviceName := include "platforma.fullname" . -}} +apiVersion: {{ include "platforma.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ template "platforma.fullname" . }} + {{- if .Values.app.istio.enabled }} + namespace: istio-system + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + {{- with .Values.app.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.app.ingress.ingressClassName }} + ingressClassName: {{ .Values.app.ingress.ingressClassName }} + {{- end -}} + {{- with .Values.app.ingress.tls }} + tls: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + rules: + {{- if .Values.app.istio.enabled }} + {{- range .Values.app.istio.hosts }} + - host: {{ tpl . $ }} + http: + paths: + {{- range $k, $v := $istioIngressGateway }} + - backend: + service: + name: {{ $v.name }} + port: + number: {{ $v.portNumber }} + path: {{ $v.path }} + pathType: {{ $v.pathType }} + {{- end }} + {{- end }} + {{- else }} + {{- range .Values.app.ingress.hosts }} + - host: {{ tpl . $ }} + http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/platforma/templates/app-isito-gateway.yaml b/charts/platforma/templates/app-isito-gateway.yaml new file mode 100644 index 0000000..3453a41 --- /dev/null +++ b/charts/platforma/templates/app-isito-gateway.yaml @@ -0,0 +1,25 @@ +{{- if .Values.app.istio.enabled }} +{{- $istioHosts := .Values.app.istio.hosts }} +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: {{ template "platforma.fullname" . }}-gateway + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.istio.gateway.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + istio: {{ .Values.app.istio.gateway.ingressGatewayName }} + servers: + - port: + number: {{ .Values.app.istio.gateway.port }} + name: {{ .Values.app.istio.gateway.portName }} + protocol: {{ .Values.app.istio.gateway.protocol }} + hosts: + {{- range $istioHosts }} + - {{ tpl . $ | quote }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/charts/platforma/templates/app-isito-virtualservice.yaml b/charts/platforma/templates/app-isito-virtualservice.yaml new file mode 100644 index 0000000..962a4c6 --- /dev/null +++ b/charts/platforma/templates/app-isito-virtualservice.yaml @@ -0,0 +1,29 @@ +{{- if .Values.app.istio.enabled }} +{{- $istioHosts := .Values.app.istio.hosts }} +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: {{ template "platforma.fullname" . }}-virtual-service + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.istio.virtualService.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + hosts: + {{- range $istioHosts }} + - {{ tpl . $ | quote }} + {{- end }} + gateways: + - {{ template "platforma.fullname" . }}-gateway + http: + - route: + - destination: + host: {{ template "platforma.fullname" . }} + port: + number: {{ .Values.app.service.port }} + match: + - uri: + prefix: {{ .Values.app.istio.virtualService.pathPrefix }} +{{- end }} \ No newline at end of file diff --git a/charts/platforma/templates/app-pdb.yaml b/charts/platforma/templates/app-pdb.yaml new file mode 100644 index 0000000..9c2516e --- /dev/null +++ b/charts/platforma/templates/app-pdb.yaml @@ -0,0 +1,22 @@ +{{- if .Values.app.podDisruptionBudget.enabled }} +apiVersion: {{ include "platforma.podDisruptionBudget.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ template "platforma.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.podDisruptionBudget.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- with .Values.app.podDisruptionBudget.minAvailable }} + minAvailable: {{ . }} +{{- end }} +{{- with .Values.app.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ . }} +{{- end }} + selector: + matchLabels: + {{- include "platforma.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/charts/platforma/templates/app-pvc.yaml b/charts/platforma/templates/app-pvc.yaml new file mode 100644 index 0000000..1bdfff3 --- /dev/null +++ b/charts/platforma/templates/app-pvc.yaml @@ -0,0 +1,107 @@ +{{- if and .Values.app.persistentVolume.database.enabled (not .Values.app.persistentVolume.database.existingClaim) .Values.app.enabled }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "platforma.fullname" . }}-database + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.persistentVolume.database.extraLabels }} + {{- toYaml . | nindent 4 }} + {{ end }} + {{- with .Values.app.persistentVolume.database.annotations }} + annotations: + {{- toYaml . | indent 4 }} + {{- end }} +spec: + {{- with .Values.app.persistentVolume.database.accessModes }} + accessModes: +{{ toYaml . | indent 4 }} + {{- end }} + resources: + requests: + storage: {{ .Values.app.persistentVolume.database.size | quote }} + {{- if .Values.app.persistentVolume.database.reclaimPolicy }} + persistentVolume.databaseReclaimPolicy: {{ .Values.app.persistentVolume.database.reclaimPolicy }} + {{- end }} + {{- if .Values.app.persistentVolume.database.storageClass }} + storageClassName: {{ .Values.app.persistentVolume.database.storageClass | quote }} + {{- end }} + {{- with .Values.app.persistentVolume.database.matchLabels }} + selector: + matchLabels: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} +--- +{{- if and .Values.app.persistentVolume.work.enabled (not .Values.app.persistentVolume.work.existingClaim) .Values.app.enabled }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "platforma.fullname" . }}-work + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.persistentVolume.work.extraLabels }} + {{- toYaml . | nindent 4 }} + {{ end }} + {{- with .Values.app.persistentVolume.work.annotations }} + annotations: + {{- toYaml . | indent 4 }} + {{- end }} +spec: + {{- with .Values.app.persistentVolume.work.accessModes }} + accessModes: +{{ toYaml . | indent 4 }} + {{- end }} + resources: + requests: + storage: {{ .Values.app.persistentVolume.work.size | quote }} + {{- if .Values.app.persistentVolume.work.reclaimPolicy }} + persistentVolume.workReclaimPolicy: {{ .Values.app.persistentVolume.work.reclaimPolicy }} + {{- end }} + {{- if .Values.app.persistentVolume.work.storageClass }} + storageClassName: {{ .Values.app.persistentVolume.work.storageClass | quote }} + {{- end }} + {{- with .Values.app.persistentVolume.work.matchLabels }} + selector: + matchLabels: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} +--- +{{- if and .Values.app.persistentVolume.softwareloader.enabled (not .Values.app.persistentVolume.softwareloader.existingClaim) .Values.app.enabled }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "platforma.fullname" . }}-softwareloader + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.persistentVolume.softwareloader.extraLabels }} + {{- toYaml . | nindent 4 }} + {{ end }} + {{- with .Values.app.persistentVolume.softwareloader.annotations }} + annotations: + {{- toYaml . | indent 4 }} + {{- end }} +spec: + {{- with .Values.app.persistentVolume.softwareloader.accessModes }} + accessModes: +{{ toYaml . | indent 4 }} + {{- end }} + resources: + requests: + storage: {{ .Values.app.persistentVolume.softwareloader.size | quote }} + {{- if .Values.app.persistentVolume.softwareloader.reclaimPolicy }} + persistentVolume.softwareloaderReclaimPolicy: {{ .Values.app.persistentVolume.softwareloader.reclaimPolicy }} + {{- end }} + {{- if .Values.app.persistentVolume.softwareloader.storageClass }} + storageClassName: {{ .Values.app.persistentVolume.softwareloader.storageClass | quote }} + {{- end }} + {{- with .Values.app.persistentVolume.softwareloader.matchLabels }} + selector: + matchLabels: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/charts/platforma/templates/app-secretstore.yaml b/charts/platforma/templates/app-secretstore.yaml new file mode 100644 index 0000000..50fd23e --- /dev/null +++ b/charts/platforma/templates/app-secretstore.yaml @@ -0,0 +1,28 @@ +{{- if .Values.app.externalSecret.enabled }} +apiVersion: external-secrets.io/v1beta1 +kind: SecretStore +metadata: + {{- with .Values.app.externalSecret.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.externalSecret.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "platforma.fullname" . }}-secretstore + namespace: {{ .Release.Namespace }} +spec: + retrySettings: + maxRetries: 5 + retryInterval: "10s" + provider: + aws: + service: SecretsManager + region: {{ .Values.app.externalSecret.awsRegion }} + auth: + jwt: + serviceAccountRef: + name: {{ template "platforma.serviceAccountName" . }} +{{- end }} diff --git a/charts/platforma/templates/app-service-debug.yaml b/charts/platforma/templates/app-service-debug.yaml new file mode 100644 index 0000000..4666655 --- /dev/null +++ b/charts/platforma/templates/app-service-debug.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "platforma.fullname" . }}-debug + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.debug.service.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.app.debug.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: +{{- if .Values.app.debug.service.clusterIP }} + clusterIP: {{ .Values.app.debug.service.clusterIP }} +{{- end }} +{{- if .Values.app.debug.service.externalIPs }} + externalIPs: +{{ toYaml .Values.app.debug.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.app.debug.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.app.debug.service.loadBalancerIP }} +{{- end }} +{{- if .Values.app.debug.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.app.debug.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: {{ .Values.app.debug.service.portName }} + port: {{ .Values.app.debug.service.port }} + protocol: TCP + targetPort: {{ .Values.app.debug.service.targetPort }} + {{- if (and (eq .Values.app.debug.service.type "NodePort") (not (empty .Values.app.debug.service.nodePort))) }} + nodePort: {{ .Values.app.debug.service.nodePort }} + {{- end }} + selector: + {{- include "platforma.selectorLabels" . | nindent 4 }} + type: {{ .Values.app.debug.service.type }} + {{- with .Values.app.debug.service.healthCheckNodePort }} + healthCheckNodePort: {{ . }} + {{- end }} + {{- with .Values.app.debug.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ . }} + {{- end }} diff --git a/charts/platforma/templates/app-service.yaml b/charts/platforma/templates/app-service.yaml new file mode 100644 index 0000000..104bf02 --- /dev/null +++ b/charts/platforma/templates/app-service.yaml @@ -0,0 +1,48 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "platforma.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.app.service.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.app.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: +{{- if .Values.app.service.clusterIP }} + clusterIP: {{ .Values.app.service.clusterIP }} +{{- end }} +{{- if .Values.app.service.externalIPs }} + externalIPs: +{{ toYaml .Values.app.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.app.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.app.service.loadBalancerIP }} +{{- end }} +{{- if .Values.app.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.app.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: {{ .Values.app.service.portName }} + port: {{ .Values.app.service.port }} + protocol: TCP + targetPort: {{ .Values.app.service.targetPort }} + {{- if (and (eq .Values.app.service.type "NodePort") (not (empty .Values.app.service.nodePort))) }} + nodePort: {{ .Values.app.service.nodePort }} + {{- end }} + selector: + {{- include "platforma.selectorLabels" . | nindent 4 }} + type: {{ .Values.app.service.type }} + {{- with .Values.app.service.healthCheckNodePort }} + healthCheckNodePort: {{ . }} + {{- end }} + {{- with .Values.app.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ . }} + {{- end }} diff --git a/charts/platforma/templates/role.yaml b/charts/platforma/templates/role.yaml new file mode 100644 index 0000000..89a2c71 --- /dev/null +++ b/charts/platforma/templates/role.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "platforma.fullname" . }}-role + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.rbac.extraLabels }} + {{- toYaml . | nindent 4}} + {{- end }} + {{- with .Values.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: [] +{{- end }} diff --git a/charts/platforma/templates/rolebinding.yaml b/charts/platforma/templates/rolebinding.yaml new file mode 100644 index 0000000..e509d27 --- /dev/null +++ b/charts/platforma/templates/rolebinding.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "platforma.fullname" . }}-rolebinding + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.rbac.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.rbac.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "platforma.fullname" . }}-role +subjects: + - kind: ServiceAccount + name: {{ template "platforma.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/charts/platforma/templates/serviceaccount.yaml b/charts/platforma/templates/serviceaccount.yaml new file mode 100644 index 0000000..7a2edb9 --- /dev/null +++ b/charts/platforma/templates/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "platforma.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "platforma.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.extraLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +{{- end }} diff --git a/charts/platforma/values.yaml b/charts/platforma/values.yaml new file mode 100644 index 0000000..e68f06d --- /dev/null +++ b/charts/platforma/values.yaml @@ -0,0 +1,528 @@ +# Default values for generic-application. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +# +nameOverride: "" +fullnameOverride: "" +# +rbac: + create: true + annotations: {} + extraLabels: {} +serviceAccount: + # -- Create service account. + create: true + # name: + extraLabels: {} + 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 +app: + enabled: true + # -- Server container name + name: app + image: + # -- Image repository + repository: quay.io/milaboratories/platforma + # -- Tag to override with, will default to the application version + # tag: "" + # -- Image pull policy + pullPolicy: IfNotPresent + # -- Override command for the container + command: "" + # -- Argument list for the command + args: [] + # -- Deployment additional labels + extraLabels: {} + #-- Deployment annotations + annotations: {} + # -- Name of Priority Class + priorityClassName: "" + # Use an alternate scheduler, e.g. "stork". + # ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + schedulerName: "" + # -- Only Pod's additional labels + podLabels: {} + # -- Only Pod's annotations + podAnnotations: {} + # prometheus.io/scrape: "false" + # prometheus.io/port: "9090" + # prometheus.io/scheme: "http" + # -- Pod's management policy + podManagementPolicy: OrderedReady + # Deployment strategy ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy + strategy: + #rollingUpdate: + # maxSurge: 1 + # maxUnavailable: 0 + #type: RollingUpdate + type: Recreate + # -- Depoyment's (continer level) security context + securityContext: + runAsUser: 0 + runAsGroup: 0 + runAsNonRoot: false + readOnlyRootFilesystem: false + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + # -- Pod's security context. + # ref: [https://kubernetes.io/docs/tasks/configure-pod-container/security-context/](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + podSecurityContext: + fsGroup: 3000 + # -- Prometheus metrics settings + metrics: + # If you enable Prometheus metrics for an application, + # add proper annotations; see podAnnotations for an example. + # You need to add them manually as a compatible layer with istio metrics. + # Add another reason that we have auto scraping enabled based on Prometheus annotations. + enabled: false + targetPort: 9090 + portName: metrics-server + # Number of old ReplicaSets to retain + # + replicaCount: 1 + horizontalPodAutoscaler: + enabled: false + minReplicas: 1 + maxReplicas: 3 + metrics: [] + # + containerWorkingDir: "/app" + # -- See `kubectl explain poddisruptionbudget.spec` for more. + # ref: [https://kubernetes.io/docs/tasks/run-application/configure-pdb/](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) + podDisruptionBudget: + enabled: false + #minAvailable: 1 + #maxUnavailable: 1 + extraLabels: {} + # -- Deployment init containers + initContainers: [] + # Inject Kubernetes services as environment variables. + # See https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#environment-variables + enableServiceLinks: true + # -- Image pull secrets. + # ref. https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # -- Node tolerations for server scheduling to nodes with taints. + # ref: [https://kubernetes.io/docs/concepts/configuration/assign-pod-node/](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) + tolerations: [] + # -- Pod's node selector. + # ref: [https://kubernetes.io/docs/user-guide/node-selection/](https://kubernetes.io/docs/user-guide/node-selection/) + nodeSelector: {} + # -- Pod affinity + affinity: {} + # -- Topology Spread Constraints ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + topologySpreadConstraints: [] + # -- Env variables + # -- Additional environment variables (ex.: secret tokens, flags) + env: {} + envValueFrom: {} + # -- External secrets. (AWS Secrets Manager) + externalSecret: + enabled: false + awsRegion: eu-central-1 + # -- ExternalSecret annotations + annotations: {} + # -- ExternalSecret extraLabels + extraLabels: {} + # -- SecretsStore target + secretRefreshInterval: 24h + secretStoreTarget: general-application-secrets + secretDataFrom: {} + # -- volumeMounts + volumeMounts: [] + # example: + # - mountPath: /cache + # name: cache-volume + # -- volumes + volumes: [] + # example: persistent volume + # - name: cache-volume + # persistentVolumeClaim: + # claimName: release-name-generic-application + # example: inmemory + # - name: cache-volume + # emptyDir: + # medium: Memory + # sizeLimit: 2Gi + structuredConfig: {} + config: | + logging: + level: "info" + + debug: + listen: "0.0.0.0:9091" + grpcServer: + listen: "0.0.0.0:6345" + monitoring: + listen: "0.0.0.0:9090" + license: + value: "env:PL_LICENSE" + + core: + logging: + extendedInfo: true + apiLevel: "info" + dbLevel: "info" + + authEnabled: true + auth: + {{- if eq .Values.app.coreConfig.auth.type "htpasswd" }} + - driver: htpasswd + path: /etc/platforma/users.htpasswd + {{- else if eq .Values.app.coreConfig.auth.type "ldap" }} + - driver: ldap + serverUrl: "ldap://ldap.chart-exmaple.local:3894" + defaultDN: "cn=%u,ou=users,ou=users,dc=chart-example,dc=local" + {{- end }} + - driver: jwt + key: "be2e30ed04e9e520e5eb0718a471bb6c3c548825e7822fdc3b901691ad27fc77" + + db: + path: {{ .Values.app.persistentVolume.database.mountPath | quote }} + + controllers: + common: + timeouts: + request: 10s + init: 1m + stop: 30s + + file: + main: + storages: + primary: + mode: primary + downloadable: true + + work: + mode: active + downloadable: false + + raw: + mode: passive + downloadable: false + + test-assets: + mode: passive + + workdirManager: work + uploadManager: primary + defaultDownloadable: primary + + transfers: + - ["primary", "work"] + - ["work", "primary"] + + - ["raw", "work"] + - ["test-assets", "work"] + + storages: + - &primaryStorage + id: "primary" + type: S3 + region: "eu-central-1" + bucketName: "example-s3-bucket-name" + keyPrefix: "platforma-primary/" + + - &rawStorage + id: "raw" + type: S3 + region: "eu-central-1" + bucketName: "example-s3-bucket-name" + keyPrefix: "corp-library/" + + - &testAssetsStorage + id: "test-assets" + type: S3 + region: "eu-central-1" + bucketName: "example-s3-bucket-name" + keyPrefix: "test-assets/" + + - &workStorage + id: "work" + type: FS + indexCachePeriod: "1m" + rootPath: {{ .Values.app.persistentVolume.work.mountPath | quote }} + + transfers: + - src: *primaryStorage + dst: *workStorage + + - src: *workStorage + dst: *primaryStorage + + - src: *rawStorage + dst: *workStorage + + - src: *testAssetsStorage + dst: *workStorage + + runner: + type: local + storageRoot: {{ .Values.app.persistentVolume.work.mountPath | quote }} + + packageLoader: + packagesRoot: {{ .Values.app.persistentVolume.softwareloader.mountPath | quote }} + registries: + - name: "milaboratories" + endpoints: + - type: "local" + path: {{ .Values.app.persistentVolume.softwareloader.mountPath | quote }} + - type: "url" + url: "https://bin.registry.platforma.bio/" + + workflows: {} + + coreConfig: + auth: + enabled: true + type: ldap + htpasswdConfig: {} + # -- Persistent volume: + persistentVolume: + # -- Create/use Persistent Volume Claim for server component. Empty dir if false + # -- If you change mountPath values here, don't forget to update platforma.yaml with the new values. + database: + enabled: true + type: "pvc" + # -- Mount path + mountPath: "/db" + # -- Array of access modes. Must match those of existing PV or dynamic provisioner. + # ref: [http://kubernetes.io/docs/user-guide/persistent-volumes/](http://kubernetes.io/docs/user-guide/persistent-volumes/) + accessModes: + - ReadWriteOnce + # -- Persistant volume annotations + annotations: {} + # -- Persistant volume extraLabels + extraLabels: {} + # -- persistentVolumeReclaimPolicy. The reclaim policy for a PersistentVolume tells the cluster what to do with the volume after it has been released of its claim. + reclaimPolicy: "" + # -- StorageClass to use for persistent volume. Requires server.persistentVolume.enabled: true. If defined, PVC created automatically + storageClass: local-path + # -- Existing Claim name. If defined, PVC must be created manually before volume will be bound + existingClaim: "" + # -- Bind Persistent Volume by labels. Must match all labels of targeted PV. + matchLabels: {} + # -- Mount path. Server data Persistent Volume mount root path. + size: 20Gi + work: + enabled: true + type: "pvc" + # -- Mount path + mountPath: "/data/work" + # -- Array of access modes. Must match those of existing PV or dynamic provisioner. + # ref: [http://kubernetes.io/docs/user-guide/persistent-volumes/](http://kubernetes.io/docs/user-guide/persistent-volumes/) + accessModes: + - ReadWriteOnce + # -- Persistant volume annotations + annotations: {} + # -- Persistant volume extraLabels + extraLabels: {} + # -- persistentVolumeReclaimPolicy. The reclaim policy for a PersistentVolume tells the cluster what to do with the volume after it has been released of its claim. + reclaimPolicy: "" + # -- StorageClass to use for persistent volume. Requires server.persistentVolume.enabled: true. If defined, PVC created automatically + storageClass: local-path + # -- Existing Claim name. If defined, PVC must be created manually before volume will be bound + existingClaim: "" + # -- Bind Persistent Volume by labels. Must match all labels of targeted PV. + matchLabels: {} + # -- Mount path. Server data Persistent Volume mount root path. + size: 400Gi + softwareloader: + enabled: true + type: "pvc" + # -- Mount path + mountPath: "/storage/controllers/software-loader" + # -- Array of access modes. Must match those of existing PV or dynamic provisioner. + # ref: [http://kubernetes.io/docs/user-guide/persistent-volumes/](http://kubernetes.io/docs/user-guide/persistent-volumes/) + accessModes: + - ReadWriteOnce + # -- Persistant volume annotations + annotations: {} + # -- Persistant volume extraLabels + extraLabels: {} + # -- persistentVolumeReclaimPolicy. The reclaim policy for a PersistentVolume tells the cluster what to do with the volume after it has been released of its claim. + reclaimPolicy: "" + # -- StorageClass to use for persistent volume. Requires server.persistentVolume.enabled: true. If defined, PVC created automatically + storageClass: local-path + # -- Existing Claim name. If defined, PVC must be created manually before volume will be bound + existingClaim: "" + # -- Bind Persistent Volume by labels. Must match all labels of targeted PV. + matchLabels: {} + # -- Mount path. Server data Persistent Volume mount root path. + size: 150Gi + # -- Resource object. + # ref: [http://kubernetes.io/docs/user-guide/compute-resources/](http://kubernetes.io/docs/user-guide/compute-resources/ + resources: {} + # Indicates whether the Container is ready to service requests. If the readiness probe fails, the endpoints controller removes the Pod's IP address from the endpoints of all Services that match the Pod. The default state of readiness before the initial delay is Failure. If a Container does not provide a readiness probe, the default state is Success. + readinessProbe: + grpc: + port: 6345 + initialDelaySeconds: 15 + periodSeconds: 15 + timeoutSeconds: 5 + failureThreshold: 3 + # Indicates whether the Container is running. If the liveness probe fails, the kubelet kills the Container, and the Container is subjected to its restart policy. If a Container does not provide a liveness probe, the default state is Success. + livenessProbe: + grpc: + port: 6345 + initialDelaySeconds: 30 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 10 + # Indicates whether the Container is done with potentially costly initialization. If set it is executed first. If it fails Container is restarted. If it succeeds liveness and readiness probes takes over. + startupProbe: {} + #startupProbe: + # tcpSocket: + # port: http + # failureThreshold: 30 + # periodSeconds: 15 + # successThreshold: 1 + # timeoutSeconds: 5 + # + # Istio + istio: + enabled: false + gateway: + ingressGatewayName: ingressgateway + port: 80 + portName: http-istio + protocol: HTTP + extraLabels: {} + virtualService: + pathPrefix: / + extraLabels: {} + hosts: + - chart.local + ingressGateway: + backends: + controller: + name: istio-ingressgateway + portNumber: 80 + path: / + pathType: Prefix + + ingress: + # -- Enable deployment of ingress for server component + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + ingressClassName: traefik + # -- Ingress annotations + annotations: {} + # -- Ingress extra labels + extraLabels: {} + # -- Array of host objects + path: / + hosts: + - pl.chart-example.local + pathType: Prefix + # Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # -- Array of TLS objects + #tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + service: + # -- Service annotations + annotations: + traefik.ingress.kubernetes.io/service.serversscheme: h2c + # -- Service labels + extraLabels: {} + # -- Service ClusterIP + clusterIP: "" + # -- Service External IPs. ref: [https://kubernetes.io/docs/user-guide/services/#external-ips]( https://kubernetes.io/docs/user-guide/services/#external-ips) + externalIPs: [] + # -- Service load balacner IP + loadBalancerIP: "" + # -- Load balancer source range + loadBalancerSourceRanges: [] + # -- Service port + port: 6345 + # -- Container port name + portName: plgrpc + # -- Container port + targetPort: 6345 + # -- Node port + # nodePort: 30000 + # -- Service type + type: ClusterIP + # Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + # externalTrafficPolicy: "local" + # healthCheckNodePort: 0 + + # Container Lifecycle Hooks. Execute a specific bash command or make an HTTP request + lifecycleHooks: {} + # postStart: + # exec: + # command: [] + debug: + ingress: + # -- Enable deployment of ingress for debug component of the server + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + ingressClassName: traefik + # -- Ingress annotations + annotations: {} + # -- Ingress extra labels + extraLabels: {} + # -- Array of host objects + path: / + hosts: + - pl-debug.chart-example.local + pathType: Prefix + # Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # -- Array of TLS objects + #tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + service: + # -- Service annotations + annotations: {} + # -- Service labels + extraLabels: {} + # -- Service ClusterIP + clusterIP: "" + # -- Service External IPs. ref: [https://kubernetes.io/docs/user-guide/services/#external-ips]( https://kubernetes.io/docs/user-guide/services/#external-ips) + externalIPs: [] + # -- Service load balacner IP + loadBalancerIP: "" + # -- Load balancer source range + loadBalancerSourceRanges: [] + # -- Service port + port: 9091 + # -- Container port name + portName: pldebug + # -- Container port + targetPort: 9091 + # -- Node port + # nodePort: 30000 + # -- Service type + type: ClusterIP + # Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + # externalTrafficPolicy: "local" + # healthCheckNodePort: 0 + # -- Pod's termination grace period in seconds + terminationGracePeriodSeconds: 30 + # Overrides pod.spec.hostAliases in the generic-application deployment's pods + hostAliases: [] + # - ip: "1.2.3.4" + # hostnames: + # - "my.host.com" + + # Enable direct access to the network interfaces of the host machine where the pod was started + hostNetwork: false + # dnsPolicy and dnsConfig for Deployments if you want non-default settings. + # These will be passed directly to the PodSpec of same. + dnsPolicy: "" + dnsConfig: ""