diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..1230149 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..e784b56 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,27 @@ +name: Release Charts + +on: + push: + branches: + - main + +jobs: + release: + permissions: + contents: write + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.6.0 + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..4108ff1 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,59 @@ +name: CI Build Test + +on: + pull_request: + branches-ignore: + - gh-pages + +jobs: + lint-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v1 + with: + version: v4.2.0 + + - uses: actions/setup-python@v5.2.0 + with: + python-version: '3.x' + check-latest: true + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.6.1 + + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed --target-branch ${{ github.event.repository.default_branch }}) + if [[ -n "$changed" ]]; then + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Linting charts + run: helm lint charts/* + + - name: Run chart-testing (lint) + if: steps.list-changed.outputs.changed == 'true' + run: ct lint --config=ct.yaml --target-branch ${{ github.event.repository.default_branch }} + + - name: Run helm unit tests + run: | + helm plugin install https://github.com/helm-unittest/helm-unittest + make unittest + + # - name: Create kind cluster + # uses: helm/kind-action@v1.10.0 + # # Only build a kind cluster if there are chart changes to test. + # if: steps.list-changed.outputs.changed == 'true' + + # - name: Run chart-testing (install) + # run: ct install --config=ct.yaml + + + # e2e-test: [] diff --git a/.gitignore b/.gitignore index 493e69b..15bce43 100644 --- a/.gitignore +++ b/.gitignore @@ -11,8 +11,13 @@ _site/ /vendor # Specific ignore for GitHub Pages -# GitHub Pages will always use its own deployed version of pages-gem +# GitHub Pages will always use its own deployed version of pages-gem # This means GitHub Pages will NOT use your Gemfile.lock and therefore it is # counterproductive to check this file into the repository. # Details at https://github.com/github/pages-gem/issues/768 Gemfile.lock + +*.tgz +/.idea/* +.vscode +.DS_Store diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..6655399 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,19 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: trailing-whitespace + exclude: "^examples|^test" + - id: end-of-file-fixer + exclude: "^examples|^test" + - id: check-yaml + # Can't check source yaml since it has go templates in it. + exclude: ^charts/.*/templates/ + args: [ --allow-multiple-documents ] + - id: check-added-large-files + - repo: https://github.com/gruntwork-io/pre-commit + rev: v0.1.23 + hooks: + - id: helmlint diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e798a17 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +##@ General +# The general settings and variables for the project +SHELL := /bin/bash + +# TODO: Move CHART_FILE_PATH and VALUES_FILE_PATH here, currently set in multiple places +# The version of the chart +VERSION := $(shell grep "^version:" charts/splunk-synthetics-runner/Chart.yaml | awk '{print $$2}') + +##@ Test +# Tasks related to testing the Helm chart + +.PHONY: lint +lint: ## Lint the Helm chart with ct + @echo "Linting Helm chart..." + ct lint --config=ct.yaml || exit 1 + +.PHONY: pre-commit +pre-commit: render ## Test the Helm chart with pre-commit + @echo "Checking the Helm chart with pre-commit..." + pre-commit run --all-files || exit 1 + +.PHONY: unittest +unittest: ## Run unittests on the Helm chart + @echo "Running unit tests on helm chart..." + cd charts/splunk-synthetics-runner && helm unittest --strict -f "../../tests/unittests/*.yaml" . || exit 1 + +.PHONY: docs +docs: ## Run unittests on the Helm chart + @echo "Update docs for helm chart..." + cd charts/splunk-synthetics-runner && helm-docs || exit 1 diff --git a/charts/splunk-synthetics-runner/.helmignore b/charts/splunk-synthetics-runner/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/splunk-synthetics-runner/.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/splunk-synthetics-runner/Chart.yaml b/charts/splunk-synthetics-runner/Chart.yaml new file mode 100644 index 0000000..0cf8ec3 --- /dev/null +++ b/charts/splunk-synthetics-runner/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: splunk-synthetics-runner +description: Private location runners for Splunk Synthetic Monitoring +type: application +version: 0.0.1 +appVersion: "0.16.7" diff --git a/charts/splunk-synthetics-runner/README.md b/charts/splunk-synthetics-runner/README.md new file mode 100644 index 0000000..118f90a --- /dev/null +++ b/charts/splunk-synthetics-runner/README.md @@ -0,0 +1,69 @@ +## Splunk Synthetic Monitoring - Kubernetes Private Locations + +![Version: 0.0.1](https://img.shields.io/badge/Version-0.0.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.16.7](https://img.shields.io/badge/AppVersion-0.16.7-informational?style=flat-square) + +Helm chart to deploy [private location runners](https://docs.splunk.com/observability/en/synthetics/test-config/private-locations.html) for [Splunk Synthetic Monitoring](https://www.splunk.com/en_us/products/synthetic-monitoring.html). + +### Installing the Chart + +To install the chart with the release name `my-splunk-synthetics-runner`: + +```console +$ helm repo add http://tbd.splunk.github.io +$ helm install my-splunk-synthetics-runner foo-bar/splunk-synthetics-runner +``` + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | Inter-pod and node affinity/anti-affinity rules. | +| automountServiceAccountToken | bool | `true` | Indicates whether a service account token should be automatically mounted to the runner pod. | +| autoscaling | object | `{"enabled":false,"maxReplicas":6,"minReplicas":1,"targetCPUUtilizationPercentage":95,"targetMemoryUtilizationPercentage":95}` | Configuration for HPA | +| autoscaling.enabled | bool | `false` | Enable HPA | +| autoscaling.maxReplicas | int | `6` | Maximum replicas of runner | +| autoscaling.minReplicas | int | `1` | Minimum replicas of runner | +| autoscaling.targetCPUUtilizationPercentage | int | `95` | Target CPU utilization | +| autoscaling.targetMemoryUtilizationPercentage | int | `95` | Target Memory utilization | +| commonLabels | object | `{}` | Additional labels which will be included on all objects and as selectors. | +| containerSecurityContext | object | `{}` | Container security context for runner container. | +| dnsConfig | object | `{}` | Specify additional DNS parameters for the runner pods. | +| dnsPolicy | string | `"ClusterFirst"` | DNS Policy to set for the runner pods. Valid values are ClusterFirst, ClusterFirstWithHostNet, Default, None | +| env | object | `{}` | Additional environment variables as map. | +| fullnameOverride | string | `""` | Overrides fully qualified app name | +| hostAliases | list | `[]` | List of hosts/IPs to be injected into the pod's hosts file. | +| image | object | `{"pullPolicy":"IfNotPresent","repository":"quay.io/signalfx/splunk-synthetics-runner","tag":""}` | Configuration for container image for Splunk synthetics runner | +| image.tag | string | `""` | Override the image tag; default is the chart appVersion. | +| imagePullSecrets | list | `[]` | ImagePullSecrets to use for pulling the images in use. | +| livenessProbe.enabled | bool | `true` | Enable liveness probe | +| livenessProbe.failureThreshold | int | `3` | | +| livenessProbe.initialDelaySeconds | int | `60` | | +| livenessProbe.periodSeconds | int | `300` | | +| livenessProbe.successThreshold | int | `1` | | +| livenessProbe.timeoutSeconds | int | `10` | | +| nameOverride | string | `""` | Overrides app name | +| nodeSelector | object | `{}` | Selector for the runner pods to fit on a node. | +| podAnnotations | object | `{}` | Additional annotations for runner pods. | +| podDisruptionBudget | object | `{"enabled":true,"minAvailable":1}` | Pod distruption budget | +| podLabels | object | `{}` | Additional labels for runner pods. | +| podSecurityContext | object | `{}` | Pod security context for runner pods. | +| priorityClassName | string | `""` | Priority class for runner pods | +| replicaCount | int | `1` | Count of runner pods. | +| resources | object | `{"limits":{"cpu":2,"memory":"8G"},"requests":{"cpu":2,"memory":"8G"}}` | Resources for runner container. | +| serviceAccount | object | `{"annotations":{},"create":true,"name":""}` | ServiceAccount config. Note that the runner pod does not need access to k8s api for its operation. | +| serviceAccount.annotations | object | `{}` | Annotations to add to service account | +| serviceAccount.create | bool | `true` | If true, service account will be created. | +| serviceAccount.name | string | `""` | The name of the service account to use. If not set, the release's fullname will be used when create is true. Set this variable to add user created service account to pod. | +| synthetics | object | `{"additionalCaCerts":{},"enableNetworkShaping":true,"logLevel":"info","secret":{"create":false,"name":"","runnerToken":""}}` | Splunk Synthetics Runner configurations | +| synthetics.additionalCaCerts | object | `{}` | Add custom CA certs to use in API/HTTP tests. Requires privilege escalation. | +| synthetics.enableNetworkShaping | bool | `true` | Enable netwrok shapping capabilities which allows runner to simulate different device's throughputs. Needs privilege escalation and CAP_NET_ADMIN. | +| synthetics.logLevel | string | `"info"` | logLevel is to set log level of the Splunk Synthetics runner. Available values are: debug, info, warn, error | +| synthetics.secret | object | `{"create":false,"name":"","runnerToken":""}` | Private location token configuration. Rotating the runner token requires an explicit rollout/restart of the deployment. | +| synthetics.secret.create | bool | `false` | Option for creating a new secret or using an existing one. When true, a new kubernetes secret will be created by the chart that will contain value from runnerToken. When false, the user must set secret.name to the name of the k8s secret the user created with the runner's token. | +| synthetics.secret.name | string | `""` | The name of the secret created by chart (if name is empty the default name is used) or the name of a secret that the user created. If secret is created outside of the helm chart, make sure the key for token is 'runner_token' in the secret. The chart references this key when passing token as env variable. | +| synthetics.secret.runnerToken | string | `""` | Used when sythentics.secret.create=true. The runner's token available in Splunk Observability when Private Location was created. | +| terminationGracePeriodSeconds | int | `10` | Duration in seconds the pod needs to terminate gracefully. | +| tolerations | list | `[]` | Tolerations to attach to runner pods for node taints. | +| updateStrategy | object | `{}` | Configure update strategy for runner pods. | +| volumeMounts | list | `[]` | Additional volumeMounts to add to the runner deployment. | +| volumes | list | `[]` | Additional volumes to add to runner deployment. | diff --git a/charts/splunk-synthetics-runner/README.md.gotmpl b/charts/splunk-synthetics-runner/README.md.gotmpl new file mode 100644 index 0000000..4029986 --- /dev/null +++ b/charts/splunk-synthetics-runner/README.md.gotmpl @@ -0,0 +1,18 @@ +## Splunk Synthetic Monitoring - Kubernetes Private Locations + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +Helm chart to deploy [private location runners](https://docs.splunk.com/observability/en/synthetics/test-config/private-locations.html) for [Splunk Synthetic Monitoring](https://www.splunk.com/en_us/products/synthetic-monitoring.html). + +### Installing the Chart + +To install the chart with the release name `my-splunk-synthetics-runner`: + +```console +$ helm repo add http://tbd.splunk.github.io +$ helm install my-splunk-synthetics-runner foo-bar/{{ template "chart.name" . }} +``` + +{{ template "chart.requirementsSection" . }} + +{{ template "chart.valuesSection" . }} diff --git a/charts/splunk-synthetics-runner/templates/NOTES.txt b/charts/splunk-synthetics-runner/templates/NOTES.txt new file mode 100644 index 0000000..87f9be8 --- /dev/null +++ b/charts/splunk-synthetics-runner/templates/NOTES.txt @@ -0,0 +1,7 @@ +Check the status of Splunk Synthetic Private Location deployment by running this comamnd: + +kubectl get deployments --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "splunk-synthetics-runner.fullname" . }},app.kubernetes.io/instance={{ .Release.Name }}" + +List the Runner Pods with the following command: + +kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "splunk-synthetics-runner.fullname" . }},app.kubernetes.io/instance={{ .Release.Name }}" diff --git a/charts/splunk-synthetics-runner/templates/_helpers.tpl b/charts/splunk-synthetics-runner/templates/_helpers.tpl new file mode 100644 index 0000000..fd152ca --- /dev/null +++ b/charts/splunk-synthetics-runner/templates/_helpers.tpl @@ -0,0 +1,107 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "splunk-synthetics-runner.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 "splunk-synthetics-runner.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "splunk-synthetics-runner.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "splunk-synthetics-runner.labels" -}} +helm.sh/chart: {{ include "splunk-synthetics-runner.chart" . }} +{{ include "splunk-synthetics-runner.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "splunk-synthetics-runner.selectorLabels" -}} +app.kubernetes.io/name: {{ include "splunk-synthetics-runner.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- if .Values.commonLabels }} +{{ toYaml .Values.commonLabels }} +{{- end }} +{{- end }} + +{{/* +Pod labels +*/}} +{{- define "splunk-synthetics-runner.podLabels" -}} +{{- $commonLabels := include "splunk-synthetics-runner.labels" . | fromYaml -}} +{{- $podLabels := mustMerge .Values.podLabels $commonLabels -}} +{{ toYaml $podLabels }} +{{- end -}} + +{{/* +Define name for the runner token secret +*/}} +{{- define "splunk-synthetics-runner.secretName" -}} +{{- default (include "splunk-synthetics-runner.fullname" .) .Values.synthetics.secret.name }} +{{- end -}} + +{{/* +Define name for the runner service account +*/}} +{{- define "splunk-synthetics-runner.serviceAccountName" -}} +{{- default (include "splunk-synthetics-runner.fullname" .) .Values.serviceAccount.name }} +{{- end -}} + +{{/* +Render security context +*/}} +{{- define "splunk-synthetics-runner.containerSecurityContext" -}} +{{- $secContext := .Values.containerSecurityContext -}} +{{- $netadminCap := dict "allowPrivilegeEscalation" true "capabilities" (dict "add" (list "NET_ADMIN")) -}} +{{- if and .Values.synthetics.enableNetworkShaping (not $secContext) -}} + {{/* if no custom security context provided but n/w shaping is enabled, add CAP_NET_ADMIN */}} + {{- $secContext = $netadminCap }} +{{- else if and $secContext .Values.synthetics.enableNetworkShaping -}} +{{/* if custom securityContext exists and net shaping is enabled, we try to merge the two for final context */}} + {{- if (((.Values.containerSecurityContext).capabilities).add) -}} + {{/* custom secContext has capabilities.add, we append NET_ADMIN */}} + {{- $_ := set $secContext.capabilities "add" (mustAppend .Values.containerSecurityContext.capabilities.add "NET_ADMIN" | uniq) -}} + {{- else -}} + {{- $secContext = mustMerge $netadminCap .Values.containerSecurityContext -}} + {{- end -}} +{{- end -}} +{{ toYaml $secContext }} +{{- end -}} + +{{/* +Render names compliant with DNS label standard as defined in RFC 1123 +*/}} +{{- define "cleanupNames" -}} + {{- $name := regexReplaceAll "\\W+" . "-" | lower -}} + {{- $name = regexReplaceAll "^-+|-+$" $name "" | trunc 63 | trimSuffix "-" -}} + {{- $name -}} +{{- end -}} diff --git a/charts/splunk-synthetics-runner/templates/configmap-ca.yaml b/charts/splunk-synthetics-runner/templates/configmap-ca.yaml new file mode 100644 index 0000000..7e71dd7 --- /dev/null +++ b/charts/splunk-synthetics-runner/templates/configmap-ca.yaml @@ -0,0 +1,10 @@ +{{- if .Values.synthetics.additionalCaCerts }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "splunk-synthetics-runner.fullname" . }} + labels: + {{- include "splunk-synthetics-runner.labels" . | nindent 4 }} +data: + {{- .Values.synthetics.additionalCaCerts | toYaml | nindent 2 }} +{{- end }} diff --git a/charts/splunk-synthetics-runner/templates/deployment.yaml b/charts/splunk-synthetics-runner/templates/deployment.yaml new file mode 100644 index 0000000..b5bb579 --- /dev/null +++ b/charts/splunk-synthetics-runner/templates/deployment.yaml @@ -0,0 +1,134 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "splunk-synthetics-runner.fullname" . }} + labels: + {{- include "splunk-synthetics-runner.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + {{- if .Values.updateStrategy }} + strategy: + {{- toYaml .Values.updateStrategy | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "splunk-synthetics-runner.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "splunk-synthetics-runner.podLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "splunk-synthetics-runner.serviceAccountName" . }} + {{- if .Values.automountServiceAccountToken }} + automountServiceAccountToken: {{ .Values.automountServiceAccountToken }} + {{- end }} + {{- if .Values.dnsPolicy }} + dnsPolicy: {{ .Values.dnsPolicy }} + {{- end }} + {{- with .Values.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- with .Values.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- if .Values.synthetics.additionalCaCerts }} + command: ["/usr/bin/sh", "-c", "--"] + args: ["sudo update-ca-certificates; exec /usr/bin/tini -s -- bundle exec bin/start_runner"] + {{- end }} + env: + {{- if not .Values.synthetics.enableNetworkShaping }} + - name: DISABLE_NETWORK_SHAPING + value: "true" + {{- end }} + - name: LOG_LEVEL + value: {{ .Values.synthetics.logLevel | upper }} + - name: RUNNER_TOKEN + valueFrom: + secretKeyRef: + name: {{ include "splunk-synthetics-runner.secretName" . }} + key: runner_token + {{- range $key, $value := .Values.env }} + - name: {{ $key }} + value: {{ $value | quote }} + {{- end }} + securityContext: + {{- include "splunk-synthetics-runner.containerSecurityContext" . | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + exec: + command: + - bin/healthcheck + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- if or .Values.synthetics.additionalCaCerts .Values.volumeMounts }} + volumeMounts: + {{- if .Values.synthetics.additionalCaCerts }} + {{- range $cert := keys .Values.synthetics.additionalCaCerts | sortAlpha }} + - name: {{ include "cleanupNames" $cert }} + mountPath: {{ printf "/usr/local/share/ca-certificates/%s" $cert }} + subPath: {{ $cert }} + readOnly: false + {{- end }} + {{- end }} + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds | default 30 }} + {{- if or .Values.synthetics.additionalCaCerts .Values.volumes }} + volumes: + {{- if .Values.synthetics.additionalCaCerts }} + {{- range $cert := keys .Values.synthetics.additionalCaCerts | sortAlpha }} + - name: {{ include "cleanupNames" $cert }} + configMap: + name: {{ include "splunk-synthetics-runner.fullname" $ }} + items: + - key: {{ $cert }} + path: {{ $cert }} + {{- end }} + {{- end }} + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- 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/charts/splunk-synthetics-runner/templates/hpa.yaml b/charts/splunk-synthetics-runner/templates/hpa.yaml new file mode 100644 index 0000000..c361231 --- /dev/null +++ b/charts/splunk-synthetics-runner/templates/hpa.yaml @@ -0,0 +1,32 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "splunk-synthetics-runner.fullname" . }} + labels: + {{- include "splunk-synthetics-runner.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "splunk-synthetics-runner.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/splunk-synthetics-runner/templates/pdb.yaml b/charts/splunk-synthetics-runner/templates/pdb.yaml new file mode 100644 index 0000000..7fd1445 --- /dev/null +++ b/charts/splunk-synthetics-runner/templates/pdb.yaml @@ -0,0 +1,17 @@ +{{- if .Values.podDisruptionBudget.enabled -}} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "splunk-synthetics-runner.fullname" . }} + labels: + {{- include "splunk-synthetics-runner.labels" . | nindent 4 }} +spec: +{{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} +{{- end }} +{{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} +{{- end }} + selector: + matchLabels: {{- include "splunk-synthetics-runner.selectorLabels" . | nindent 6 }} +{{- end -}} diff --git a/charts/splunk-synthetics-runner/templates/secret.yaml b/charts/splunk-synthetics-runner/templates/secret.yaml new file mode 100644 index 0000000..9c00919 --- /dev/null +++ b/charts/splunk-synthetics-runner/templates/secret.yaml @@ -0,0 +1,11 @@ +{{- if .Values.synthetics.secret.create -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "splunk-synthetics-runner.secretName" . }} + labels: + {{- include "splunk-synthetics-runner.labels" . | nindent 4 }} +type: Opaque +data: + runner_token: {{ .Values.synthetics.secret.runnerToken }} +{{- end -}} diff --git a/charts/splunk-synthetics-runner/templates/serviceaccount.yaml b/charts/splunk-synthetics-runner/templates/serviceaccount.yaml new file mode 100644 index 0000000..8c9110c --- /dev/null +++ b/charts/splunk-synthetics-runner/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "splunk-synthetics-runner.serviceAccountName" . }} + labels: + {{- include "splunk-synthetics-runner.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/charts/splunk-synthetics-runner/values.schema.json b/charts/splunk-synthetics-runner/values.schema.json new file mode 100644 index 0000000..d5b5555 --- /dev/null +++ b/charts/splunk-synthetics-runner/values.schema.json @@ -0,0 +1,703 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "http://example.com/example.json", + "type": "object", + "default": {}, + "title": "Root Schema", + "required": [ + "replicaCount", + "image", + "imagePullSecrets", + "nameOverride", + "fullnameOverride", + "commonLabels", + "podAnnotations", + "podLabels", + "podSecurityContext", + "containerSecurityContext", + "updateStrategy", + "synthetics", + "resources", + "livenessProbe", + "automountServiceAccountToken", + "serviceAccount", + "autoscaling", + "terminationGracePeriodSeconds", + "env", + "volumes", + "volumeMounts", + "nodeSelector", + "tolerations", + "affinity", + "priorityClassName", + "dnsPolicy", + "dnsConfig", + "hostAliases", + "podDisruptionBudget" + ], + "properties": { + "replicaCount": { + "type": "integer", + "default": 0, + "title": "The replicaCount Schema", + "examples": [ + 1 + ] + }, + "image": { + "type": "object", + "default": {}, + "title": "The image Schema", + "required": [ + "repository", + "pullPolicy", + "tag" + ], + "properties": { + "repository": { + "type": "string", + "default": "", + "title": "The repository Schema", + "examples": [ + "quay.io/signalfx/splunk-synthetics-runner" + ] + }, + "pullPolicy": { + "type": "string", + "default": "", + "title": "The pullPolicy Schema", + "examples": [ + "IfNotPresent" + ] + }, + "tag": { + "type": "string", + "default": "", + "title": "The tag Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "repository": "quay.io/signalfx/splunk-synthetics-runner", + "pullPolicy": "IfNotPresent", + "tag": "" + }] + }, + "imagePullSecrets": { + "type": "array", + "default": [], + "title": "The imagePullSecrets Schema", + "items": {}, + "examples": [ + [] + ] + }, + "nameOverride": { + "type": "string", + "default": "", + "title": "The nameOverride Schema", + "examples": [ + "" + ] + }, + "fullnameOverride": { + "type": "string", + "default": "", + "title": "The fullnameOverride Schema", + "examples": [ + "" + ] + }, + "commonLabels": { + "type": "object", + "default": {}, + "title": "The commonLabels Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "podAnnotations": { + "type": "object", + "default": {}, + "title": "The podAnnotations Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "podLabels": { + "type": "object", + "default": {}, + "title": "The podLabels Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "podSecurityContext": { + "type": "object", + "default": {}, + "title": "The podSecurityContext Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "containerSecurityContext": { + "type": "object", + "default": {}, + "title": "The containerSecurityContext Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "updateStrategy": { + "type": "object", + "default": {}, + "title": "The updateStrategy Schema", + "required": [], + "properties": {}, + "examples": [{ + "type": "RollingUpdate", + "rollingUpdate": { + "maxSurge": "25%", + "maxUnavailable": "25%" + } + }] + }, + "synthetics": { + "type": "object", + "default": {}, + "title": "The synthetics Schema", + "required": [ + "enableNetworkShaping", + "secret" + ], + "properties": { + "enableNetworkShaping": { + "type": "boolean", + "default": false, + "title": "The enableNetworkShaping Schema", + "examples": [ + true + ] + }, + "logLevel": { + "type": "string", + "default": "", + "title": "The logLevel Schema", + "examples": [ + "info" + ] + }, + "additionalCaCerts": { + "type": "object", + "default": {}, + "title": "The additionalCaCerts Schema", + "examples": [ + {"example.com.cert": "-----BEGIN CERTIFICATE-----\nMIIBIjANBgkqAQ8AMIIBCgKCAQEAwJw..."} + ] + }, + "secret": { + "type": "object", + "default": {}, + "title": "The secret Schema", + "required": [ + "name", + "create", + "runnerToken" + ], + "properties": { + "name": { + "type": "string", + "default": "", + "title": "The name Schema", + "examples": [ + "" + ] + }, + "create": { + "type": "boolean", + "default": false, + "title": "The create Schema", + "examples": [ + false + ] + }, + "runnerToken": { + "type": "string", + "default": "", + "title": "The runnerToken Schema", + "examples": [ + "" + ] + } + }, + "examples": [{ + "name": "", + "create": false, + "runnerToken": "" + }] + } + }, + "examples": [{ + "enableNetworkShaping": true, + "logLevel": "info", + "additionalCaCerts": null, + "secret": { + "name": "", + "create": false, + "runnerToken": "" + } + }] + }, + "resources": { + "type": "object", + "default": {}, + "title": "The resources Schema", + "required": [ + "limits", + "requests" + ], + "properties": { + "limits": { + "type": "object", + "default": {}, + "title": "The limits Schema", + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "type": "integer", + "default": 0, + "title": "The cpu Schema", + "examples": [ + 2 + ] + }, + "memory": { + "type": "string", + "default": "", + "title": "The memory Schema", + "examples": [ + "8G" + ] + } + }, + "examples": [{ + "cpu": 2, + "memory": "8G" + }] + }, + "requests": { + "type": "object", + "default": {}, + "title": "The requests Schema", + "required": [ + "cpu", + "memory" + ], + "properties": { + "cpu": { + "type": "integer", + "default": 0, + "title": "The cpu Schema", + "examples": [ + 2 + ] + }, + "memory": { + "type": "string", + "default": "", + "title": "The memory Schema", + "examples": [ + "8G" + ] + } + }, + "examples": [{ + "cpu": 2, + "memory": "8G" + }] + } + }, + "examples": [{ + "limits": { + "cpu": 2, + "memory": "8G" + }, + "requests": { + "cpu": 2, + "memory": "8G" + } + }] + }, + "livenessProbe": { + "type": "object", + "default": {}, + "title": "The livenessProbe Schema", + "required": [ + "enabled", + "initialDelaySeconds", + "periodSeconds", + "timeoutSeconds", + "successThreshold", + "failureThreshold" + ], + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + true + ] + }, + "initialDelaySeconds": { + "type": "integer", + "default": 0, + "title": "The initialDelaySeconds Schema", + "examples": [ + 60 + ] + }, + "periodSeconds": { + "type": "integer", + "default": 0, + "title": "The periodSeconds Schema", + "examples": [ + 300 + ] + }, + "timeoutSeconds": { + "type": "integer", + "default": 0, + "title": "The timeoutSeconds Schema", + "examples": [ + 10 + ] + }, + "successThreshold": { + "type": "integer", + "default": 0, + "title": "The successThreshold Schema", + "examples": [ + 1 + ] + }, + "failureThreshold": { + "type": "integer", + "default": 0, + "title": "The failureThreshold Schema", + "examples": [ + 3 + ] + } + }, + "examples": [{ + "enabled": true, + "initialDelaySeconds": 60, + "periodSeconds": 300, + "timeoutSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }] + }, + "automountServiceAccountToken": { + "type": "boolean", + "default": false, + "title": "The automountServiceAccountToken Schema", + "examples": [ + true + ] + }, + "serviceAccount": { + "type": "object", + "default": {}, + "title": "The serviceAccount Schema", + "required": [ + "create" + ], + "properties": { + "create": { + "type": "boolean", + "default": false, + "title": "The create Schema", + "examples": [ + true + ] + }, + "name": { + "type": "string", + "default": "", + "title": "The name Schema", + "examples": [ + "" + ] + }, + "annotations": {} + }, + "examples": [{ + "create": true, + "name": "" + }] + }, + "autoscaling": { + "type": "object", + "default": {}, + "title": "The autoscaling Schema", + "required": [ + "enabled", + "minReplicas", + "maxReplicas", + "targetCPUUtilizationPercentage", + "targetMemoryUtilizationPercentage" + ], + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + false + ] + }, + "minReplicas": { + "type": "integer", + "default": 0, + "title": "The minReplicas Schema", + "examples": [ + 1 + ] + }, + "maxReplicas": { + "type": "integer", + "default": 0, + "title": "The maxReplicas Schema", + "examples": [ + 6 + ] + }, + "targetCPUUtilizationPercentage": { + "type": "integer", + "default": 0, + "title": "The targetCPUUtilizationPercentage Schema", + "examples": [ + 95 + ] + }, + "targetMemoryUtilizationPercentage": { + "type": "integer", + "default": 0, + "title": "The targetMemoryUtilizationPercentage Schema", + "examples": [ + 95 + ] + } + }, + "examples": [{ + "enabled": false, + "minReplicas": 1, + "maxReplicas": 6, + "targetCPUUtilizationPercentage": 95, + "targetMemoryUtilizationPercentage": 95 + }] + }, + "terminationGracePeriodSeconds": { + "type": "integer", + "default": 0, + "title": "The terminationGracePeriodSeconds Schema", + "examples": [ + 10 + ] + }, + "env": { + "type": "object", + "default": {}, + "title": "The env Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "volumes": { + "type": "array", + "default": [], + "title": "The volumes Schema", + "items": {}, + "examples": [ + [] + ] + }, + "volumeMounts": { + "type": "array", + "default": [], + "title": "The volumeMounts Schema", + "items": {}, + "examples": [ + [] + ] + }, + "nodeSelector": { + "type": "object", + "default": {}, + "title": "The nodeSelector Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "tolerations": { + "type": "array", + "default": [], + "title": "The tolerations Schema", + "items": {}, + "examples": [ + [] + ] + }, + "affinity": { + "type": "object", + "default": {}, + "title": "The affinity Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "priorityClassName": { + "type": "string", + "default": "", + "title": "The priorityClassName Schema", + "examples": [ + "" + ] + }, + "dnsPolicy": { + "type": "string", + "default": "", + "title": "The dnsPolicy Schema", + "examples": [ + "ClusterFirst" + ] + }, + "dnsConfig": { + "type": "object", + "default": {}, + "title": "The dnsConfig Schema", + "required": [], + "properties": {}, + "examples": [{}] + }, + "hostAliases": { + "type": "array", + "default": [], + "title": "The hostAliases Schema", + "items": {}, + "examples": [ + [] + ] + }, + "podDisruptionBudget": { + "type": "object", + "default": {}, + "title": "The podDisruptionBudget Schema", + "required": [ + "enabled", + "minAvailable" + ], + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "title": "The enabled Schema", + "examples": [ + true + ] + }, + "minAvailable": { + "type": "integer", + "default": 0, + "title": "The minAvailable Schema", + "examples": [ + 1 + ] + } + }, + "examples": [{ + "enabled": true, + "minAvailable": 1 + }] + } + }, + "examples": [{ + "replicaCount": 1, + "image": { + "repository": "quay.io/signalfx/splunk-synthetics-runner", + "pullPolicy": "IfNotPresent", + "tag": "" + }, + "imagePullSecrets": [], + "nameOverride": "", + "fullnameOverride": "", + "commonLabels": {}, + "podAnnotations": {}, + "podLabels": {}, + "podSecurityContext": {}, + "containerSecurityContext": {}, + "updateStrategy": {}, + "synthetics": { + "enableNetworkShaping": true, + "logLevel": "info", + "additionalCaCerts": {}, + "secret": { + "name": "", + "create": false, + "runnerToken": "" + } + }, + "resources": { + "limits": { + "cpu": 2, + "memory": "8G" + }, + "requests": { + "cpu": 2, + "memory": "8G" + } + }, + "livenessProbe": { + "enabled": true, + "initialDelaySeconds": 60, + "periodSeconds": 300, + "timeoutSeconds": 10, + "successThreshold": 1, + "failureThreshold": 3 + }, + "automountServiceAccountToken": true, + "serviceAccount": { + "create": true, + "name": "" + }, + "autoscaling": { + "enabled": false, + "minReplicas": 1, + "maxReplicas": 6, + "targetCPUUtilizationPercentage": 95, + "targetMemoryUtilizationPercentage": 95 + }, + "terminationGracePeriodSeconds": 10, + "env": {}, + "volumes": [], + "volumeMounts": [], + "nodeSelector": {}, + "tolerations": [], + "affinity": {}, + "priorityClassName": "", + "dnsPolicy": "ClusterFirst", + "dnsConfig": {}, + "hostAliases": [], + "podDisruptionBudget": { + "enabled": true, + "minAvailable": 1 + } + }] +} diff --git a/charts/splunk-synthetics-runner/values.yaml b/charts/splunk-synthetics-runner/values.yaml new file mode 100644 index 0000000..83809be --- /dev/null +++ b/charts/splunk-synthetics-runner/values.yaml @@ -0,0 +1,175 @@ +# Default values for splunk-synthetics-runner. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# -- Count of runner pods. +replicaCount: 1 + +# -- Configuration for container image for Splunk synthetics runner +image: + repository: quay.io/signalfx/splunk-synthetics-runner + pullPolicy: IfNotPresent + # -- Override the image tag; default is the chart appVersion. + tag: "" + +# -- ImagePullSecrets to use for pulling the images in use. +imagePullSecrets: [] + +# -- Overrides app name +nameOverride: "" + +# -- Overrides fully qualified app name +fullnameOverride: "" + +# -- Additional labels which will be included on all objects and as selectors. +commonLabels: {} + +# -- Additional annotations for runner pods. +podAnnotations: {} + +# -- Additional labels for runner pods. +podLabels: {} + +# -- Pod security context for runner pods. +podSecurityContext: {} + +# -- Container security context for runner container. +containerSecurityContext: {} + +# -- Configure update strategy for runner pods. +updateStrategy: {} + # type: RollingUpdate + # rollingUpdate: + # maxSurge: 25% + # maxUnavailable: 25% + +# -- Splunk Synthetics Runner configurations +synthetics: + # -- Enable netwrok shapping capabilities which allows runner to simulate + # different device's throughputs. + # Needs privilege escalation and CAP_NET_ADMIN. + enableNetworkShaping: true + + # -- logLevel is to set log level of the Splunk Synthetics runner. + # Available values are: debug, info, warn, error + logLevel: info + + # -- Add custom CA certs to use in API/HTTP tests. Requires privilege escalation. + additionalCaCerts: {} + + # -- Private location token configuration. + # Rotating the runner token requires an explicit rollout/restart of the deployment. + secret: + # -- The name of the secret created by chart (if name is empty the default name is used) + # or the name of a secret that the user created. + # If secret is created outside of the helm chart, make sure the key for token + # is 'runner_token' in the secret. The chart references this key + # when passing token as env variable. + name: "" + # -- Option for creating a new secret or using an existing one. + # When true, a new kubernetes secret will be created by the chart that will + # contain value from runnerToken. + # When false, the user must set secret.name to the name of the k8s secret + # the user created with the runner's token. + create: false + # -- Used when sythentics.secret.create=true. The runner's token available + # in Splunk Observability when Private Location was created. + runnerToken: "" + +# -- Resources for runner container. +resources: + # Recommended resources for runner. + limits: + cpu: 2 + memory: 8G + requests: + cpu: 2 + memory: 8G + +# Adjust the periodSeconds to be greater than frequency of tests configured +# or the probe could result in restarts when runner has no jobs scheduled +livenessProbe: + # -- Enable liveness probe + enabled: true + initialDelaySeconds: 60 + periodSeconds: 300 + timeoutSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + +# -- Indicates whether a service account token should be automatically mounted +# to the runner pod. +automountServiceAccountToken: true + +# -- ServiceAccount config. Note that the runner pod does not need access to +# k8s api for its operation. +serviceAccount: + # -- If true, service account will be created. + create: true + # -- The name of the service account to use. If not set, the release's fullname + # will be used when create is true. Set this variable to add user created + # service account to pod. + name: "" + # -- Annotations to add to service account + annotations: {} + +# -- Configuration for HPA +autoscaling: + # -- Enable HPA + enabled: false + # -- Minimum replicas of runner + minReplicas: 1 + # -- Maximum replicas of runner + maxReplicas: 6 + # -- Target CPU utilization + targetCPUUtilizationPercentage: 95 + # -- Target Memory utilization + targetMemoryUtilizationPercentage: 95 + +# -- Duration in seconds the pod needs to terminate gracefully. +terminationGracePeriodSeconds: 10 + +# -- Additional environment variables as map. +env: {} + +# -- Additional volumes to add to runner deployment. +volumes: [] + # - name: cache-volume + # emptyDir: + # sizeLimit: 500Mi + +# -- Additional volumeMounts to add to the runner deployment. +volumeMounts: [] + # - mountPath: /cache + # name: cache-volume + +# -- Selector for the runner pods to fit on a node. +nodeSelector: {} + +# -- Tolerations to attach to runner pods for node taints. +tolerations: [] + +# -- Inter-pod and node affinity/anti-affinity rules. +affinity: {} + +# -- Priority class for runner pods +priorityClassName: "" + +# -- DNS Policy to set for the runner pods. Valid values are +# ClusterFirst, ClusterFirstWithHostNet, Default, None +dnsPolicy: ClusterFirst + +# -- Specify additional DNS parameters for the runner pods. +dnsConfig: {} + +# -- List of hosts/IPs to be injected into the pod's hosts file. +hostAliases: [] + # - ip: "1.2.3.4" + # hostnames: + # - "private.domain.com" + +# -- Pod distruption budget +podDisruptionBudget: + enabled: true + minAvailable: 1 + # maxUnavailable: 1 diff --git a/ct.yaml b/ct.yaml new file mode 100644 index 0000000..848a68d --- /dev/null +++ b/ct.yaml @@ -0,0 +1,8 @@ +# See https://github.com/helm/chart-testing#configuration +remote: origin +chart-dirs: + - charts +helm-extra-args: --timeout 300s +check-version-increment: false +validate-chart-schema: false +target-branch: main diff --git a/tests/unittests/configmap-ca_tests.yaml b/tests/unittests/configmap-ca_tests.yaml new file mode 100644 index 0000000..9f6aa32 --- /dev/null +++ b/tests/unittests/configmap-ca_tests.yaml @@ -0,0 +1,74 @@ +suite: Test ConfigMap +templates: + - templates/configmap-ca.yaml + - templates/deployment.yaml +values: + - ./values/configmap-ca_tests.yaml +tests: + - it: should create a ConfigMap with the correct name + templates: + - templates/configmap-ca.yaml + asserts: + - isKind: + of: ConfigMap + - matchRegex: + path: metadata.name + pattern: ".*splunk-synthetics-runner$" + - it: should have the correct data keys and values + templates: + - templates/configmap-ca.yaml + asserts: + - equal: + path: data["customer.test.com.cert"] + value: | + -----BEGIN CERTIFICATE----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7 + -----END CERTIFICATE----- + - equal: + path: data["another.test.com.cert"] + value: |- + -----BEGIN CERTIFICATE----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8 + -----END CERTIFICATE----- + - it: should add correct volumeMounts to deployment + templates: + - templates/deployment.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].volumeMounts + value: + - name: another-test-com-cert + mountPath: /usr/local/share/ca-certificates/another.test.com.cert + subPath: another.test.com.cert + readOnly: false + - name: customer-test-com-cert + mountPath: /usr/local/share/ca-certificates/customer.test.com.cert + subPath: customer.test.com.cert + readOnly: false + - it: should add correct volumes to deployment + templates: + - templates/deployment.yaml + asserts: + - equal: + path: spec.template.spec.volumes + value: + - name: another-test-com-cert + configMap: + name: RELEASE-NAME-splunk-synthetics-runner + items: + - key: another.test.com.cert + path: another.test.com.cert + - name: customer-test-com-cert + configMap: + name: RELEASE-NAME-splunk-synthetics-runner + items: + - key: customer.test.com.cert + path: customer.test.com.cert + - it: should add cmd/args to pod spec + templates: + - templates/deployment.yaml + asserts: + - exists: + path: spec.template.spec.containers[0].args + - exists: + path: spec.template.spec.containers[0].command diff --git a/tests/unittests/values/configmap-ca_tests.yaml b/tests/unittests/values/configmap-ca_tests.yaml new file mode 100644 index 0000000..df41e94 --- /dev/null +++ b/tests/unittests/values/configmap-ca_tests.yaml @@ -0,0 +1,10 @@ +synthetics: + additionalCaCerts: + customer.test.com.cert: | + -----BEGIN CERTIFICATE----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7 + -----END CERTIFICATE----- + another.test.com.cert: | + -----BEGIN CERTIFICATE----- + MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8 + -----END CERTIFICATE----- \ No newline at end of file