From fb407618dc0e338a9d3c12df5edc175b4b73ab64 Mon Sep 17 00:00:00 2001 From: Markus Pesch Date: Mon, 22 Sep 2025 07:05:21 +0000 Subject: [PATCH] feat: support network policies (#952) The following patch adds support for network policies. The patch does not contain any specific network policies, as it is uncertain in which environment and with which access rights gitea will be deployed. With regard to third-party components such as PostgreSQL or Valkey, the network policy may need to be adjusted. Whether this happens directly in the helm chart or whether the user has to enter it themselves is open to discussion. During testing, I defined a few sample network policies to get Gitea up and running. These are only examples. Reviewed-on: https://gitea.com/gitea/helm-gitea/pulls/952 Reviewed-by: DaanSelen Co-authored-by: Markus Pesch Co-committed-by: Markus Pesch --- README.md | 11 ++ templates/_helpers.tpl | 6 ++ templates/_networkPolicy.tpl | 19 ++++ templates/_pod.tpl | 17 +++ templates/gitea/deployment.yaml | 10 +- templates/gitea/networkPolicy.yaml | 32 ++++++ .../helm/networkPolicy/networkPolicy.yaml | 100 ++++++++++++++++++ values.yaml | 94 ++++++++++++++++ 8 files changed, 281 insertions(+), 8 deletions(-) create mode 100644 templates/_networkPolicy.tpl create mode 100644 templates/_pod.tpl create mode 100644 templates/gitea/networkPolicy.yaml create mode 100644 unittests/helm/networkPolicy/networkPolicy.yaml diff --git a/README.md b/README.md index e712bd7..b21a7bf 100644 --- a/README.md +++ b/README.md @@ -1158,6 +1158,17 @@ To comply with the Gitea helm chart definition of the digest parameter, a "custo | `gitea.startupProbe.successThreshold` | Success threshold for startup probe | `1` | | `gitea.startupProbe.failureThreshold` | Failure threshold for startup probe | `10` | +### Network Policy + +| Name | Description | Value | +| --------------------------- | ------------------------------------------------------------------------- | ------- | +| `networkPolicy.enabled` | Enable network policies in general. | `false` | +| `networkPolicy.annotations` | Additional network policy annotations. | `{}` | +| `networkPolicy.labels` | Additional network policy labels. | `{}` | +| `networkPolicy.policyTypes` | List of policy types. Supported is ingress, egress or ingress and egress. | `[]` | +| `networkPolicy.egress` | Concrete egress network policy implementation. | `[]` | +| `networkPolicy.ingress` | Concrete ingress network policy implementation. | `[]` | + ### valkey-cluster Valkey cluster and [Valkey](#valkey) cannot be enabled at the same time. diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index f993b95..b9c5ba6 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -87,6 +87,12 @@ storageClassName: {{ $storageClass | quote }} {{- end }} {{- end -}} +{{/* +Common annotations +*/}} +{{- define "gitea.annotations" -}} +{{- end }} + {{/* Common labels */}} diff --git a/templates/_networkPolicy.tpl b/templates/_networkPolicy.tpl new file mode 100644 index 0000000..f533714 --- /dev/null +++ b/templates/_networkPolicy.tpl @@ -0,0 +1,19 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* annotations */}} + +{{- define "gitea.networkPolicy.annotations" -}} +{{ include "gitea.annotations" . }} +{{- if .Values.networkPolicy.annotations }} +{{ toYaml .Values.networkPolicy.annotations }} +{{- end }} +{{- end }} + +{{/* labels */}} + +{{- define "gitea.networkPolicy.labels" -}} +{{ include "gitea.labels" . }} +{{- if .Values.networkPolicy.labels }} +{{ toYaml .Values.networkPolicy.labels }} +{{- end }} +{{- end }} diff --git a/templates/_pod.tpl b/templates/_pod.tpl new file mode 100644 index 0000000..0febb46 --- /dev/null +++ b/templates/_pod.tpl @@ -0,0 +1,17 @@ +--- + +{{/* labels */}} + +{{- define "gitea.pod.labels" -}} +{{- include "gitea.labels" . }} +{{- if .Values.deployment.labels }} +{{ toYaml .Values.deployment.labels }} +{{- end }} +{{- end }} + +{{- define "gitea.pod.selectorLabels" -}} +{{- include "gitea.selectorLabels" . }} +{{- if .Values.deployment.labels }} +{{ toYaml .Values.deployment.labels }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/templates/gitea/deployment.yaml b/templates/gitea/deployment.yaml index 40ad134..f8f2d65 100644 --- a/templates/gitea/deployment.yaml +++ b/templates/gitea/deployment.yaml @@ -23,10 +23,7 @@ spec: {{- end }} selector: matchLabels: - {{- include "gitea.selectorLabels" . | nindent 6 }} - {{- if .Values.deployment.labels }} - {{- toYaml .Values.deployment.labels | nindent 6 }} - {{- end }} + {{- include "gitea.pod.selectorLabels" . | nindent 6 }} template: metadata: annotations: @@ -41,10 +38,7 @@ spec: {{- toYaml . | nindent 8 }} {{- end }} labels: - {{- include "gitea.labels" . | nindent 8 }} - {{- if .Values.deployment.labels }} - {{- toYaml .Values.deployment.labels | nindent 8 }} - {{- end }} + {{- include "gitea.pod.labels" . | nindent 8 }} spec: {{- if .Values.schedulerName }} schedulerName: "{{ .Values.schedulerName }}" diff --git a/templates/gitea/networkPolicy.yaml b/templates/gitea/networkPolicy.yaml new file mode 100644 index 0000000..c328bc7 --- /dev/null +++ b/templates/gitea/networkPolicy.yaml @@ -0,0 +1,32 @@ +{{- if .Values.networkPolicy.enabled }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + {{- with (include "gitea.networkPolicy.annotations" . | fromYaml) }} + annotations: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + {{- with (include "gitea.networkPolicy.labels" . | fromYaml) }} + labels: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "gitea.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + {{- include "gitea.pod.selectorLabels" $ | nindent 6 }} + {{- with .Values.networkPolicy.policyTypes }} + policyTypes: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.networkPolicy.egress }} + egress: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.networkPolicy.ingress }} + ingress: + {{- toYaml . | nindent 2 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/unittests/helm/networkPolicy/networkPolicy.yaml b/unittests/helm/networkPolicy/networkPolicy.yaml new file mode 100644 index 0000000..e1624bf --- /dev/null +++ b/unittests/helm/networkPolicy/networkPolicy.yaml @@ -0,0 +1,100 @@ +chart: + appVersion: 0.1.0 + version: 0.1.0 +suite: NetworkPolicy template +release: + name: gitea-unittest + namespace: testing +templates: + - templates/gitea/networkPolicy.yaml +tests: + - it: Skip rendering networkPolicy + set: + networkPolicy.enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: Render default networkPolicy + set: + networkPolicy.enabled: true + asserts: + - hasDocuments: + count: 1 + - containsDocument: + apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + name: gitea-unittest + namespace: testing + - notExists: + path: metadata.annotations + - equal: + path: metadata.labels + value: + app: gitea + app.kubernetes.io/instance: gitea-unittest + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: gitea + app.kubernetes.io/version: 0.1.0 + helm.sh/chart: gitea-0.1.0 + version: 0.1.0 + - equal: + path: spec.podSelector.matchLabels + value: + app.kubernetes.io/instance: gitea-unittest + app.kubernetes.io/name: gitea + - notExists: + path: spec.policyTypes + - notExists: + path: spec.egress + - notExists: + path: spec.ingress + + - it: Template networkPolicy with policyTypes, egress and ingress configuration + set: + networkPolicy.enabled: true + networkPolicy.policyTypes: + - Egress + - Ingress + networkPolicy.ingress: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: monitoring + podSelector: + matchLabels: + app.kubernetes.io/name: prometheus + networkPolicy.egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: ingress-nginx + podSelector: + matchLabels: + app.kubernetes.io/name: ingress-nginx + asserts: + - equal: + path: spec.policyTypes + value: + - Egress + - Ingress + - equal: + path: spec.egress + value: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: ingress-nginx + podSelector: + matchLabels: + app.kubernetes.io/name: ingress-nginx + - equal: + path: spec.ingress + value: + - from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: monitoring + podSelector: + matchLabels: + app.kubernetes.io/name: prometheus diff --git a/values.yaml b/values.yaml index 4f323cb..f16791a 100644 --- a/values.yaml +++ b/values.yaml @@ -513,6 +513,100 @@ gitea: successThreshold: 1 failureThreshold: 10 + +## @section Network Policy +networkPolicy: + ## @param networkPolicy.enabled Enable network policies in general. + ## @param networkPolicy.annotations Additional network policy annotations. + ## @param networkPolicy.labels Additional network policy labels. + ## @param networkPolicy.policyTypes List of policy types. Supported is ingress, egress or ingress and egress. + ## @param networkPolicy.egress Concrete egress network policy implementation. + ## @skip networkPolicy.egress Skip individual egress configuration. + ## @param networkPolicy.ingress Concrete ingress network policy implementation. + ## @skip networkPolicy.ingress Skip individual ingress configuration. + enabled: false + annotations: {} + labels: {} + policyTypes: [] + # - Egress + # - Ingress + egress: [] + # Allow outgoing DNS traffic to the internal running DNS-Server. For example core-dns. + # + # - to: + # - namespaceSelector: + # matchLabels: + # kubernetes.io/metadata.name: kube-system + # podSelector: + # matchLabels: + # k8s-app: kube-dns + # ports: + # - port: 53 + # protocol: TCP + # - port: 53 + # protocol: UDP + + # Allow outgoing traffic via HTTPS. For example for oAuth2, Gravatar and other third party APIs. + # + # - to: + # ports: + # - port: 443 + # protocol: TCP + + # Allow outgoing traffic to PostgreSQL. + # + # - to: + # - podSelector: + # matchLabels: + # app.kubernetes.io/name: postgresql-ha + # ports: [] + # # Avoid explicit list of ports, because Gitea tries to ping the PostgreSQL database during the initialization + # # process. The ICMP protocol is currently not supported as list of protocols by kubernetes. For this reason would + # # lead listing of the ports to an issue. Therefore, please handle the database ports with care. + # # + # # - port: 5432 + # # protocol: TCP + + # Allow outgoing traffic to Valkey. + # + # - to: + # - podSelector: + # matchLabels: + # app.kubernetes.io/name: valkey-cluster + # ports: + # - port: 6379 + # protocol: TCP + # - port: 16379 + # protocol: TCP + + ingress: [] + # Allow incoming HTTP traffic from prometheus. + # + # - from: + # - namespaceSelector: + # matchLabels: + # kubernetes.io/metadata.name: monitoring + # podSelector: + # matchLabels: + # app.kubernetes.io/name: prometheus + # ports: + # - port: http + # protocol: TCP + + # Allow incoming HTTP traffic from ingress-nginx. + # + # - from: + # - namespaceSelector: + # matchLabels: + # kubernetes.io/metadata.name: ingress-nginx + # podSelector: + # matchLabels: + # app.kubernetes.io/name: ingress-nginx + # ports: + # - port: http + # protocol: TCP + + ## @section valkey-cluster ## @param valkey-cluster.enabled Enable valkey cluster # ⚠️ The valkey charts do not work well with special characters in the password ().