add sonarqube

This commit is contained in:
2026-04-27 21:52:01 +07:00
parent 142dd15922
commit e42544c877
256 changed files with 12484 additions and 0 deletions

View File

@@ -0,0 +1,37 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range .Values.ingress.hosts }}
http://{{ .name }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "sonarqube.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w {{ template "sonarqube.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "sonarqube.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.externalPort }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "sonarqube.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:{{ .Values.service.externalPort }} -n {{ .Release.Namespace }}
{{- end }}
{{- if eq .Values.edition "community" }}
DEPRECATION NOTICE: The SonarQube Community Edition has been replaced by the SonarQube Community Build.
Please use "community.enabled=true" to use the latest SonarQube Community Build.
The "community" value is deprecated and won't be supported for "edition" anymore.
{{- end }}
WARNING:
Please note that the SonarQube image runs with a non-root user (uid=1000) belonging to the root group (guid=0). In this way, the chart can support arbitrary user ids as recommended in OpenShift.
Please visit https://docs.openshift.com/container-platform/4.14/openshift_images/create-images.html#use-uid_create-images for more information.
{{ if or (.Values.nginx).enabled (index .Values "ingress-nginx" "enabled") }}
WARNING: The ingress-nginx controller dependency is deprecated. A replacement for this dependency will be included in a future release.
Please visit https://artifacthub.io/packages/helm/sonarqube/sonarqube#ingress-usage for more information.
{{- end }}
{{ if hasKey .Values.deploymentStrategy "type" }}
WARNING: Setting the deployment strategy type is deprecated and will be removed in a future release. It will be hard-coded to Recreate.
{{- end }}
{{ if eq .Values.deploymentType "StatefulSet" }}
WARNING: The deploymentType value is deprecated and won't be supported anymore. SonarQube will be deployed as a Deployment by default.
{{- end }}

View File

@@ -0,0 +1,434 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "sonarqube.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).
*/}}
{{- define "sonarqube.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name (include "sonarqube.name" .) | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "sonarqube.labels" -}}
app: {{ include "sonarqube.name" . }}
chart: {{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "sonarqube.selectorLabels" -}}
app: {{ include "sonarqube.name" . }}
release: {{ .Release.Name }}
{{- end -}}
{{/*
Workload labels (Deployment or StatefulSet)
*/}}
{{- define "sonarqube.workloadLabels" -}}
{{- include "sonarqube.labels" . }}
app.kubernetes.io/name: {{ .Release.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
app.kubernetes.io/part-of: sonarqube
app.kubernetes.io/component: {{ include "sonarqube.fullname" . }}
app.kubernetes.io/version: {{ (tpl (include "image.tag" .) . ) | trunc 63 | trimSuffix "-" | quote }}
{{- end -}}
{{/*
Expand the Application Image name.
*/}}
{{- define "sonarqube.image" -}}
{{- if and .Values.global .Values.global.azure .Values.global.azure.images .Values.global.azure.images.sonarqube }}
{{- printf "%s/%s:%s" .Values.global.azure.images.sonarqube.registry .Values.global.azure.images.sonarqube.image .Values.global.azure.images.sonarqube.tag }}
{{- else }}
{{- printf "%s:%s" .Values.image.repository (tpl (include "image.tag" .) .) }}
{{- end -}}
{{- end -}}
{{/*
Check if Azure configuration is complete
*/}}
{{- define "sonarqube.azure.enabled" -}}
{{- if and .Values.global .Values.global.azure -}}
{{- with .Values.global.azure -}}
{{- if and .identity .extension .marketplace -}}
{{- if and .identity.clientId .extension.resourceId .marketplace.planId -}}
{{- true -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Define the image.tag value that computes the right tag to be used as `sonarqube.image`
The tag is derived from the following parameters:
- .Values.image.tag
- .Values.community.enabled
- .Values.community.buildNumber
- .Values.edition
- .Chart.AppVersion
The logic to generate the tag is as follows:
There should not be a default edition, with users that specify it.
The edition must be one of these values: developer/enterprise.
When edition is used and image.tag is not, we use appVersion for paid editions and the latest release of SQ-CB for the community.
The CI supports the release of the Server edition.
*/}}
{{- define "image.tag" -}}
{{- $imageTag := "" -}}
{{- if not (empty .Values.edition) -}}
{{- if or (empty .Values.image) (empty .Values.image.tag) -}}
{{- $imageTag = printf "%s-%s" .Chart.AppVersion .Values.edition -}}
{{- else -}}
{{- $imageTag = printf "%s" .Values.image.tag -}}
{{- end -}}
{{- else if (and (.Values.community) .Values.community.enabled) -}}
{{- if or (empty .Values.image) (empty .Values.image.tag) -}}
{{- if not (empty .Values.community.buildNumber) -}}
{{- $imageTag = printf "%s-%s" .Values.community.buildNumber "community" -}}
{{- else -}}
{{- $imageTag = printf "community" -}}
{{- end -}}
{{- else -}}
{{- $imageTag = printf "%s" .Values.image.tag -}}
{{- end -}}
{{- end -}}
{{- printf "%s" $imageTag -}}
{{- end -}}
{{/*
Determine the k8s secret containing the JDBC credentials
*/}}
{{- define "jdbc.secret" -}}
{{- if or .Values.jdbcOverwrite.enabled .Values.jdbcOverwrite.enable -}}
{{- if .Values.jdbcOverwrite.jdbcSecretName -}}
{{- .Values.jdbcOverwrite.jdbcSecretName -}}
{{- else -}}
{{- template "sonarqube.fullname" . -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Determine JDBC username
*/}}
{{- define "jdbc.username" -}}
{{- if and (or .Values.jdbcOverwrite.enabled .Values.jdbcOverwrite.enable) .Values.jdbcOverwrite.jdbcUsername -}}
{{- .Values.jdbcOverwrite.jdbcUsername | quote -}}
{{- end -}}
{{- end -}}
{{/*
Determine the k8s secretKey contrining the JDBC password
*/}}
{{- define "jdbc.secretPasswordKey" -}}
{{- if or .Values.jdbcOverwrite.enabled .Values.jdbcOverwrite.enable -}}
{{- if and .Values.jdbcOverwrite.jdbcSecretName .Values.jdbcOverwrite.jdbcSecretPasswordKey -}}
{{- .Values.jdbcOverwrite.jdbcSecretPasswordKey -}}
{{- else -}}
{{- "jdbc-password" -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Determine JDBC password if internal secret is used
*/}}
{{- define "jdbc.internalSecretPasswd" -}}
{{- if or .Values.jdbcOverwrite.enabled .Values.jdbcOverwrite.enable -}}
{{- .Values.jdbcOverwrite.jdbcPassword | b64enc | quote -}}
{{- end -}}
{{- end -}}
{{/*
Set sonarqube.jvmOpts
*/}}
{{- define "sonarqube.jvmOpts" -}}
{{- $tempJvm := .Values.jvmOpts -}}
{{- if and .Values.sonarProperties (hasKey (.Values.sonarProperties) "sonar.web.javaOpts")}}
{{- $tempJvm = (get .Values.sonarProperties "sonar.web.javaOpts") -}}
{{- else if .Values.env -}}
{{- range $index, $val := .Values.env -}}
{{- if eq $val.name "SONAR_WEB_JAVAOPTS" -}}
{{- $tempJvm = $val.value -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and .Values.caCerts.enabled .Values.prometheusExporter.enabled -}}
{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=%d:%s/conf/prometheus-config.yaml -Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder (int .Values.prometheusExporter.webBeanPort) .Values.sonarqubeFolder .Values.sonarqubeFolder $tempJvm | trim }}
{{- else if .Values.caCerts.enabled -}}
{{ printf "-Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder $tempJvm | trim }}
{{- else if .Values.prometheusExporter.enabled -}}
{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=%d:%s/conf/prometheus-config.yaml %s" .Values.sonarqubeFolder (int .Values.prometheusExporter.webBeanPort) .Values.sonarqubeFolder $tempJvm | trim }}
{{- else -}}
{{ printf "%s" $tempJvm }}
{{- end -}}
{{- end -}}
{{/*
Set sonarqube.jvmCEOpts
*/}}
{{- define "sonarqube.jvmCEOpts" -}}
{{- $tempJvm := .Values.jvmCeOpts -}}
{{- if and .Values.sonarProperties (hasKey (.Values.sonarProperties) "sonar.ce.javaOpts")}}
{{- $tempJvm = (get .Values.sonarProperties "sonar.ce.javaOpts") -}}
{{- else if .Values.env -}}
{{- range $index, $val := .Values.env -}}
{{- if eq $val.name "SONAR_CE_JAVAOPTS" -}}
{{- $tempJvm = $val.value -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- if and .Values.caCerts.enabled .Values.prometheusExporter.enabled -}}
{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=%d:%s/conf/prometheus-ce-config.yaml -Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder (int .Values.prometheusExporter.ceBeanPort) .Values.sonarqubeFolder .Values.sonarqubeFolder $tempJvm | trim }}
{{- else if .Values.caCerts.enabled -}}
{{ printf "-Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder $tempJvm | trim }}
{{- else if .Values.prometheusExporter.enabled -}}
{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=%d:%s/conf/prometheus-ce-config.yaml %s" .Values.sonarqubeFolder (int .Values.prometheusExporter.ceBeanPort) .Values.sonarqubeFolder $tempJvm | trim }}
{{- else -}}
{{ printf "%s" $tempJvm }}
{{- end -}}
{{- end -}}
{{/*
Set prometheusExporter.downloadURL
*/}}
{{- define "prometheusExporter.downloadURL" -}}
{{- if .Values.prometheusExporter.downloadURL -}}
{{ printf "%s" .Values.prometheusExporter.downloadURL }}
{{- else -}}
{{ printf "https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/%s/jmx_prometheus_javaagent-%s.jar" .Values.prometheusExporter.version .Values.prometheusExporter.version }}
{{- end -}}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "sonarqube.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "sonarqube.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
{{/*
Set sonarqube.webcontext, ensuring it starts and ends with a slash, in order to ease probes url template
*/}}
{{- define "sonarqube.webcontext" -}}
{{- $tempWebcontext := .Values.sonarWebContext -}}
{{- if and .Values.sonarProperties (hasKey (.Values.sonarProperties) "sonar.web.context") -}}
{{- $tempWebcontext = (get .Values.sonarProperties "sonar.web.context") -}}
{{- end -}}
{{- range $index, $val := .Values.env -}}
{{- if eq $val.name "SONAR_WEB_CONTEXT" -}}
{{- $tempWebcontext = $val.value -}}
{{- end -}}
{{- end -}}
{{- if not (hasPrefix "/" $tempWebcontext) -}}
{{- $tempWebcontext = print "/" $tempWebcontext -}}
{{- end -}}
{{- if not (hasSuffix "/" $tempWebcontext) -}}
{{- $tempWebcontext = print $tempWebcontext "/" -}}
{{- end -}}
{{ printf "%s" $tempWebcontext }}
{{- end -}}
{{/*
Set combined_env, ensuring we dont have any duplicates with our features and some of the user provided env vars
*/}}
{{- define "sonarqube.combined_env" -}}
{{- $filteredEnv := list -}}
{{- range $index,$val := .Values.env -}}
{{- if not (has $val.name (list "SONAR_WEB_CONTEXT" "SONAR_WEB_JAVAOPTS" "SONAR_CE_JAVAOPTS")) -}}
{{- $filteredEnv = append $filteredEnv $val -}}
{{- end -}}
{{- end -}}
{{- $filteredEnv = append $filteredEnv (dict "name" "SONAR_WEB_CONTEXT" "value" (include "sonarqube.webcontext" .)) -}}
{{- $filteredEnv = append $filteredEnv (dict "name" "SONAR_WEB_JAVAOPTS" "value" (include "sonarqube.jvmOpts" .)) -}}
{{- $filteredEnv = append $filteredEnv (dict "name" "SONAR_CE_JAVAOPTS" "value" (include "sonarqube.jvmCEOpts" .)) -}}
{{- toJson $filteredEnv -}}
{{- end -}}
{{/*
generate Proxy env var from httpProxySecret
*/}}
{{- define "sonarqube.proxyFromSecret" -}}
- name: http_proxy
valueFrom:
secretKeyRef:
name: {{ .Values.httpProxySecret }}
key: http_proxy
- name: https_proxy
valueFrom:
secretKeyRef:
name: {{ .Values.httpProxySecret }}
key: https_proxy
- name: no_proxy
valueFrom:
secretKeyRef:
name: {{ .Values.httpProxySecret }}
key: no_proxy
{{- end -}}
{{/*
generate prometheusExporter proxy env var
*/}}
{{- define "sonarqube.prometheusExporterProxy.env" -}}
{{- if .Values.httpProxySecret -}}
{{- include "sonarqube.proxyFromSecret" . }}
{{- else -}}
- name: http_proxy
valueFrom:
secretKeyRef:
name: {{ template "sonarqube.fullname" . }}-http-proxies
key: PROMETHEUS-EXPORTER-HTTP-PROXY
- name: https_proxy
valueFrom:
secretKeyRef:
name: {{ template "sonarqube.fullname" . }}-http-proxies
key: PROMETHEUS-EXPORTER-HTTPS-PROXY
- name: no_proxy
valueFrom:
secretKeyRef:
name: {{ template "sonarqube.fullname" . }}-http-proxies
key: PROMETHEUS-EXPORTER-NO-PROXY
{{- end -}}
{{- end -}}
{{/*
generate install-plugins proxy env var
*/}}
{{- define "sonarqube.install-plugins-proxy.env" -}}
{{- if .Values.httpProxySecret -}}
{{- include "sonarqube.proxyFromSecret" . }}
{{- else -}}
- name: http_proxy
valueFrom:
secretKeyRef:
name: {{ template "sonarqube.fullname" . }}-http-proxies
key: PLUGINS-HTTP-PROXY
- name: https_proxy
valueFrom:
secretKeyRef:
name: {{ template "sonarqube.fullname" . }}-http-proxies
key: PLUGINS-HTTPS-PROXY
- name: no_proxy
valueFrom:
secretKeyRef:
name: {{ template "sonarqube.fullname" . }}-http-proxies
key: PLUGINS-NO-PROXY
{{- end -}}
{{- end -}}
{{/*
Remove incompatible user/group values that do not work in Openshift out of the box
*/}}
{{- define "sonarqube.securityContext" -}}
{{- $adaptedSecurityContext := .Values.securityContext -}}
{{- if .Values.OpenShift.enabled -}}
{{- $adaptedSecurityContext = omit $adaptedSecurityContext "fsGroup" "runAsUser" "runAsGroup" -}}
{{- end -}}
{{- toYaml $adaptedSecurityContext -}}
{{- end -}}
{{/*
Remove incompatible user/group values that do not work in Openshift out of the box
*/}}
{{- define "sonarqube.containerSecurityContext" -}}
{{- $adaptedContainerSecurityContext := .Values.containerSecurityContext -}}
{{- if .Values.OpenShift.enabled -}}
{{- $adaptedContainerSecurityContext = omit $adaptedContainerSecurityContext "fsGroup" "runAsUser" "runAsGroup" -}}
{{- end -}}
{{- toYaml $adaptedContainerSecurityContext -}}
{{- end -}}
{{/*
Remove incompatible user/group values that do not work in Openshift out of the box
*/}}
{{- define "sonarqube.initContainerSecurityContext" -}}
{{- $adaptedInitContainerSecurityContext := .Values.initContainers.securityContext -}}
{{- if .Values.OpenShift.enabled -}}
{{- $adaptedInitContainerSecurityContext = omit $adaptedInitContainerSecurityContext "fsGroup" "runAsUser" "runAsGroup" -}}
{{- end -}}
{{- toYaml $adaptedInitContainerSecurityContext -}}
{{- end -}}
{{/*
generate caCerts volume
*/}}
{{- define "sonarqube.volumes.caCerts" -}}
{{- if .Values.caCerts.enabled -}}
- name: ca-certs
{{- if .Values.caCerts.secret }}
secret:
secretName: {{ .Values.caCerts.secret }}
{{- else if .Values.caCerts.configMap }}
configMap:
name: {{ .Values.caCerts.configMap.name }}
items:
- key: {{ .Values.caCerts.configMap.key }}
path: {{ .Values.caCerts.configMap.path }}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
This helper deeply merges two maps (structs). It recursively merges nested maps and takes the values from `map2` when keys overlap.
*/}}
{{- define "deepMerge" -}}
{{- $map1 := .map1 -}}
{{- $map2 := .map2 -}}
{{- $result := dict -}}
{{- /* Merge keys from map1 */}}
{{- range $key, $value := $map1 -}}
{{- $_ := set $result $key $value -}}
{{- end -}}
{{- /* Merge keys from map2 (overriding map1 if the key exists) */}}
{{- range $key, $value := $map2 -}}
{{- if hasKey $map1 $key -}}
{{- /* If both maps have the same key and the value is a map, we need to merge recursively */}}
{{- if and (kindIs "map" $value) (kindIs "map" (index $map1 $key)) -}}
{{- $_ := set $result $key (fromYaml (include "deepMerge" (dict "map1" (index $map1 $key) "map2" $value))) -}}
{{- else -}}
{{- /* Otherwise, just take the value from map2 */}}
{{- $_ := set $result $key $value -}}
{{- end -}}
{{- else -}}
{{- /* If map2 has a key not in map1, just add it to the result */}}
{{- $_ := set $result $key $value -}}
{{- end -}}
{{- end -}}
{{- toYaml $result -}}
{{- end -}}
{{- define "accountDeprecation" -}}
{{- $map1 := .Values.setAdminPassword -}}
{{- $map2 := .Values.account -}}
{{- $accountDeprecation := (include "deepMerge" (dict "map1" $map1 "map2" $map2)) -}}
{{- $accountDeprecation }}
{{- end -}}

View File

@@ -0,0 +1,486 @@
{{- define "sonarqube.pod" -}}
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
{{- if and .Values.persistence.enabled .Values.initFs.enabled (not .Values.OpenShift.enabled) }}
checksum/init-fs: {{ include (print $.Template.BasePath "/init-fs.yaml") . | sha256sum }}
{{- end }}
{{- if and .Values.initSysctl.enabled (not .Values.OpenShift.enabled) }}
checksum/init-sysctl: {{ include (print $.Template.BasePath "/init-sysctl.yaml") . | sha256sum }}
{{- end }}
checksum/plugins: {{ include (print $.Template.BasePath "/install-plugins.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- if .Values.prometheusExporter.enabled }}
checksum/prometheus-config: {{ include (print $.Template.BasePath "/prometheus-config.yaml") . | sha256sum }}
checksum/prometheus-ce-config: {{ include (print $.Template.BasePath "/prometheus-ce-config.yaml") . | sha256sum }}
{{- end }}
{{- with .Values.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
labels:
{{- include "sonarqube.selectorLabels" . | nindent 4 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
automountServiceAccountToken: {{ .Values.serviceAccount.automountToken }}
{{- with .Values.schedulerName }}
schedulerName: {{ . }}
{{- end }}
{{- with (include "sonarqube.securityContext" .) }}
securityContext: {{- . | nindent 4 }}
{{- end }}
{{- if or .Values.image.pullSecrets .Values.image.pullSecret }}
imagePullSecrets:
{{- if .Values.image.pullSecret }}
- name: {{ .Values.image.pullSecret }}
{{- end }}
{{- with .Values.image.pullSecrets }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
initContainers:
{{- if .Values.extraInitContainers }}
{{- toYaml .Values.extraInitContainers | nindent 4 }}
{{- end }}
{{- if .Values.caCerts.enabled }}
- name: ca-certs
image: {{ default (include "sonarqube.image" $) .Values.caCerts.image }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ["sh"]
args: ["-c", "cp -f \"${JAVA_HOME}/lib/security/cacerts\" /tmp/certs/cacerts; if [ \"$(ls /tmp/secrets/ca-certs)\" ]; then for f in /tmp/secrets/ca-certs/*; do keytool -importcert -file \"${f}\" -alias \"$(basename \"${f}\")\" -keystore /tmp/certs/cacerts -storepass changeit -trustcacerts -noprompt; done; fi;"]
{{- with (include "sonarqube.initContainerSecurityContext" .) }}
securityContext: {{- . | nindent 8 }}
{{- end }}
{{- with .Values.initContainers.resources }}
resources: {{- toYaml . | nindent 8 }}
{{- end }}
volumeMounts:
- mountPath: /tmp/certs
name: sonarqube
subPath: certs
- mountPath: /tmp/secrets/ca-certs
name: ca-certs
env:
{{- (include "sonarqube.combined_env" . | fromJsonArray) | toYaml | trim | nindent 8 }}
{{- end }}
{{- if and (or .Values.initSysctl.enabled .Values.elasticsearch.configureNode) (not .Values.OpenShift.enabled) }}
- name: init-sysctl
image: {{ default (include "sonarqube.image" $) .Values.initSysctl.image }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- with (default (fromYaml (include "sonarqube.initContainerSecurityContext" .)) (.Values.initSysctl.securityContext )) }}
securityContext: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with (default .Values.initContainers.resources .Values.initSysctl.resources) }}
resources: {{- toYaml . | nindent 8 }}
{{- end }}
command: ["/bin/bash", "-e", "/tmp/scripts/init_sysctl.sh"]
volumeMounts:
- name: init-sysctl
mountPath: /tmp/scripts/
env:
{{- (include "sonarqube.combined_env" . | fromJsonArray) | toYaml | trim | nindent 8 }}
{{- end }}
{{- if or .Values.sonarProperties .Values.sonarSecretProperties .Values.sonarSecretKey (not .Values.elasticsearch.bootstrapChecks) }}
- name: concat-properties
image: {{ default (include "sonarqube.image" $) .Values.initContainers.image }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
command:
- sh
- -c
- |
#!/bin/sh
if [ -f /tmp/props/sonar.properties ]; then
cat /tmp/props/sonar.properties > /tmp/result/sonar.properties
fi
if [ -f /tmp/props/secret.properties ]; then
cat /tmp/props/secret.properties > /tmp/result/sonar.properties
fi
if [ -f /tmp/props/sonar.properties -a -f /tmp/props/secret.properties ]; then
awk 1 /tmp/props/sonar.properties /tmp/props/secret.properties > /tmp/result/sonar.properties
fi
volumeMounts:
- mountPath: /tmp/result
name: concat-dir
{{- if or .Values.sonarProperties .Values.sonarSecretKey (not .Values.elasticsearch.bootstrapChecks) }}
- mountPath: /tmp/props/sonar.properties
name: config
subPath: sonar.properties
{{- end }}
{{- if .Values.sonarSecretProperties }}
- mountPath: /tmp/props/secret.properties
name: secret-config
subPath: secret.properties
{{- end }}
{{- with (include "sonarqube.initContainerSecurityContext" .) }}
securityContext: {{- . | nindent 8 }}
{{- end }}
{{- with .Values.initContainers.resources }}
resources: {{- toYaml . | nindent 8 }}
{{- end }}
env:
{{- (include "sonarqube.combined_env" . | fromJsonArray) | toYaml | trim | nindent 8 }}
{{- end }}
{{- if .Values.prometheusExporter.enabled }}
- name: inject-prometheus-exporter
image: {{ default (include "sonarqube.image" $) .Values.prometheusExporter.image }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- with (default (fromYaml (include "sonarqube.initContainerSecurityContext" .)) .Values.prometheusExporter.securityContext) }}
securityContext: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with (default .Values.initContainers.resources .Values.prometheusExporter.resources)}}
resources: {{- toYaml . | nindent 8 }}
{{- end }}
command: ["/bin/sh", "-c"]
args: ["curl -s '{{ include "prometheusExporter.downloadURL" . }}' {{ if $.Values.prometheusExporter.noCheckCertificate }}--insecure{{ end }} --output /data/jmx_prometheus_javaagent.jar -v"]
volumeMounts:
- mountPath: /data
name: sonarqube
subPath: data
env:
{{- with (include "sonarqube.prometheusExporterProxy.env" .) }}
{{- . | nindent 8 }}
{{- end }}
{{- (include "sonarqube.combined_env" . | fromJsonArray) | toYaml | trim | nindent 8 }}
{{- end }}
{{- if and .Values.persistence.enabled .Values.initFs.enabled (not .Values.OpenShift.enabled) }}
- name: init-fs
image: {{ default (include "sonarqube.image" $) .Values.initFs.image }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- with (default (fromYaml (include "sonarqube.initContainerSecurityContext" .)) .Values.initFs.securityContext) }}
securityContext: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with (default .Values.initContainers.resources .Values.initFs.resources) }}
resources: {{- toYaml . | nindent 8 }}
{{- end }}
command: ["sh", "-e", "/tmp/scripts/init_fs.sh"]
volumeMounts:
- name: init-fs
mountPath: /tmp/scripts/
- mountPath: {{ .Values.sonarqubeFolder }}/data
name: sonarqube
subPath: data
- mountPath: {{ .Values.sonarqubeFolder }}/temp
name: sonarqube
subPath: temp
- mountPath: {{ .Values.sonarqubeFolder }}/logs
name: sonarqube
subPath: logs
- mountPath: /tmp
name: tmp-dir
{{- if .Values.caCerts.enabled }}
- mountPath: {{ .Values.sonarqubeFolder }}/certs
name: sonarqube
subPath: certs
{{- end }}
- mountPath: {{ .Values.sonarqubeFolder }}/extensions
name: sonarqube
subPath: extensions
{{- with .Values.persistence.mounts }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
{{- if .Values.plugins.install }}
- name: install-plugins
image: {{ default (include "sonarqube.image" $) .Values.plugins.image }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ["sh", "-e", "/tmp/scripts/install_plugins.sh"]
{{- with (default (fromYaml (include "sonarqube.initContainerSecurityContext" .)) .Values.plugins.securityContext) }}
securityContext: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with (default .Values.initContainers.resources .Values.plugins.resource) }}
resources: {{- toYaml . | nindent 8 }}
{{- end }}
volumeMounts:
- mountPath: {{ .Values.sonarqubeFolder }}/extensions/plugins
name: sonarqube
subPath: extensions/plugins
- name: install-plugins
mountPath: /tmp/scripts/
{{- if .Values.plugins.netrcCreds }}
- name: plugins-netrc-file
mountPath: /root
{{- end }}
env:
{{- with (include "sonarqube.install-plugins-proxy.env" .) }}
{{- . | nindent 8 }}
{{- end }}
{{- (include "sonarqube.combined_env" . | fromJsonArray) | toYaml | trim | nindent 8 }}
{{- end }}
{{- if and .Values.jdbcOverwrite.oracleJdbcDriver .Values.jdbcOverwrite.oracleJdbcDriver.url }}
- name: install-oracle-jdbc-driver
image: {{ default (include "sonarqube.image" $) .Values.initContainers.image }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ["sh", "-e", "/tmp/scripts/install_oracle_jdbc_driver.sh"]
{{- with (default (fromYaml (include "sonarqube.initContainerSecurityContext" .)) .Values.initContainers.securityContext) }}
securityContext: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.initContainers.resources }}
resources: {{- toYaml . | nindent 8 }}
{{- end }}
volumeMounts:
- mountPath: {{ .Values.sonarqubeFolder }}/extensions/jdbc-driver/oracle
name: sonarqube
subPath: extensions/jdbc-driver/oracle
- name: install-oracle-jdbc-driver
mountPath: /tmp/scripts/
{{- if .Values.jdbcOverwrite.oracleJdbcDriver.netrcCreds }}
- name: oracle-jdbc-driver-netrc-file
mountPath: /root
{{- end }}
{{- if .Values.caCerts.enabled }}
- mountPath: /tmp/secrets/ca-certs
name: ca-certs
{{- end }}
env:
{{- (include "sonarqube.combined_env" . | fromJsonArray) | toYaml | trim | nindent 8 }}
{{- end }}
containers:
{{- with .Values.extraContainers }}
{{- toYaml . | nindent 4 }}
{{- end }}
- name: {{ .Chart.Name }}
image: {{ include "sonarqube.image" . }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.internalPort }}
protocol: TCP
{{- if .Values.prometheusExporter.enabled }}
- name: monitoring-web
containerPort: {{ .Values.prometheusExporter.webBeanPort }}
protocol: TCP
- name: monitoring-ce
containerPort: {{ .Values.prometheusExporter.ceBeanPort }}
protocol: TCP
{{- end }}
resources: {{- toYaml .Values.resources | nindent 8 }}
env:
- name: SONAR_HELM_CHART_VERSION
value: {{ .Chart.Version | replace "+" "_" }}
{{- if .Values.OpenShift.enabled }}
- name: IS_HELM_OPENSHIFT_ENABLED
value: "true"
{{- end }}
{{- if or .Values.jdbcOverwrite.enabled .Values.jdbcOverwrite.enable }}
- name: SONAR_JDBC_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "jdbc.secret" . }}
key: {{ include "jdbc.secretPasswordKey" . }}
{{- end }}
- name: SONAR_WEB_SYSTEMPASSCODE
valueFrom:
secretKeyRef:
{{- if and .Values.monitoringPasscodeSecretName .Values.monitoringPasscodeSecretKey }}
name: {{ .Values.monitoringPasscodeSecretName }}
key: {{ .Values.monitoringPasscodeSecretKey }}
{{- else }}
name: {{ include "sonarqube.fullname" . }}-monitoring-passcode
key: SONAR_WEB_SYSTEMPASSCODE
{{- end }}
{{- (include "sonarqube.combined_env" . | fromJsonArray) | toYaml | trim | nindent 8 }}
envFrom:
{{- if or .Values.jdbcOverwrite.enabled .Values.jdbcOverwrite.enable }}
- configMapRef:
name: {{ include "sonarqube.fullname" . }}-jdbc-config
{{- end }}
{{- if include "sonarqube.azure.enabled" . }}
- configMapRef:
name: {{ template "sonarqube.fullname" . }}-azure-config
{{- end }}
{{- range .Values.extraConfig.secrets }}
- secretRef:
name: {{ . }}
{{- end }}
{{- range .Values.extraConfig.configmaps }}
- configMapRef:
name: {{ . }}
{{- end }}
livenessProbe:
{{- tpl (omit .Values.livenessProbe "sonarWebContext" | toYaml) . | nindent 8 }}
readinessProbe:
{{- tpl (omit .Values.readinessProbe "sonarWebContext" | toYaml) . | nindent 8 }}
startupProbe:
httpGet:
scheme: HTTP
path: {{ .Values.startupProbe.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/system/status
port: http
initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.startupProbe.periodSeconds }}
failureThreshold: {{ .Values.startupProbe.failureThreshold }}
timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }}
{{- with (include "sonarqube.containerSecurityContext" .) }}
securityContext: {{- . | nindent 8 }}
{{- end }}
volumeMounts:
- mountPath: {{ .Values.sonarqubeFolder }}/data
name: sonarqube
subPath: data
- mountPath: {{ .Values.sonarqubeFolder }}/temp
name: sonarqube
subPath: temp
- mountPath: {{ .Values.sonarqubeFolder }}/logs
name: sonarqube
subPath: logs
- mountPath: /tmp
name: tmp-dir
{{- if or .Values.sonarProperties .Values.sonarSecretProperties .Values.sonarSecretKey (not .Values.elasticsearch.bootstrapChecks) }}
- mountPath: {{ .Values.sonarqubeFolder }}/conf/
name: concat-dir
{{- end }}
{{- if .Values.sonarSecretKey }}
- mountPath: {{ .Values.sonarqubeFolder }}/secret/
name: secret
{{- end }}
{{- if .Values.caCerts.enabled }}
- mountPath: {{ .Values.sonarqubeFolder }}/certs
name: sonarqube
subPath: certs
{{- end }}
- mountPath: {{ .Values.sonarqubeFolder }}/extensions
name: sonarqube
subPath: extensions
{{- if .Values.prometheusExporter.enabled }}
- mountPath: {{ .Values.sonarqubeFolder }}/conf/prometheus-config.yaml
subPath: prometheus-config.yaml
name: prometheus-config
- mountPath: {{ .Values.sonarqubeFolder }}/conf/prometheus-ce-config.yaml
subPath: prometheus-ce-config.yaml
name: prometheus-ce-config
{{- end }}
{{- with .Values.persistence.mounts }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.extraVolumeMounts }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.priorityClassName }}
priorityClassName: {{ . }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector: {{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.hostAliases }}
hostAliases: {{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations: {{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.affinity }}
affinity: {{- toYaml . | nindent 4 }}
{{- end }}
serviceAccountName: {{ include "sonarqube.serviceAccountName" . }}
volumes:
{{- with .Values.persistence.volumes }}
{{- tpl (toYaml . | nindent 4) $ }}
{{- end }}
{{- with .Values.extraVolumes }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if or .Values.sonarProperties .Values.sonarSecretKey ( not .Values.elasticsearch.bootstrapChecks) }}
- name: config
configMap:
name: {{ include "sonarqube.fullname" . }}-config
items:
- key: sonar.properties
path: sonar.properties
{{- end }}
{{- if .Values.sonarSecretProperties }}
- name: secret-config
secret:
secretName: {{ .Values.sonarSecretProperties }}
items:
- key: secret.properties
path: secret.properties
{{- end }}
{{- if .Values.sonarSecretKey }}
- name: secret
secret:
secretName: {{ .Values.sonarSecretKey }}
items:
- key: sonar-secret.txt
path: sonar-secret.txt
{{- end }}
{{- include "sonarqube.volumes.caCerts" . | nindent 4 }}
{{- if .Values.plugins.netrcCreds }}
- name: plugins-netrc-file
secret:
secretName: {{ .Values.plugins.netrcCreds }}
items:
- key: netrc
path: .netrc
{{- end }}
{{- if and .Values.jdbcOverwrite.oracleJdbcDriver .Values.jdbcOverwrite.oracleJdbcDriver.netrcCreds }}
- name: oracle-jdbc-driver-netrc-file
secret:
secretName: {{ .Values.jdbcOverwrite.oracleJdbcDriver.netrcCreds }}
items:
- key: netrc
path: .netrc
{{- end }}
{{- if and .Values.initSysctl.enabled (not .Values.OpenShift.enabled) }}
- name: init-sysctl
configMap:
name: {{ include "sonarqube.fullname" . }}-init-sysctl
items:
- key: init_sysctl.sh
path: init_sysctl.sh
{{- end }}
{{- if and .Values.persistence.enabled .Values.initFs.enabled (not .Values.OpenShift.enabled) }}
- name: init-fs
configMap:
name: {{ include "sonarqube.fullname" . }}-init-fs
items:
- key: init_fs.sh
path: init_fs.sh
{{- end }}
{{- if .Values.plugins.install }}
- name: install-plugins
configMap:
name: {{ include "sonarqube.fullname" . }}-install-plugins
items:
- key: install_plugins.sh
path: install_plugins.sh
{{- end }}
{{- if and .Values.jdbcOverwrite.oracleJdbcDriver .Values.jdbcOverwrite.oracleJdbcDriver.url }}
- name: install-oracle-jdbc-driver
configMap:
name: {{ include "sonarqube.fullname" . }}-install-oracle-jdbc-driver
items:
- key: install_oracle_jdbc_driver.sh
path: install_oracle_jdbc_driver.sh
{{- end }}
{{- if .Values.prometheusExporter.enabled }}
- name: prometheus-config
configMap:
name: {{ include "sonarqube.fullname" . }}-prometheus-config
items:
- key: prometheus-config.yaml
path: prometheus-config.yaml
- name: prometheus-ce-config
configMap:
name: {{ include "sonarqube.fullname" . }}-prometheus-ce-config
items:
- key: prometheus-ce-config.yaml
path: prometheus-ce-config.yaml
{{- end }}
- name: sonarqube
{{- if and .Values.persistence.enabled (not .Values.persistence.hostPath) }}
persistentVolumeClaim:
claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ include "sonarqube.fullname" . }}{{- end }}
{{- else if and .Values.persistence.enabled .Values.persistence.hostPath }}
hostPath:
path: {{ .Values.persistence.hostPath.path }}
type: {{ .Values.persistence.hostPath.type }}
{{- else }}
emptyDir: {{- toYaml .Values.emptyDir | nindent 8 }}
{{- end }}
- name : tmp-dir
emptyDir: {{- toYaml .Values.emptyDir | nindent 8 }}
{{- if or .Values.sonarProperties .Values.sonarSecretProperties .Values.sonarSecretKey ( not .Values.elasticsearch.bootstrapChecks) }}
- name : concat-dir
emptyDir: {{- toYaml .Values.emptyDir | nindent 8 }}
{{- end }}
{{- end -}}

View File

@@ -0,0 +1,12 @@
{{- if include "sonarqube.azure.enabled" . }}
{{- $azure := .Values.global.azure }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "sonarqube.fullname" . }}-azure-config
labels: {{- include "sonarqube.labels" . | nindent 4 }}
data:
CLIENT_ID: {{ $azure.identity.clientId | quote }}
EXTENSION_RESOURCE_ID: {{ $azure.extension.resourceId | quote }}
PLAN_ID: {{ $azure.marketplace.planId | quote }}
{{- end }}

View File

@@ -0,0 +1,72 @@
{{ $accountDeprecation := fromYaml (include "accountDeprecation" . ) }}
{{ $_ := set .Values "account" $accountDeprecation }}
{{- if .Values.account }}
{{- if or .Values.account.adminPassword .Values.account.newPassword .Values.account.adminPasswordSecretName .Values.account.passwordSecretName }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ template "sonarqube.fullname" . }}-change-admin-password-hook
labels: {{- include "sonarqube.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": post-install, post-upgrade
"helm.sh/hook-delete-policy": hook-succeeded
{{- range $key, $value := .Values.adminJobAnnotations | default .Values.account.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
template:
metadata:
name: {{ template "sonarqube.fullname" . }}-change-admin-password-hook
labels: {{- include "sonarqube.labels" . | nindent 8 }}
annotations:
# Disable Istio sidecar injection for this hook pod
"sidecar.istio.io/inject": "false"
spec:
restartPolicy: OnFailure
{{- if or .Values.image.pullSecrets .Values.image.pullSecret }}
imagePullSecrets:
{{- if .Values.image.pullSecret }}
- name: {{ .Values.image.pullSecret }}
{{- end }}
{{- with .Values.image.pullSecrets }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}
serviceAccountName: {{ template "sonarqube.serviceAccountName" . }}
{{- with .Values.tolerations }}
tolerations: {{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity: {{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ template "sonarqube.fullname" . }}-change-default-admin-password
image: {{ .Values.curlContainerImage | default ( .Values.account.image | default (include "sonarqube.image" .) ) }}
{{- with (default (fromYaml (include "sonarqube.initContainerSecurityContext" .)) .Values.account.securityContext) }}
securityContext: {{- toYaml . | nindent 10 }}
{{- end }}
command: ["sh", "-c", 'until curl -sSi --connect-timeout 100 {{ template "sonarqube.fullname" . }}:{{ default 9000 .Values.service.internalPort }}{{ .Values.account.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/system/status | grep -w UP; do sleep 10; done; curl -sSi --connect-timeout 100 -u admin:"$CURRENT_ADMIN_PASSWORD" -X POST "{{ template "sonarqube.fullname" . }}:{{ default 9000 .Values.service.internalPort }}{{ .Values.account.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/users/change_password?login=admin" --data-urlencode "previousPassword=$CURRENT_ADMIN_PASSWORD" --data-urlencode "password=$ADMIN_PASSWORD"']
env:
- name: ADMIN_PASSWORD
valueFrom:
secretKeyRef:
{{- if or .Values.account.adminPassword .Values.account.newPassword }}
name: {{ template "sonarqube.fullname" . }}-admin-password
{{- else }}
name: {{ .Values.account.adminPasswordSecretName | default .Values.account.passwordSecretName }}
{{- end }}
key: password
- name: CURRENT_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
{{- if or .Values.account.adminPassword .Values.account.newPassword }}
name: {{ template "sonarqube.fullname" . }}-admin-password
{{- else }}
name: {{ .Values.account.adminPasswordSecretName | default .Values.account.passwordSecretName }}
{{- end }}
key: currentPassword
{{- with (default .Values.resources .Values.account.resources) }}
resources: {{- toYaml . | nindent 10 }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "sonarqube.fullname" . }}-config
labels: {{- include "sonarqube.labels" . | nindent 4 }}
data:
sonar.properties: |
{{- range $key, $val := .Values.sonarProperties }}
{{ $key }}={{ $val }}
{{- end }}
{{- if not .Values.elasticsearch.bootstrapChecks }}
sonar.es.bootstrap.checks.disable=true
{{- end }}
{{- if .Values.sonarSecretKey }}
sonar.secretKeyPath={{ .Values.sonarqubeFolder }}/secret/sonar-secret.txt
{{- end }}

View File

@@ -0,0 +1,16 @@
{{- if eq .Values.deploymentType "Deployment" }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ template "sonarqube.fullname" . }}
labels: {{- include "sonarqube.workloadLabels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
selector:
matchLabels: {{- include "sonarqube.selectorLabels" . | nindent 6 }}
{{- with .Values.deploymentStrategy }}
strategy: {{- toYaml . | nindent 4 }}
{{- end }}
template: {{- include "sonarqube.pod" . | nindent 4 }}
{{- end }}

View File

@@ -0,0 +1,35 @@
{{- if .Values.httproute.enabled -}}
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: {{ template "sonarqube.fullname" . }}-http-route
labels:
{{- include "sonarqube.labels" . | nindent 4 }}
{{- with .Values.httproute.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
parentRefs:
- name: {{ .Values.httproute.gateway }}
{{- if .Values.httproute.gatewayNamespace }}
namespace: {{ .Values.httproute.gatewayNamespace }}
{{- end }}
hostnames:
{{- with .Values.httproute.hostnames }}
{{- toYaml . | nindent 4 }}
{{- end }}
rules:
{{- if .Values.httproute.rules -}}
{{- with .Values.httproute.rules -}}
{{ toYaml . | nindent 4 }}
{{- end }}
{{- else }}
- matches:
- path:
type: PathPrefix
value: {{ include "sonarqube.webcontext" . }}
backendRefs:
- name: {{ include "sonarqube.fullname" . }}
port: {{ .Values.service.externalPort }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,44 @@
{{- if .Values.ingress.enabled -}}
{{- $serviceName := include "sonarqube.fullname" . -}}
{{- $servicePort := .Values.service.externalPort -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ template "sonarqube.fullname" . }}
labels:
{{- include "sonarqube.labels" . | nindent 4 }}
{{- with .Values.ingress.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if or .Values.ingress.annotations (.Values.nginx).enabled (index .Values "ingress-nginx" "enabled") }}
annotations:
{{- range $key, $value := .Values.ingress.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- if and (or (.Values.nginx).enabled (index .Values "ingress-nginx" "enabled")) (not (hasKey (.Values.ingress.annotations) "nginx.ingress.kubernetes.io/proxy-body-size")) }}
nginx.ingress.kubernetes.io/proxy-body-size: "64m"
{{- end -}}
{{- end }}
spec:
{{- if .Values.ingress.ingressClassName }}
ingressClassName: {{ .Values.ingress.ingressClassName }}
{{- else if or (.Values.nginx).enabled (index .Values "ingress-nginx" "enabled") }}
ingressClassName: "nginx"
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ printf "%s" .name }}
http:
paths:
- backend:
service:
name: {{ default $serviceName .serviceName }}
port:
number: {{ default $servicePort .servicePort }}
path: {{ .path | default (include "sonarqube.webcontext" $) }}
pathType: {{ default "ImplementationSpecific" .pathType }}
{{- end }}
{{- with .Values.ingress.tls }}
tls: {{- toYaml . | nindent 4 }}
{{- end -}}
{{- end }}

View File

@@ -0,0 +1,21 @@
{{- if and .Values.persistence.enabled .Values.initFs.enabled (not .Values.OpenShift.enabled) }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "sonarqube.fullname" . }}-init-fs
labels: {{- include "sonarqube.labels" . | nindent 4 }}
data:
init_fs.sh: |-
chown -R {{ .Values.persistence.uid }}:{{ .Values.persistence.guid }} {{ .Values.sonarqubeFolder }}/data
chown -R {{ .Values.persistence.uid }}:{{ .Values.persistence.guid }} {{ .Values.sonarqubeFolder }}/temp
chown -R {{ .Values.persistence.uid }}:{{ .Values.persistence.guid }} {{ .Values.sonarqubeFolder }}/logs
{{- if or .Values.plugins.install (and .Values.jdbcOverwrite.oracleJdbcDriver .Values.jdbcOverwrite.oracleJdbcDriver.url) }}
chown -R {{ .Values.persistence.uid }}:{{ .Values.persistence.guid }} {{ .Values.sonarqubeFolder }}/extensions
{{- end }}
{{- if .Values.caCerts.enabled }}
chown -R {{ .Values.persistence.uid }}:{{ .Values.persistence.guid }} {{ .Values.sonarqubeFolder }}/certs
{{- end }}
{{- range .Values.persistence.mounts }}
chown -R {{ $.Values.persistence.uid }}:{{ $.Values.persistence.guid }} {{ .mountPath }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,51 @@
{{- if and .Values.initSysctl.enabled (not .Values.OpenShift.enabled) }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "sonarqube.fullname" . }}-init-sysctl
labels: {{- include "sonarqube.labels" . | nindent 4 }}
data:
init_sysctl.sh: |-
set -o errexit
set -o xtrace
{{- if .Values.initSysctl.vmMaxMapCount }}
vmMaxMapCount={{ .Values.initSysctl.vmMaxMapCount | int }}
if [[ "$(sysctl -n vm.max_map_count)" -lt $vmMaxMapCount ]]; then
sysctl -w vm.max_map_count=$vmMaxMapCount
if [[ "$(sysctl -n vm.max_map_count)" -lt $vmMaxMapCount ]]; then
echo "Failed to set initSysctl.vmMaxMapCount"; exit 1
fi
fi
{{- end }}
{{- if .Values.initSysctl.fsFileMax }}
fsFileMax={{ .Values.initSysctl.fsFileMax | int }}
if [[ "$(sysctl -n fs.file-max)" -lt $fsFileMax ]]; then
sysctl -w fs.file-max=$fsFileMax
if [[ "$(sysctl -n fs.file-max)" -lt $fsFileMax ]]; then
echo "Failed to set initSysctl.fsFileMax"; exit 1
fi
fi
{{- end }}
{{- if .Values.initSysctl.nofile }}
nofile={{ .Values.initSysctl.nofile | int }}
if [[ "$(ulimit -n)" != "unlimited" ]]; then
if [[ "$(ulimit -n)" -lt $nofile ]]; then
ulimit -n $nofile
if [[ "$(ulimit -n)" -lt $nofile ]]; then
echo "Failed to set initSysctl.nofile"; exit 1
fi
fi
fi
{{- end }}
{{- if .Values.initSysctl.nproc }}
nproc={{ .Values.initSysctl.nproc | int }}
if [[ "$(ulimit -u)" != "unlimited" ]]; then
if [[ "$(ulimit -u)" -lt $nproc ]]; then
ulimit -u $nproc
if [[ "$(ulimit -u)" -lt $nproc ]]; then
echo "Failed to set initSysctl.nproc"; exit 1
fi
fi
fi
{{- end }}
{{- end }}

View File

@@ -0,0 +1,12 @@
{{- if and .Values.jdbcOverwrite.oracleJdbcDriver .Values.jdbcOverwrite.oracleJdbcDriver.url }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "sonarqube.fullname" . }}-install-oracle-jdbc-driver
labels: {{- include "sonarqube.labels" . | nindent 4 }}
data:
install_oracle_jdbc_driver.sh: |-
rm -f {{ .Values.sonarqubeFolder }}/extensions/jdbc-driver/oracle/*
cd {{ .Values.sonarqubeFolder }}/extensions/jdbc-driver/oracle
curl {{- if .Values.caCerts.enabled }} --cacert /tmp/secrets/ca-certs/* {{- end }} {{ if .Values.jdbcOverwrite.oracleJdbcDriver.netrcCreds }}--netrc-file /root/.netrc{{ end }} -fsSLO {{ .Values.jdbcOverwrite.oracleJdbcDriver.url }}
{{- end }}

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "sonarqube.fullname" . }}-install-plugins
labels: {{- include "sonarqube.labels" . | nindent 4 }}
data:
install_plugins.sh: |-
{{- if .Values.plugins.install }}
rm -f {{ .Values.sonarqubeFolder }}/extensions/plugins/*
cd {{ .Values.sonarqubeFolder }}/extensions/plugins
{{- range $index, $val := .Values.plugins.install }}
curl {{ if $.Values.plugins.noCheckCertificate }}--insecure{{ end }} {{ if $.Values.plugins.netrcCreds }}--netrc-file /root/.netrc{{ end }} -fsSLO {{ $val | quote }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,10 @@
{{- if or .Values.jdbcOverwrite.enabled .Values.jdbcOverwrite.enable }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "sonarqube.fullname" . }}-jdbc-config
labels: {{- include "sonarqube.labels" . | nindent 4 }}
data:
SONAR_JDBC_USERNAME: {{ template "jdbc.username" . }}
SONAR_JDBC_URL: {{ .Values.jdbcOverwrite.jdbcUrl | trim | quote }}
{{- end }}

View File

@@ -0,0 +1,67 @@
{{- if .Values.networkPolicy.enabled }}
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ template "sonarqube.fullname" . }}-network-policy
labels: {{- include "sonarqube.labels" . | nindent 4 }}
spec:
podSelector:
matchLabels:
app: {{ template "sonarqube.name" . }}
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: {{ template "sonarqube.name" . }}
release: {{ .Release.Name }}
ports:
- port: {{ .Values.service.internalPort }}
{{ if .Values.prometheusExporter.enabled }}
- from:
- namespaceSelector:
matchLabels:
networking/namespace: {{ .Values.networkPolicy.prometheusNamespace }}
ports:
- port: {{ .Values.prometheusExporter.ceBeanPort }}
protocol: TCP
- port: {{ .Values.prometheusExporter.webBeanPort }}
protocol: TCP
{{ end }}
egress:
- to:
- namespaceSelector:
matchLabels:
networking/namespace: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
- to:
- ipBlock:
cidr: 0.0.0.0/0
{{- end -}}
{{- if and .Values.networkPolicy.enabled (or .Values.networkPolicy.additionalNetworkPolicies .Values.networkPolicy.additionalNetworkPolicys) }}
---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: {{ template "sonarqube.fullname" . }}-additional-network-policy
labels: {{- include "sonarqube.labels" . | nindent 4 }}
spec:
{{- if.Values.networkPolicy.additionalNetworkPolicys -}}
{{- with .Values.networkPolicy.additionalNetworkPolicys -}}
{{ toYaml . | nindent 2 }}
{{- end -}}
{{- else -}}
{{- with .Values.networkPolicy.additionalNetworkPolicies -}}
{{ toYaml . | nindent 2 }}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,10 @@
{{- if .Values.prometheusExporter.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "sonarqube.fullname" . }}-prometheus-ce-config
labels: {{- include "sonarqube.labels" . | nindent 4 }}
data:
prometheus-ce-config.yaml: |-
{{- default .Values.prometheusExporter.config .Values.prometheusExporter.ceConfig | toYaml | nindent 4 }}
{{- end }}

View File

@@ -0,0 +1,10 @@
{{- if .Values.prometheusExporter.enabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "sonarqube.fullname" . }}-prometheus-config
labels: {{- include "sonarqube.labels" . | nindent 4 }}
data:
prometheus-config.yaml: |-
{{- toYaml .Values.prometheusExporter.config | nindent 4 }}
{{- end }}

View File

@@ -0,0 +1,68 @@
{{- if .Values.prometheusMonitoring.podMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: {{ template "sonarqube.name" . }}
{{- if .Values.prometheusMonitoring.podMonitor.namespace }}
namespace: {{ .Values.prometheusMonitoring.podMonitor.namespace | quote }}
{{- else }}
namespace: {{ .Release.Namespace }}
{{- end }}
labels:
app: {{ template "sonarqube.name" . }}
{{- with .Values.prometheusMonitoring.podMonitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.prometheusMonitoring.podMonitor.jobLabel }}
jobLabel: {{ .Values.prometheusMonitoring.podMonitor.jobLabel | quote }}
{{- end }}
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
app: {{ template "sonarqube.name" . }}
podMetricsEndpoints:
- port: http
path: {{ include "sonarqube.webcontext" . }}api/monitoring/metrics
scheme: http
{{- if .Values.prometheusMonitoring.podMonitor.interval }}
interval: {{ .Values.prometheusMonitoring.podMonitor.interval }}
{{- end }}
{{- if .Values.prometheusMonitoring.podMonitor.scrapeTimeout }}
scrapeTimeout: {{ .Values.prometheusMonitoring.podMonitor.scrapeTimeout }}
{{- end }}
bearerTokenSecret:
{{- if and .Values.monitoringPasscodeSecretName .Values.monitoringPasscodeSecretKey }}
name: {{ .Values.monitoringPasscodeSecretName }}
key: {{ .Values.monitoringPasscodeSecretKey }}
{{- else }}
name: {{ template "sonarqube.fullname" . }}-monitoring-passcode
key: SONAR_WEB_SYSTEMPASSCODE
{{- end }}
{{- if .Values.prometheusExporter.enabled }}
{{- if .Values.prometheusExporter.ceBeanPort }}
- port: monitoring-ce
path: /
scheme: http
{{- if .Values.prometheusMonitoring.podMonitor.interval }}
interval: {{ .Values.prometheusMonitoring.podMonitor.interval }}
{{- end }}
{{- if .Values.prometheusMonitoring.podMonitor.scrapeTimeout }}
scrapeTimeout: {{ .Values.prometheusMonitoring.podMonitor.scrapeTimeout }}
{{- end }}
{{- end }}
{{- if .Values.prometheusExporter.webBeanPort }}
- port: monitoring-web
path: /
scheme: http
{{- if .Values.prometheusMonitoring.podMonitor.interval }}
interval: {{ .Values.prometheusMonitoring.podMonitor.interval }}
{{- end }}
{{- if .Values.prometheusMonitoring.podMonitor.scrapeTimeout }}
scrapeTimeout: {{ .Values.prometheusMonitoring.podMonitor.scrapeTimeout }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,26 @@
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: {{ template "sonarqube.fullname" . }}
labels: {{- include "sonarqube.labels" . | nindent 4 }}
{{- if .Values.persistence.annotations }}
annotations:
{{- range $key, $value := .Values.persistence.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
spec:
accessModes:
- {{ .Values.persistence.accessMode | quote }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- if .Values.persistence.storageClass }}
{{- if (eq "-" .Values.persistence.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.persistence.storageClass }}"
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,32 @@
{{- if and .Values.OpenShift.route.enabled .Values.OpenShift.enabled -}}
kind: Route
apiVersion: route.openshift.io/v1
metadata:
name: {{ template "sonarqube.fullname" . }}
labels:
{{- include "sonarqube.labels" . | nindent 4 }}
{{- with .Values.OpenShift.route.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.OpenShift.route.annotations }}
annotations: {{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.OpenShift.route.host }}
host: {{ . }}
{{- end }}
{{- with .Values.OpenShift.route.path }}
path: {{ . }}
{{- end }}
to:
kind: Service
name: {{ include "sonarqube.fullname" . }}
port:
targetPort: http
{{- with .Values.OpenShift.route.tls }}
tls: {{- toYaml . | nindent 4 }}
{{- end -}}
{{- with .Values.OpenShift.route.wildcardPolicy }}
wildcardPolicy: {{ . }}
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,52 @@
{{ $accountDeprecation := fromYaml (include "accountDeprecation" . ) }}
{{ $_ := set .Values "account" $accountDeprecation }}
---
{{- if and (or .Values.jdbcOverwrite.enabled .Values.jdbcOverwrite.enable) (not .Values.jdbcOverwrite.jdbcSecretName) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "sonarqube.fullname" . }}
labels: {{- include "sonarqube.labels" . | nindent 4 }}
type: Opaque
data:
{{ template "jdbc.secretPasswordKey" . }}: {{ template "jdbc.internalSecretPasswd" . }}
{{- end }}
---
{{- if and .Values.monitoringPasscode (not .Values.monitoringPasscodeSecretName) (not .Values.monitoringPasscodeSecretKey) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "sonarqube.fullname" . }}-monitoring-passcode
labels: {{- include "sonarqube.labels" . | nindent 4 }}
type: Opaque
data:
SONAR_WEB_SYSTEMPASSCODE: {{ .Values.monitoringPasscode | b64enc | quote }}
{{- end }}
---
{{- if .Values.account }}
{{- if or .Values.account.adminPassword .Values.account.newPassword }}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "sonarqube.fullname" . }}-admin-password
labels: {{- include "sonarqube.labels" . | nindent 4 }}
type: Opaque
stringData:
password: {{ .Values.account.adminPassword | default .Values.account.newPassword | quote }}
currentPassword: {{ .Values.account.currentAdminPassword | default .Values.account.currentPassword | quote }}
{{- end }}
{{- end }}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ template "sonarqube.fullname" . }}-http-proxies
labels: {{- include "sonarqube.labels" . | nindent 4 }}
type: Opaque
stringData:
PLUGINS-HTTP-PROXY: {{ default .Values.httpProxy .Values.plugins.httpProxy | quote }}
PLUGINS-HTTPS-PROXY: {{ default .Values.httpsProxy .Values.plugins.httpsProxy | quote }}
PLUGINS-NO-PROXY: {{ default .Values.noProxy .Values.plugins.noProxy | quote }}
PROMETHEUS-EXPORTER-HTTP-PROXY: {{ default .Values.httpProxy .Values.prometheusExporter.httpProxy | quote }}
PROMETHEUS-EXPORTER-HTTPS-PROXY: {{ default .Values.httpsProxy .Values.prometheusExporter.httpsProxy | quote }}
PROMETHEUS-EXPORTER-NO-PROXY: {{ default .Values.noProxy .Values.prometheusExporter.noProxy | quote }}

View File

@@ -0,0 +1,39 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "sonarqube.fullname" . }}
labels:
{{- include "sonarqube.labels" . | nindent 4 }}
{{- range $key, $value := .Values.service.labels }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- if .Values.service.annotations }}
annotations:
{{- range $key, $value := .Values.service.annotations }}
{{ $key }}: {{ $value | quote }}
{{- end }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.externalPort }}
targetPort: http
protocol: TCP
name: http
{{- if .Values.service.nodePort }}
nodePort: {{ .Values.service.nodePort }}
{{- end }}
selector:
app: {{ template "sonarqube.name" . }}
release: {{ .Release.Name }}
{{- if eq .Values.service.type "LoadBalancer" }}
{{- if .Values.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{- range .Values.service.loadBalancerSourceRanges }}
- {{ . }}
{{- end }}
{{- end -}}
{{- if .Values.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,12 @@
{{- if .Values.serviceAccount.create -}}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "sonarqube.serviceAccountName" . }}
{{- with .Values.serviceAccount.annotations }}
annotations: {{- toYaml . | nindent 4 }}
{{- end }}
labels: {{- include "sonarqube.labels" . | nindent 4 }}
automountServiceAccountToken: {{ .Values.serviceAccount.automountToken }}
{{- end -}}

View File

@@ -0,0 +1,60 @@
{{- if and (.Values.OpenShift.enabled) (.Values.OpenShift.createSCC) }}
# This SCC allows any user ID but restricts capabilties and host access
apiVersion: security.openshift.io/v1
kind: SecurityContextConstraints
metadata:
annotations:
kubernetes.io/description: "allows pod to run as root, privileged and run sysctl"
"helm.sh/hook": pre-install
name: {{ .Release.Name }}-privileged-scc
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegedContainer: true
allowPrivilegeEscalation: true
allowedCapabilities: []
allowedFlexVolumes: []
allowedUnsafeSysctls: []
defaultAddCapabilities: []
defaultAllowPrivilegeEscalation: true
fsGroup:
type: RunAsAny
readOnlyRootFilesystem: false
requiredDropCapabilities:
- KILL
- MKNOD
- SETUID
- SETGID
runAsUser:
type: RunAsAny
# This can be customized for your host machine
seLinuxContext:
type: MustRunAs
# seLinuxOptions:
# level:
# user:
# role:
# type:
supplementalGroups:
type: RunAsAny
# This can be customized for your host machine
volumes:
- configMap
- downwardAPI
- emptyDir
- persistentVolumeClaim
- projected
- secret
# If you want a priority on your SCC -- set for a value more than 0
priority: 11
users:
{{- if .Values.serviceAccount.name }}
- system:serviceaccount:{{ .Release.Namespace }}:{{ .Values.serviceAccount.name }}
{{- else }}
- system:serviceaccount:{{ .Release.Namespace }}:{{ .Release.Name }}-sonarqube
{{- end }}
{{- end }}

View File

@@ -0,0 +1,14 @@
{{- if eq .Values.deploymentType "StatefulSet" -}}
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ template "sonarqube.fullname" . }}
labels: {{- include "sonarqube.workloadLabels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
serviceName: {{ template "sonarqube.fullname" . }}
selector:
matchLabels: {{- include "sonarqube.selectorLabels" . | nindent 6 }}
template: {{- include "sonarqube.pod" . | nindent 4 }}
{{- end }}

View File

@@ -0,0 +1,42 @@
{{- if .Values.tests.enabled -}}
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-ui-test"
annotations:
"helm.sh/hook": test-success
# Disable Istio sidecar injection for this test pod
"sidecar.istio.io/inject": "false"
labels: {{- include "sonarqube.labels" . | nindent 4 }}
spec:
automountServiceAccountToken: false
{{- if or .Values.image.pullSecrets .Values.image.pullSecret }}
imagePullSecrets:
{{- if .Values.image.pullSecret }}
- name: {{ .Values.image.pullSecret }}
{{- end }}
{{- with .Values.image.pullSecrets }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
containers:
- name: {{ .Release.Name }}-ui-test
image: {{ .Values.tests.image | default (include "sonarqube.image" .) | quote }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ['curl']
args: [
'--retry-connrefused',
'--retry',
'12',
'--retry-delay',
'1',
'--max-time',
'5',
'-s',
'{{ template "sonarqube.fullname" . }}:{{ .Values.service.internalPort }}/api/system/status'
]
{{- with .Values.tests.resources }}
resources: {{- toYaml . | nindent 8 }}
{{- end }}
restartPolicy: Never
{{- end -}}

View File

@@ -0,0 +1,29 @@
{{/*
This file is for validating the values.yaml file.
It is used to validate the values.yaml file before the installation starts.
*/}}
{{- define "sonarqube.fail" -}}
{{- printf "\n ** The values.yaml file is not valid. ** \n %s\n" . | fail -}}
{{- end -}}
{{/*
* Validates the monitoring passcode logic.
*/}}
{{- if or (and (not .Values.monitoringPasscode) (not .Values.monitoringPasscodeSecretName) (not .Values.monitoringPasscodeSecretKey)) (and (not .Values.monitoringPasscodeSecretName) .Values.monitoringPasscodeSecretKey) (and .Values.monitoringPasscodeSecretName (not .Values.monitoringPasscodeSecretKey)) -}}
{{- include "sonarqube.fail" "Please provide a passcode either setting \"monitoringPasscode\" or \"monitoringPasscodeSecretName\" and \"monitoringPasscodeSecretKey\"" -}}
{{- end -}}
{{/*
* Validates the community.enabled, edition, and tag logic.
*/}}
{{- if eq .Values.edition "community" -}}
{{- include "sonarqube.fail" "'community' is not a valid edition. If you want to use SonarQube Community Build, unset 'edition' and set 'community.enabled=true' instead." -}}
{{- else if and (.Values.community.enabled) (not (empty .Values.edition)) -}}
{{- include "sonarqube.fail" "You can't set 'community.enabled=true' and an 'edition' at the same time." -}}
{{- else if not .Values.community.enabled -}}
{{- if empty .Values.edition -}}
{{- include "sonarqube.fail" "You must choose an 'edition' to install: 'developer' or 'enterprise'. If you want to use SonarQube Community Build, unset 'edition' and set 'community.enabled=true' instead." -}}
{{- else if not (has .Values.edition (list "developer" "enterprise")) -}}
{{- include "sonarqube.fail" "The 'edition' must be either 'developer' or 'enterprise'." -}}
{{- end -}}
{{- end -}}