diff --git a/docs/using-lagoon-advanced/service-types.md b/docs/using-lagoon-advanced/service-types.md index d0e62c1b52..35e501a8cb 100644 --- a/docs/using-lagoon-advanced/service-types.md +++ b/docs/using-lagoon-advanced/service-types.md @@ -26,7 +26,8 @@ This table lists all service types that can be defined via `lagoon.type` within | `postgres` | A meta-service which will tell Lagoon to automatically decide between `postgres-single` and `postgres-dbaas`. | - | - | - | - | - | | `postgres-single` | Postgres container. Creates cron job for backups running every 24h executing `/lagoon/postgres-backup.sh localhost`. | TCP connection on `5432` | `5432` | No | Yes | `lagoon.persistent.size` | | `postgres-dbaas` | Uses a shared PostgreSQL server via the DBaaS Operator. | Not Needed | `5432` | No | - | - | -| `python` | Python container. No persistent storage. | TCP connection on `8800` | `8800` | Yes | No | - | +| `python` | Python container. No persistent storage. | HTTP connection on `8800` | `8800` | Yes | No | - | +| `python-persistent` | Python container. With persistent storage. | HTTP connection on `8800` | `8800` | Yes | Yes | - | | `redis` | Redis container. | TCP connection on `6379` | `6379` | No | No | - | | `redis-persistent` | Redis container with auto-generated persistent storage mounted under `/data`. | TCP connection on `6379` | `6379` | No | Yes | `lagoon.persistent.size` | | `solr` | Solr container with auto-generated persistent storage mounted under `/var/solr`. | TCP connection on `8983` | `8983` | No | Yes | `lagoon.persistent.size` | diff --git a/images/kubectl-build-deploy-dind/helmcharts/python-persistent/.helmignore b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/.helmignore new file mode 100644 index 0000000000..50af031725 --- /dev/null +++ b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/images/kubectl-build-deploy-dind/helmcharts/python-persistent/Chart.yaml b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/Chart.yaml new file mode 100644 index 0000000000..0f55f86f16 --- /dev/null +++ b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +name: python-persistent +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: 0.1.0 diff --git a/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/_helpers.tpl b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/_helpers.tpl new file mode 100644 index 0000000000..84963b3186 --- /dev/null +++ b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/_helpers.tpl @@ -0,0 +1,115 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "python-persistent.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). +*/}} +{{- define "python-persistent.fullname" -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "python-persistent.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create full hostname for autogenerated hosts +*/}} +{{- define "python-persistent.autogeneratedHost" -}} +{{- if .root.Values.autogeneratedRouteDomain -}} +{{ if not .prefix }} +{{- printf "%s" .root.Values.autogeneratedRouteDomain | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s.%s" .prefix .root.Values.autogeneratedRouteDomain | trimSuffix "-" -}} +{{- end -}} +{{- else -}} +{{ if not .prefix }} +{{- printf "%s.%s" .root.Release.Name .root.Values.routesAutogenerateSuffix | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s.%s.%s" .prefix .root.Release.Name .root.Values.routesAutogenerateSuffix | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create short hostname for autogenerated hosts. +This is used to work around problems with long CN fields in certificates. +*/}} +{{- define "python-persistent.autogeneratedShortHost" -}} +{{- if .root.Values.shortAutogeneratedRouteDomain -}} +{{- printf "%s" .root.Values.shortAutogeneratedRouteDomain }} +{{- else -}} +{{- printf "%s.%s" .root.Release.Name .root.Values.routesAutogenerateShortSuffix }} +{{- end -}} +{{- end }} + +{{/* +Generate name of Persistent Storage +Uses the Release Name (Lagoon Service Name) unless it's overwritten via .Values.persistentStorage.name +*/}} +{{- define "python-persistent.persistentStorageName" -}} +{{- default .Release.Name .Values.persistentStorage.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Common labels +*/}} +{{- define "python-persistent.labels" -}} +helm.sh/chart: {{ include "python-persistent.chart" . }} +{{ include "python-persistent.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{ include "python-persistent.lagoonLabels" . }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "python-persistent.selectorLabels" -}} +app.kubernetes.io/name: {{ include "python-persistent.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create a PriorityClassName. +(this is based on the Lagoon Environment Type)). +*/}} +{{- define "python-persistent.lagoonPriority" -}} +{{- printf "lagoon-priority-%s" .Values.environmentType }} +{{- end -}} + +{{/* +Lagoon Labels +*/}} +{{- define "python-persistent.lagoonLabels" -}} +lagoon.sh/service: {{ .Release.Name }} +lagoon.sh/service-type: {{ .Chart.Name }} +lagoon.sh/project: {{ .Values.project }} +lagoon.sh/environment: {{ .Values.environment }} +lagoon.sh/environmentType: {{ .Values.environmentType }} +lagoon.sh/buildType: {{ .Values.buildType }} +{{- end -}} + +{{/* +Annotations +*/}} +{{- define "python-persistent.annotations" -}} +lagoon.sh/version: {{ .Values.lagoonVersion | quote }} +{{- if .Values.branch }} +lagoon.sh/branch: {{ .Values.branch | quote }} +{{- end }} +{{- if .Values.prNumber }} +lagoon.sh/prNumber: {{ .Values.prNumber | quote }} +lagoon.sh/prHeadBranch: {{ .Values.prHeadBranch | quote }} +lagoon.sh/prBaseBranch: {{ .Values.prBaseBranch | quote }} +{{- end }} +{{- end -}} diff --git a/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/cronjob.yaml b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/cronjob.yaml new file mode 100644 index 0000000000..ea9e568d7a --- /dev/null +++ b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/cronjob.yaml @@ -0,0 +1,86 @@ +{{- range $cronjobName, $cronjobConfig := .Values.nativeCronjobs }} +--- +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + name: cronjob-{{ $.Release.Name }}-{{ $cronjobName }} + labels: + {{- include "python-persistent.labels" $ | nindent 4 }} + annotations: + {{- include "python-persistent.annotations" $ | nindent 4 }} +spec: + schedule: {{ $cronjobConfig.schedule | quote }} + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 0 + failedJobsHistoryLimit: 1 + startingDeadlineSeconds: 240 + jobTemplate: + metadata: + labels: + {{- include "python-persistent.labels" $ | nindent 8 }} + annotations: + {{- include "python-persistent.annotations" $ | nindent 8 }} + spec: + backoffLimit: 0 + template: + metadata: + labels: + {{- include "python-persistent.labels" $ | nindent 12 }} + annotations: + {{- include "python-persistent.annotations" $ | nindent 12 }} + spec: + {{- with $.Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 12 }} + {{- end }} + priorityClassName: {{ include "python-persistent.lagoonPriority" $ }} + enableServiceLinks: false + securityContext: + {{- toYaml $.Values.podSecurityContext | nindent 12 }} + volumes: + - name: lagoon-sshkey + secret: + defaultMode: 420 + secretName: lagoon-sshkey + - name: {{ $.Values.persistentStorage.name }} + persistentVolumeClaim: + claimName: {{ $.Values.persistentStorage.name }} + containers: + - image: {{ $.Values.image | quote }} + name: cronjob-{{ $.Release.Name }}-{{ $cronjobName }} + securityContext: + {{- toYaml $.Values.securityContext | nindent 16 }} + imagePullPolicy: {{ $.Values.imagePullPolicy }} + command: + - /lagoon/cronjob.sh + - {{ $cronjobConfig.command }} + env: + - name: LAGOON_GIT_SHA + value: {{ $.Values.gitSha | quote }} + - name: SERVICE_NAME + value: {{ $.Release.Name | quote }} + envFrom: + - configMapRef: + name: lagoon-env + resources: + {{- toYaml $.Values.resources | nindent 16 }} + volumeMounts: + - mountPath: /var/run/secrets/lagoon/sshkey/ + name: lagoon-sshkey + readOnly: true + - name: {{ $.Values.persistentStorage.name }} + mountPath: {{ $.Values.persistentStorage.path | quote }} + restartPolicy: Never + {{- with $.Values.nodeSelector }} + nodeSelector: + {{- toYaml $ | nindent 12 }} + {{- end }} + {{- with $.Values.affinity }} + affinity: + {{- toYaml $ | nindent 12 }} + {{- end }} + {{- with $.Values.tolerations }} + tolerations: + {{- toYaml $ | nindent 12 }} + {{- end }} +{{- end }} diff --git a/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/deployment.yaml b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/deployment.yaml new file mode 100644 index 0000000000..0accf38922 --- /dev/null +++ b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/deployment.yaml @@ -0,0 +1,81 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "python-persistent.fullname" . }} + labels: + {{- include "python-persistent.labels" . | nindent 4 }} + annotations: + {{- include "python-persistent.annotations" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "python-persistent.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "python-persistent.labels" . | nindent 8 }} + annotations: + {{- include "python-persistent.annotations" . | nindent 8 }} + lagoon.sh/configMapSha: {{ .Values.configMapSha | quote }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: {{ include "python-persistent.persistentStorageName" . }} + persistentVolumeClaim: + claimName: {{ include "python-persistent.persistentStorageName" . }} + priorityClassName: {{ include "python-persistent.lagoonPriority" . }} + enableServiceLinks: false + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - image: {{ .Values.image | quote }} + name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + imagePullPolicy: {{ .Values.imagePullPolicy }} + ports: + - name: http + containerPort: 8800 + protocol: TCP + readinessProbe: + tcpSocket: + port: 8800 + initialDelaySeconds: 15 + timeoutSeconds: 1 + livenessProbe: + tcpSocket: + port: 8800 + initialDelaySeconds: 60 + periodSeconds: 5 + env: + ## LAGOON_GIT_SHA is injected directly and not loaded via `lagoon-env` config + ## This will cause the pod to redeploy on every deployment, even the files have not changed + - name: LAGOON_GIT_SHA + value: {{ .Values.gitSha | quote }} + - name: CRONJOBS + value: | + {{- toYaml .Values.inPodCronjobs | nindent 16 }} + envFrom: + - configMapRef: + name: lagoon-env + volumeMounts: + - name: {{ include "python-persistent.persistentStorageName" . }} + mountPath: {{ .Values.persistentStorage.path | quote }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- 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/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/ingress.yaml b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/ingress.yaml new file mode 100644 index 0000000000..4c9d8f7cb2 --- /dev/null +++ b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/ingress.yaml @@ -0,0 +1,74 @@ +{{- if .Values.routesAutogenerateEnabled -}} +{{- $fullName := include "python-persistent.fullname" . -}} +--- +apiVersion: networking.k8s.io/v1beta1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + lagoon.sh/autogenerated: "true" + {{- include "python-persistent.labels" . | nindent 4 }} + annotations: + {{- if eq .Values.routesAutogenerateInsecure "Allow"}} + nginx.ingress.kubernetes.io/ssl-redirect: "false" + ingress.kubernetes.io/ssl-redirect: "false" + {{- else if eq .Values.routesAutogenerateInsecure "Redirect"}} + nginx.ingress.kubernetes.io/ssl-redirect: "true" + ingress.kubernetes.io/ssl-redirect: "true" + {{- else if eq .Values.routesAutogenerateInsecure "None"}} + nginx.ingress.kubernetes.io/ssl-redirect: "true" + ingress.kubernetes.io/ssl-redirect: "true" + {{- end }} + nginx.ingress.kubernetes.io/server-snippet: |- + add_header X-Robots-Tag "noindex, nofollow"; + kubernetes.io/tls-acme: "true" + # use a specific fastly service + {{- if .Values.fastly.serviceId }} + fastly.amazee.io/service-id: "{{ .Values.fastly.serviceId }}" + {{- end }} + fastly.amazee.io/watch: "{{ .Values.fastly.watch }}" + # use a custom secret for this ingress (customer supplied fastly integration) + {{- if .Values.fastly.apiSecretName }} + fastly.amazee.io/api-secret-name: "{{ .Values.fastly.apiSecretName }}" + {{- end }} + {{- include "python-persistent.annotations" . | nindent 4 }} +spec: + tls: + - hosts: + {{- $host := include "python-persistent.autogeneratedHost" (dict "root" $) }} + {{- if and .Values.routesAutogenerateShortSuffix (gt ($host | len) 63) }} + - {{ include "python-persistent.autogeneratedShortHost" (dict "root" $) | quote }} + {{- end }} + {{- if and .Values.shortAutogeneratedRouteDomain (gt ($host | len) 63) }} + - {{ include "python-persistent.autogeneratedShortHost" (dict "root" $) | quote }} + {{- end }} + - {{ $host | quote }} + {{- if $.Values.routesAutogeneratePrefixes }} + {{- range $k, $prefix := $.Values.routesAutogeneratePrefixes }} + {{- $host := include "python-persistent.autogeneratedHost" (dict "root" $ "prefix" $prefix) }} + - {{ $host | quote }} + {{- end }} + {{- end }} + secretName: {{ $fullName }}-tls + rules: + {{- $host := include "python-persistent.autogeneratedHost" (dict "root" $) }} + - host: {{ $host | quote }} + http: + paths: + - backend: + serviceName: {{ $fullName }} + servicePort: {{ $.Values.service.port }} + {{- if $.Values.routesAutogeneratePrefixes }} + {{- range $k, $prefix := $.Values.routesAutogeneratePrefixes }} + {{- $host := include "python-persistent.autogeneratedHost" (dict "root" $ "prefix" $prefix) }} + - host: {{ $host | quote }} + http: + paths: + - backend: + serviceName: {{ $fullName }} + servicePort: {{ $.Values.service.port }} + {{- end }} + {{- end }} +{{- else }} +# empty +{{- end }} diff --git a/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/pvc.yaml b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/pvc.yaml new file mode 100644 index 0000000000..e8d620a6c8 --- /dev/null +++ b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/pvc.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "python-persistent.persistentStorageName" . }} + labels: + {{- include "python-persistent.labels" . | nindent 4 }} + annotations: + k8up.syn.tools/backup: "true" + {{- include "python-persistent.annotations" . | nindent 4 }} +spec: + accessModes: + - ReadWriteMany + storageClassName: bulk + resources: + requests: + storage: {{ .Values.persistentStorage.size | quote }} diff --git a/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/service.yaml b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/service.yaml new file mode 100644 index 0000000000..3caff42808 --- /dev/null +++ b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/templates/service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "python-persistent.fullname" . }} + labels: + {{- include "python-persistent.labels" . | nindent 4 }} + annotations: + {{- include "python-persistent.annotations" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "python-persistent.selectorLabels" . | nindent 4 }} diff --git a/images/kubectl-build-deploy-dind/helmcharts/python-persistent/values.yaml b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/values.yaml new file mode 100644 index 0000000000..6581125beb --- /dev/null +++ b/images/kubectl-build-deploy-dind/helmcharts/python-persistent/values.yaml @@ -0,0 +1,57 @@ +# Default values for python-persistent. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: "" + +environmentType: production + +persistentStorage: + size: 5Gi + +imagePullPolicy: Always + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 8800 + +## example fastly block +fastly: + watch: false +# serviceId: '' +# apiSecretName: '' + +resources: + # limits: + # cpu: 100m + # memory: 128Mi + requests: + cpu: 10m + memory: 10Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +inPodCronjobs: "" + +configMapSha: ""