From 0ca36b0c2d55ca8f62e767b90f56b184b17c17d2 Mon Sep 17 00:00:00 2001
From: Stefan Nica <snica@suse.com>
Date: Tue, 6 Oct 2020 23:45:30 +0200
Subject: [PATCH] Add integration tests to the helm chart

Adds the ability to run helm integration tests using `helm test`.
---
 templates/_helpers.tpl      | 39 +++++++++++++++++
 templates/tests/api.yaml    | 86 +++++++++++++++++++++++++++++++++++++
 templates/tests/secret.yaml | 11 +++++
 values.yaml                 | 35 +++++++++++++++
 4 files changed, 171 insertions(+)
 create mode 100644 templates/tests/api.yaml
 create mode 100644 templates/tests/secret.yaml

diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl
index 3a49107..0d49fc8 100644
--- a/templates/_helpers.tpl
+++ b/templates/_helpers.tpl
@@ -581,3 +581,42 @@ postgres://{{ template "harbor.database.username" . }}:{{ template "harbor.datab
     {{- include "harbor.nginx" . -}}
   {{- end -}}
 {{- end -}}
+
+{{- define "harbor.test" -}}
+  {{- printf "%s-test" (include "harbor.fullname" .) -}}
+{{- end -}}
+
+{{- define "harbor.tests.api.abortOnFailure" -}}
+  {{- if .Values.tests.api.abortOnFailure -}}
+    {{- printf "-X" }}
+  {{- end -}}
+{{- end -}}
+
+{{- define "harbor.tests.api.include" -}}
+  {{- if .Values.tests.api.include -}}
+    {{- printf "-i %s" (.Values.tests.api.include | join " -i ") }}
+  {{- end -}}
+{{- end -}}
+
+# Build exclude list accordingly to enabled services
+{{- define "harbor.tests.api.exclude" -}}
+  {{- $el := .Values.tests.api.exclude -}}
+  {{- if not .Values.chartmuseum.enabled -}}
+    {{- $el = append $el "list_helm_charts" -}}
+  {{- end -}}
+  {{- if not .Values.notary.enabled -}}
+    {{- $el = append $el "sign_image" -}}
+  {{- end -}}
+  {{- if not .Values.trivy.enabled -}}
+    {{- $el = append $el "push_index" -}}
+    {{- $el = append $el "scan" -}}
+    {{- $el = append $el "scan_all" -}}
+  {{- end -}}
+  {{- if $el -}}
+    {{- printf "-e %s" ($el | join " -e ") }}
+  {{- end -}}
+{{- end -}}
+
+{{- define "harbor.tests.api.options" -}}
+  {{- printf "%s %s %s" (include "harbor.tests.api.include" .) (include "harbor.tests.api.exclude" .) (include "harbor.tests.api.abortOnFailure" .) }}
+{{- end -}}
diff --git a/templates/tests/api.yaml b/templates/tests/api.yaml
new file mode 100644
index 0000000..f76e0db
--- /dev/null
+++ b/templates/tests/api.yaml
@@ -0,0 +1,86 @@
+{{- if .Values.tests.api.enabled }}
+apiVersion: v1
+kind: Pod
+metadata:
+  name: "{{ template "harbor.test" . }}-api"
+  labels:
+{{ include "harbor.labels" . | indent 4 }}
+    component: tests-api
+  annotations:
+    {{- if .Values.tests.api.podAnnotations }}
+      {{ toYaml .Values.tests.api.podAnnotations | indent 4 }}
+    {{- end }}
+    helm.sh/hook: test-success
+spec:
+  {{- with .Values.imagePullSecrets }}
+  imagePullSecrets:
+    {{- toYaml . | nindent 4 }}
+  {{- end }}
+  containers:
+    - name: api-tests
+      image: {{ .Values.tests.api.image.repository }}:{{ .Values.tests.api.image.tag }}
+      imagePullPolicy: {{ .Values.imagePullPolicy }}
+      env:
+        - name: HARBOR_IP
+          value: {{ .Values.externalURL | replace "https://" "" }}
+        - name: HARBOR_PASSWORD
+          valueFrom:
+            secretKeyRef:
+              name: {{ template "harbor.core" . }}
+              key: HARBOR_ADMIN_PASSWORD
+        {{- if and .Values.notary.enabled (eq .Values.expose.type "ingress") }}
+        - name: NOTARY_URL
+          value: https://{{ .Values.expose.ingress.hosts.notary }}
+        {{- end }}
+        - name: ROBOT_OPTIONS
+          value: "{{ template "harbor.tests.api.options" . }}"
+        {{- if and .Values.tests.dockerCredentials.username .Values.tests.dockerCredentials.password }}
+        - name: DOCKER_USER
+          value: {{ .Values.tests.dockerCredentials.username }}
+        - name: DOCKER_PWD
+          valueFrom:
+            secretKeyRef:
+              name: {{ template "harbor.test" . }}
+              key: .docker-password
+        {{- end }}
+        {{- if .Values.tests.imagesPullRepository }}
+        - name: HARBOR_TEST_IMAGES_REPOSITORY
+          value: {{ .Values.tests.imagesPullRepository }}
+        {{- end }}
+      volumeMounts:
+        {{- if .Values.expose.tls.enabled }}
+        - name: ca-download
+          mountPath: /usr/share/pki/trust/anchors/harbor-ca.crt
+          subPath: ca.crt
+          readOnly: true
+        {{- end }}
+        {{- if .Values.caBundleSecretName }}
+        - name: ca-bundle-certs
+          mountPath: /usr/share/pki/trust/anchors/custom-ca.crt
+          subPath: ca.crt
+          readOnly: true
+        {{- end }}
+      securityContext:
+        privileged: true
+        allowPrivilegeEscalation: true
+{{- if .Values.tests.api.resources }}
+      resources:
+{{ toYaml .Values.tests.api.resources | indent 8 }}
+{{- end }}
+  volumes:
+    {{- if .Values.expose.tls.enabled }}
+    - name: ca-download
+      secret:
+      {{- if .Values.caSecretName }}
+        secretName: {{ .Values.caSecretName }}
+      {{- else if eq (include "harbor.autoGenCertForIngress" .) "true" }}
+        secretName: "{{ template "harbor.ingress" . }}"
+      {{- else if eq (include "harbor.autoGenCertForNginx" .) "true" }}
+        secretName: {{ template "harbor.tlsSecretForNginx" . }}
+      {{- end }}
+    {{- end }}
+    {{- if .Values.caBundleSecretName }}
+{{ include "harbor.caBundleVolume" . | indent 4 }}
+    {{- end }}
+  restartPolicy: Never
+{{- end }}
diff --git a/templates/tests/secret.yaml b/templates/tests/secret.yaml
new file mode 100644
index 0000000..4bdb406
--- /dev/null
+++ b/templates/tests/secret.yaml
@@ -0,0 +1,11 @@
+{{- if and .Values.tests.api.enabled .Values.tests.dockerCredentials.password }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: "{{ template "harbor.test" . }}"
+  labels:
+{{ include "harbor.labels" . | indent 4 }}
+type: Opaque
+data:
+  .docker-password: {{ .Values.tests.dockerCredentials.password | b64enc | quote }}
+{{- end }}
diff --git a/values.yaml b/values.yaml
index ca20145..abb0282 100644
--- a/values.yaml
+++ b/values.yaml
@@ -741,3 +741,38 @@ redis:
     password: ""
   ## Additional deployment annotations
   podAnnotations: {}
+
+
+# Tests that can be executed by using helm test
+tests:
+  # Credentials to be used to authenticate on the DockerHub repository.
+  # All interations from the tests to DockerHub will be made using that account.
+  # For password it is recommended to use an 'Access Token'.
+  dockerCredentials:
+    username: ""
+    password: ""
+  # Repository from where to pull the images used for the tests.
+  # By default the images are pulled from DockerHub
+  imagesPullRepository: ""
+  api:
+    # Enable/disable API tests
+    enabled: true
+    # Stops test execution if any test fails
+    abortOnFailure: false
+    # Select test cases to run by tag
+    include: []
+    # Select test cases not to run by tag. These tests are not run
+    # even if included on the include list.
+    # Note: Some tests are automatically skipped according to the
+    # harbor enabled services/features.
+    exclude:
+      - singularity # CLI not yet included in the harbor-test-image
+    image:
+      repository: registry.suse.com/harbor/harbor-test
+      tag: 2.1.2
+    # resources:
+    #  requests:
+    #    memory: 128Mi
+    #    cpu: 100m
+    podAnnotations: {}
+
-- 
2.24.3 (Apple Git-128)

