From c8c8128dfeb025596935bf4f61c1f9caa6f4c66b Mon Sep 17 00:00:00 2001 From: Sven Tasche Date: Tue, 28 Nov 2023 12:05:17 +0100 Subject: [PATCH] feat(teuto-portal-k8s-worker): initial implementation (#622) add helmchart for the teutoportal-worker --- charts/teuto-portal-k8s-worker/Chart.lock | 6 + charts/teuto-portal-k8s-worker/Chart.yaml | 19 ++ .../ci/worker-values.yaml | 15 ++ .../templates/_helpers.tpl | 12 + .../templates/deployment.yaml | 73 ++++++ .../templates/service.yaml | 14 ++ .../templates/servicemonitor.yaml | 15 ++ .../values.schema.json | 223 ++++++++++++++++++ charts/teuto-portal-k8s-worker/values.yaml | 40 ++++ 9 files changed, 417 insertions(+) create mode 100644 charts/teuto-portal-k8s-worker/Chart.lock create mode 100644 charts/teuto-portal-k8s-worker/Chart.yaml create mode 100644 charts/teuto-portal-k8s-worker/ci/worker-values.yaml create mode 100644 charts/teuto-portal-k8s-worker/templates/_helpers.tpl create mode 100644 charts/teuto-portal-k8s-worker/templates/deployment.yaml create mode 100644 charts/teuto-portal-k8s-worker/templates/service.yaml create mode 100644 charts/teuto-portal-k8s-worker/templates/servicemonitor.yaml create mode 100644 charts/teuto-portal-k8s-worker/values.schema.json create mode 100644 charts/teuto-portal-k8s-worker/values.yaml diff --git a/charts/teuto-portal-k8s-worker/Chart.lock b/charts/teuto-portal-k8s-worker/Chart.lock new file mode 100644 index 000000000..83ace4982 --- /dev/null +++ b/charts/teuto-portal-k8s-worker/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: https://charts.bitnami.com/bitnami + version: 2.13.3 +digest: sha256:282692f64a30ce2f8e2135866b3ba8d5e26ad4381fc0265a2125de6b2669871c +generated: "2023-11-27T14:50:27.810547185+01:00" diff --git a/charts/teuto-portal-k8s-worker/Chart.yaml b/charts/teuto-portal-k8s-worker/Chart.yaml new file mode 100644 index 000000000..2e8112196 --- /dev/null +++ b/charts/teuto-portal-k8s-worker/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v2 +name: teuto-portal-k8s-worker +description: A Helm chart for deploying the portal worker application to k8s +type: application +version: 0.1.0 +appVersion: "1.0.0" + +maintainers: + - name: cwrau + email: cwr@teuto.net + - name: marvinWolff + email: mw@teuto.net + - name: tasches + email: st@teuto.net + +dependencies: + - name: common + version: 2.13.3 + repository: https://charts.bitnami.com/bitnami diff --git a/charts/teuto-portal-k8s-worker/ci/worker-values.yaml b/charts/teuto-portal-k8s-worker/ci/worker-values.yaml new file mode 100644 index 000000000..881b4ac43 --- /dev/null +++ b/charts/teuto-portal-k8s-worker/ci/worker-values.yaml @@ -0,0 +1,15 @@ +worker: + database: + host: localhost + credentials: + secret: + name: db-credentials + config: + flavourPrefixFilter: + - teuto + - teuto-net + syncInterval: 10s + loggingFormat: json + kubeconfig: + secret: + name: k8s-access-token diff --git a/charts/teuto-portal-k8s-worker/templates/_helpers.tpl b/charts/teuto-portal-k8s-worker/templates/_helpers.tpl new file mode 100644 index 000000000..ce22a23fc --- /dev/null +++ b/charts/teuto-portal-k8s-worker/templates/_helpers.tpl @@ -0,0 +1,12 @@ +{{- define "portalworker.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.worker.image "global" .Values.global) }} +{{- end -}} + +{{- define "portalworker.jdbc" -}} +{{- $port := .Values.worker.database.port | int -}} +{{ printf "jdbc:postgresql://%s:%d/teuto_domain?currentSchema=app_public" .Values.worker.database.host $port }} +{{- end -}} + +{{- define "portalworker.dbcredentials.secretName" -}} +{{ required "A secretName containing the database credentials is required" .Values.worker.database.credentials.secret.name }} +{{- end -}} diff --git a/charts/teuto-portal-k8s-worker/templates/deployment.yaml b/charts/teuto-portal-k8s-worker/templates/deployment.yaml new file mode 100644 index 000000000..437036003 --- /dev/null +++ b/charts/teuto-portal-k8s-worker/templates/deployment.yaml @@ -0,0 +1,73 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: {{- include "common.labels.standard" $ | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: {{- include "common.labels.matchLabels" $ | nindent 6 }} + template: + metadata: + labels: {{- include "common.labels.standard" $ | nindent 8 }} + spec: + {{- include "common.images.renderPullSecrets" ( dict "images" (list .Values.worker.image) "context" $) | indent 6 }} + securityContext: {{- toYaml .Values.global.securityContext | nindent 8 }} + automountServiceAccountToken: false + containers: + - name: {{ .Chart.Name }} + securityContext: {{- toYaml .Values.global.podSecurityContext | nindent 12 }} + image: {{ template "portalworker.image". }} + {{- if .Values.worker.image.digest }} + imagePullPolicy: IfNotPresent + {{- else }} + imagePullPolicy: Always + {{- end }} + env: + - name: JDBC_URL + value: {{ include "portalworker.jdbc" . | quote }} + - name: DB_PORT + value: {{ .Values.worker.database.port | quote }} + - name: KUBECONFIG + value: "/kubeconfig" + {{- with (include "portalworker.dbcredentials.secretName" $) }} + - name: DB_USERNAME + valueFrom: + secretKeyRef: + name: {{ . }} + key: username + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: {{ . }} + key: password + {{- end }} + {{- range $k, $v := .Values.worker.config }} + {{- if or (typeIs "bool" $v) ($v) }} + - name: {{ regexReplaceAll `_(\d+)` ($k | snakecase | upper) "$1" }} + value: {{ $v | join "," | quote }} + {{- end -}} + {{- end }} + ports: + - name: metrics + containerPort: 9090 + protocol: TCP + livenessProbe: + httpGet: + path: /-/healthy + port: metrics + resources: {{- toYaml .Values.worker.resources | nindent 12 }} + volumeMounts: + - mountPath: /kubeconfig + name: clusterconfig + subPath: config + readOnly: true + - mountPath: /tmp + name: tmp + volumes: + - name: tmp + emptyDir: {} + - name: clusterconfig + secret: + secretName: {{ required "k8s access token for the management cluster must be provided" .Values.worker.kubeconfig.secret.name }} \ No newline at end of file diff --git a/charts/teuto-portal-k8s-worker/templates/service.yaml b/charts/teuto-portal-k8s-worker/templates/service.yaml new file mode 100644 index 000000000..6e1bba343 --- /dev/null +++ b/charts/teuto-portal-k8s-worker/templates/service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "common.names.fullname" . }}-service + namespace: {{ .Release.Namespace }} + labels: {{- include "common.labels.standard" $ | nindent 4 }} +spec: + selector: {{- include "common.labels.matchLabels" $ | nindent 4 }} + ports: + - name: metrics + protocol: TCP + port: 9090 + targetPort: metrics + type: ClusterIP \ No newline at end of file diff --git a/charts/teuto-portal-k8s-worker/templates/servicemonitor.yaml b/charts/teuto-portal-k8s-worker/templates/servicemonitor.yaml new file mode 100644 index 000000000..0873b8db8 --- /dev/null +++ b/charts/teuto-portal-k8s-worker/templates/servicemonitor.yaml @@ -0,0 +1,15 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: {{- include "common.labels.standard" $ | nindent 4 }} + name: "{{ include "common.names.fullname" . }}-service" + namespace: {{ .Release.Namespace }} +spec: + endpoints: + - path: /metrics + port: metrics + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + selector: + matchLabels: {{- include "common.labels.matchLabels" $ | nindent 6 }} \ No newline at end of file diff --git a/charts/teuto-portal-k8s-worker/values.schema.json b/charts/teuto-portal-k8s-worker/values.schema.json new file mode 100644 index 000000000..9d822bc89 --- /dev/null +++ b/charts/teuto-portal-k8s-worker/values.schema.json @@ -0,0 +1,223 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema", + "type": "object", + "title": "portal worker helmchart", + "properties": { + "global": { + "imageRegistry": { + "type": "string" + }, + "imagePullSecrets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "podSecurityContext": { + "type": "object", + "properties": { + "runAsNonRoot": { + "type": "boolean" + }, + "readOnlyRootFilesystem": { + "type": "boolean" + }, + "allowPrivilegeEscalation": { + "type": "boolean" + }, + "privileged": { + "type": "boolean" + }, + "capabilities": { + "type": "object", + "properties": { + "drop": { + "type": "array", + "items": { + "type": "string" + } + }, + "runAsGroup": { + "type": "integer" + }, + "runAsUser": { + "type": "integer" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "securityContext": { + "type": "object", + "properties": { + "fsGroup": { + "type": "integer" + }, + "runAsUser": { + "type": "integer" + }, + "runAsGroup": { + "type": "integer" + }, + "runAsNonRoot": { + "type": "boolean" + }, + "fsGroupChangePolicy": { + "type": "string", + "enum": [ + "Always", + "OnRootMismatch" + ] + } + }, + "additionalProperties": false + } + }, + "worker": { + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "registry": { + "type": "string", + "description": "The host of the registry", + "examples": [ + "docker.io" + ] + }, + "repository": { + "type": "string", + "description": "The image path in the registry", + "examples": [ + "bitnami/kubectl" + ] + }, + "tag": { + "type": "string" + }, + "digest": { + "type": "string" + } + }, + "additionalProperties": false + }, + "database": { + "type": "object", + "properties": { + "credentials": { + "type": "object", + "properties": { + "secret": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "name" + ] + }, + "additionalProperties": false + }, + "additionalProperties": false + }, + "host": { + "type": "string" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + } + }, + "additionalProperties": false, + "required": [ + "host" + ] + }, + "kubeconfig": { + "type": "object", + "properties": { + "secret": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "name" + ] + }, + "additionalProperties": false + }, + "additionalProperties": false + }, + "config": { + "type": "object", + "properties": { + "dryRun": { + "type": "boolean" + }, + "singleRun": { + "type": "boolean" + }, + "otelExporterTracesEndpoint": { + "type": "string" + }, + "syncInterval": { + "type": "string", + "pattern": "(^(\\d+[h,m,s] *){1,3}$)" + }, + "watchK8sEvents": { + "type": "boolean" + }, + "minimumCPUFlavour": { + "type": "integer", + "minimum": 1 + }, + "flavourPrefixFilter": { + "type": "array", + "items": { + "type": "string" + } + }, + "clusterNamespace": { + "type": "string" + }, + "loggingFormat": { + "type": "string" + } + }, + "additionalProperties": false + }, + "resources": { + "$ref": "#/$defs/resourceRequirements" + } + }, + "additionalProperties": false + }, + "common": { + "type": "object", + "description": "Values for sub-chart" + } + }, + "additionalProperties": false, + "$defs": { + "resourceRequirements": { + "$ref": "https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/master-standalone-strict/_definitions.json#/definitions/io.k8s.api.core.v1.ResourceRequirements" + } + } +} \ No newline at end of file diff --git a/charts/teuto-portal-k8s-worker/values.yaml b/charts/teuto-portal-k8s-worker/values.yaml new file mode 100644 index 000000000..189fb70e2 --- /dev/null +++ b/charts/teuto-portal-k8s-worker/values.yaml @@ -0,0 +1,40 @@ +global: + imageRegistry: registry-gitlab.teuto.net + imagePullSecrets: [] + podSecurityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + privileged: false + capabilities: + drop: + - ALL + runAsGroup: 1000 + runAsUser: 1000 + + securityContext: + fsGroup: 1000 + runAsUser: 1000 + runAsGroup: 1000 + runAsNonRoot: true + fsGroupChangePolicy: OnRootMismatch + +worker: + image: + repository: 4teuto/dev/teuto-portal-k8s-worker/teuto-portal-k8s-worker-k8s-worker/teuto-portal-k8s-worker-k8s-worker + tag: 1.0.0 + database: + credentials: + secret: + name: "" + host: localhost + port: 5432 + kubeconfig: + secret: + name: "" + resources: + limits: + cpu: 500m + memory: 1Gi + requests: + memory: 256Mi