From 95477026bc85657a682b870aca9398283d5d6398 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Tue, 14 May 2024 19:13:52 +0200 Subject: [PATCH] feat(application-with-volume): Experimental volume chart --- chart/application-with-volume/.helmignore | 23 +++++ chart/application-with-volume/Chart.yaml | 17 ++++ .../templates/_helpers.tpl | 57 ++++++++++++ .../templates/deployment.yaml | 86 +++++++++++++++++++ .../templates/ingress.yaml | 55 ++++++++++++ .../templates/pvc.yaml | 16 ++++ .../templates/service.yaml | 19 ++++ chart/application-with-volume/values.yaml | 77 +++++++++++++++++ 8 files changed, 350 insertions(+) create mode 100644 chart/application-with-volume/.helmignore create mode 100644 chart/application-with-volume/Chart.yaml create mode 100644 chart/application-with-volume/templates/_helpers.tpl create mode 100644 chart/application-with-volume/templates/deployment.yaml create mode 100644 chart/application-with-volume/templates/ingress.yaml create mode 100644 chart/application-with-volume/templates/pvc.yaml create mode 100644 chart/application-with-volume/templates/service.yaml create mode 100644 chart/application-with-volume/values.yaml diff --git a/chart/application-with-volume/.helmignore b/chart/application-with-volume/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/chart/application-with-volume/.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/chart/application-with-volume/Chart.yaml b/chart/application-with-volume/Chart.yaml new file mode 100644 index 00000000..66503051 --- /dev/null +++ b/chart/application-with-volume/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: epinio-application-with-volume +description: The helm chart for epinio applications to be deployed with a volume +icon: https://raw.githubusercontent.com/odit-services/epinio-helm-charts/main/assets/epinio.png +home: https://github.com/odit-services/epinio-helm-charts +type: application +version: 0.1.26 +keywords: +- epinio +- paas +maintainers: +- email: info@odit.services + name: ODIT.Services +sources: +- https://github.com/odit-services/epinio-helm-charts +annotations: + artifacthub.io/license: Apache-2.0 diff --git a/chart/application-with-volume/templates/_helpers.tpl b/chart/application-with-volume/templates/_helpers.tpl new file mode 100644 index 00000000..93d2192c --- /dev/null +++ b/chart/application-with-volume/templates/_helpers.tpl @@ -0,0 +1,57 @@ +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "epinio-application.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "epinio-application.labels" -}} +app.kubernetes.io/managed-by: epinio +app.kubernetes.io/part-of: {{ .Release.Namespace | quote }} +helm.sh/chart: {{ include "epinio-application.chart" . }} +{{ include "epinio-application.selectorLabels" . }} +{{- end }} + +{{/* +Common annotations +*/}} +{{- define "epinio-application.annotations" -}} +epinio.io/created-by: {{ .Values.epinio.username | quote }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "epinio-application.selectorLabels" -}} +app.kubernetes.io/name: {{ .Values.epinio.appName | quote }} +app.kubernetes.io/component: application +{{- end }} + +{{/* +Removes characters that are invalid for kubernetes resource names from the +given string +*/}} +{{- define "epinio-name-sanitize" -}} +{{ regexReplaceAll "[^-a-z0-9]*" . "" }} +{{- end }} + +{{/* +Resource name sanitization and truncation. +- Always suffix the sha1sum (40 characters long) +- Always add an "r" prefix to make sure we don't have leading digits +- The rest of the characters up to 63 are the original string with invalid +character removed. +*/}} +{{- define "epinio-truncate" -}} +{{ print "r" (trunc 21 (include "epinio-name-sanitize" .)) "-" (sha1sum .) }} +{{- end }} + +{{/* +Application listening port +*/}} +{{- define "epinio-app-listening-port" -}} +{{ default 8080 (default (dict "appListeningPort" "8080") .Values.userConfig).appListeningPort }} +{{- end }} diff --git a/chart/application-with-volume/templates/deployment.yaml b/chart/application-with-volume/templates/deployment.yaml new file mode 100644 index 00000000..53cb4df3 --- /dev/null +++ b/chart/application-with-volume/templates/deployment.yaml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "epinio-truncate" .Values.epinio.appName }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "epinio-application.labels" . | nindent 4 }} + annotations: + {{- include "epinio-application.annotations" . | nindent 4 }} +spec: + replicas: {{ .Values.epinio.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ .Values.epinio.appName | quote }} + template: + metadata: + annotations: + app.kubernetes.io/name: {{ .Values.epinio.appName | quote }} + {{- include "epinio-application.annotations" . | nindent 8 }} + {{- with .Values.epinio.start }} + epinio.io/start: {{ . | quote }} + {{- end }} + labels: + {{- include "epinio-application.labels" . | nindent 8 }} + epinio.io/stage-id: {{ .Values.epinio.stageID | quote }} + epinio.io/app-container: {{ include "epinio-truncate" .Values.epinio.appName }} + spec: + serviceAccount: {{ .Release.Namespace }} + serviceAccountName: {{ .Release.Namespace }} + automountServiceAccountToken: true + volumes: + - name: data + persistentVolumeClaim: + claimName: {{ include "epinio-truncate" .Values.epinio.appName }} + {{- with .Values.epinio.configurations }} + {{- range . }} + - name: {{ . }} + secret: + defaultMode: 420 + secretName: {{ . }} + {{- end }} + {{- end }} + containers: + - name: {{ include "epinio-truncate" .Values.epinio.appName }} + ports: + - containerPort: {{ include "epinio-app-listening-port" . }} + protocol: TCP + volumeMounts: + - name: data + mountPath: {{ .Values.userconfig.storagePath }} + {{- with .Values.epinio.configpaths }} + {{- range . }} + - mountPath: /configurations/{{ .path }} + name: {{ .name }} + readOnly: true + {{- end }} + {{- end }} + env: + - name: PORT + value: {{ include "epinio-app-listening-port" . | quote }} + {{- range .Values.epinio.env }} + - name: {{ .name | quote }} + value: {{ .value | quote }} + {{- end}} + image: {{ .Values.epinio.imageURL }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end}} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/chart/application-with-volume/templates/ingress.yaml b/chart/application-with-volume/templates/ingress.yaml new file mode 100644 index 00000000..39f72e15 --- /dev/null +++ b/chart/application-with-volume/templates/ingress.yaml @@ -0,0 +1,55 @@ +{{- range .Values.epinio.routes }} +{{- if not .secret }} +--- +apiVersion: "cert-manager.io/v1" +kind: Certificate +metadata: + name: {{ include "epinio-truncate" (print $.Values.epinio.appName "-" .id) }} + labels: + {{- include "epinio-application.labels" $ | nindent 4 }} + annotations: + {{- include "epinio-application.annotations" $ | nindent 4 }} +spec: + secretName: {{ include "epinio-truncate" (print $.Values.epinio.appName "-" .id "-tls") }} + dnsNames: + - {{ .domain | quote }} + issuerRef: + name : {{ $.Values.epinio.tlsIssuer | quote }} + kind: ClusterIssuer +{{- end }} +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "epinio-truncate" (print $.Values.epinio.appName "-" .id) }} + namespace: {{ $.Release.Namespace | quote }} + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + {{- include "epinio-application.annotations" $ | nindent 4 }} + labels: + {{- include "epinio-application.labels" $ | nindent 4 }} +spec: + {{- with $.Values.epinio.ingress }} + ingressClassName: {{ . | quote }} + {{- end }} + rules: + - host: {{ .domain | quote }} + http: + paths: + - backend: + service: + name: {{ include "epinio-truncate" $.Values.epinio.appName }} + port: + number: 8080 + path: {{ .path | quote }} + pathType: ImplementationSpecific + tls: + - hosts: + - {{ .domain | quote }} +{{- if .secret }} + secretName: {{ .secret | quote }} +{{- else }} + secretName: {{ include "epinio-truncate" (print $.Values.epinio.appName "-" .id "-tls") }} +{{- end }} +{{- end }} diff --git a/chart/application-with-volume/templates/pvc.yaml b/chart/application-with-volume/templates/pvc.yaml new file mode 100644 index 00000000..5158cf9e --- /dev/null +++ b/chart/application-with-volume/templates/pvc.yaml @@ -0,0 +1,16 @@ +--- +apiVersion: "v1" +kind: PersistentVolumeClaim +metadata: + name: {{ include "epinio-truncate" .Values.epinio.appName }} + labels: + {{- include "epinio-application.labels" $ | nindent 4 }} + annotations: + {{- include "epinio-application.annotations" $ | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + storageClassName: {{ .Values.userConfig.storageClassName }} + resources: + requests: + storage: {{ .Values.userConfig.storageSize }} \ No newline at end of file diff --git a/chart/application-with-volume/templates/service.yaml b/chart/application-with-volume/templates/service.yaml new file mode 100644 index 00000000..54f52801 --- /dev/null +++ b/chart/application-with-volume/templates/service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + {{- include "epinio-application.annotations" . | nindent 4 }} + labels: + {{- include "epinio-application.labels" . | nindent 4 }} + name: {{ include "epinio-truncate" .Values.epinio.appName }} + namespace: {{ .Release.Namespace | quote }} +spec: + ports: + - port: 8080 + protocol: TCP + targetPort: {{ include "epinio-app-listening-port" . }} + selector: + {{- include "epinio-application.selectorLabels" . | nindent 4 }} + type: ClusterIP diff --git a/chart/application-with-volume/values.yaml b/chart/application-with-volume/values.yaml new file mode 100644 index 00000000..8df717d5 --- /dev/null +++ b/chart/application-with-volume/values.yaml @@ -0,0 +1,77 @@ +# Default values for epinio-application. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# This is the API between the epinio server's deployment code, and +# charts implementing the deployment, like this one. + +# appName :: string :: application name +# replicaCount :: integer :: number of instances (pods) to deploy +# stageID :: string :: id of stage run generating the app image +# imageURL :: string :: reference to app image in registry +# username :: string :: user triggering deployment +# routes :: sequence (route) :: routes (= domain+path+id) the app has to be reachable at +# env :: sequence (assignment) :: app environment variables and values +# configurations :: sequence (string) :: names of the configurations to import into the app +# configpaths :: sequence (config) :: names and mount paths of the bound configurations +# start :: integer :: time of deployment, nanoseconds +# ingress :: string :: ingress class name to use, if any +# tlsIssuer :: string :: name of cert issuer +## +# assignment :: map ('name' -> string, 'value' -> string) +# route :: map ('id' -> string, 'domain' -> string, 'path' -> string) +# config :: map ('name' -> string, 'path' -> string) +# +# The field 'configpaths' is a replacement and extension of field 'configurations', separating a +# configuration's name from from its mounting path in the application container. This allows for +# using a more human-readable path. The server fills both fields so that old(er) charts can still +# work, even if they are unable to take advantage of the nicer paths of the extension. + +# The `start` element can be used to force a restart of specific resources with each +# re-deployment. This standard chart uses it in a pod template annotation, forcing pod +# restart. +# +# This is required because an app may have to ingest changes to resources outside of +# itself. I.e. an update to a bound configuration + +image: + pullPolicy: IfNotPresent + +imagePullSecrets: [] + +epinio: + tlsIssuer: ~ + ingress: ~ + appName: placeholder + # namespace: .Release.Namespace + replicaCount: 1 + stageID: 999 + imageURL: ~ + username: user + routes: ~ + env: ~ + configurations: ~ + start: ~ + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +userConfig: + storageClass: hcloud-volumes + storageSize: 1Gi + storagePath: /data