diff --git a/.gitleaksignore b/.gitleaksignore new file mode 100644 index 0000000..5a80ba9 --- /dev/null +++ b/.gitleaksignore @@ -0,0 +1 @@ +607a5d5d16b365165d8636e526ed92a2ea116719:charts/snyk-broker/tests/broker_deployment_ca_test.yaml:private-key:271 diff --git a/charts/snyk-broker/templates/_helpers.tpl b/charts/snyk-broker/templates/_helpers.tpl index cb11f8f..6b877a0 100644 --- a/charts/snyk-broker/templates/_helpers.tpl +++ b/charts/snyk-broker/templates/_helpers.tpl @@ -139,3 +139,42 @@ include "snyk-broker.genericSecretName" (dict "Context" $ "secretName" "secret-n {{- define "snyk-broker.caCertSecretName" -}} {{- include "snyk-broker.genericSecretName" (dict "Context" . "secretName" "cacert-secret" ) -}} {{- end }} + +{{/* +Handle tlsRejectUnauthorized. +If this is set to `false` (bool) we _want_ to disable trust. We don't allow `true`. +If this is set to "" we want to enable trust - any other allowed string value disables. +If this is set to `"0"` Helm might cast it as an integer - we need to catch that. +Checking for definition is insufficient +*/}} +{{- define "snyk-broker.setTlsRejectUnauthorized" -}} +{{- $tlsRejectUnauthorized := .Values.tlsRejectUnauthorized -}} +{{- if eq (kindOf $tlsRejectUnauthorized ) "bool" -}} +true +{{- end }} +{{- if ( and ( eq (kindOf $tlsRejectUnauthorized ) "string") ( not ( eq $tlsRejectUnauthorized "" ) ) ) -}} +true +{{- end }} +{{- if eq (toString $tlsRejectUnauthorized) "0" -}} +true +{{- end }} +{{- end }} + +{{/* +NoProxy helper +Ensure all values are trimmed, separated by comma, and do not contain protocol or port +Validate against RFC 1123 +*/}} +{{- define "snyk-broker.noProxy" -}} +{{- $proxyUrls := .Values.noProxy | nospace -}} +{{- $proxyUrlsWithoutProtocol := mustRegexReplaceAll "http(s?)://" $proxyUrls "" -}} +{{- $sanitisedProxyUrls := "" -}} +{{- range $proxyUrlsWithoutProtocol | split "," -}} +{{- if ( mustRegexMatch "^[a-zA-Z0-9.-]+$" . ) -}} +{{- $sanitisedProxyUrls = printf "%s,%s" $sanitisedProxyUrls . -}} +{{- else }} +{{- fail (printf "Entry %s for .Values.noProxy is invalid. Specify hostname only (no schema or port)" . ) -}} +{{- end }} +{{- end }} +{{- $sanitisedProxyUrls | trimPrefix "," -}} +{{- end }} diff --git a/charts/snyk-broker/templates/broker_deployment.yaml b/charts/snyk-broker/templates/broker_deployment.yaml index e38ad34..4e627b1 100644 --- a/charts/snyk-broker/templates/broker_deployment.yaml +++ b/charts/snyk-broker/templates/broker_deployment.yaml @@ -1,3 +1,4 @@ +{{ $setTlsRejectUnauthorized := include "snyk-broker.setTlsRejectUnauthorized" . }} apiVersion: apps/v1 kind: Deployment metadata: @@ -428,7 +429,7 @@ spec: - name: HTTPS_KEY value: /home/node/tls-cert/tls.key {{- end }} - {{- if or ( and .Values.tlsRejectUnauthorized (not .Values.caCert ) (not .Values.caCertFile) ) ( and (or .Values.caCert .Values.caCertFile ) .Values.disableCaCertTrust ) }} + {{- if or ( and $setTlsRejectUnauthorized (not .Values.caCert ) (not .Values.caCertFile) ) ( and (or .Values.caCert .Values.caCertFile ) .Values.disableCaCertTrust ) }} # Troubleshooting - Set to 0 for SSL inspection testing - name: NODE_TLS_REJECT_UNAUTHORIZED value: "0" @@ -449,7 +450,7 @@ spec: {{- if .Values.noProxy }} # No Proxy Settings - name: NO_PROXY - value: {{ .Values.noProxy }} + value: {{ include "snyk-broker.noProxy" . }} {{- end }} {{- if (include "snyk-broker.acceptJson" .)}} diff --git a/charts/snyk-broker/templates/code_agent_deployment.yaml b/charts/snyk-broker/templates/code_agent_deployment.yaml index dbd291a..5b50819 100644 --- a/charts/snyk-broker/templates/code_agent_deployment.yaml +++ b/charts/snyk-broker/templates/code_agent_deployment.yaml @@ -1,3 +1,4 @@ +{{ $setTlsRejectUnauthorized := include "snyk-broker.setTlsRejectUnauthorized" . }} {{- if .Values.enableCodeAgent }} apiVersion: apps/v1 kind: Deployment @@ -8,9 +9,7 @@ metadata: app.kubernetes.io/name: {{ .Release.Name }}-ca app.kubernetes.io/instance: {{ .Release.Name }} spec: - {{- if not .Values.autoscaling.enabled }} replicas: 1 - {{- end }} selector: matchLabels: app.kubernetes.io/name: {{ .Release.Name }}-ca @@ -60,7 +59,7 @@ spec: secretKeyRef: name: snyk-token{{if not .Values.disableSuffixes }}-{{ .Release.Name }}{{ end }} key: snyk-token-key - {{- if .Values.tlsRejectUnauthorized }} + {{- if $setTlsRejectUnauthorized }} # Troubleshooting - Set to 0 for SSL inspection testing - name: NODE_TLS_REJECT_UNAUTHORIZED value: "0" @@ -73,15 +72,14 @@ spec: {{- if .Values.noProxy }} # No Proxy Settings - name: NO_PROXY - value: {{ .Values.noProxy }} + value: {{ include "snyk-broker.noProxy" . }} {{- end }} {{- range .Values.env }} # custom env var in override.yaml - name: {{ .name }} - value: {{ .value | squote }} + value: {{ .value | squote }} {{- end}} - ---- +--- apiVersion: v1 kind: Service metadata: @@ -97,5 +95,4 @@ spec: selector: app.kubernetes.io/name: {{ .Release.Name }}-ca app.kubernetes.io/instance: {{ .Release.Name }} - {{- end }} diff --git a/charts/snyk-broker/templates/cra_deployment.yaml b/charts/snyk-broker/templates/cra_deployment.yaml index fb83432..6620369 100644 --- a/charts/snyk-broker/templates/cra_deployment.yaml +++ b/charts/snyk-broker/templates/cra_deployment.yaml @@ -1,3 +1,4 @@ +{{ $setTlsRejectUnauthorized := include "snyk-broker.setTlsRejectUnauthorized" . }} {{- if eq .Values.scmType "container-registry-agent" }} apiVersion: apps/v1 kind: Deployment @@ -52,7 +53,7 @@ spec: env: - name: SNYK_PORT value: {{ .Values.deployment.container.crSnykPort | squote }} - {{- if .Values.tlsRejectUnauthorized }} + {{- if $setTlsRejectUnauthorized }} # Troubleshooting - Set to 0 for SSL inspection testing - name: NODE_TLS_REJECT_UNAUTHORIZED value: "0" diff --git a/charts/snyk-broker/tests/broker_cra_deployment_disable_tls_test.yaml b/charts/snyk-broker/tests/broker_cra_deployment_disable_tls_test.yaml new file mode 100644 index 0000000..d2434a7 --- /dev/null +++ b/charts/snyk-broker/tests/broker_cra_deployment_disable_tls_test.yaml @@ -0,0 +1,93 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/helm-unittest/helm-unittest/main/schema/helm-testsuite.json +suite: test broker deployment with CA +chart: + version: 0.0.0 +templates: + - broker_deployment.yaml + - cra_deployment.yaml + - code_agent_deployment.yaml +values: + - ./fixtures/default_values.yaml + - ./fixtures/default_values_cra.yaml +set: + enableCodeAgent: true + +tests: + - it: disables tls trust with "disable" (string) + set: + tlsRejectUnauthorized: "disable" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NODE_TLS_REJECT_UNAUTHORIZED + value: "0" + documentSelector: + path: kind + value: Deployment + - it: disables tls trust with "0" (string) + set: + tlsRejectUnauthorized: "0" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NODE_TLS_REJECT_UNAUTHORIZED + value: "0" + documentSelector: + path: kind + value: Deployment + - it: disables tls trust with "false" (string) + set: + tlsRejectUnauthorized: "false" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NODE_TLS_REJECT_UNAUTHORIZED + value: "0" + documentSelector: + path: kind + value: Deployment + - it: disables tls trust with false (boolean) + set: + tlsRejectUnauthorized: false + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NODE_TLS_REJECT_UNAUTHORIZED + value: "0" + documentSelector: + path: kind + value: Deployment + - it: disables tls trust with '0' (integer) + set: + tlsRejectUnauthorized: 0 + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NODE_TLS_REJECT_UNAUTHORIZED + value: "0" + documentSelector: + path: kind + value: Deployment + - it: enables tls trust by default "" (string) + set: + tlsRejectUnauthorized: "" + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: NODE_TLS_REJECT_UNAUTHORIZED + value: "0" + documentSelector: + path: kind + value: Deployment + - it: does not allow true (bool) + set: + tlsRejectUnauthorized: true + asserts: + - failedTemplate: + errorMessage: "values don't meet the specifications of the schema(s) in the following chart(s):\nsnyk-broker:\n- tlsRejectUnauthorized: tlsRejectUnauthorized must be one of the following: \"\", 0, \"0\", \"false\", false, \"disable\"\n" diff --git a/charts/snyk-broker/tests/broker_deployment_ca_test.yaml b/charts/snyk-broker/tests/broker_deployment_ca_test.yaml index 2ab0b38..644fcb2 100644 --- a/charts/snyk-broker/tests/broker_deployment_ca_test.yaml +++ b/charts/snyk-broker/tests/broker_deployment_ca_test.yaml @@ -265,3 +265,9 @@ tests: documentSelector: path: metadata.name value: RELEASE-NAME-snyk-broker-cacert-secret + + - it: rejects a non-PEM certificate + set: + caCertFile: "\n \n-----BEGIN RSA PRIVATE KEY-----\nCERTIFICATE GOES HERE\n-----END RSA PRIVATE KEY-----\n\n\n" #gitleaks:allow + asserts: + - failedTemplate: {} diff --git a/charts/snyk-broker/tests/broker_deployment_proxy_test.yaml b/charts/snyk-broker/tests/broker_deployment_proxy_test.yaml new file mode 100644 index 0000000..3448cf6 --- /dev/null +++ b/charts/snyk-broker/tests/broker_deployment_proxy_test.yaml @@ -0,0 +1,99 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/helm-unittest/helm-unittest/main/schema/helm-testsuite.json +suite: test broker proxy configuration +chart: + version: 0.0.0 +templates: + - broker_deployment.yaml +values: + - ./fixtures/default_values.yaml + +tests: + - it: sets an https proxy + set: + httpsProxy: &proxy http://my.proxy:8080 + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: HTTPS_PROXY + value: *proxy + - it: sets an http proxy + set: + httpProxy: *proxy + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: HTTP_PROXY + value: *proxy + - it: sets both https and http proxy + set: + httpProxy: *proxy + httpsProxy: *proxy + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: HTTP_PROXY + value: *proxy + - contains: + path: spec.template.spec.containers[0].env + content: + name: HTTPS_PROXY + value: *proxy + - it: rejects proxy without protocol + set: + httpsProxy: no.protocol.proxy:8080 + asserts: + - failedTemplate: {} + - it: sets noproxy without protocol + set: + noProxy: my.ghe.io + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NO_PROXY + value: my.ghe.io + - it: corrects noproxy by removing protocol + set: + noProxy: https://my.ghe.io + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NO_PROXY + value: my.ghe.io + - it: sets noproxy with multiple domains + set: + noProxy: my.ghe.io,my.other.host.tld + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NO_PROXY + value: my.ghe.io,my.other.host.tld + - it: corrects noproxy with multiple domains, one with protocol + set: + noProxy: my.ghe.io,https://my.private.site + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NO_PROXY + value: my.ghe.io,my.private.site + - it: corrects noproxy with multiple domains, one with protocol, with spaces + set: + noProxy: my.ghe.io, https://my.private.site + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: NO_PROXY + value: my.ghe.io,my.private.site + - it: rejects noproxy with multiple domains, one with protocol, one with a port + set: + noProxy: my.ghe.io, https://my.private.site,notadomain:12334 + asserts: + - failedTemplate: + errorMessage: Entry notadomain:12334 for .Values.noProxy is invalid. Specify hostname only (no schema or port) diff --git a/charts/snyk-broker/values.schema.json b/charts/snyk-broker/values.schema.json index 1b0b70c..d50e963 100644 --- a/charts/snyk-broker/values.schema.json +++ b/charts/snyk-broker/values.schema.json @@ -161,6 +161,8 @@ "quay-cr", "nexus-cr", "github-cr", + "google-artifact-cr", + "gitlab-cr", "ecr", "digitalocean-cr" ] @@ -263,7 +265,8 @@ "type": "string" }, "caCertFile": { - "type": "string" + "type": "string", + "pattern": "^$|^\\s*-----BEGIN CERTIFICATE-----(?:.|\\s)*-----END CERTIFICATE-----\\s*$" }, "disableCaCertTrust": { "type": "boolean" @@ -271,10 +274,12 @@ "tlsRejectUnauthorized":{ "type": [ "string", - "boolean" + "boolean", + "integer" ], "enum":[ "", + 0, "0", "false", false, @@ -288,7 +293,7 @@ "$ref": "#/$defs/urlWithSchema" }, "noProxy": { - "$ref": "#/$defs/urlWithSchema" + "type": "string" }, "acceptJson":{ "type": "string" diff --git a/charts/snyk-broker/values.yaml b/charts/snyk-broker/values.yaml index bf7bdfa..de9a420 100644 --- a/charts/snyk-broker/values.yaml +++ b/charts/snyk-broker/values.yaml @@ -254,6 +254,9 @@ httpProxy: "" httpsProxy: "" # No Proxy URL - This will apply to both Snyk Broker and Snyk Code Agent +# Do not specify protocol (http(s)://) or port +# Separate multiple entries by a comma +# e.g. my.first.host,my.second.host noProxy: "" # For custom accept.json, specify the path to the accept.json using the --set-file command when installing the chart