diff --git a/.ct.yaml b/.ct.yaml index 5c2f82e..fed514d 100644 --- a/.ct.yaml +++ b/.ct.yaml @@ -4,3 +4,4 @@ debug: true target-branch: main check-version-increment: false validate-maintainers: false +helm-extra-args: -f chart/ci/values.yaml diff --git a/.editorconfig b/.editorconfig index 643607e..c3b0ee6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,3 +13,6 @@ max_line_length = 140 [*.md] trim_trailing_whitespace = false + +[*.yml,*.yaml] +quote_type = single diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index a16f8fe..0d85705 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -8,13 +8,17 @@ on: - develop jobs: - chart: name: 'Build and Test Helm Chart' runs-on: ubuntu-latest + strategy: + matrix: + k8s_version: + - 1.23.13 + - 1.24.7 + - 1.25.3 steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v4 with: fetch-depth: 0 @@ -24,6 +28,8 @@ jobs: with: version: v3.11.2 + # Python is required because `ct lint` runs Yamale (https://github.com/23andMe/Yamale) and + # yamllint (https://github.com/adrienverge/yamllint) which require Python - uses: actions/setup-python@v5 with: python-version: '3.9' @@ -32,22 +38,31 @@ jobs: - name: Helm Chart Testing uses: helm/chart-testing-action@v2.6.1 + - name: Helm Setup + run: | + helm repo add bitnami https://charts.bitnami.com/bitnami + - name: Run chart-testing (list-changed) id: list-changed run: | - changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }}) + changed=$(ct list-changed --config .ct.yaml --target-branch ${{ github.event.repository.default_branch }}) if [[ -n "$changed" ]]; then echo "changed=true" >> "$GITHUB_OUTPUT" fi - name: Run chart-testing (lint) if: steps.list-changed.outputs.changed == 'true' - run: ct lint --target-branch ${{ github.event.repository.default_branch }} + run: ct lint --config .ct.yaml --target-branch ${{ github.event.repository.default_branch }} - name: Create kind cluster if: steps.list-changed.outputs.changed == 'true' uses: helm/kind-action@v1.10.0 + with: + version: v0.17.0 + node_image: kindest/node:v${{ matrix.k8s_version }} + cluster_name: kind-cluster-${{ matrix.k8s_version }} + config: test/integration/kind-cluster.yaml - name: Run chart-testing (install) if: steps.list-changed.outputs.changed == 'true' - run: ct install --target-branch ${{ github.event.repository.default_branch }} \ No newline at end of file + run: ct install --config .ct.yaml --target-branch ${{ github.event.repository.default_branch }} --helm-extra-set-args "--timeout 10m" diff --git a/chart/ci/values.yaml b/chart/ci/values.yaml index 88d070e..7f8bcb6 100644 --- a/chart/ci/values.yaml +++ b/chart/ci/values.yaml @@ -1,10 +1,36 @@ -postgresql: - config: - dbName: automatisch - auth: - password: admin +persistence: + enabled: false + volumeSize: 1Gi +replicaCount: 1 app: credentials: ENCRYPTION_KEY: "123" WEBHOOK_SECRET_KEY: "123" - APP_SECRET_KEY: "123" \ No newline at end of file + APP_SECRET_KEY: "123" +postgresql: + persistence: + enabled: false + auth: + dbName: automatisch + password: admin + postgresPassword: admin + primary: + livenessProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + # on setup only! + failureThreshold: 30 + successThreshold: 1 + readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + # on setup only! + failureThreshold: 20 + successThreshold: 1 +redis: + persistence: + enabled: false \ No newline at end of file diff --git a/chart/templates/deployment-app.yaml b/chart/templates/deployment-app.yaml index 7df264f..528df9f 100644 --- a/chart/templates/deployment-app.yaml +++ b/chart/templates/deployment-app.yaml @@ -49,9 +49,7 @@ spec: - name: PORT value: "3000" - name: HOST - valueFrom: - fieldRef: - fieldPath: status.podIP + value: "localhost" {{- include "ah.envValues" . | nindent 12 }} ports: - name: ah-tcp @@ -101,9 +99,14 @@ spec: - mountPath: "/automatisch/logs" name: logs volumes: + {{- if .Values.persistence.enabled }} - name: storage persistentVolumeClaim: claimName: {{ include "ah.fullname" . }} + {{- else }} + - name: storage + emptyDir: {} + {{- end }} - name: cache emptyDir: sizeLimit: 100Mi diff --git a/chart/templates/deployment-redis.yaml b/chart/templates/deployment-redis.yaml index ca5a238..4f00d32 100644 --- a/chart/templates/deployment-redis.yaml +++ b/chart/templates/deployment-redis.yaml @@ -52,9 +52,14 @@ spec: - mountPath: "/data" name: storage volumes: + {{- if .Values.redis.persistence.enabled }} - name: storage persistentVolumeClaim: claimName: {{ include "ah.fullname" . }}-redis + {{- else }} + - name: storage + emptyDir: {} + {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/chart/templates/pvc-postgres.yaml b/chart/templates/pvc-postgres.yaml index adfad4b..0b7801d 100644 --- a/chart/templates/pvc-postgres.yaml +++ b/chart/templates/pvc-postgres.yaml @@ -1,4 +1,4 @@ -{{- if .Values.postgresql.enabled -}} +{{- if and .Values.postgresql.enabled .Values.postgresql.persistence.enabled -}} apiVersion: v1 kind: PersistentVolumeClaim metadata: diff --git a/chart/templates/pvc-redis.yaml b/chart/templates/pvc-redis.yaml index 3842418..edcb19e 100644 --- a/chart/templates/pvc-redis.yaml +++ b/chart/templates/pvc-redis.yaml @@ -1,4 +1,4 @@ -{{- if .Values.redis.enabled -}} +{{- if and .Values.redis.enabled .Values.redis.persistence.enabled -}} apiVersion: v1 kind: PersistentVolumeClaim metadata: diff --git a/chart/templates/pvc.yaml b/chart/templates/pvc.yaml index cd13481..aa5ed58 100644 --- a/chart/templates/pvc.yaml +++ b/chart/templates/pvc.yaml @@ -1,3 +1,4 @@ +{{- if .Values.persistence.enabled -}} apiVersion: v1 kind: PersistentVolumeClaim metadata: @@ -12,4 +13,5 @@ spec: - {{ .Values.global.accessMode }} resources: requests: - storage: {{ .Values.persistence.volumeSize }} \ No newline at end of file + storage: {{ .Values.persistence.volumeSize }} + {{- end }} \ No newline at end of file diff --git a/chart/templates/secret-app.yaml b/chart/templates/secret-app.yaml index e8218db..5337b8f 100644 --- a/chart/templates/secret-app.yaml +++ b/chart/templates/secret-app.yaml @@ -9,6 +9,6 @@ stringData: {{ include "ah.camelcase" $k }}: {{ $v | quote }} {{- end }} dbHost: "{{ include "ah.fullname" . }}-postgresql" - dbName: "{{ .Values.postgresql.config.dbName }}" + dbName: "{{ .Values.postgresql.auth.database }}" dbUser: "{{ .Values.postgresql.auth.username }}" dbPassword: "{{ .Values.postgresql.auth.password }}" \ No newline at end of file diff --git a/chart/values.yaml b/chart/values.yaml index 756a0d3..77d0613 100644 --- a/chart/values.yaml +++ b/chart/values.yaml @@ -1,10 +1,10 @@ -# Default values for ah. +# Default values for Automatisch chart. # This is a YAML-formatted file. # Declare variables to be passed into your templates. global: - storageClass: + storageClass: "" accessMode: ReadWriteOnce -replicaCount: 1 +replicaCount: 2 # -- Update policy updateStrategy: "RollingUpdate" image: @@ -14,6 +14,7 @@ image: # renovate: datasource=docker depName=automatischio/automatisch tag: "0.12.0" persistence: + enabled: true volumeSize: 3Gi postgresql: enabled: true @@ -41,6 +42,7 @@ postgresql: password: postgresPassword: persistence: + enabled: true volumeSize: 5Gi primary: persistence: @@ -74,6 +76,7 @@ redis: # @ignore, Configure resource limits resources: {} persistence: + enabled: true volumeSize: 3Gi imagePullSecrets: [] diff --git a/k8s.yaml b/k8s.yaml deleted file mode 100644 index 22d3f1c..0000000 --- a/k8s.yaml +++ /dev/null @@ -1,488 +0,0 @@ ---- -# Source: automatisch/templates/serviceaccount.yaml -apiVersion: v1 -kind: ServiceAccount -metadata: - name: release-name-automatisch - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm ---- -# Source: automatisch/templates/secret-app.yaml -apiVersion: v1 -kind: Secret -metadata: - name: release-name-automatisch - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -stringData: - appSecretKey: 4 - encryptionKey: 1 - webhookSecretKey: 2 - dbName: "automatisch" - dbUser: "automatischUser" - dbPassword: "" ---- -# Source: automatisch/templates/pvc-postgres.yaml -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: release-name-automatisch-postgres - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 10Gi ---- -# Source: automatisch/templates/pvc-redis.yaml -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: release-name-automatisch-redis - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 5Gi ---- -# Source: automatisch/templates/pvc.yaml -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: release-name-automatisch - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 10Gi ---- -# Source: automatisch/templates/service-app.yaml -apiVersion: v1 -kind: Service -metadata: - name: release-name-automatisch - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -spec: - type: ClusterIP - ports: - - port: 3000 - targetPort: ah-tcp - protocol: TCP - name: app - selector: - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name ---- -# Source: automatisch/templates/service-postgres.yaml -apiVersion: v1 -kind: Service -metadata: - name: release-name-automatisch-postgres - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -spec: - type: ClusterIP - ports: - - port: 5432 - targetPort: postgres-tcp - protocol: TCP - name: postgres - selector: - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name ---- -# Source: automatisch/templates/service-redis.yaml -apiVersion: v1 -kind: Service -metadata: - name: release-name-automatisch-redis - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -spec: - type: ClusterIP - ports: - - port: 6379 - targetPort: redis-tcp - protocol: TCP - name: redis - selector: - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name ---- -# Source: automatisch/templates/deployment-app.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: release-name-automatisch - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name - template: - metadata: - labels: - app.kubernetes.io/name: automatisch - app.kubernetes.io/instance: release-name - spec: - serviceAccountName: release-name-automatisch - securityContext: - fsGroup: 2000 - runAsNonRoot: true - runAsUser: 1000 - containers: - - name: main - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - image: "automatischio/automatisch:0.9.3" - imagePullPolicy: IfNotPresent - env: - - name: PORT=3000 - - name: HOST=localhost - - - - name: "APP_ENV" - value: "production" - - name: "LOG_LEVEL" - value: "info" - - name: "PROTOCOL" - value: "http" - - name: APP_SECRET_KEY - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: "$v" - - name: ENCRYPTION_KEY - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: "$v" - - name: WEBHOOK_SECRET_KEY - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: "$v" - - name: REDIS_HOST - value: "release-name-automatisch-redis" - - name: POSTGRES_HOST - value: "release-name-automatisch-postgres" - - name: POSTGRES_DATABASE - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: dbName - - name: POSTGRES_USERNAME - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: dbUser - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: dbPassword - ports: - - name: ah-tcp - containerPort: 3000 - protocol: TCP - livenessProbe: - httpGet: - path: / - port: 3000 - initialDelaySeconds: 5 - readinessProbe: - httpGet: - path: / - port: 3000 - initialDelaySeconds: 15 - resources: - limits: - cpu: 200m - memory: 256Mi - requests: - cpu: 100m - memory: 128Mi - volumeMounts: - - mountPath: "/automatisch/storage" - name: storage - - name: worker - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - image: "automatischio/automatisch:0.9.3" - imagePullPolicy: IfNotPresent - env: - - name: WORKER - value: true - - - - name: "APP_ENV" - value: "production" - - name: "LOG_LEVEL" - value: "info" - - name: "PROTOCOL" - value: "http" - - name: APP_SECRET_KEY - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: "$v" - - name: ENCRYPTION_KEY - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: "$v" - - name: WEBHOOK_SECRET_KEY - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: "$v" - - name: REDIS_HOST - value: "release-name-automatisch-redis" - - name: POSTGRES_HOST - value: "release-name-automatisch-postgres" - - name: POSTGRES_DATABASE - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: dbName - - name: POSTGRES_USERNAME - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: dbUser - - name: POSTGRES_PASSWORD - valueFrom: - secretKeyRef: - name: "release-name-automatisch" - key: dbPassword - resources: - limits: - cpu: 200m - memory: 256Mi - requests: - cpu: 100m - memory: 128Mi - volumeMounts: - - mountPath: "/automatisch/storage" - name: storage - volumes: - - name: storage - persistentVolumeClaim: - claimName: release-name-automatisch ---- -# Source: automatisch/templates/deployment-postgres.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: release-name-automatisch-postgres - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name - template: - metadata: - labels: - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name - spec: - serviceAccountName: release-name-automatisch - securityContext: - fsGroup: 2000 - runAsNonRoot: true - runAsUser: 1000 - containers: - - name: automatisch - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - image: "postgres:14.5" - imagePullPolicy: IfNotPresent - env: - - name: POSTGRES_DB - value: automatisch - - name: POSTGRES_USER - value: automatischUser - - name: POSTGRES_PASSWORD - value: - ports: - - name: postgres-tcp - containerPort: 5432 - protocol: TCP - livenessProbe: - tcpSocket: - port: 5432 - initialDelaySeconds: 15 - readinessProbe: - exec: - command: - - CMD-SHELL - - pg_isready - - -U - - ${POSTGRES_USER} - - -d - - ${POSTGRES_DB} - initialDelaySeconds: 5 - resources: - limits: - cpu: 200m - memory: 256Mi - requests: - cpu: 100m - memory: 128Mi - volumeMounts: - - mountPath: "/var/lib/postgresql/data" - name: storage - volumes: - - name: storage - persistentVolumeClaim: - claimName: release-name-automatisch-postgres ---- -# Source: automatisch/templates/deployment-redis.yaml -apiVersion: apps/v1 -kind: Deployment -metadata: - name: release-name-automatisch-redis - labels: - helm.sh/chart: automatisch-0.2.0 - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name - app.kubernetes.io/version: "0.9.3" - app.kubernetes.io/managed-by: Helm -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name - template: - metadata: - labels: - app.kubernetes.io/name: automatisch-redis - app.kubernetes.io/instance: release-name - spec: - serviceAccountName: release-name-automatisch - securityContext: - fsGroup: 2000 - runAsNonRoot: true - runAsUser: 1000 - containers: - - name: automatisch - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - image: "redis:7.2.2" - imagePullPolicy: IfNotPresent - ports: - - name: redis-tcp - containerPort: 6379 - protocol: TCP - livenessProbe: - tcpSocket: - port: 6379 - initialDelaySeconds: 15 - readinessProbe: - exec: - command: - - redis-cli - - ping - initialDelaySeconds: 5 - resources: - limits: - cpu: 200m - memory: 256Mi - requests: - cpu: 100m - memory: 128Mi - volumeMounts: - - mountPath: "/data" - name: storage - volumes: - - name: storage - persistentVolumeClaim: - claimName: release-name-automatisch-redis diff --git a/test/integration/kind-cluster.yaml b/test/integration/kind-cluster.yaml new file mode 100644 index 0000000..f9314bf --- /dev/null +++ b/test/integration/kind-cluster.yaml @@ -0,0 +1,20 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + kubeadmConfigPatches: + - | + kind: InitConfiguration + nodeRegistration: + kubeletExtraArgs: + node-labels: "ingress-ready=true" + extraPortMappings: + - containerPort: 80 + hostPort: 80 + protocol: TCP + - containerPort: 443 + hostPort: 443 + protocol: TCP + - containerPort: 30003 + hostPort: 30003 + protocol: TCP