diff --git a/charts/jenkins/README.md b/charts/jenkins/README.md index 7ad4a65db..322368c3a 100644 --- a/charts/jenkins/README.md +++ b/charts/jenkins/README.md @@ -10,6 +10,10 @@ Jenkins Configuration as Code, optional plugin installation with support, Gateway API, Ingress, NetworkPolicy, ExternalSecret, ServiceMonitor, PodDisruptionBudget, and Helm tests. +NetworkPolicy supports `networkPolicy.egress.extraEgress` for appending custom egress +rules without replacing the chart-generated DNS, cluster, internet, and +`networkPolicy.egress.extraRules` controls. + ## Install ```bash diff --git a/charts/jenkins/templates/NOTES.txt b/charts/jenkins/templates/NOTES.txt index 716692476..c89d8ae71 100644 --- a/charts/jenkins/templates/NOTES.txt +++ b/charts/jenkins/templates/NOTES.txt @@ -1,20 +1,20 @@ {{/* SPDX-License-Identifier: Apache-2.0 */}} Jenkins deployed successfully! -ACCESS: +1. Access kubectl port-forward svc/{{ include "jenkins.fullname" . }} -n {{ .Release.Namespace }} 8080:{{ .Values.service.httpPort }} Open: http://localhost:8080/ -SERVICE: +2. Service Internal URL: http://{{ include "jenkins.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.httpPort }}/ {{- if .Values.agent.enabled }} Agent TCP: {{ include "jenkins.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.agent.servicePort }} {{- end }} -IMAGE: +3. Image {{ include "jenkins.image" . }} -ADMIN: +4. Admin {{- if .Values.admin.create }} Admin Secret: {{ include "jenkins.adminSecretName" . }} Username: @@ -25,20 +25,20 @@ ADMIN: Admin bootstrap: disabled {{- end }} -CONFIGURATION: +5. Configuration JCasC: {{ ternary "enabled" "disabled" .Values.jcasC.enabled }} Plugin bootstrap: {{ ternary "enabled" "disabled" .Values.plugins.install.enabled }} Persistence: {{ ternary "enabled" "disabled" .Values.persistence.enabled }} -NETWORKING: +6. Networking Ingress: {{ ternary "enabled" "disabled" .Values.ingress.enabled }} Gateway API: {{ ternary "enabled" "disabled" .Values.gateway.enabled }} NetworkPolicy: {{ ternary "enabled" "disabled" .Values.networkPolicy.enabled }} -OBSERVABILITY: +7. Observability ServiceMonitor: {{ ternary "enabled" "disabled" .Values.metrics.serviceMonitor.enabled }} -OPERATIONS: +8. Operations Run Helm tests: helm test {{ .Release.Name }} -n {{ .Release.Namespace }} @@ -46,7 +46,7 @@ OPERATIONS: kubectl get pods -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} kubectl logs -n {{ .Release.Namespace }} statefulset/{{ include "jenkins.fullname" . }} -DOCUMENTATION: +9. Documentation Chart: https://helmforge.dev/docs/charts/jenkins Source: https://github.com/helmforgedev/charts/tree/main/charts/jenkins Jenkins: https://www.jenkins.io diff --git a/charts/jenkins/templates/_helpers.tpl b/charts/jenkins/templates/_helpers.tpl index b742843f7..37921fe51 100644 --- a/charts/jenkins/templates/_helpers.tpl +++ b/charts/jenkins/templates/_helpers.tpl @@ -96,3 +96,24 @@ app.kubernetes.io/part-of: helmforge {{- $javaOpts -}} {{- end -}} {{- end -}} + +{{- define "jenkins.validate.externalSecrets" -}} +{{- if and .Values.externalSecrets.enabled (not .Values.admin.existingSecret) -}} +{{- fail "externalSecrets.enabled requires admin.existingSecret to be set to prevent credential drift between the chart-managed Secret and the ExternalSecret." -}} +{{- end -}} +{{- $externalSecretData := .Values.externalSecrets.data | default list -}} +{{- $externalSecretDataFrom := .Values.externalSecrets.dataFrom | default list -}} +{{- if and .Values.externalSecrets.enabled (eq (add (len $externalSecretData) (len $externalSecretDataFrom)) 0) -}} +{{- fail "externalSecrets.data or externalSecrets.dataFrom must not be empty when externalSecrets.enabled=true" -}} +{{- end -}} +{{- end -}} + +{{- define "jenkins.validate" -}} +{{- include "jenkins.validate.externalSecrets" . -}} +{{- if and .Values.jcasC.enabled (eq (len (.Values.jcasC.configScripts | default dict)) 0) -}} +{{- fail "jcasC.enabled requires at least one jcasC.configScripts entry" -}} +{{- end -}} +{{- if and .Values.plugins.install.enabled (eq (len (.Values.plugins.install.list | default list)) 0) -}} +{{- fail "plugins.install.enabled requires at least one plugins.install.list entry" -}} +{{- end -}} +{{- end -}} diff --git a/charts/jenkins/templates/externalsecret.yaml b/charts/jenkins/templates/externalsecret.yaml index 649df85c7..32c7c2546 100644 --- a/charts/jenkins/templates/externalsecret.yaml +++ b/charts/jenkins/templates/externalsecret.yaml @@ -1,13 +1,8 @@ {{/* SPDX-License-Identifier: Apache-2.0 */}} +{{- include "jenkins.validate.externalSecrets" . }} {{- if .Values.externalSecrets.enabled }} -{{- if not .Values.admin.existingSecret }} - {{- fail "externalSecrets.enabled requires admin.existingSecret to be set to prevent credential drift between the chart-managed Secret and the ExternalSecret." }} -{{- end }} {{- $externalSecretData := .Values.externalSecrets.data | default list -}} {{- $externalSecretDataFrom := .Values.externalSecrets.dataFrom | default list -}} -{{- if eq (add (len $externalSecretData) (len $externalSecretDataFrom)) 0 }} - {{- fail "externalSecrets.data or externalSecrets.dataFrom must not be empty when externalSecrets.enabled=true" }} -{{- end }} apiVersion: {{ .Values.externalSecrets.apiVersion }} kind: ExternalSecret metadata: diff --git a/charts/jenkins/templates/networkpolicy.yaml b/charts/jenkins/templates/networkpolicy.yaml index 9a03fe815..f34288f30 100644 --- a/charts/jenkins/templates/networkpolicy.yaml +++ b/charts/jenkins/templates/networkpolicy.yaml @@ -64,5 +64,8 @@ spec: {{- with .Values.networkPolicy.egress.extraRules }} {{- toYaml . | nindent 4 }} {{- end }} + {{- with .Values.networkPolicy.egress.extraEgress }} + {{- toYaml . | nindent 4 }} + {{- end }} {{- end }} {{- end }} diff --git a/charts/jenkins/templates/statefulset.yaml b/charts/jenkins/templates/statefulset.yaml index 926cfb5cf..b9e56ead2 100644 --- a/charts/jenkins/templates/statefulset.yaml +++ b/charts/jenkins/templates/statefulset.yaml @@ -1,4 +1,5 @@ {{/* SPDX-License-Identifier: Apache-2.0 */}} +{{- include "jenkins.validate" . }} apiVersion: apps/v1 kind: StatefulSet metadata: diff --git a/charts/jenkins/tests/networkpolicy-extra-egress-values.yaml b/charts/jenkins/tests/networkpolicy-extra-egress-values.yaml new file mode 100644 index 000000000..aded8e6cd --- /dev/null +++ b/charts/jenkins/tests/networkpolicy-extra-egress-values.yaml @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +networkPolicy: + enabled: true + egress: + extraEgress: + - to: + - ipBlock: + cidr: 10.0.0.0/8 + ports: + - protocol: TCP + port: 443 diff --git a/charts/jenkins/tests/networkpolicy_test.yaml b/charts/jenkins/tests/networkpolicy_test.yaml index b3a05c249..71eb82592 100644 --- a/charts/jenkins/tests/networkpolicy_test.yaml +++ b/charts/jenkins/tests/networkpolicy_test.yaml @@ -32,3 +32,17 @@ tests: content: Egress - exists: path: spec.egress + + - it: should append extra egress rules + values: + - networkpolicy-extra-egress-values.yaml + asserts: + - contains: + path: spec.egress + content: + to: + - ipBlock: + cidr: 10.0.0.0/8 + ports: + - protocol: TCP + port: 443 diff --git a/charts/jenkins/tests/test_connection_test.yaml b/charts/jenkins/tests/test_connection_test.yaml new file mode 100644 index 000000000..8f0349c99 --- /dev/null +++ b/charts/jenkins/tests/test_connection_test.yaml @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: Apache-2.0 +suite: Helm Test +templates: + - templates/tests/test-connection.yaml +release: + name: test + namespace: default +tests: + - it: should render the Helm test hook pod + asserts: + - isKind: + of: Pod + - equal: + path: metadata.name + value: test-jenkins-test-connection + - equal: + path: metadata.annotations["helm.sh/hook"] + value: test + - equal: + path: metadata.annotations["helm.sh/hook-delete-policy"] + value: before-hook-creation,hook-succeeded diff --git a/charts/jenkins/values.schema.json b/charts/jenkins/values.schema.json index cf0930de6..78e0a23b4 100644 --- a/charts/jenkins/values.schema.json +++ b/charts/jenkins/values.schema.json @@ -277,7 +277,16 @@ "type": "object" }, "egress": { - "type": "object" + "type": "object", + "additionalProperties": true, + "properties": { + "extraEgress": { + "type": "array", + "items": { + "type": "object" + } + } + } } } }, diff --git a/charts/jenkins/values.yaml b/charts/jenkins/values.yaml index 5433e692e..43e84717c 100644 --- a/charts/jenkins/values.yaml +++ b/charts/jenkins/values.yaml @@ -188,6 +188,8 @@ networkPolicy: allowInternet: true # -- Extra egress rules. extraRules: [] + # -- Additional egress rules appended after generated egress rules. + extraEgress: [] # ============================================================================= # Service Account and RBAC