diff --git a/charts/simple-cronjob/.helmignore b/charts/simple-cronjob/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/simple-cronjob/.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/simple-cronjob/CHANGELOG.md b/charts/simple-cronjob/CHANGELOG.md new file mode 100644 index 0000000..ea8c60f --- /dev/null +++ b/charts/simple-cronjob/CHANGELOG.md @@ -0,0 +1,19 @@ +# 0.1.4 + +* Synchonize volumes configuration between simple-app and simple-worker + +# 0.1.3 + +* Synchronize fullname generation between simple-app and simple-worker + +# 0.1.2 + +* Name container the same as release (helps to read logs in GCP) + +# 0.1.1 + +* Add option to mount existing secrets and config maps as volume + +# 0.1.0 + +* Initial release \ No newline at end of file diff --git a/charts/simple-cronjob/Chart.yaml b/charts/simple-cronjob/Chart.yaml new file mode 100644 index 0000000..249d3d6 --- /dev/null +++ b/charts/simple-cronjob/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: simple-cronjob +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. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: "0.1.0" + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/charts/simple-cronjob/Makefile b/charts/simple-cronjob/Makefile new file mode 100644 index 0000000..5a62a8a --- /dev/null +++ b/charts/simple-cronjob/Makefile @@ -0,0 +1,4 @@ +# helm plugin install https://github.com/helm-unittest/helm-unittest.git + +test: + helm unittest . diff --git a/charts/simple-cronjob/templates/NOTES.txt b/charts/simple-cronjob/templates/NOTES.txt new file mode 100644 index 0000000..e69de29 diff --git a/charts/simple-cronjob/templates/_helpers.tpl b/charts/simple-cronjob/templates/_helpers.tpl new file mode 100644 index 0000000..c4aca7a --- /dev/null +++ b/charts/simple-cronjob/templates/_helpers.tpl @@ -0,0 +1,57 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "simple-app.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 "simple-app.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "simple-app.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "simple-app.labels" -}} +helm.sh/chart: {{ include "simple-app.chart" . }} +{{ include "simple-app.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "simple-app.selectorLabels" -}} +app.kubernetes.io/name: {{ include "simple-app.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "simple-app.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "simple-app.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/simple-cronjob/templates/configs-configmap.yaml b/charts/simple-cronjob/templates/configs-configmap.yaml new file mode 100644 index 0000000..4aa9286 --- /dev/null +++ b/charts/simple-cronjob/templates/configs-configmap.yaml @@ -0,0 +1,13 @@ +{{ if .Values.configs }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "simple-app.fullname" . }} + labels: + {{- include "simple-app.labels" . | nindent 4 }} +data: + {{- range .Values.configs }} + {{ .name }}: | + {{- .value | nindent 4 }} + {{- end }} +{{ end }} \ No newline at end of file diff --git a/charts/simple-cronjob/templates/cronjob.yaml b/charts/simple-cronjob/templates/cronjob.yaml new file mode 100644 index 0000000..fa8ffe9 --- /dev/null +++ b/charts/simple-cronjob/templates/cronjob.yaml @@ -0,0 +1,112 @@ +{{- $fullName := include "simple-app.fullname" . -}} + +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ include "simple-app.fullname" . }} + labels: + {{- include "simple-app.labels" . | nindent 4 }} +spec: + schedule: "{{ .Values.schedule }}" + timeZone: "{{ .Values.timeZone }}" + concurrencyPolicy: "{{ .Values.concurrencyPolicy }}" + jobTemplate: + spec: + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 12 }} + {{- end }} + labels: + {{- include "simple-app.selectorLabels" . | nindent 12 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 12 }} + {{- end }} + serviceAccountName: {{ include "simple-app.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 12 }} + volumes: + {{- if .Values.shmSize }} + - name: shared-memory + emptyDir: + medium: Memory + sizeLimit: {{ .Values.shmSize }} + {{- end }} + {{- range .Values.volumes }} + - name: {{ .name }} + {{- if .emptyDir }} + emptyDir: + sizeLimit: {{ .size }} + {{- else if .size }} + persistentVolumeClaim: + claimName: {{ $fullName }}-{{ .name }} + {{- else if .configMap }} + configMap: + {{- .configMap | toYaml | nindent 16 }} + {{- else if .secret }} + secret: + {{- .secret | toYaml | nindent 16 }} + {{- end }} + {{- end }} + {{- range .Values.configs }} + - name: configs + configMap: + name: {{ $fullName }} + {{- end }} + restartPolicy: "OnFailure" + containers: + - name: {{ include "simple-app.fullname" . }} + securityContext: + {{- toYaml .Values.securityContext | nindent 16 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.command }} + command: + {{- .Values.command | toYaml | nindent 16 }} + {{ end }} + {{- if .Values.env }} + env: + {{- .Values.env | toYaml | nindent 16 }} + {{ end }} + livenessProbe: + exec: + command: + - echo + - ok + readinessProbe: + exec: + command: + - echo + - ok + resources: + {{- toYaml .Values.resources | nindent 16 }} + volumeMounts: + {{- if .Values.shmSize }} + - name: shared-memory + mountPath: /dev/shm + {{- end }} + {{- range .Values.volumes }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + {{- range .Values.configs }} + - name: configs + mountPath: {{ if .mountPath }}"{{ .mountPath }}"{{ else }}"/configs/{{ .name }}"{{ end }} + subPath: {{ .name }} + readOnly: true + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 12 }} + {{- end }} diff --git a/charts/simple-cronjob/templates/pvc.yaml b/charts/simple-cronjob/templates/pvc.yaml new file mode 100644 index 0000000..9d52277 --- /dev/null +++ b/charts/simple-cronjob/templates/pvc.yaml @@ -0,0 +1,21 @@ +{{- $fullName := include "simple-app.fullname" . -}} +{{- $labels := include "simple-app.labels" . | nindent 4 -}} + +{{ range .Values.volumes }} +{{- if not .emptyDir }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ $fullName }}-{{ .name }} + labels: + {{- $labels }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .size }} + +--- +{{ end }} +{{ end }} \ No newline at end of file diff --git a/charts/simple-cronjob/templates/serviceaccount.yaml b/charts/simple-cronjob/templates/serviceaccount.yaml new file mode 100644 index 0000000..95c5c50 --- /dev/null +++ b/charts/simple-cronjob/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "simple-app.serviceAccountName" . }} + labels: + {{- include "simple-app.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/simple-cronjob/tests/__snapshot__/simple_test.yaml.snap b/charts/simple-cronjob/tests/__snapshot__/simple_test.yaml.snap new file mode 100644 index 0000000..af68122 --- /dev/null +++ b/charts/simple-cronjob/tests/__snapshot__/simple_test.yaml.snap @@ -0,0 +1,81 @@ +All manifests should match snapshot: + 1: | + apiVersion: batch/v1 + kind: CronJob + metadata: + labels: + app.kubernetes.io/instance: simple + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: simple-cronjob + app.kubernetes.io/version: 1.16.0 + helm.sh/chart: simple-cronjob-0.0.0 + name: simple + spec: + concurrencyPolicy: Forbid + jobTemplate: + spec: + template: + metadata: + labels: + app.kubernetes.io/instance: simple + app.kubernetes.io/name: simple-cronjob + spec: + containers: + - env: + - name: TEST + value: test + image: test:1.1.1 + imagePullPolicy: IfNotPresent + livenessProbe: + exec: + command: + - echo + - ok + name: simple + readinessProbe: + exec: + command: + - echo + - ok + resources: {} + securityContext: {} + volumeMounts: + - mountPath: /data + name: data + restartPolicy: OnFailure + securityContext: {} + serviceAccountName: simple + volumes: + - name: data + persistentVolumeClaim: + claimName: simple-data + schedule: '*/1 * * * *' + timeZone: GMT + 2: | + apiVersion: v1 + kind: PersistentVolumeClaim + metadata: + labels: + app.kubernetes.io/instance: simple + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: simple-cronjob + app.kubernetes.io/version: 1.16.0 + helm.sh/chart: simple-cronjob-0.0.0 + name: simple-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + 3: | + apiVersion: v1 + kind: ServiceAccount + metadata: + labels: + app.kubernetes.io/instance: simple + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: simple-cronjob + app.kubernetes.io/version: 1.16.0 + helm.sh/chart: simple-cronjob-0.0.0 + name: simple diff --git a/charts/simple-cronjob/tests/simple-values.yaml b/charts/simple-cronjob/tests/simple-values.yaml new file mode 100644 index 0000000..455bb77 --- /dev/null +++ b/charts/simple-cronjob/tests/simple-values.yaml @@ -0,0 +1,14 @@ +# yaml-language-server: $schema=../values.schema.json + +image: + repository: test + tag: 1.1.1 + +env: + - name: TEST + value: test + +volumes: + - name: data + size: 1Gi + mountPath: /data diff --git a/charts/simple-cronjob/tests/simple_test.yaml b/charts/simple-cronjob/tests/simple_test.yaml new file mode 100644 index 0000000..f7c6689 --- /dev/null +++ b/charts/simple-cronjob/tests/simple_test.yaml @@ -0,0 +1,183 @@ +suite: simple-app simple case + +values: + - simple-values.yaml + +release: + name: simple + namespace: default + +chart: + version: 0.0.0 + +tests: + - it: All manifests should match snapshot + templates: + - cronjob.yaml + - serviceaccount.yaml + - pvc.yaml + asserts: + - matchSnapshot: {} + + - it: CronJob should be named as release + template: cronjob.yaml + asserts: + - isKind: + of: CronJob + - equal: + path: metadata.name + value: simple + + - it: CronJob image tag should be set correctly + template: cronjob.yaml + asserts: + - isKind: + of: CronJob + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].image + value: test:1.1.1 + + - it: CronJob should use imagePullSecrets if specified + template: cronjob.yaml + set: + imagePullSecrets: + - name: test + asserts: + - isKind: + of: CronJob + - equal: + path: spec.jobTemplate.spec.template.spec.imagePullSecrets + value: + - name: test + + - it: CronJob should mount shared memory volume if shmMem specified + template: cronjob.yaml + set: + shmSize: 1Gi + asserts: + - isKind: + of: CronJob + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0] + value: + mountPath: /dev/shm + name: shared-memory + - equal: + path: spec.jobTemplate.spec.template.spec.volumes[0] + value: + emptyDir: + medium: Memory + sizeLimit: 1Gi + name: shared-memory + + - it: CronJob should have correctly mounted configs + template: cronjob.yaml + set: + configs: + - name: test.json + mountPath: /etc/test.json + value: | + { + "test": "test" + } + - name: test2.json + value: | + { + "test2": "test2" + } + asserts: + - isKind: + of: CronJob + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[1] + value: + mountPath: /etc/test.json + name: configs + subPath: test.json + readOnly: true + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[2] + value: + mountPath: /configs/test2.json + name: configs + subPath: test2.json + readOnly: true + - contains: + path: spec.jobTemplate.spec.template.spec.volumes + content: + configMap: + name: simple + name: configs + + - it: CronJob should have correctly mounted volumes with pvc + template: cronjob.yaml + asserts: + - isKind: + of: CronJob + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0] + value: + mountPath: /data + name: data + - equal: + path: spec.jobTemplate.spec.template.spec.volumes[0] + value: + name: data + persistentVolumeClaim: + claimName: simple-data + + - it: CronJob should have correctly mounted volumes without pvc + template: cronjob.yaml + set: + volumes: + - name: data + size: 1Gi + mountPath: /data + emptyDir: true + asserts: + - isKind: + of: CronJob + - equal: + path: spec.jobTemplate.spec.template.spec.containers[0].volumeMounts[0] + value: + mountPath: /data + name: data + - equal: + path: spec.jobTemplate.spec.template.spec.volumes[0] + value: + name: data + emptyDir: + sizeLimit: 1Gi + + - it: PVC should not be created if emptyDir + template: pvc.yaml + set: + volumes: + - name: data + size: 1Gi + mountPath: /data + emptyDir: true + asserts: + - hasDocuments: + count: 0 + + - it: PVC should have correctly mounted volumes with pvc + template: pvc.yaml + asserts: + - isKind: + of: PersistentVolumeClaim + - equal: + path: spec.resources.requests.storage + value: 1Gi + + - it: PVC should have correctly mounted volumes without pvc + template: pvc.yaml + set: + volumes: + - name: data + size: 1Gi + mountPath: /data + emptyDir: true + asserts: + - hasDocuments: + count: 0 diff --git a/charts/simple-cronjob/values.schema.json b/charts/simple-cronjob/values.schema.json new file mode 100644 index 0000000..6c02c5d --- /dev/null +++ b/charts/simple-cronjob/values.schema.json @@ -0,0 +1,183 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "simple-app values schema", + "type": "object", + "properties": { + "nameOverride": { + "type": "string" + }, + "fullnameOverride": { + "type": "string" + }, + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "imagePullSecrets": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + } + }, + "domain": { + "type": "string" + }, + "env": { + "type": "array", + "items": { + "type": "object" + } + }, + "schedule": { + "type": "string" + }, + "timeZone": { + "type": "string" + }, + "concurrencyPolicy": { + "type": "string" + }, + "command": { + "type": "array", + "items": { + "type": "string" + } + }, + "shmSize": { + "type": "string" + }, + "volumes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "mountPath": { + "type": "string" + }, + "size": { + "type": "string" + }, + "emptyDir": { + "type": "boolean" + } + } + } + }, + "configs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "mountPath": { + "type": "string" + }, + "value": { + "type": "string" + } + } + } + }, + "livenessProbe": { + "type": "object" + }, + "readinessProbe": { + "type": "object" + }, + "replicaCount": { + "type": "integer" + }, + "serviceAccount": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "annotations": { + "type": "object" + } + } + }, + "podAnnotations": { + "type": "object" + }, + "podSecurityContext": { + "type": "object" + }, + "securityContext": { + "type": "object" + }, + "ingress": { + "type": "object" + }, + "gateway": { + "type": "object" + }, + "resources": { + "type": "object" + }, + "autoscaling": { + "type": "object" + }, + "nodeSelector": { + "type": "object" + }, + "tolerations": { + "type": "array", + "items": { + "type": "object" + } + }, + "affinity": { + "type": "object" + }, + "gke": { + "type": "object", + "properties": { + "managedCertificate": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "iap": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "clientID": { + "type": "string" + }, + "oauth2ClientSecret": { + "type": "string" + } + } + } + } + } + } + } + }, + "additionalProperties": false +} \ No newline at end of file diff --git a/charts/simple-cronjob/values.yaml b/charts/simple-cronjob/values.yaml new file mode 100644 index 0000000..c836ff1 --- /dev/null +++ b/charts/simple-cronjob/values.yaml @@ -0,0 +1,104 @@ +# Default values for simple-app. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +nameOverride: "" +fullnameOverride: "" + +image: + repository: nginx + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] + +# Environment variables for container +env: {} + +schedule: "*/1 * * * *" +timeZone: "GMT" + +concurrencyPolicy: "Forbid" + +volumes: [] + # if "size" is set, it will create a PVC + # - name: data + # size: 1Gi + # mountPath: /data + + # if "emptyDir" is set, it will create an emptyDir + # - name: cache + # emptyDir: true + # size: 1Gi + # mountPath: /cache + + # if "secret" is set, it will use the secret + # - name: secret + # secret: + # secretName: secret + # mountPath: /secret + + # if "configMap" is set, it will use the configMap + # - name: config + # configMap: + # name: config + # mountPath: /config + + +configs: [] + # - name: conn.json + # mountPath: /etc/conn.json + # value: | + # { + # "client": "pg", + # "connection": { + # } + # } + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +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 + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {}