Add Jenkins Helm Chart with initial configuration, README, and changelog, using previous values.yaml

This commit is contained in:
2026-04-12 17:10:24 +07:00
parent 886f56059f
commit 48f18f4c8c
38 changed files with 7662 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
{{- $prefix := .Values.controller.jenkinsUriPrefix | default "" -}}
{{- $url := "" -}}
1. Get your '{{ .Values.controller.admin.username }}' user password by running:
kubectl exec --namespace {{ template "jenkins.namespace" . }} -it svc/{{ template "jenkins.fullname" . }} -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo
{{- if .Values.controller.ingress.hostName -}}
{{- if .Values.controller.ingress.tls -}}
{{- $url = print "https://" .Values.controller.ingress.hostName $prefix -}}
{{- else -}}
{{- $url = print "http://" .Values.controller.ingress.hostName $prefix -}}
{{- end }}
2. Visit {{ $url }}
{{- else }}
2. Get the Jenkins URL to visit by running these commands in the same shell:
{{- if contains "NodePort" .Values.controller.serviceType }}
export NODE_PORT=$(kubectl get --namespace {{ template "jenkins.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "jenkins.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ template "jenkins.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}")
{{- if .Values.controller.httpsKeyStore.enable -}}
{{- $url = print "https://$NODE_IP:$NODE_PORT" $prefix -}}
{{- else -}}
{{- $url = print "http://$NODE_IP:$NODE_PORT" $prefix -}}
{{- end }}
echo {{ $url }}
{{- else if contains "LoadBalancer" .Values.controller.serviceType }}
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 --namespace {{ template "jenkins.namespace" . }} -w {{ template "jenkins.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ template "jenkins.namespace" . }} {{ template "jenkins.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}")
{{- if .Values.controller.httpsKeyStore.enable -}}
{{- $url = print "https://$SERVICE_IP:" .Values.controller.servicePort $prefix -}}
{{- else -}}
{{- $url = print "http://$SERVICE_IP:" .Values.controller.servicePort $prefix -}}
{{- end }}
echo {{ $url }}
{{- else if contains "ClusterIP" .Values.controller.serviceType -}}
{{- if .Values.controller.httpsKeyStore.enable -}}
{{- $url = print "https://127.0.0.1:" .Values.controller.servicePort $prefix -}}
{{- else -}}
{{- $url = print "http://127.0.0.1:" .Values.controller.servicePort $prefix -}}
{{- end }}
echo {{ $url }}
kubectl --namespace {{ template "jenkins.namespace" . }} port-forward svc/{{template "jenkins.fullname" . }} {{ .Values.controller.servicePort }}:{{ .Values.controller.servicePort }}
{{- end }}
{{- end }}
3. Login with the password from step 1 and the username: {{ .Values.controller.admin.username }}
4. Configure security realm and authorization strategy
5. Use Jenkins Configuration as Code by specifying configScripts in your values.yaml file, see documentation: {{ $url }}/configuration-as-code and examples: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos
For more information on running Jenkins on Kubernetes, visit:
https://cloud.google.com/solutions/jenkins-on-container-engine
For more information about Jenkins Configuration as Code, visit:
https://jenkins.io/projects/jcasc/
{{ if and (eq .Values.controller.image.repository "jenkins/jenkins") (eq .Values.controller.image.registry "docker.io") }}
NOTE: Consider using a custom image with pre-installed plugins
{{- else if .Values.controller.installPlugins }}
NOTE: Consider disabling `installPlugins` if your image already contains plugins.
{{- end }}
{{- if .Values.persistence.enabled }}
{{- else }}
#################################################################################
###### WARNING: Persistence is disabled!!! You will lose your data when #####
###### the Jenkins pod is terminated. #####
#################################################################################
{{- end }}
+724
View File
@@ -0,0 +1,724 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "jenkins.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Expand the label of the chart.
*/}}
{{- define "jenkins.label" -}}
{{- printf "%s-%s" (include "jenkins.name" .) .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels for all Jenkins resources
*/}}
{{- define "jenkins.labels" -}}
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
"app.kubernetes.io/managed-by": "{{ .Release.Service }}"
"app.kubernetes.io/instance": "{{ .Release.Name }}"
"app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
{{- if .Values.renderHelmLabels }}
"helm.sh/chart": "{{ template "jenkins.label" .}}"
{{- end }}
{{- with .Values.extraLabels }}
{{- toYaml . | nindent 0 }}
{{- end }}
{{- end -}}
{{/*
Allow the release namespace to be overridden for multi-namespace deployments in combined charts.
*/}}
{{- define "jenkins.namespace" -}}
{{- if .Values.namespaceOverride -}}
{{- .Values.namespaceOverride -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}
{{- define "jenkins.agent.namespace" -}}
{{- if .Values.agent.namespace -}}
{{- tpl .Values.agent.namespace . -}}
{{- else -}}
{{- if .Values.namespaceOverride -}}
{{- .Values.namespaceOverride -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- end -}}
{{- 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 "jenkins.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 -}}
{{/*
Returns the admin password
https://github.com/helm/charts/issues/5167#issuecomment-619137759
*/}}
{{- define "jenkins.password" -}}
{{- if .Values.controller.admin.password -}}
{{- .Values.controller.admin.password | b64enc | quote }}
{{- else -}}
{{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "jenkins.fullname" .)).data -}}
{{- if $secret -}}
{{/*
Reusing current password since secret exists
*/}}
{{- index $secret ( .Values.controller.admin.passwordKey | default "jenkins-admin-password" ) -}}
{{- else -}}
{{/*
Generate new password
*/}}
{{- randAlphaNum 22 | b64enc | quote }}
{{- end -}}
{{- end -}}
{{- end -}}
{{/*
Returns the Jenkins URL
*/}}
{{- define "jenkins.url" -}}
{{- if .Values.controller.jenkinsUrl }}
{{- .Values.controller.jenkinsUrl }}
{{- else }}
{{- if .Values.controller.ingress.hostName }}
{{- if .Values.controller.ingress.tls }}
{{- default "https" .Values.controller.jenkinsUrlProtocol }}://{{ tpl .Values.controller.ingress.hostName $ }}{{ default "" .Values.controller.jenkinsUriPrefix }}
{{- else }}
{{- default "http" .Values.controller.jenkinsUrlProtocol }}://{{ tpl .Values.controller.ingress.hostName $ }}{{ default "" .Values.controller.jenkinsUriPrefix }}
{{- end }}
{{- else }}
{{- default "http" .Values.controller.jenkinsUrlProtocol }}://{{ template "jenkins.fullname" . }}:{{.Values.controller.servicePort}}{{ default "" .Values.controller.jenkinsUriPrefix }}
{{- end}}
{{- end}}
{{- end -}}
{{/*
Returns configuration as code default config
*/}}
{{- define "jenkins.casc.defaults" -}}
jenkins:
{{- $configScripts := toYaml .Values.controller.JCasC.configScripts }}
{{- if and (.Values.controller.JCasC.authorizationStrategy) (not (contains "authorizationStrategy:" $configScripts)) }}
authorizationStrategy:
{{- tpl .Values.controller.JCasC.authorizationStrategy . | nindent 4 }}
{{- end }}
{{- if and (.Values.controller.JCasC.securityRealm) (not (contains "securityRealm:" $configScripts)) }}
securityRealm:
{{- tpl .Values.controller.JCasC.securityRealm . | nindent 4 }}
{{- end }}
disableRememberMe: {{ .Values.controller.disableRememberMe }}
{{- if .Values.controller.legacyRemotingSecurityEnabled }}
remotingSecurity:
enabled: true
{{- end }}
mode: {{ .Values.controller.executorMode }}
numExecutors: {{ .Values.controller.numExecutors }}
{{- if not (kindIs "invalid" .Values.controller.customJenkinsLabels) }}
labelString: "{{ join " " .Values.controller.customJenkinsLabels }}"
{{- end }}
{{- if .Values.controller.projectNamingStrategy }}
{{- if kindIs "string" .Values.controller.projectNamingStrategy }}
projectNamingStrategy: "{{ .Values.controller.projectNamingStrategy }}"
{{- else }}
projectNamingStrategy:
{{- toYaml .Values.controller.projectNamingStrategy | nindent 4 }}
{{- end }}
{{- end }}
markupFormatter:
{{- if .Values.controller.enableRawHtmlMarkupFormatter }}
rawHtml:
disableSyntaxHighlighting: true
{{- else }}
{{- toYaml .Values.controller.markupFormatter | nindent 4 }}
{{- end }}
clouds:
- kubernetes:
containerCapStr: "{{ .Values.agent.containerCap }}"
{{- if .Values.agent.garbageCollection.enabled }}
garbageCollection:
{{- if .Values.agent.garbageCollection.namespaces }}
namespaces: |-
{{- .Values.agent.garbageCollection.namespaces | nindent 10 }}
{{- end }}
timeout: "{{ .Values.agent.garbageCollection.timeout }}"
{{- end }}
{{- if .Values.agent.jnlpregistry }}
jnlpregistry: "{{ .Values.agent.jnlpregistry }}"
{{- end }}
defaultsProviderTemplate: "{{ .Values.agent.defaultsProviderTemplate }}"
connectTimeout: "{{ .Values.agent.kubernetesConnectTimeout }}"
readTimeout: "{{ .Values.agent.kubernetesReadTimeout }}"
{{- if .Values.agent.directConnection }}
directConnection: true
{{- else }}
{{- if .Values.agent.jenkinsUrl }}
jenkinsUrl: "{{ tpl .Values.agent.jenkinsUrl . }}"
{{- else }}
jenkinsUrl: "http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{.Values.controller.servicePort}}{{ default "" .Values.controller.jenkinsUriPrefix }}"
{{- end }}
{{- if not .Values.agent.websocket }}
{{- if .Values.agent.jenkinsTunnel }}
jenkinsTunnel: "{{ tpl .Values.agent.jenkinsTunnel . }}"
{{- else }}
jenkinsTunnel: "{{ template "jenkins.fullname" . }}-agent.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{ .Values.controller.agentListenerPort }}"
{{- end }}
{{- else }}
webSocket: true
{{- end }}
{{- end }}
skipTlsVerify: {{ .Values.agent.skipTlsVerify | default false}}
usageRestricted: {{ .Values.agent.usageRestricted | default false}}
maxRequestsPerHostStr: {{ .Values.agent.maxRequestsPerHostStr | quote }}
retentionTimeout: {{ .Values.agent.retentionTimeout | quote }}
waitForPodSec: {{ .Values.agent.waitForPodSec | quote }}
name: "{{ .Values.controller.cloudName }}"
namespace: "{{ template "jenkins.agent.namespace" . }}"
restrictedPssSecurityContext: {{ .Values.agent.restrictedPssSecurityContext }}
serverUrl: "{{ .Values.kubernetesURL }}"
credentialsId: "{{ .Values.credentialsId }}"
{{- if .Values.agent.enabled }}
podLabels:
- key: "jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}"
value: "true"
{{- range $key, $val := .Values.agent.podLabels }}
- key: {{ $key | quote }}
value: {{ $val | quote }}
{{- end }}
templates:
{{- if not .Values.agent.disableDefaultAgent }}
{{- include "jenkins.casc.podTemplate" . | nindent 8 }}
{{- end }}
{{- if .Values.additionalAgents }}
{{- /* save .Values.agent */}}
{{- $agent := .Values.agent }}
{{- range $name, $additionalAgent := .Values.additionalAgents }}
{{- $additionalContainersEmpty := and (hasKey $additionalAgent "additionalContainers") (empty $additionalAgent.additionalContainers) }}
{{- /* merge original .Values.agent into additional agent to ensure it at least has the default values */}}
{{- $additionalAgent := merge $additionalAgent $agent }}
{{- /* clear list of additional containers in case it is configured empty for this agent (merge might have overwritten that) */}}
{{- if $additionalContainersEmpty }}
{{- $_ := set $additionalAgent "additionalContainers" list }}
{{- end }}
{{- /* set .Values.agent to $additionalAgent */}}
{{- $_ := set $.Values "agent" $additionalAgent }}
{{- include "jenkins.casc.podTemplate" $ | nindent 8 }}
{{- end }}
{{- /* restore .Values.agent */}}
{{- $_ := set .Values "agent" $agent }}
{{- end }}
{{- if .Values.agent.podTemplates }}
{{- range $key, $val := .Values.agent.podTemplates }}
{{- tpl $val $ | nindent 8 }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.additionalClouds }}
{{- /* save root */}}
{{- $oldRoot := deepCopy $ }}
{{- range $name, $additionalCloud := .Values.additionalClouds }}
{{- $newRoot := deepCopy $ }}
{{- /* clear additionalAgents from the copy if override set to `true` */}}
{{- if .additionalAgentsOverride }}
{{- $_ := set $newRoot.Values "additionalAgents" list}}
{{- end}}
{{- $newValues := merge $additionalCloud $newRoot.Values }}
{{- $_ := set $newRoot "Values" $newValues }}
{{- /* clear additionalClouds from the copy */}}
{{- $_ := set $newRoot.Values "additionalClouds" list }}
{{- with $newRoot}}
- kubernetes:
containerCapStr: "{{ .Values.agent.containerCap }}"
{{- if .Values.agent.garbageCollection.enabled }}
garbageCollection:
{{- if .Values.agent.garbageCollection.namespaces }}
namespaces: |-
{{- .Values.agent.garbageCollection.namespaces | nindent 10 }}
{{- end }}
timeout: "{{ .Values.agent.garbageCollection.timeout }}"
{{- end }}
{{- if .Values.agent.jnlpregistry }}
jnlpregistry: "{{ .Values.agent.jnlpregistry }}"
{{- end }}
defaultsProviderTemplate: "{{ .Values.agent.defaultsProviderTemplate }}"
connectTimeout: "{{ .Values.agent.kubernetesConnectTimeout }}"
readTimeout: "{{ .Values.agent.kubernetesReadTimeout }}"
{{- if .Values.agent.directConnection }}
directConnection: true
{{- else }}
{{- if .Values.agent.jenkinsUrl }}
jenkinsUrl: "{{ tpl .Values.agent.jenkinsUrl . }}"
{{- else }}
jenkinsUrl: "http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{.Values.controller.servicePort}}{{ default "" .Values.controller.jenkinsUriPrefix }}"
{{- end }}
{{- if not .Values.agent.websocket }}
{{- if .Values.agent.jenkinsTunnel }}
jenkinsTunnel: "{{ tpl .Values.agent.jenkinsTunnel . }}"
{{- else }}
jenkinsTunnel: "{{ template "jenkins.fullname" . }}-agent.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{ .Values.controller.agentListenerPort }}"
{{- end }}
{{- else }}
webSocket: true
{{- end }}
{{- end }}
skipTlsVerify: {{ .Values.agent.skipTlsVerify | default false}}
usageRestricted: {{ .Values.agent.usageRestricted | default false}}
maxRequestsPerHostStr: {{ .Values.agent.maxRequestsPerHostStr | quote }}
retentionTimeout: {{ .Values.agent.retentionTimeout | quote }}
waitForPodSec: {{ .Values.agent.waitForPodSec | quote }}
name: {{ $name | quote }}
namespace: "{{ template "jenkins.agent.namespace" . }}"
restrictedPssSecurityContext: {{ .Values.agent.restrictedPssSecurityContext }}
serverUrl: "{{ .Values.kubernetesURL }}"
credentialsId: "{{ .Values.credentialsId }}"
{{- if .Values.agent.enabled }}
podLabels:
- key: "jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}"
value: "true"
{{- range $key, $val := .Values.agent.podLabels }}
- key: {{ $key | quote }}
value: {{ $val | quote }}
{{- end }}
templates:
{{- if not .Values.agent.disableDefaultAgent }}
{{- include "jenkins.casc.podTemplate" . | nindent 8 }}
{{- end }}
{{- if .Values.additionalAgents }}
{{- /* save .Values.agent */}}
{{- $agent := .Values.agent }}
{{- range $name, $additionalAgent := .Values.additionalAgents }}
{{- $additionalContainersEmpty := and (hasKey $additionalAgent "additionalContainers") (empty $additionalAgent.additionalContainers) }}
{{- /* merge original .Values.agent into additional agent to ensure it at least has the default values */}}
{{- $additionalAgent := merge $additionalAgent $agent }}
{{- /* clear list of additional containers in case it is configured empty for this agent (merge might have overwritten that) */}}
{{- if $additionalContainersEmpty }}
{{- $_ := set $additionalAgent "additionalContainers" list }}
{{- end }}
{{- /* set .Values.agent to $additionalAgent */}}
{{- $_ := set $.Values "agent" $additionalAgent }}
{{- include "jenkins.casc.podTemplate" $ | nindent 8 }}
{{- end }}
{{- /* restore .Values.agent */}}
{{- $_ := set .Values "agent" $agent }}
{{- end }}
{{- with .Values.agent.podTemplates }}
{{- range $key, $val := . }}
{{- tpl $val $ | nindent 8 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- /* restore root */}}
{{- $_ := set $ "Values" $oldRoot.Values }}
{{- end }}
slaveAgentPort: {{ .Values.controller.agentListenerPort }}
{{- if and .Values.controller.csrf.defaultCrumbIssuer.enabled (eq .Chart.AppVersion (index (splitList "-" (include "controller.image.tag" .)) 0)) (lt (atoi (index (splitList "." .Chart.AppVersion) 1)) 543) }}
crumbIssuer:
standard:
excludeClientIPFromCrumb: {{ if .Values.controller.csrf.defaultCrumbIssuer.proxyCompatability }}true{{ else }}false{{- end }}
{{- end }}
{{- include "jenkins.casc.security" . }}
{{- with .Values.controller.scriptApproval }}
scriptApproval:
approvedSignatures:
{{- range $key, $val := . }}
- "{{ $val }}"
{{- end }}
{{- end }}
unclassified:
location:
{{- with .Values.controller.jenkinsAdminEmail }}
adminAddress: {{ . }}
{{- end }}
url: {{ template "jenkins.url" . }}
{{- end -}}
{{/*
Returns a name template to be used for jcasc configmaps, using
suffix passed in at call as index 0
*/}}
{{- define "jenkins.casc.configName" -}}
{{- $name := index . 0 -}}
{{- $root := index . 1 -}}
"{{- include "jenkins.fullname" $root -}}-jenkins-{{ $name }}"
{{- end -}}
{{/*
Returns kubernetes pod template configuration as code
*/}}
{{- define "jenkins.casc.podTemplate" -}}
- name: "{{ .Values.agent.podName }}"
namespace: "{{ template "jenkins.agent.namespace" . }}"
{{- if .Values.agent.annotations }}
annotations:
{{- range $key, $value := .Values.agent.annotations }}
- key: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- end }}
id: {{ sha256sum (toYaml .Values.agent) }}
containers:
- name: "{{ .Values.agent.sideContainerName }}"
alwaysPullImage: {{ .Values.agent.alwaysPullImage }}
args: "{{ .Values.agent.args | replace "$" "^$" }}"
{{- with .Values.agent.command }}
command: {{ . }}
{{- end }}
envVars:
- envVar:
{{- if .Values.agent.directConnection }}
key: "JENKINS_DIRECT_CONNECTION"
{{- if .Values.agent.jenkinsTunnel }}
value: "{{ tpl .Values.agent.jenkinsTunnel . }}"
{{- else }}
value: "{{ template "jenkins.fullname" . }}-agent.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{ .Values.controller.agentListenerPort }}"
{{- end }}
{{- else }}
key: "JENKINS_URL"
{{- if .Values.agent.jenkinsUrl }}
value: {{ tpl .Values.agent.jenkinsUrl . }}
{{- else }}
value: "http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{.Values.controller.servicePort}}{{ default "/" .Values.controller.jenkinsUriPrefix }}"
{{- end }}
{{- end }}
{{- if ne .Values.agent.image.registry "" }}
image: "{{ .Values.agent.image.registry}}/{{ .Values.agent.image.repository }}:{{ .Values.agent.image.tag }}"
{{- else }}
image: "{{ .Values.agent.image.repository }}:{{ .Values.agent.image.tag }}"
{{- end }}
{{- if .Values.agent.livenessProbe }}
livenessProbe:
execArgs: {{.Values.agent.livenessProbe.execArgs | quote}}
failureThreshold: {{.Values.agent.livenessProbe.failureThreshold}}
initialDelaySeconds: {{.Values.agent.livenessProbe.initialDelaySeconds}}
periodSeconds: {{.Values.agent.livenessProbe.periodSeconds}}
successThreshold: {{.Values.agent.livenessProbe.successThreshold}}
timeoutSeconds: {{.Values.agent.livenessProbe.timeoutSeconds}}
{{- end }}
privileged: "{{- if .Values.agent.privileged }}true{{- else }}false{{- end }}"
resourceLimitCpu: {{.Values.agent.resources.limits.cpu}}
resourceLimitMemory: {{.Values.agent.resources.limits.memory}}
{{- with .Values.agent.resources.limits.ephemeralStorage }}
resourceLimitEphemeralStorage: {{.}}
{{- end }}
resourceRequestCpu: {{.Values.agent.resources.requests.cpu}}
resourceRequestMemory: {{.Values.agent.resources.requests.memory}}
{{- with .Values.agent.resources.requests.ephemeralStorage }}
resourceRequestEphemeralStorage: {{.}}
{{- end }}
{{- with .Values.agent.runAsUser }}
runAsUser: {{ . }}
{{- end }}
{{- with .Values.agent.runAsGroup }}
runAsGroup: {{ . }}
{{- end }}
ttyEnabled: {{ .Values.agent.TTYEnabled }}
workingDir: {{ .Values.agent.workingDir }}
{{- range $additionalContainers := .Values.agent.additionalContainers }}
- name: "{{ $additionalContainers.sideContainerName }}"
alwaysPullImage: {{ $additionalContainers.alwaysPullImage | default $.Values.agent.alwaysPullImage }}
args: "{{ $additionalContainers.args | replace "$" "^$" }}"
{{- with $additionalContainers.command }}
command: {{ . }}
{{- end }}
envVars:
- envVar:
key: "JENKINS_URL"
{{- if $additionalContainers.jenkinsUrl }}
value: {{ tpl ($additionalContainers.jenkinsUrl) . }}
{{- else }}
value: "http://{{ template "jenkins.fullname" $ }}.{{ template "jenkins.namespace" $ }}.svc.{{ $.Values.clusterZone }}:{{ $.Values.controller.servicePort }}{{ default "/" $.Values.controller.jenkinsUriPrefix }}"
{{- end }}
image: "{{ $additionalContainers.image.repository }}:{{ $additionalContainers.image.tag }}"
{{- if $additionalContainers.livenessProbe }}
livenessProbe:
execArgs: {{$additionalContainers.livenessProbe.execArgs | quote}}
failureThreshold: {{$additionalContainers.livenessProbe.failureThreshold}}
initialDelaySeconds: {{$additionalContainers.livenessProbe.initialDelaySeconds}}
periodSeconds: {{$additionalContainers.livenessProbe.periodSeconds}}
successThreshold: {{$additionalContainers.livenessProbe.successThreshold}}
timeoutSeconds: {{$additionalContainers.livenessProbe.timeoutSeconds}}
{{- end }}
privileged: "{{- if $additionalContainers.privileged }}true{{- else }}false{{- end }}"
resourceLimitCpu: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.limits.cpu }}{{ else }}{{ $.Values.agent.resources.limits.cpu }}{{ end }}
resourceLimitMemory: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.limits.memory }}{{ else }}{{ $.Values.agent.resources.limits.memory }}{{ end }}
resourceRequestCpu: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.requests.cpu }}{{ else }}{{ $.Values.agent.resources.requests.cpu }}{{ end }}
resourceRequestMemory: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.requests.memory }}{{ else }}{{ $.Values.agent.resources.requests.memory }}{{ end }}
{{- if or $additionalContainers.runAsUser $.Values.agent.runAsUser }}
runAsUser: {{ $additionalContainers.runAsUser | default $.Values.agent.runAsUser }}
{{- end }}
{{- if or $additionalContainers.runAsGroup $.Values.agent.runAsGroup }}
runAsGroup: {{ $additionalContainers.runAsGroup | default $.Values.agent.runAsGroup }}
{{- end }}
ttyEnabled: {{ $additionalContainers.TTYEnabled | default $.Values.agent.TTYEnabled }}
workingDir: {{ $additionalContainers.workingDir | default $.Values.agent.workingDir }}
{{- end }}
{{- if or .Values.agent.envVars .Values.agent.secretEnvVars }}
envVars:
{{- range $index, $var := .Values.agent.envVars }}
- envVar:
key: {{ $var.name }}
value: {{ tpl $var.value $ }}
{{- end }}
{{- range $index, $var := .Values.agent.secretEnvVars }}
- secretEnvVar:
key: {{ $var.key }}
secretName: {{ $var.secretName }}
secretKey: {{ $var.secretKey }}
optional: {{ $var.optional | default false }}
{{- end }}
{{- end }}
idleMinutes: {{ .Values.agent.idleMinutes }}
instanceCap: {{ int .Values.agent.instanceCap }}
{{- if .Values.agent.hostNetworking }}
hostNetwork: {{ .Values.agent.hostNetworking }}
{{- end }}
{{- if .Values.agent.imagePullSecretName }}
imagePullSecrets:
- name: {{ .Values.agent.imagePullSecretName }}
{{- end }}
label: "{{ .Release.Name }}-{{ .Values.agent.componentName }} {{ .Values.agent.customJenkinsLabels | join " " }}"
{{- if .Values.agent.nodeSelector }}
nodeSelector:
{{- $local := dict "first" true }}
{{- range $key, $value := .Values.agent.nodeSelector }}
{{- if $local.first }} {{ else }},{{ end }}
{{- $key }}={{ tpl $value $ }}
{{- $_ := set $local "first" false }}
{{- end }}
{{- end }}
nodeUsageMode: {{ quote .Values.agent.nodeUsageMode }}
podRetention: {{ .Values.agent.podRetention }}
showRawYaml: {{ .Values.agent.showRawYaml }}
{{- $asaname := default (include "jenkins.serviceAccountAgentName" .) .Values.agent.serviceAccount -}}
{{- if or (.Values.agent.useDefaultServiceAccount) (.Values.agent.serviceAccount) }}
serviceAccount: "{{ $asaname }}"
{{- end }}
slaveConnectTimeoutStr: "{{ .Values.agent.connectTimeout }}"
{{- if .Values.agent.volumes }}
volumes:
{{- range $index, $volume := .Values.agent.volumes }}
-{{- if (eq $volume.type "ConfigMap") }} configMapVolume:
{{- else if (eq $volume.type "EmptyDir") }} emptyDirVolume:
{{- else if (eq $volume.type "EphemeralVolume") }} genericEphemeralVolume:
{{- else if (eq $volume.type "HostPath") }} hostPathVolume:
{{- else if (eq $volume.type "Nfs") }} nfsVolume:
{{- else if (eq $volume.type "PVC") }} persistentVolumeClaim:
{{- else if (eq $volume.type "Secret") }} secretVolume:
{{- else }} {{ $volume.type }}:
{{- end }}
{{- range $key, $value := $volume }}
{{- if not (eq $key "type") }}
{{ $key }}: {{ if kindIs "string" $value }}{{ tpl $value $ | quote }}{{ else }}{{ $value }}{{ end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.agent.workspaceVolume }}
workspaceVolume:
{{- if (eq .Values.agent.workspaceVolume.type "DynamicPVC") }}
dynamicPVC:
{{- else if (eq .Values.agent.workspaceVolume.type "EmptyDir") }}
emptyDirWorkspaceVolume:
{{- else if (eq .Values.agent.workspaceVolume.type "EphemeralVolume") }}
genericEphemeralVolume:
{{- else if (eq .Values.agent.workspaceVolume.type "HostPath") }}
hostPathWorkspaceVolume:
{{- else if (eq .Values.agent.workspaceVolume.type "Nfs") }}
nfsWorkspaceVolume:
{{- else if (eq .Values.agent.workspaceVolume.type "PVC") }}
persistentVolumeClaimWorkspaceVolume:
{{- else }}
{{ .Values.agent.workspaceVolume.type }}:
{{- end }}
{{- range $key, $value := .Values.agent.workspaceVolume }}
{{- if not (eq $key "type") }}
{{ $key }}: {{ if kindIs "string" $value }}{{ tpl $value $ | quote }}{{ else }}{{ $value }}{{ end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.agent.yamlTemplate }}
yaml: |-
{{- tpl (trim .Values.agent.yamlTemplate) . | nindent 4 }}
{{- end }}
yamlMergeStrategy: {{ .Values.agent.yamlMergeStrategy }}
inheritYamlMergeStrategy: {{ .Values.agent.inheritYamlMergeStrategy }}
{{- end -}}
{{- define "jenkins.kubernetes-version" -}}
{{- if .Values.controller.installPlugins -}}
{{- range .Values.controller.installPlugins -}}
{{- if hasPrefix "kubernetes:" . }}
{{- $split := splitList ":" . }}
{{- printf "%s" (index $split 1 ) -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- define "jenkins.casc.security" }}
security:
{{- with .Values.controller.JCasC }}
{{- if .security }}
{{- .security | toYaml | nindent 2 }}
{{- end }}
{{- end }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "jenkins.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "jenkins.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
{{/*
Create the name of the service account for Jenkins agents to use
*/}}
{{- define "jenkins.serviceAccountAgentName" -}}
{{- if .Values.serviceAccountAgent.create -}}
{{ default (printf "%s-%s" (include "jenkins.fullname" .) "agent") .Values.serviceAccountAgent.name }}
{{- else -}}
{{ default "default" .Values.serviceAccountAgent.name }}
{{- end -}}
{{- end -}}
{{/*
Create a full tag name for controller image
*/}}
{{- define "controller.image.tag" -}}
{{- if .Values.controller.image.tagLabel -}}
{{- default (printf "%s-%s" .Chart.AppVersion .Values.controller.image.tagLabel) .Values.controller.image.tag -}}
{{- else -}}
{{- default .Chart.AppVersion .Values.controller.image.tag -}}
{{- end -}}
{{- end -}}
{{/*
Create the HTTP port for interacting with the controller
*/}}
{{- define "controller.httpPort" -}}
{{- if .Values.controller.httpsKeyStore.enable -}}
{{- .Values.controller.httpsKeyStore.httpPort -}}
{{- else -}}
{{- .Values.controller.targetPort -}}
{{- end -}}
{{- end -}}
{{- define "jenkins.configReloadContainer" -}}
{{- $root := index . 0 -}}
{{- $containerName := index . 1 -}}
{{- $containerType := index . 2 -}}
- name: {{ $containerName }}
image: "{{ $root.Values.controller.sidecars.configAutoReload.image.registry }}/{{ $root.Values.controller.sidecars.configAutoReload.image.repository }}:{{ $root.Values.controller.sidecars.configAutoReload.image.tag }}"
imagePullPolicy: {{ $root.Values.controller.sidecars.configAutoReload.imagePullPolicy }}
{{- if $root.Values.controller.sidecars.configAutoReload.containerSecurityContext }}
securityContext: {{- toYaml $root.Values.controller.sidecars.configAutoReload.containerSecurityContext | nindent 4 }}
{{- end }}
{{- if $root.Values.controller.sidecars.configAutoReload.envFrom }}
envFrom:
{{ (tpl (toYaml $root.Values.controller.sidecars.configAutoReload.envFrom) $root) | indent 4 }}
{{- end }}
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: LABEL
value: "{{ template "jenkins.fullname" $root }}-jenkins-config"
- name: HEALTH_PORT
value: "{{ $root.Values.controller.sidecars.configAutoReload.healthPort }}"
- name: FOLDER
value: "{{ $root.Values.controller.sidecars.configAutoReload.folder }}"
- name: NAMESPACE
value: '{{ $root.Values.controller.sidecars.configAutoReload.searchNamespace | default (include "jenkins.namespace" $root) }}'
{{- if eq $containerType "init" }}
- name: METHOD
value: "LIST"
{{- else if $root.Values.controller.sidecars.configAutoReload.sleepTime }}
- name: METHOD
value: "SLEEP"
- name: SLEEP_TIME
value: "{{ $root.Values.controller.sidecars.configAutoReload.sleepTime }}"
{{- end }}
{{- if eq $containerType "sidecar" }}
- name: REQ_URL
value: "{{- default "http" $root.Values.controller.sidecars.configAutoReload.scheme }}://localhost:{{- include "controller.httpPort" $root -}}{{- $root.Values.controller.jenkinsUriPrefix -}}/reload-configuration-as-code/?casc-reload-token=$(POD_NAME)"
- name: REQ_METHOD
value: "POST"
- name: REQ_RETRY_CONNECT
value: "{{ $root.Values.controller.sidecars.configAutoReload.reqRetryConnect }}"
{{- if $root.Values.controller.sidecars.configAutoReload.skipTlsVerify }}
- name: REQ_SKIP_TLS_VERIFY
value: "true"
{{- end }}
{{- end }}
{{- if $root.Values.controller.sidecars.configAutoReload.env }}
{{- range $envVarItem := $root.Values.controller.sidecars.configAutoReload.env -}}
{{- if or (ne $containerType "init") (ne .name "METHOD") }}
{{- (tpl (toYaml (list $envVarItem)) $root) | nindent 4 }}
{{- end -}}
{{- end -}}
{{- end }}
{{- if $root.Values.controller.sidecars.configAutoReload.logging.configuration.override }}
- name: LOG_CONFIG
value: "{{ $root.Values.controller.jenkinsHome }}/auto-reload/auto-reload-config.yaml"
{{- end }}
resources:
{{ toYaml $root.Values.controller.sidecars.configAutoReload.resources | indent 4 }}
volumeMounts:
- name: sc-config-volume
mountPath: {{ $root.Values.controller.sidecars.configAutoReload.folder | quote }}
- name: jenkins-home
mountPath: {{ $root.Values.controller.jenkinsHome }}
{{- if $root.Values.persistence.subPath }}
subPath: {{ $root.Values.persistence.subPath }}
{{- end }}
- name: tmp-volume
mountPath: /tmp
{{- if $root.Values.controller.sidecars.configAutoReload.logging.configuration.override }}
- name: auto-reload-config
mountPath: {{ $root.Values.controller.jenkinsHome }}/auto-reload
- name: auto-reload-config-logs
mountPath: {{ $root.Values.controller.jenkinsHome }}/auto-reload-logs
{{- end }}
{{- if $root.Values.controller.sidecars.configAutoReload.additionalVolumeMounts }}
{{ (tpl (toYaml $root.Values.controller.sidecars.configAutoReload.additionalVolumeMounts) $root) | indent 4 }}
{{- end }}
{{- end -}}
{{- define "controller.replicas" -}}
{{- $replicas := int (default 1 .Values.controller.replicas) -}}
{{- if or (lt $replicas 0) (gt $replicas 1) -}}
{{- fail "controller.replicas must be 0 or 1" -}}
{{- end -}}
{{- .Values.controller.replicas -}}
{{- end -}}
@@ -0,0 +1,54 @@
{{- if .Values.controller.sidecars.configAutoReload.logging.configuration.override }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.fullname" . }}-auto-reload-config
namespace: {{ template "jenkins.namespace" . }}
labels:
{{ include "jenkins.labels" . | nindent 4 }}
data:
auto-reload-config.yaml: |-
version: 1
disable_existing_loggers: false
root:
level: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.logLevel }}
handlers:
{{- if .Values.controller.sidecars.configAutoReload.logging.configuration.logToConsole}}
- console
{{- end }}
{{- if .Values.controller.sidecars.configAutoReload.logging.configuration.logToFile }}
- file
{{- end }}
handlers:
{{- if .Values.controller.sidecars.configAutoReload.logging.configuration.logToConsole}}
console:
class: logging.StreamHandler
level: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.logLevel }}
formatter: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.formatter }}
{{- end }}
{{- if .Values.controller.sidecars.configAutoReload.logging.configuration.logToFile }}
file:
class : logging.handlers.RotatingFileHandler
formatter: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.formatter }}
filename: {{ .Values.controller.jenkinsHome }}/auto-reload-logs/file.log
maxBytes: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.maxBytes }}
backupCount: {{ .Values.controller.sidecars.configAutoReload.logging.configuration.backupCount }}
{{- end }}
formatters:
JSON:
"()": logger.JsonFormatter
format: "%(levelname)s %(message)s"
rename_fields:
message: msg
levelname: level
LOGFMT:
"()": logger.LogfmtFormatter
keys:
- time
- level
- msg
mapping:
time: asctime
level: levelname
msg: message
{{- end }}
@@ -0,0 +1,15 @@
{{- if .Values.controller.initScripts -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.fullname" . }}-init-scripts
namespace: {{ template "jenkins.namespace" . }}
labels:
{{ include "jenkins.labels" . | nindent 4 }}
data:
{{- range $key, $val := .Values.controller.initScripts }}
init{{ $key }}.groovy: |-
{{ tpl $val $ | indent 4 }}
{{- end }}
{{- end }}
+89
View File
@@ -0,0 +1,89 @@
{{- $jenkinsHome := .Values.controller.jenkinsHome -}}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
{{ include "jenkins.labels" . | nindent 4 }}
data:
apply_config.sh: |-
set -e
{{- if .Values.controller.initializeOnce }}
if [ -f {{ .Values.controller.jenkinsHome }}/initialization-completed ]; then
echo "controller was previously initialized, refusing to re-initialize"
exit 0
fi
{{- end }}
echo "disable Setup Wizard"
# Prevent Setup Wizard when JCasC is enabled
echo $JENKINS_VERSION > {{ .Values.controller.jenkinsHome }}/jenkins.install.UpgradeWizard.state
echo $JENKINS_VERSION > {{ .Values.controller.jenkinsHome }}/jenkins.install.InstallUtil.lastExecVersion
{{- if .Values.controller.overwritePlugins }}
echo "remove all plugins from shared volume"
# remove all plugins from shared volume
rm -rf {{ .Values.controller.jenkinsHome }}/plugins/*
{{- end }}
{{- if .Values.controller.JCasC.overwriteConfiguration }}
echo "deleting all XML config files"
rm -f {{ .Values.controller.jenkinsHome }}/config.xml
rm -f {{ .Values.controller.jenkinsHome }}/*plugins*.xml
find {{ .Values.controller.jenkinsHome }} -maxdepth 1 -type f -iname '*configuration*.xml' -exec rm -f {} \;
{{- end }}
{{- if .Values.controller.installPlugins }}
echo "download plugins"
# Install missing plugins
cp /var/jenkins_config/plugins.txt {{ .Values.controller.jenkinsHome }};
rm -rf {{ .Values.controller.jenkinsRef }}/plugins/*.lock
version () { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
if [ -f "{{ .Values.controller.jenkinsWar }}" ] && [ -n "$(command -v jenkins-plugin-cli)" 2>/dev/null ] && [ $(version $(jenkins-plugin-cli --version)) -ge $(version "2.1.1") ]; then
jenkins-plugin-cli --verbose --war "{{ .Values.controller.jenkinsWar }}" --plugin-file "{{ .Values.controller.jenkinsHome }}/plugins.txt" --latest {{ .Values.controller.installLatestPlugins }}{{- if .Values.controller.installLatestSpecifiedPlugins }} --latest-specified{{- end }};
else
/usr/local/bin/install-plugins.sh `echo $(cat {{ .Values.controller.jenkinsHome }}/plugins.txt)`;
fi
echo "copy plugins to shared volume"
# Copy plugins to shared volume
yes n | cp -i {{ .Values.controller.jenkinsRef }}/plugins/* /var/jenkins_plugins/;
{{- end }}
{{- if not .Values.controller.sidecars.configAutoReload.enabled }}
echo "copy configuration as code files"
mkdir -p {{ .Values.controller.jenkinsHome }}/casc_configs;
rm -rf {{ .Values.controller.jenkinsHome }}/casc_configs/*
{{- if or .Values.controller.JCasC.defaultConfig .Values.controller.JCasC.configScripts }}
cp -v /var/jenkins_config/*.yaml {{ .Values.controller.jenkinsHome }}/casc_configs
{{- end }}
{{- end }}
echo "finished initialization"
{{- if .Values.controller.initializeOnce }}
touch {{ .Values.controller.jenkinsHome }}/initialization-completed
{{- end }}
{{- if not .Values.controller.sidecars.configAutoReload.enabled }}
# Only add config to this script if we aren't auto-reloading otherwise the pod will restart upon each config change:
{{- if .Values.controller.JCasC.defaultConfig }}
jcasc-default-config.yaml: |-
{{- include "jenkins.casc.defaults" . |nindent 4}}
{{- end }}
{{- range $key, $val := .Values.controller.JCasC.configScripts }}
{{ $key }}.yaml: |-
{{ tpl $val $| indent 4 }}
{{- end }}
{{- end }}
plugins.txt: |-
{{- if .Values.controller.installPlugins }}
{{- range $installPlugin := .Values.controller.installPlugins }}
{{- $installPlugin | nindent 4 }}
{{- end }}
{{- range $addlPlugin := .Values.controller.additionalPlugins }}
{{- /* duplicate plugin check */}}
{{- range $installPlugin := $.Values.controller.installPlugins }}
{{- if eq (splitList ":" $addlPlugin | first) (splitList ":" $installPlugin | first) }}
{{- $message := print "[PLUGIN CONFLICT] controller.additionalPlugins contains '" $addlPlugin "'" }}
{{- $message := print $message " but controller.installPlugins already contains '" $installPlugin "'." }}
{{- $message := print $message " Override controller.installPlugins to use '" $addlPlugin "' plugin." }}
{{- fail $message }}
{{- end }}
{{- end }}
{{- $addlPlugin | nindent 4 }}
{{- end }}
{{- end }}
+151
View File
@@ -0,0 +1,151 @@
{{- if .Values.checkDeprecation }}
{{- if .Values.master }}
{{ fail "`master` does no longer exist. It has been renamed to `controller`" }}
{{- end }}
{{- if .Values.controller.imageTag }}
{{ fail "`controller.imageTag` does no longer exist. Please use `controller.image.tag` instead" }}
{{- end }}
{{- if .Values.controller.slaveListenerPort }}
{{ fail "`controller.slaveListenerPort` does no longer exist. It has been renamed to `controller.agentListenerPort`" }}
{{- end }}
{{- if .Values.controller.slaveHostPort }}
{{ fail "`controller.slaveHostPort` does no longer exist. It has been renamed to `controller.agentListenerHostPort`" }}
{{- end }}
{{- if .Values.controller.slaveKubernetesNamespace }}
{{ fail "`controller.slaveKubernetesNamespace` does no longer exist. It has been renamed to `agent.namespace`" }}
{{- end }}
{{- if .Values.controller.slaveDefaultsProviderTemplate }}
{{ fail "`controller.slaveDefaultsProviderTemplate` does no longer exist. It has been renamed to `agent.defaultsProviderTemplate`" }}
{{- end }}
{{- if .Values.controller.useSecurity }}
{{ fail "`controller.useSecurity` does no longer exist. It has been renamed to `controller.adminSecret`" }}
{{- end }}
{{- if .Values.controller.slaveJenkinsUrl }}
{{ fail "`controller.slaveJenkinsUrl` does no longer exist. It has been renamed to `agent.jenkinsUrl`" }}
{{- end }}
{{- if .Values.controller.slaveJenkinsTunnel }}
{{ fail "`controller.slaveJenkinsTunnel` does no longer exist. It has been renamed to `agent.jenkinsTunnel`" }}
{{- end }}
{{- if .Values.controller.slaveConnectTimeout }}
{{ fail "`controller.slaveConnectTimeout` does no longer exist. It has been renamed to `agent.kubernetesConnectTimeout`" }}
{{- end }}
{{- if .Values.controller.slaveReadTimeout }}
{{ fail "`controller.slaveReadTimeout` does no longer exist. It has been renamed to `agent.kubernetesReadTimeout`" }}
{{- end }}
{{- if .Values.controller.slaveListenerServiceType }}
{{ fail "`controller.slaveListenerServiceType` does no longer exist. It has been renamed to `controller.agentListenerServiceType`" }}
{{- end }}
{{- if .Values.controller.slaveListenerLoadBalancerIP }}
{{ fail "`controller.slaveListenerLoadBalancerIP` does no longer exist. It has been renamed to `controller.agentListenerLoadBalancerIP`" }}
{{- end }}
{{- if .Values.controller.slaveListenerServiceAnnotations }}
{{ fail "`controller.slaveListenerServiceAnnotations` does no longer exist. It has been renamed to `controller.agentListenerServiceAnnotations`" }}
{{- end }}
{{- if .Values.agent.slaveConnectTimeout }}
{{ fail "`agent.slaveConnectTimeout` does no longer exist. It has been renamed to `agent.connectTimeout`" }}
{{- end }}
{{- if .Values.NetworkPolicy }}
{{- if .Values.NetworkPolicy.Enabled }}
{{ fail "`NetworkPolicy.Enabled` does no longer exist. It has been renamed to `networkPolicy.enabled`" }}
{{- end }}
{{- if .Values.NetworkPolicy.ApiVersion }}
{{ fail "`NetworkPolicy.ApiVersion` does no longer exist. It has been renamed to `networkPolicy.apiVersion`" }}
{{- end }}
{{ fail "NetworkPolicy.* values have been renamed, please check the documentation" }}
{{- end }}
{{- if .Values.rbac.install }}
{{ fail "`rbac.install` does no longer exist. It has been renamed to `rbac.create` and is enabled by default!" }}
{{- end }}
{{- if .Values.rbac.serviceAccountName }}
{{ fail "`rbac.serviceAccountName` does no longer exist. It has been renamed to `serviceAccount.name`" }}
{{- end }}
{{- if .Values.rbac.serviceAccountAnnotations }}
{{ fail "`rbac.serviceAccountAnnotations` does no longer exist. It has been renamed to `serviceAccount.annotations`" }}
{{- end }}
{{- if .Values.rbac.roleRef }}
{{ fail "`rbac.roleRef` does no longer exist. RBAC roles are now generated, please check the documentation" }}
{{- end }}
{{- if .Values.rbac.roleKind }}
{{ fail "`rbac.roleKind` does no longer exist. RBAC roles are now generated, please check the documentation" }}
{{- end }}
{{- if .Values.rbac.roleBindingKind }}
{{ fail "`rbac.roleBindingKind` does no longer exist. RBAC roles are now generated, please check the documentation" }}
{{- end }}
{{- if .Values.controller.JCasC.pluginVersion }}
{{ fail "controller.JCasC.pluginVersion has been deprecated, please use controller.installPlugins instead" }}
{{- end }}
{{- if .Values.controller.deploymentLabels }}
{{ fail "`controller.deploymentLabels` does no longer exist. It has been renamed to `controller.statefulSetLabels`" }}
{{- end }}
{{- if .Values.controller.deploymentAnnotations }}
{{ fail "`controller.deploymentAnnotations` does no longer exist. It has been renamed to `controller.statefulSetAnnotations`" }}
{{- end }}
{{- if .Values.controller.rollingUpdate }}
{{ fail "`controller.rollingUpdate` does no longer exist. It is no longer relevant, since a StatefulSet is used for the Jenkins controller" }}
{{- end }}
{{- if .Values.controller.tag }}
{{ fail "`controller.tag` no longer exists. It has been renamed to `controller.image.tag'" }}
{{- end }}
{{- if .Values.controller.tagLabel }}
{{ fail "`controller.tagLabel` no longer exists. It has been renamed to `controller.image.tagLabel`" }}
{{- end }}
{{- if .Values.controller.adminSecret }}
{{ fail "`controller.adminSecret` no longer exists. It has been renamed to `controller.admin.createSecret`" }}
{{- end }}
{{- if .Values.controller.adminUser }}
{{ fail "`controller.adminUser` no longer exists. It has been renamed to `controller.admin.username`" }}
{{- end }}
{{- if .Values.controller.adminPassword }}
{{ fail "`controller.adminPassword` no longer exists. It has been renamed to `controller.admin.password`" }}
{{- end }}
{{- if .Values.controller.sidecars.other }}
{{ fail "`controller.sidecars.other` no longer exists. It has been renamed to `controller.sidecars.additionalSidecarContainers`" }}
{{- end }}
{{- if .Values.agent.tag }}
{{ fail "`controller.agent.tag` no longer exists. It has been renamed to `controller.agent.image.tag`" }}
{{- end }}
{{- if .Values.backup }}
{{ fail "`controller.backup` no longer exists." }}
{{- end }}
{{- if .Values.helmtest.bats.tag }}
{{ fail "`helmtest.bats.tag` no longer exists. It has been renamed to `helmtest.bats.image.tag`" }}
{{- end }}
{{- end }}
@@ -0,0 +1,18 @@
{{- if .Values.extraObjects -}}
{{- $extraObjects := .Values.extraObjects -}}
{{- if kindIs "map" $extraObjects -}}
{{- $extraObjects = values $extraObjects -}}
{{- end -}}
{{- range $index, $object := $extraObjects -}}
{{- if $object }}
---
{{- if kindIs "string" $object -}}
{{- tpl $object $ | nindent 0 -}}
{{- else -}}
{{- tpl (toYaml $object) $ | nindent 0 -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{- end -}}
+35
View File
@@ -0,0 +1,35 @@
{{- if not (contains "jenkins-home" (quote .Values.persistence.volumes)) }}
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
{{- if .Values.persistence.annotations }}
annotations:
{{ toYaml .Values.persistence.annotations | indent 4 }}
{{- end }}
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.persistence.labels }}
{{ toYaml .Values.persistence.labels | indent 4 }}
{{- end }}
spec:
{{- if .Values.persistence.dataSource }}
dataSource:
{{ toYaml .Values.persistence.dataSource | indent 4 }}
{{- end }}
accessModes:
- {{ .Values.persistence.accessMode | quote }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- if .Values.persistence.storageClass }}
{{- if (eq "-" .Values.persistence.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ tpl .Values.persistence.storageClass . }}"
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,94 @@
{{- $root := . }}
{{- if .Values.controller.sidecars.configAutoReload.enabled }}
{{- range $key, $val := .Values.controller.JCasC.configScripts }}
{{- if $val }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.casc.configName" (list (printf "config-%s" $key) $ )}}
namespace: {{ template "jenkins.namespace" $root }}
labels:
{{- include "jenkins.labels" $root | nindent 4 }}
{{ template "jenkins.fullname" $root }}-jenkins-config: "true"
{{- if $root.Values.controller.JCasC.configMapAnnotations }}
annotations:
{{ toYaml $root.Values.controller.JCasC.configMapAnnotations | indent 4 }}
{{- end }}
data:
{{ $key }}.yaml: |-
{{ tpl $val $| indent 4 }}
{{- end }}
{{- end }}
{{- if .Values.controller.JCasC.defaultConfig }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.casc.configName" (list "jcasc-config" $ )}}
namespace: {{ template "jenkins.namespace" $root }}
labels:
{{- include "jenkins.labels" $root | nindent 4 }}
{{ template "jenkins.fullname" $root }}-jenkins-config: "true"
{{- if $root.Values.controller.JCasC.configMapAnnotations }}
annotations:
{{ toYaml $root.Values.controller.JCasC.configMapAnnotations | indent 4 }}
{{- end }}
data:
jcasc-default-config.yaml: |-
{{- include "jenkins.casc.defaults" . | nindent 4 }}
{{- end}}
{{- $configScripts := toYaml .Values.controller.JCasC.configScripts }}
{{- if and .Values.controller.JCasC.securityRealm (not (contains "securityRealm:" $configScripts)) (not .Values.controller.JCasC.defaultConfig) }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.casc.configName" (list "config-securityrealm" $ )}}
namespace: {{ template "jenkins.namespace" $root }}
labels:
"app.kubernetes.io/name": {{ template "jenkins.name" $root}}
{{- if .Values.renderHelmLabels }}
"helm.sh/chart": "{{ $root.Chart.Name }}-{{ $root.Chart.Version | replace "+" "_" }}"
{{- end }}
"app.kubernetes.io/managed-by": "{{ $.Release.Service }}"
"app.kubernetes.io/instance": "{{ $.Release.Name }}"
"app.kubernetes.io/component": "{{ $.Values.controller.componentName }}"
{{ template "jenkins.fullname" $root }}-jenkins-config: "true"
{{- if $root.Values.controller.JCasC.configMapAnnotations }}
annotations:
{{ toYaml $root.Values.controller.JCasC.configMapAnnotations | indent 4 }}
{{- end }}
data:
securityrealm.yaml: |-
jenkins:
securityRealm:
{{- tpl .Values.controller.JCasC.securityRealm . | nindent 8 }}
{{- end }}
{{- if and .Values.controller.JCasC.authorizationStrategy (not (contains "authorizationStrategy:" $configScripts)) (not .Values.controller.JCasC.defaultConfig) }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.casc.configName" (list "config-authorizationstrategy" $ )}}
namespace: {{ template "jenkins.namespace" $root }}
labels:
"app.kubernetes.io/name": {{ template "jenkins.name" $root}}
{{- if .Values.renderHelmLabels }}
"helm.sh/chart": "{{ $root.Chart.Name }}-{{ $root.Chart.Version | replace "+" "_" }}"
{{- end }}
"app.kubernetes.io/managed-by": "{{ $.Release.Service }}"
"app.kubernetes.io/instance": "{{ $.Release.Name }}"
"app.kubernetes.io/component": "{{ $.Values.controller.componentName }}"
{{ template "jenkins.fullname" $root }}-jenkins-config: "true"
{{- if $root.Values.controller.JCasC.configMapAnnotations }}
annotations:
{{ toYaml $root.Values.controller.JCasC.configMapAnnotations | indent 4 }}
{{- end }}
data:
authorizationstrategy.yaml: |-
jenkins:
authorizationStrategy:
{{- tpl .Values.controller.JCasC.authorizationStrategy . | nindent 8 }}
{{- end }}
{{- end }}
@@ -0,0 +1,37 @@
{{- if .Values.controller.agentListenerEnabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ template "jenkins.fullname" . }}-agent
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.controller.agentListenerServiceAnnotations }}
annotations:
{{- toYaml .Values.controller.agentListenerServiceAnnotations | nindent 4 }}
{{- end }}
spec:
{{- if .Values.controller.agentListenerExternalTrafficPolicy }}
externalTrafficPolicy: {{.Values.controller.agentListenerExternalTrafficPolicy}}
{{- end }}
ports:
- port: {{ .Values.controller.agentListenerPort }}
targetPort: {{ .Values.controller.agentListenerPort }}
{{- if (and (eq .Values.controller.agentListenerServiceType "NodePort") (not (empty .Values.controller.agentListenerNodePort))) }}
nodePort: {{ .Values.controller.agentListenerNodePort }}
{{- end }}
name: agent-listener
selector:
"app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
"app.kubernetes.io/instance": "{{ .Release.Name }}"
type: {{ .Values.controller.agentListenerServiceType }}
{{if eq .Values.controller.agentListenerServiceType "LoadBalancer"}}
{{- if .Values.controller.agentListenerLoadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{ toYaml .Values.controller.agentListenerLoadBalancerSourceRanges | indent 4 }}
{{- end }}
{{- end }}
{{- if and (eq .Values.controller.agentListenerServiceType "LoadBalancer") (.Values.controller.agentListenerLoadBalancerIP) }}
loadBalancerIP: {{ .Values.controller.agentListenerLoadBalancerIP }}
{{- end }}
{{- end }}
@@ -0,0 +1,18 @@
{{- if .Values.awsSecurityGroupPolicies.enabled -}}
{{- range .Values.awsSecurityGroupPolicies.policies -}}
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
name: {{ .name }}
namespace: {{ template "jenkins.namespace" $ }}
labels:
{{ include "jenkins.labels" $ | nindent 4 }}
spec:
podSelector:
{{- toYaml .podSelector | nindent 6}}
securityGroups:
groupIds:
{{- toYaml .securityGroupIds | nindent 6}}
---
{{- end -}}
{{- end -}}
@@ -0,0 +1,20 @@
{{- if and .Values.controller.prometheus.enabled .Values.controller.prometheus.alertingrules }}
---
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: {{ template "jenkins.fullname" . }}
{{- if .Values.controller.prometheus.prometheusRuleNamespace }}
namespace: {{ .Values.controller.prometheus.prometheusRuleNamespace }}
{{- else }}
namespace: {{ template "jenkins.namespace" . }}
{{- end }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- range $key, $val := .Values.controller.prometheus.alertingRulesAdditionalLabels }}
{{ $key }}: {{ $val | quote }}
{{- end}}
spec:
groups:
{{ toYaml .Values.controller.prometheus.alertingrules | indent 2 }}
{{- end }}
@@ -0,0 +1,18 @@
{{- if .Values.controller.backendconfig.enabled }}
apiVersion: {{ .Values.controller.backendconfig.apiVersion }}
kind: BackendConfig
metadata:
name: {{ .Values.controller.backendconfig.name }}
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.controller.backendconfig.labels }}
{{ toYaml .Values.controller.backendconfig.labels | indent 4 }}
{{- end }}
{{- if .Values.controller.backendconfig.annotations }}
annotations:
{{ toYaml .Values.controller.backendconfig.annotations | indent 4 }}
{{- end }}
spec:
{{ toYaml .Values.controller.backendconfig.spec | indent 2 }}
{{- end }}
@@ -0,0 +1,40 @@
{{- if .Values.controller.httpRoute.enabled }}
{{- $root := . }}
{{- $hostnames := (list) }}
{{- if .Values.controller.httpRoute.reuseIngressConfiguration }}
{{- if .Values.controller.ingress.hostName }}
{{- $hostnames = append $hostnames .Values.controller.ingress.hostName }}
{{- end }}
{{- if .Values.controller.ingress.resourceRootUrl }}
{{- $hostnames = append $hostnames .Values.controller.ingress.resourceRootUrl }}
{{- end }}
{{- else }}
{{- $hostnames = default (list) .Values.controller.httpRoute.hostnames }}
{{- end }}
apiVersion: {{ .Values.controller.httpRoute.apiVersion }}
kind: {{ .Values.controller.httpRoute.kind }}
metadata:
name: {{ include "jenkins.fullname" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.controller.httpRoute.annotations }}
annotations:
{{- tpl (toYaml .Values.controller.httpRoute.annotations) . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.controller.httpRoute.parentRefs }}
parentRefs:
{{- toYaml . | nindent 4 }}
{{- end }}
hostnames:
{{- range $hostnames }}
- {{ . | quote }}
{{- end }}
rules:
{{- if .Values.controller.httpRoute.extraRules }}
{{- toYaml .Values.controller.httpRoute.extraRules | nindent 2 }}
{{- end }}
- backendRefs:
- name: {{ include "jenkins.fullname" $root }}
port: {{ $root.Values.controller.servicePort }}
{{- end }}
@@ -0,0 +1,90 @@
{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }}
{{- if .Values.controller.ingress.enabled }}
{{- if semverCompare ">=1.19-0" $kubeTargetVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" $kubeTargetVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: {{ .Values.controller.ingress.apiVersion }}
{{- end }}
kind: Ingress
metadata:
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.controller.ingress.labels }}
{{ toYaml .Values.controller.ingress.labels | indent 4 }}
{{- end }}
{{- if .Values.controller.ingress.annotations }}
annotations:
{{ tpl (toYaml .Values.controller.ingress.annotations) . | indent 4 }}
{{- end }}
name: {{ template "jenkins.fullname" . }}
spec:
{{- if .Values.controller.ingress.ingressClassName }}
ingressClassName: {{ tpl .Values.controller.ingress.ingressClassName . | quote }}
{{- end }}
rules:
- http:
paths:
{{- if empty (.Values.controller.ingress.paths) }}
- backend:
{{- if semverCompare ">=1.19-0" $kubeTargetVersion }}
service:
name: {{ template "jenkins.fullname" . }}
port:
number: {{ .Values.controller.servicePort }}
pathType: {{ .Values.controller.ingress.pathType }}
{{- else }}
serviceName: {{ template "jenkins.fullname" . }}
servicePort: {{ .Values.controller.servicePort }}
{{- end }}
{{- if .Values.controller.ingress.path }}
path: {{ .Values.controller.ingress.path }}
{{- end -}}
{{- else }}
{{ tpl (toYaml .Values.controller.ingress.paths | indent 6) . }}
{{- end -}}
{{- if .Values.controller.ingress.hostName }}
host: {{ tpl .Values.controller.ingress.hostName . | quote }}
{{- end }}
{{- if .Values.controller.ingress.resourceRootUrl }}
- http:
paths:
- backend:
{{- if semverCompare ">=1.19-0" $kubeTargetVersion }}
service:
name: {{ template "jenkins.fullname" . }}
port:
number: {{ .Values.controller.servicePort }}
pathType: {{ .Values.controller.ingress.pathType }}
{{- else }}
serviceName: {{ template "jenkins.fullname" . }}
servicePort: {{ .Values.controller.servicePort }}
{{- end }}
host: {{ tpl .Values.controller.ingress.resourceRootUrl . | quote }}
{{- end }}
{{- if .Values.controller.ingress.tls }}
{{- $withTlsEntries := false }}
{{- range .Values.controller.ingress.tls }}
{{- if gt (len .) 0 }}
{{- $withTlsEntries = true }}
{{- end }}
{{- end }}
{{- if $withTlsEntries }}
tls:
{{- range .Values.controller.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ tpl . $ | quote }}
{{- end }}
{{- if $.Values.controller.ingress.resourceRootUrl }}
- {{ tpl $.Values.controller.ingress.resourceRootUrl $ | quote }}
{{- end }}
{{- if .secretName }}
secretName: {{ tpl (.secretName | toString) $ | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,64 @@
{{- if .Values.networkPolicy.enabled }}
kind: NetworkPolicy
apiVersion: {{ .Values.networkPolicy.apiVersion }}
metadata:
name: "{{ .Release.Name }}-{{ .Values.controller.componentName }}"
namespace: {{ template "jenkins.namespace" . }}
labels:
{{ include "jenkins.labels" . | nindent 4 }}
spec:
podSelector:
matchLabels:
"app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
"app.kubernetes.io/instance": "{{ .Release.Name }}"
ingress:
# Allow web access to the UI
- ports:
- port: {{ .Values.controller.targetPort }}
{{- if .Values.controller.agentListenerEnabled }}
# Allow inbound connections from agents
- from:
{{- if .Values.networkPolicy.internalAgents.allowed }}
- podSelector:
matchLabels:
"jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}": "true"
{{- range $k,$v:= .Values.networkPolicy.internalAgents.podLabels }}
{{ $k }}: {{ $v }}
{{- end }}
{{- if .Values.networkPolicy.internalAgents.namespaceLabels }}
namespaceSelector:
matchLabels:
{{- range $k,$v:= .Values.networkPolicy.internalAgents.namespaceLabels }}
{{ $k }}: {{ $v }}
{{- end }}
{{- end }}
{{- end }}
{{- if or .Values.networkPolicy.externalAgents.ipCIDR .Values.networkPolicy.externalAgents.except }}
- ipBlock:
cidr: {{ required "ipCIDR is required if you wish to allow external agents to connect to Jenkins Controller." .Values.networkPolicy.externalAgents.ipCIDR }}
{{- if .Values.networkPolicy.externalAgents.except }}
except:
{{- range .Values.networkPolicy.externalAgents.except }}
- {{ . }}
{{- end }}
{{- end }}
{{- end }}
ports:
- port: {{ .Values.controller.agentListenerPort }}
{{- end }}
{{- if .Values.agent.enabled }}
---
kind: NetworkPolicy
apiVersion: {{ .Values.networkPolicy.apiVersion }}
metadata:
name: "{{ .Release.Name }}-{{ .Values.agent.componentName }}"
namespace: {{ template "jenkins.namespace" . }}
labels:
{{ include "jenkins.labels" . | nindent 4 }}
spec:
podSelector:
matchLabels:
# DefaultDeny
"jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}": "true"
{{- end }}
{{- end }}
@@ -0,0 +1,28 @@
{{- if .Values.controller.podDisruptionBudget.enabled }}
{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }}
{{- if semverCompare ">=1.21-0" $kubeTargetVersion -}}
apiVersion: policy/v1
{{- else if semverCompare ">=1.5-0" $kubeTargetVersion -}}
apiVersion: policy/v1beta1
{{- else -}}
apiVersion: {{ .Values.controller.podDisruptionBudget.apiVersion }}
{{- end }}
kind: PodDisruptionBudget
metadata:
name: {{ template "jenkins.fullname" . }}-pdb
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.controller.podDisruptionBudget.labels -}}
{{ toYaml .Values.controller.podDisruptionBudget.labels | nindent 4 }}
{{- end }}
{{- if .Values.controller.podDisruptionBudget.annotations }}
annotations: {{ toYaml .Values.controller.podDisruptionBudget.annotations | nindent 4 }}
{{- end }}
spec:
maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }}
selector:
matchLabels:
"app.kubernetes.io/instance": "{{ .Release.Name }}"
"app.kubernetes.io/name": '{{ template "jenkins.name" .}}'
{{- end }}
@@ -0,0 +1,24 @@
{{- if .Values.controller.googlePodMonitor.enabled }}
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
name: {{ template "jenkins.fullname" . }}
{{- if .Values.controller.googlePodMonitor.serviceMonitorNamespace }}
namespace: {{ .Values.controller.googlePodMonitor.serviceMonitorNamespace }}
{{- else }}
namespace: {{ template "jenkins.namespace" . }}
{{- end }}
labels:
{{ include "jenkins.labels" . | nindent 4 }}
spec:
endpoints:
- interval: {{ .Values.controller.googlePodMonitor.scrapeInterval }}
port: http
path: {{ .Values.controller.jenkinsUriPrefix }}{{ .Values.controller.googlePodMonitor.scrapeEndpoint }}
selector:
matchLabels:
"app.kubernetes.io/instance": "{{ .Release.Name }}"
"app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
{{- end }}
@@ -0,0 +1,32 @@
{{- if .Values.controller.route.enabled }}
apiVersion: route.openshift.io/v1
kind: Route
metadata:
namespace: {{ template "jenkins.namespace" . }}
labels:
app: {{ template "jenkins.fullname" . }}
release: "{{ .Release.Name }}"
heritage: "{{ .Release.Service }}"
component: "{{ .Release.Name }}-{{ .Values.controller.componentName }}"
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.controller.route.labels }}
{{ toYaml .Values.controller.route.labels | indent 4 }}
{{- end }}
{{- if .Values.controller.route.annotations }}
annotations:
{{ toYaml .Values.controller.route.annotations | indent 4 }}
{{- end }}
name: {{ template "jenkins.fullname" . }}
spec:
host: {{ .Values.controller.route.path }}
port:
targetPort: http
tls:
insecureEdgeTerminationPolicy: Redirect
termination: edge
to:
kind: Service
name: {{ template "jenkins.fullname" . }}
weight: 100
wildcardPolicy: None
{{- end }}
@@ -0,0 +1,50 @@
{{- if .Values.controller.secondaryingress.enabled }}
{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }}
{{- $serviceName := include "jenkins.fullname" . -}}
{{- $servicePort := .Values.controller.servicePort -}}
{{- if semverCompare ">=1.19-0" $kubeTargetVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" $kubeTargetVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: {{ .Values.controller.secondaryingress.apiVersion }}
{{- end }}
kind: Ingress
metadata:
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.controller.secondaryingress.labels -}}
{{ toYaml .Values.controller.secondaryingress.labels | nindent 4 }}
{{- end }}
{{- if .Values.controller.secondaryingress.annotations }}
annotations: {{ toYaml .Values.controller.secondaryingress.annotations | nindent 4 }}
{{- end }}
name: {{ template "jenkins.fullname" . }}-secondary
spec:
{{- if .Values.controller.secondaryingress.ingressClassName }}
ingressClassName: {{ .Values.controller.secondaryingress.ingressClassName | quote }}
{{- end }}
rules:
- host: {{ .Values.controller.secondaryingress.hostName }}
http:
paths:
{{- range .Values.controller.secondaryingress.paths }}
- path: {{ . | quote }}
backend:
{{ if semverCompare ">=1.19-0" $kubeTargetVersion }}
service:
name: {{ $serviceName }}
port:
number: {{ $servicePort }}
pathType: ImplementationSpecific
{{ else }}
serviceName: {{ $serviceName }}
servicePort: {{ $servicePort }}
{{ end }}
{{- end}}
{{- if .Values.controller.secondaryingress.tls }}
tls:
{{ toYaml .Values.controller.secondaryingress.tls | indent 4 }}
{{- end -}}
{{- end }}
@@ -0,0 +1,39 @@
{{- if and .Values.controller.prometheus.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ template "jenkins.fullname" . }}
{{- if .Values.controller.prometheus.serviceMonitorNamespace }}
namespace: {{ .Values.controller.prometheus.serviceMonitorNamespace }}
{{- else }}
namespace: {{ template "jenkins.namespace" . }}
{{- end }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- range $key, $val := .Values.controller.prometheus.serviceMonitorAdditionalLabels }}
{{ $key }}: {{ $val | quote }}
{{- end}}
spec:
endpoints:
- interval: {{ .Values.controller.prometheus.scrapeInterval }}
port: http
path: {{ .Values.controller.jenkinsUriPrefix }}{{ .Values.controller.prometheus.scrapeEndpoint }}
{{- with .Values.controller.prometheus.relabelings }}
relabelings:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.controller.prometheus.metricRelabelings }}
metricRelabelings:
{{- toYaml . | nindent 6 }}
{{- end }}
jobLabel: {{ template "jenkins.fullname" . }}
namespaceSelector:
matchNames:
- "{{ template "jenkins.namespace" $ }}"
selector:
matchLabels:
"app.kubernetes.io/instance": "{{ .Release.Name }}"
"app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
{{- end }}
@@ -0,0 +1,425 @@
{{- if .Capabilities.APIVersions.Has "apps/v1" }}
apiVersion: apps/v1
{{- else }}
apiVersion: apps/v1beta1
{{- end }}
kind: StatefulSet
metadata:
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- range $key, $val := .Values.controller.statefulSetLabels }}
{{ $key }}: {{ $val | quote }}
{{- end}}
{{- if .Values.controller.statefulSetAnnotations }}
annotations:
{{ toYaml .Values.controller.statefulSetAnnotations | indent 4 }}
{{- end }}
spec:
serviceName: {{ template "jenkins.fullname" . }}
replicas: {{ include "controller.replicas" . }}
selector:
matchLabels:
"app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
"app.kubernetes.io/instance": "{{ .Release.Name }}"
{{- if .Values.controller.updateStrategy }}
updateStrategy:
{{ toYaml .Values.controller.updateStrategy | indent 4 }}
{{- end }}
template:
metadata:
labels:
{{- include "jenkins.labels" . | nindent 8 }}
{{- range $key, $val := .Values.controller.podLabels }}
{{ $key }}: {{ $val | quote }}
{{- end}}
annotations:
checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }}
{{- if .Values.controller.initScripts }}
checksum/config-init-scripts: {{ include (print $.Template.BasePath "/config-init-scripts.yaml") . | sha256sum }}
{{- end }}
{{- if .Values.controller.podAnnotations }}
{{ tpl (toYaml .Values.controller.podAnnotations | indent 8) . }}
{{- end }}
spec:
{{- if .Values.controller.schedulerName }}
schedulerName: {{ .Values.controller.schedulerName }}
{{- end }}
{{- if .Values.controller.nodeSelector }}
nodeSelector:
{{ toYaml .Values.controller.nodeSelector | indent 8 }}
{{- end }}
{{- if .Values.controller.tolerations }}
tolerations:
{{ toYaml .Values.controller.tolerations | indent 8 }}
{{- end }}
{{- if .Values.controller.affinity }}
affinity:
{{ toYaml .Values.controller.affinity | indent 8 }}
{{- end }}
{{- if .Values.controller.topologySpreadConstraints }}
topologySpreadConstraints:
{{ toYaml .Values.controller.topologySpreadConstraints | indent 8 }}
{{- end }}
{{- if .Values.controller.dnsConfig }}
dnsConfig:
{{ toYaml .Values.controller.dnsConfig | indent 8 }}
{{- end }}
{{- if quote .Values.controller.terminationGracePeriodSeconds }}
terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
{{- end }}
{{- if .Values.controller.priorityClassName }}
priorityClassName: {{ .Values.controller.priorityClassName }}
{{- end }}
{{- if .Values.controller.shareProcessNamespace }}
shareProcessNamespace: true
{{- end }}
{{- if not .Values.controller.enableServiceLinks }}
enableServiceLinks: false
{{- end }}
{{- if .Values.controller.usePodSecurityContext }}
securityContext:
{{- if kindIs "map" .Values.controller.podSecurityContextOverride }}
{{- tpl (toYaml .Values.controller.podSecurityContextOverride | nindent 8) . -}}
{{- else }}
{{/* The rest of this section should be replaced with the contents of this comment one the runAsUser, fsGroup, and securityContextCapabilities Helm chart values have been removed:
runAsUser: 1000
fsGroup: 1000
fsGroupChangePolicy: OnRootMismatch
runAsNonRoot: true
*/}}
runAsUser: {{ default 0 .Values.controller.runAsUser }}
{{- if and (.Values.controller.runAsUser) (.Values.controller.fsGroup) }}
{{- if not (eq (int .Values.controller.runAsUser) 0) }}
fsGroup: {{ .Values.controller.fsGroup }}
fsGroupChangePolicy: {{ .Values.controller.fsGroupChangePolicy }}
runAsNonRoot: true
{{- end }}
{{- if .Values.controller.securityContextCapabilities }}
capabilities:
{{- toYaml .Values.controller.securityContextCapabilities | nindent 10 }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
serviceAccountName: "{{ template "jenkins.serviceAccountName" . }}"
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
{{- if .Values.controller.hostNetworking }}
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
{{- end }}
{{- if .Values.controller.hostAliases }}
hostAliases:
{{- toYaml .Values.controller.hostAliases | nindent 8 }}
{{- end }}
initContainers:
{{- if .Values.controller.customInitContainers }}
{{ tpl (toYaml .Values.controller.customInitContainers) . | indent 8 }}
{{- end }}
{{- if .Values.controller.sidecars.configAutoReload.enabled }}
{{- include "jenkins.configReloadContainer" (list $ "config-reload-init" "init") | nindent 8 }}
{{- end}}
- name: "init"
image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}"
imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}"
{{- if .Values.controller.containerSecurityContext }}
securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }}
{{- end }}
command: [ "sh", "/var/jenkins_config/apply_config.sh" ]
{{- if .Values.controller.initContainerEnvFrom }}
envFrom:
{{ (tpl (toYaml .Values.controller.initContainerEnvFrom) .) | indent 12 }}
{{- end }}
{{- if .Values.controller.initContainerEnv }}
env:
{{ (tpl (toYaml .Values.controller.initContainerEnv) .) | indent 12 }}
{{- end }}
resources:
{{- if .Values.controller.initContainerResources }}
{{ toYaml .Values.controller.initContainerResources | indent 12 }}
{{- else }}
{{ toYaml .Values.controller.resources | indent 12 }}
{{- end }}
volumeMounts:
{{- if .Values.persistence.mounts }}
{{ toYaml .Values.persistence.mounts | indent 12 }}
{{- end }}
- mountPath: {{ .Values.controller.jenkinsHome }}
name: jenkins-home
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- mountPath: /var/jenkins_config
name: jenkins-config
{{- if .Values.controller.installPlugins }}
{{- if .Values.controller.overwritePluginsFromImage }}
- mountPath: {{ .Values.controller.jenkinsRef }}/plugins
name: plugins
{{- end }}
- mountPath: /var/jenkins_plugins
name: plugin-dir
- mountPath: /tmp
name: tmp-volume
{{- end }}
{{- if or .Values.controller.initScripts .Values.controller.initConfigMap }}
- mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d
name: init-scripts
{{- end }}
{{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }}
{{- $httpsJKSDirPath := printf "%s" .Values.controller.httpsKeyStore.path }}
- mountPath: {{ $httpsJKSDirPath }}
name: jenkins-https-keystore
{{- end }}
containers:
- name: jenkins
image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}"
imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}"
{{- if .Values.controller.containerSecurityContext }}
securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }}
{{- end }}
{{- if .Values.controller.overrideArgs }}
args: [
{{- range $overrideArg := .Values.controller.overrideArgs }}
"{{- tpl $overrideArg $ }}",
{{- end }}
]
{{- else if .Values.controller.httpsKeyStore.enable }}
{{- $httpsJKSFilePath := printf "%s/%s" .Values.controller.httpsKeyStore.path .Values.controller.httpsKeyStore.fileName }}
args: [ "--httpPort={{.Values.controller.httpsKeyStore.httpPort}}", "--httpsPort={{.Values.controller.targetPort}}", '--httpsKeyStore={{ $httpsJKSFilePath }}', "--httpsKeyStorePassword=$(JENKINS_HTTPS_KEYSTORE_PASSWORD)" ]
{{- else }}
args: [ "--httpPort={{.Values.controller.targetPort}}"]
{{- end }}
{{- if .Values.controller.lifecycle }}
lifecycle:
{{ toYaml .Values.controller.lifecycle | indent 12 }}
{{- end }}
{{- if .Values.controller.terminationMessagePath }}
terminationMessagePath: {{ .Values.controller.terminationMessagePath }}
{{- end }}
{{- if .Values.controller.terminationMessagePolicy }}
terminationMessagePolicy: {{ .Values.controller.terminationMessagePolicy }}
{{- end }}
{{- if .Values.controller.containerEnvFrom }}
envFrom:
{{ (tpl ( toYaml .Values.controller.containerEnvFrom) .) | indent 12 }}
{{- end }}
env:
{{- if .Values.controller.containerEnv }}
{{ (tpl ( toYaml .Values.controller.containerEnv) .) | indent 12 }}
{{- end }}
{{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }}
- name: SECRETS
value: /run/secrets/additional
{{- end }}
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: JAVA_OPTS
value: >-
{{ if .Values.controller.sidecars.configAutoReload.enabled }} -Dcasc.reload.token=$(POD_NAME) {{ end }}{{ default "" .Values.controller.javaOpts }}
- name: JENKINS_OPTS
value: >-
{{ if .Values.controller.jenkinsUriPrefix }}--prefix={{ .Values.controller.jenkinsUriPrefix }} {{ end }} --webroot=/var/jenkins_cache/war {{ default "" .Values.controller.jenkinsOpts}}
- name: JENKINS_SLAVE_AGENT_PORT
value: "{{ .Values.controller.agentListenerPort }}"
{{- if .Values.controller.httpsKeyStore.enable }}
- name: JENKINS_HTTPS_KEYSTORE_PASSWORD
{{- if not .Values.controller.httpsKeyStore.disableSecretMount }}
valueFrom:
secretKeyRef:
name: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretName }} {{ else if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks {{ end }}
key: "{{ .Values.controller.httpsKeyStore.jenkinsHttpsJksPasswordSecretKey }}"
{{- else }}
value: {{ .Values.controller.httpsKeyStore.password }}
{{- end }}
{{- end }}
- name: CASC_JENKINS_CONFIG
value: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }}{{- if .Values.controller.JCasC.configUrls }},{{ join "," .Values.controller.JCasC.configUrls }}{{- end }}
ports:
{{- if .Values.controller.httpsKeyStore.enable }}
- containerPort: {{.Values.controller.httpsKeyStore.httpPort}}
{{- else }}
- containerPort: {{.Values.controller.targetPort}}
{{- end }}
name: http
- containerPort: {{ .Values.controller.agentListenerPort }}
name: agent-listener
{{- if .Values.controller.agentListenerHostPort }}
hostPort: {{ .Values.controller.agentListenerHostPort }}
{{- end }}
{{- if .Values.controller.jmxPort }}
- containerPort: {{ .Values.controller.jmxPort }}
name: jmx
{{- end }}
{{- range $index, $port := .Values.controller.extraPorts }}
- containerPort: {{ $port.port }}
name: {{ $port.name }}
{{- end }}
{{- if and .Values.controller.healthProbes .Values.controller.probes}}
{{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.GitVersion }}
startupProbe:
{{ tpl (toYaml .Values.controller.probes.startupProbe | indent 12) .}}
{{- end }}
livenessProbe:
{{ tpl (toYaml .Values.controller.probes.livenessProbe | indent 12) .}}
readinessProbe:
{{ tpl (toYaml .Values.controller.probes.readinessProbe | indent 12) .}}
{{- end }}
resources:
{{ toYaml .Values.controller.resources | indent 12 }}
volumeMounts:
{{- if .Values.persistence.mounts }}
{{ toYaml .Values.persistence.mounts | indent 12 }}
{{- end }}
{{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }}
{{- $httpsJKSDirPath := printf "%s" .Values.controller.httpsKeyStore.path }}
- mountPath: {{ $httpsJKSDirPath }}
name: jenkins-https-keystore
{{- end }}
- mountPath: {{ .Values.controller.jenkinsHome }}
name: jenkins-home
readOnly: false
{{- if .Values.persistence.subPath }}
subPath: {{ .Values.persistence.subPath }}
{{- end }}
- mountPath: /var/jenkins_config
name: jenkins-config
readOnly: true
{{- if .Values.controller.installPlugins }}
- mountPath: {{ .Values.controller.jenkinsRef }}/plugins/
name: plugin-dir
readOnly: false
{{- end }}
{{- if or .Values.controller.initScripts .Values.controller.initConfigMap }}
- mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d
name: init-scripts
{{- end }}
{{- if .Values.controller.sidecars.configAutoReload.enabled }}
- name: sc-config-volume
mountPath: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }}
{{- end }}
{{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }}
- name: jenkins-secrets
mountPath: /run/secrets/additional
readOnly: true
{{- end }}
- name: jenkins-cache
mountPath: /var/jenkins_cache
- mountPath: /tmp
name: tmp-volume
{{- if .Values.controller.sidecars.configAutoReload.enabled }}
{{- include "jenkins.configReloadContainer" (list $ "config-reload" "sidecar") | nindent 8 }}
{{- end}}
{{- if .Values.controller.sidecars.additionalSidecarContainers}}
{{ tpl (toYaml .Values.controller.sidecars.additionalSidecarContainers | indent 8) .}}
{{- end }}
volumes:
{{- if .Values.persistence.volumes }}
{{ tpl (toYaml .Values.persistence.volumes | indent 6) . }}
{{- end }}
{{- if .Values.controller.sidecars.configAutoReload.logging.configuration.override }}
- name: auto-reload-config
configMap:
name: {{ template "jenkins.fullname" . }}-auto-reload-config
- name: auto-reload-config-logs
emptyDir: {}
{{- end }}
{{- if .Values.controller.installPlugins }}
{{- if .Values.controller.overwritePluginsFromImage }}
- name: plugins
emptyDir: {}
{{- end }}
{{- end }}
{{- if and .Values.controller.initScripts .Values.controller.initConfigMap }}
- name: init-scripts
projected:
sources:
- configMap:
name: {{ template "jenkins.fullname" . }}-init-scripts
- configMap:
name: {{ .Values.controller.initConfigMap }}
{{- else if .Values.controller.initConfigMap }}
- name: init-scripts
configMap:
name: {{ .Values.controller.initConfigMap }}
{{- else if .Values.controller.initScripts }}
- name: init-scripts
configMap:
name: {{ template "jenkins.fullname" . }}-init-scripts
{{- end }}
- name: jenkins-config
configMap:
name: {{ template "jenkins.fullname" . }}
{{- if .Values.controller.installPlugins }}
- name: plugin-dir
emptyDir: {}
{{- end }}
{{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.admin.createSecret }}
- name: jenkins-secrets
projected:
sources:
{{- if .Values.controller.additionalSecrets }}
- secret:
name: {{ template "jenkins.fullname" . }}-additional-secrets
{{- end }}
{{- if .Values.controller.additionalExistingSecrets }}
{{- range $key, $value := .Values.controller.additionalExistingSecrets }}
- secret:
name: {{ tpl $value.name $ }}
items:
- key: {{ tpl $value.keyName $ }}
path: {{ tpl $value.name $ }}-{{ tpl $value.keyName $ }}
{{- end }}
{{- end }}
{{- if .Values.controller.admin.createSecret }}
- secret:
name: {{ .Values.controller.admin.existingSecret | default (include "jenkins.fullname" .) }}
items:
- key: {{ .Values.controller.admin.userKey | default "jenkins-admin-user" }}
path: chart-admin-username
- key: {{ .Values.controller.admin.passwordKey | default "jenkins-admin-password" }}
path: chart-admin-password
{{- end }}
{{- if .Values.controller.existingSecret }}
- secret:
name: {{ .Values.controller.existingSecret }}
{{- end }}
{{- end }}
- name: jenkins-cache
emptyDir: {}
{{- if not (contains "jenkins-home" (quote .Values.persistence.volumes)) }}
- name: jenkins-home
{{- if .Values.persistence.enabled }}
persistentVolumeClaim:
claimName: {{ .Values.persistence.existingClaim | default (include "jenkins.fullname" .) }}
{{- else }}
emptyDir: {}
{{- end -}}
{{- end }}
- name: sc-config-volume
emptyDir: {}
- name: tmp-volume
emptyDir: {}
{{- if and .Values.controller.httpsKeyStore.enable (not .Values.controller.httpsKeyStore.disableSecretMount) }}
- name: jenkins-https-keystore
secret:
secretName: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks {{ end }}
items:
- key: {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretKey }}
path: {{ .Values.controller.httpsKeyStore.fileName }}
{{- end }}
{{- if .Values.controller.imagePullSecretName }}
imagePullSecrets:
- name: {{ .Values.controller.imagePullSecretName }}
{{- end -}}
@@ -0,0 +1,55 @@
{{- if .Values.controller.serviceEnabled }}
apiVersion: v1
kind: Service
metadata:
name: {{template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.controller.serviceLabels }}
{{ toYaml .Values.controller.serviceLabels | indent 4 }}
{{- end }}
{{- if .Values.controller.serviceAnnotations }}
annotations:
{{ toYaml .Values.controller.serviceAnnotations | indent 4 }}
{{- end }}
spec:
{{- if .Values.controller.serviceExternalTrafficPolicy }}
externalTrafficPolicy: {{.Values.controller.serviceExternalTrafficPolicy}}
{{- end }}
{{- if (and (eq .Values.controller.serviceType "ClusterIP") (not (empty .Values.controller.clusterIP))) }}
clusterIP: {{.Values.controller.clusterIP}}
{{- end }}
ports:
- port: {{.Values.controller.servicePort}}
name: http
targetPort: {{ .Values.controller.targetPort }}
{{- if (and (eq .Values.controller.serviceType "NodePort") (not (empty .Values.controller.nodePort))) }}
nodePort: {{.Values.controller.nodePort}}
{{- end }}
{{- range $index, $port := .Values.controller.extraPorts }}
- port: {{ $port.port }}
name: {{ $port.name }}
{{- if $port.targetPort }}
targetPort: {{ $port.targetPort }}
{{- else }}
targetPort: {{ $port.port }}
{{- end -}}
{{- end }}
{{- if .Values.controller.publishNotReadyAddresses }}
publishNotReadyAddresses: true
{{- end }}
selector:
"app.kubernetes.io/component": "{{ .Values.controller.componentName }}"
"app.kubernetes.io/instance": "{{ .Release.Name }}"
type: {{.Values.controller.serviceType}}
{{if eq .Values.controller.serviceType "LoadBalancer"}}
{{- if .Values.controller.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{ toYaml .Values.controller.loadBalancerSourceRanges | indent 4 }}
{{- end }}
{{if .Values.controller.loadBalancerIP}}
loadBalancerIP: {{.Values.controller.loadBalancerIP}}
{{end}}
{{end}}
{{- end }}
+150
View File
@@ -0,0 +1,150 @@
{{ if .Values.rbac.create }}
{{- $serviceName := include "jenkins.fullname" . -}}
# This role is used to allow Jenkins scheduling of agents via Kubernetes plugin.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ $serviceName }}-schedule-agents
namespace: {{ template "jenkins.agent.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["pods", "pods/exec", "pods/log", "persistentvolumeclaims", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods", "pods/exec", "persistentvolumeclaims"]
verbs: ["create", "delete", "deletecollection", "patch", "update"]
---
# We bind the role to the Jenkins service account. The role binding is created in the namespace
# where the agents are supposed to run.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $serviceName }}-schedule-agents
namespace: {{ template "jenkins.agent.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ $serviceName }}-schedule-agents
subjects:
- kind: ServiceAccount
name: {{ template "jenkins.serviceAccountName" .}}
namespace: {{ template "jenkins.namespace" . }}
---
{{- if .Values.rbac.readSecrets }}
# This is needed if you want to use https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/
# as it needs permissions to get/watch/list Secrets
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ template "jenkins.fullname" . }}-read-secrets
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $serviceName }}-read-secrets
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "jenkins.fullname" . }}-read-secrets
subjects:
- kind: ServiceAccount
name: {{ template "jenkins.serviceAccountName" . }}
namespace: {{ template "jenkins.namespace" . }}
---
{{- end}}
{{- if .Values.rbac.useOpenShiftNonRootSCC }}
# This is needed if you are running on OpenShift and using the default
# containerSecurityContext in the chart. It grants the Jenkins service account
# permission to use the "nonroot" and "nonroot-v2" SecurityContextConstraints.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ $serviceName }}-use-nonroot-scc
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
rules:
- apiGroups: ["security.openshift.io"]
resources: ["securitycontextconstraints"]
resourceNames: ["nonroot", "nonroot-v2"]
verbs: ["use"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $serviceName }}-use-nonroot-scc
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "jenkins.fullname" . }}-use-nonroot-scc
subjects:
- kind: ServiceAccount
name: {{ template "jenkins.serviceAccountName" . }}
namespace: {{ template "jenkins.namespace" . }}
---
{{- end}}
{{- if .Values.controller.sidecars.configAutoReload.enabled }}
# The sidecar container which is responsible for reloading configuration changes
# needs permissions to watch ConfigMaps
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ template "jenkins.fullname" . }}-casc-reload
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ $serviceName }}-watch-configmaps
namespace: {{ template "jenkins.namespace" . }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ template "jenkins.fullname" . }}-casc-reload
subjects:
- kind: ServiceAccount
name: {{ template "jenkins.serviceAccountName" . }}
namespace: {{ template "jenkins.namespace" . }}
{{- end}}
{{ end }}
@@ -0,0 +1,15 @@
{{- if .Values.controller.additionalSecrets -}}
---
apiVersion: v1
kind: Secret
metadata:
name: {{ template "jenkins.fullname" . }}-additional-secrets
namespace: {{ template "jenkins.namespace" . }}
labels:
{{ include "jenkins.labels" . | nindent 4 }}
type: Opaque
data:
{{- range .Values.controller.additionalSecrets }}
{{ .name }}: {{ .value | b64enc }}
{{- end }}
{{- end }}
@@ -0,0 +1,23 @@
{{- if .Values.controller.secretClaims -}}
{{- $root := . -}}
{{- $namespace := include "jenkins.namespace" . -}}
{{- $serviceName := include "jenkins.fullname" . -}}
{{ range .Values.controller.secretClaims }}
---
kind: SecretClaim
apiVersion: vaultproject.io/v1
metadata:
name: {{ $serviceName }}-{{ .name | default .path | lower }}
namespace: {{ $namespace }}
labels:
{{- $baseLabels := include "jenkins.labels" $root | fromYaml }}
{{- $overrideLabels := dict "app.kubernetes.io/name" $serviceName }}
{{- toYaml (merge $overrideLabels $baseLabels) | nindent 4 }}
spec:
type: {{ .type | default "Opaque" }}
path: {{ .path }}
{{- if .renew }}
renew: {{ .renew }}
{{- end }}
{{- end }}
{{- end }}
@@ -0,0 +1,14 @@
{{- if and .Values.controller.httpsKeyStore.enable ( not .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName ) (not .Values.controller.httpsKeyStore.disableSecretMount) -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "jenkins.fullname" . }}-https-jks
namespace: {{ template "jenkins.namespace" . }}
labels:
{{ include "jenkins.labels" . | nindent 4 }}
type: Opaque
data:
jenkins-jks-file: |
{{ .Values.controller.httpsKeyStore.jenkinsKeyStoreBase64Encoded | indent 4 }}
https-jks-password: {{ .Values.controller.httpsKeyStore.password | b64enc }}
{{- end }}
+14
View File
@@ -0,0 +1,14 @@
{{- if and (not .Values.controller.admin.existingSecret) (.Values.controller.admin.createSecret) -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ template "jenkins.fullname" . }}
namespace: {{ template "jenkins.namespace" . }}
labels:
{{ include "jenkins.labels" . | nindent 4 }}
type: Opaque
data:
jenkins-admin-password: {{ template "jenkins.password" . }}
jenkins-admin-user: {{ .Values.controller.admin.username | b64enc | quote }}
{{- end }}
@@ -0,0 +1,21 @@
{{ if .Values.serviceAccountAgent.create }}
apiVersion: v1
kind: ServiceAccount
automountServiceAccountToken: {{ .Values.serviceAccountAgent.automountServiceAccountToken }}
metadata:
name: {{ include "jenkins.serviceAccountAgentName" . }}
namespace: {{ template "jenkins.agent.namespace" . }}
{{- if .Values.serviceAccountAgent.annotations }}
annotations:
{{ tpl (toYaml .Values.serviceAccountAgent.annotations) . | indent 4 }}
{{- end }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.serviceAccountAgent.extraLabels }}
{{ tpl (toYaml .Values.serviceAccountAgent.extraLabels) . | indent 4 }}
{{- end }}
{{- if .Values.serviceAccountAgent.imagePullSecretName }}
imagePullSecrets:
- name: {{ .Values.serviceAccountAgent.imagePullSecretName }}
{{- end -}}
{{ end }}
@@ -0,0 +1,21 @@
{{ if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
metadata:
name: {{ include "jenkins.serviceAccountName" . }}
namespace: {{ template "jenkins.namespace" . }}
{{- if .Values.serviceAccount.annotations }}
annotations:
{{ tpl (toYaml .Values.serviceAccount.annotations) . | indent 4 }}
{{- end }}
labels:
{{- include "jenkins.labels" . | nindent 4 }}
{{- if .Values.serviceAccount.extraLabels }}
{{ tpl (toYaml .Values.serviceAccount.extraLabels) . | indent 4 }}
{{- end }}
{{- if .Values.serviceAccount.imagePullSecretName }}
imagePullSecrets:
- name: {{ .Values.serviceAccount.imagePullSecretName }}
{{- end -}}
{{ end }}
@@ -0,0 +1,49 @@
{{- if .Values.controller.testEnabled }}
apiVersion: v1
kind: Pod
metadata:
name: "{{ .Release.Name }}-ui-test-{{ randAlphaNum 5 | lower }}"
namespace: {{ template "jenkins.namespace" . }}
annotations:
"helm.sh/hook": test-success
spec:
{{- if .Values.controller.nodeSelector }}
nodeSelector:
{{ toYaml .Values.controller.nodeSelector | indent 4 }}
{{- end }}
{{- if .Values.controller.tolerations }}
tolerations:
{{ toYaml .Values.controller.tolerations | indent 4 }}
{{- end }}
initContainers:
- name: "test-framework"
image: "{{ .Values.helmtest.bats.image.registry }}/{{ .Values.helmtest.bats.image.repository }}:{{ .Values.helmtest.bats.image.tag }}"
command:
- "bash"
- "-c"
args:
- |
# copy bats to tools dir
set -ex
cp -R /opt/bats /tools/bats/
volumeMounts:
- mountPath: /tools
name: tools
containers:
- name: {{ .Release.Name }}-ui-test
image: "{{ .Values.controller.image.registry }}/{{ .Values.controller.image.repository }}:{{- include "controller.image.tag" . -}}"
command: ["/tools/bats/bin/bats", "-t", "/tests/run.sh"]
volumeMounts:
- mountPath: /tests
name: tests
readOnly: true
- mountPath: /tools
name: tools
volumes:
- name: tests
configMap:
name: {{ template "jenkins.fullname" . }}-tests
- name: tools
emptyDir: {}
restartPolicy: Never
{{- end }}
@@ -0,0 +1,14 @@
{{- if .Values.controller.testEnabled }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ template "jenkins.fullname" . }}-tests
namespace: {{ template "jenkins.namespace" . }}
annotations:
"helm.sh/hook": test
data:
run.sh: |-
@test "Testing Jenkins UI is accessible" {
curl --retry 48 --retry-delay 10 {{ template "jenkins.fullname" . }}:{{ .Values.controller.servicePort }}{{ default "" .Values.controller.jenkinsUriPrefix }}/login
}
{{- end }}