From 35770ab87ae331e4bda9093b5de1f43492584d24 Mon Sep 17 00:00:00 2001 From: MergeCheck Date: Fri, 3 Jul 2026 17:07:27 -0300 Subject: [PATCH 1/3] fix(notediscovery): align template standards --- charts/notediscovery/README.md | 14 ++++ charts/notediscovery/templates/NOTES.txt | 81 +++++++++++++++---- charts/notediscovery/templates/_helpers.tpl | 10 +++ .../notediscovery/templates/deployment.yaml | 2 +- charts/notediscovery/templates/ingress.yaml | 4 +- .../templates/networkpolicy.yaml | 22 +++++ .../tests/networkpolicy_test.yaml | 23 ++++++ .../podlabels-selector-instance-values.yaml | 3 + .../tests/podlabels-selector-name-values.yaml | 3 + .../tests/test-connection.yaml | 0 .../notediscovery/tests/validation_test.yaml | 18 +++++ charts/notediscovery/values.schema.json | 3 +- charts/notediscovery/values.yaml | 2 + 13 files changed, 166 insertions(+), 19 deletions(-) create mode 100644 charts/notediscovery/tests/podlabels-selector-instance-values.yaml create mode 100644 charts/notediscovery/tests/podlabels-selector-name-values.yaml rename charts/notediscovery/{templates => }/tests/test-connection.yaml (100%) diff --git a/charts/notediscovery/README.md b/charts/notediscovery/README.md index b2ec202d..038f4596 100644 --- a/charts/notediscovery/README.md +++ b/charts/notediscovery/README.md @@ -83,6 +83,13 @@ resources: networkPolicy: enabled: true + extraEgress: + - to: + - ipBlock: + cidr: 10.0.0.0/8 + ports: + - protocol: TCP + port: 8443 ``` Create the existing Secret with a complete NoteDiscovery config file: @@ -140,6 +147,13 @@ Multiple pods require storage semantics chosen by the operator, typically a shared ReadWriteMany claim; the default generated claim is a single-writer volume. +## Network Policy + +`networkPolicy.enabled=true` restricts inbound HTTP traffic to the configured +`networkPolicy.ingressFrom` peers, or to all namespaces when `ingressFrom` is +empty. `networkPolicy.extraEgress` enables egress isolation and appends custom +egress rules after built-in DNS and HTTPS allowances. + ## Documentation - [Storage](docs/storage.md) diff --git a/charts/notediscovery/templates/NOTES.txt b/charts/notediscovery/templates/NOTES.txt index 0bf4dbad..550404a4 100644 --- a/charts/notediscovery/templates/NOTES.txt +++ b/charts/notediscovery/templates/NOTES.txt @@ -1,38 +1,87 @@ {{/* SPDX-License-Identifier: Apache-2.0 */}} +1. Summary + NoteDiscovery release: {{ .Release.Name }} Namespace: {{ .Release.Namespace }} +Application port: {{ .Values.service.port }} +Data directory: {{ .Values.persistence.mountPath }} + +2. Workload + +Check the Deployment and rollout status: -Workload: kubectl get deploy {{ include "notediscovery.fullname" . }} -n {{ .Release.Namespace }} kubectl rollout status deploy/{{ include "notediscovery.fullname" . }} -n {{ .Release.Namespace }} -Service: +3. Access + +Check the Service: + kubectl get svc {{ include "notediscovery.fullname" . }} -n {{ .Release.Namespace }} -Local access: +Use a local port-forward when Ingress or Gateway API is not enabled: + kubectl port-forward svc/{{ include "notediscovery.fullname" . }} 8000:{{ .Values.service.port }} -n {{ .Release.Namespace }} - Open http://127.0.0.1:8000 -Runtime configuration: - Data directory: {{ .Values.persistence.mountPath }} - Search enabled: {{ .Values.notediscovery.searchEnabled }} - Authentication enabled: {{ .Values.auth.enabled }} +Then open: + + http://127.0.0.1:8000 + +4. Credentials -Persistence: +Authentication enabled: {{ .Values.auth.enabled }} + +{{- if .Values.auth.existingSecret }} +The complete NoteDiscovery config is read from Secret {{ .Values.auth.existingSecret }} key {{ .Values.auth.existingSecretKey }}. +{{- else if .Values.auth.enabled }} +The chart renders the generated authenticated config into a Secret. +{{- else }} +Authentication is disabled. Enable auth or provide auth.existingSecret before exposing NoteDiscovery to shared users. +{{- end }} + +5. Configuration + +Search enabled: {{ .Values.notediscovery.searchEnabled }} {{- if .Values.persistence.existingClaim }} - Existing PVC {{ .Values.persistence.existingClaim }} is mounted. +Storage: existing PVC {{ .Values.persistence.existingClaim }} is mounted. {{- else if .Values.persistence.enabled }} - PVC is enabled. Back up the data volume before upgrades. +Storage: chart-managed PVC is enabled. Back up the data volume before upgrades. +{{- else }} +Storage: persistence is disabled and NoteDiscovery data is stored in an emptyDir. +{{- end }} +{{- if .Values.networkPolicy.enabled }} +NetworkPolicy: enabled. {{- else }} - Persistence is disabled and NoteDiscovery data is stored in an emptyDir. +NetworkPolicy: disabled. {{- end }} -Troubleshooting: - kubectl logs deploy/{{ include "notediscovery.fullname" . }} -n {{ .Release.Namespace }} - kubectl describe pod -l app.kubernetes.io/instance={{ .Release.Name }} -n {{ .Release.Namespace }} +6. Validation + +Run Helm tests: -Validation: helm test {{ .Release.Name }} -n {{ .Release.Namespace }} + +Run the HelmForge chart gate from the ops repo: + make validate-chart CHART=notediscovery +7. Troubleshooting + +Inspect logs and pod events: + + kubectl logs deploy/{{ include "notediscovery.fullname" . }} -n {{ .Release.Namespace }} + kubectl describe pod -l app.kubernetes.io/instance={{ .Release.Name }} -n {{ .Release.Namespace }} + +If the app is exposed, ensure notediscovery.allowedOrigins includes the public origin. + +8. Resources + +Chart documentation: + + https://github.com/helmforgedev/charts/tree/main/charts/notediscovery + +Upstream project: + + https://github.com/gamosoft/NoteDiscovery + Happy Helmforging :) diff --git a/charts/notediscovery/templates/_helpers.tpl b/charts/notediscovery/templates/_helpers.tpl index aadcb2dd..c6f4fb66 100644 --- a/charts/notediscovery/templates/_helpers.tpl +++ b/charts/notediscovery/templates/_helpers.tpl @@ -152,10 +152,20 @@ Validate chart values. {{- if and (gt (int .Values.replicaCount) 1) (not .Values.persistence.existingClaim) -}} {{- fail "replicaCount > 1 requires persistence.existingClaim because NoteDiscovery stores notes as local files on a single writable volume" -}} {{- end -}} +{{- if and .Values.ingress.enabled (empty .Values.ingress.hosts) -}} +{{- fail "ingress.hosts must contain at least one host when ingress.enabled=true" -}} +{{- end -}} {{- if and .Values.auth.enabled (not .Values.auth.existingSecret) (or (empty .Values.auth.secretKey) (empty .Values.auth.password)) -}} {{- fail "auth.secretKey and auth.password are required when auth.enabled=true unless auth.existingSecret is set" -}} {{- end -}} {{- if and .Values.externalSecrets.enabled (empty .Values.externalSecrets.items) -}} {{- fail "externalSecrets.items must contain at least one item when externalSecrets.enabled=true" -}} {{- end -}} +{{- $podLabels := .Values.podLabels | default dict -}} +{{- if hasKey $podLabels "app.kubernetes.io/name" -}} +{{- fail "podLabels must not override the selector label app.kubernetes.io/name" -}} +{{- end -}} +{{- if hasKey $podLabels "app.kubernetes.io/instance" -}} +{{- fail "podLabels must not override the selector label app.kubernetes.io/instance" -}} +{{- end -}} {{- end -}} diff --git a/charts/notediscovery/templates/deployment.yaml b/charts/notediscovery/templates/deployment.yaml index a2db624d..9554dc0e 100644 --- a/charts/notediscovery/templates/deployment.yaml +++ b/charts/notediscovery/templates/deployment.yaml @@ -15,7 +15,7 @@ spec: template: metadata: labels: - {{- include "notediscovery.labels" . | nindent 8 }} + {{- include "notediscovery.selectorLabels" . | nindent 8 }} {{- with .Values.podLabels }} {{- toYaml . | nindent 8 }} {{- end }} diff --git a/charts/notediscovery/templates/ingress.yaml b/charts/notediscovery/templates/ingress.yaml index 8f42a9ac..ddf3b24b 100644 --- a/charts/notediscovery/templates/ingress.yaml +++ b/charts/notediscovery/templates/ingress.yaml @@ -11,7 +11,9 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: - ingressClassName: {{ .Values.ingress.ingressClassName | quote }} + {{- with .Values.ingress.ingressClassName }} + ingressClassName: {{ . | quote }} + {{- end }} {{- with .Values.ingress.tls }} tls: {{- toYaml . | nindent 4 }} diff --git a/charts/notediscovery/templates/networkpolicy.yaml b/charts/notediscovery/templates/networkpolicy.yaml index 02c604b5..37bf1e8d 100644 --- a/charts/notediscovery/templates/networkpolicy.yaml +++ b/charts/notediscovery/templates/networkpolicy.yaml @@ -12,6 +12,9 @@ spec: {{- include "notediscovery.selectorLabels" . | nindent 6 }} policyTypes: - Ingress + {{- if .Values.networkPolicy.extraEgress }} + - Egress + {{- end }} ingress: - from: {{- if .Values.networkPolicy.ingressFrom }} @@ -22,4 +25,23 @@ spec: ports: - protocol: TCP port: http + {{- with .Values.networkPolicy.extraEgress }} + egress: + - to: + - namespaceSelector: {} + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + - to: + - ipBlock: + cidr: 0.0.0.0/0 + - ipBlock: + cidr: ::/0 + ports: + - protocol: TCP + port: 443 + {{- toYaml . | nindent 4 }} + {{- end }} {{- end }} diff --git a/charts/notediscovery/tests/networkpolicy_test.yaml b/charts/notediscovery/tests/networkpolicy_test.yaml index 40897f6f..279f37d2 100644 --- a/charts/notediscovery/tests/networkpolicy_test.yaml +++ b/charts/notediscovery/tests/networkpolicy_test.yaml @@ -14,3 +14,26 @@ tests: content: protocol: TCP port: http + - notContains: + path: spec.policyTypes + content: Egress + - it: enables egress isolation when extraEgress is configured + values: + - networkpolicy-values.yaml + set: + networkPolicy.extraEgress[0].to[0].ipBlock.cidr: 10.0.0.0/8 + networkPolicy.extraEgress[0].ports[0].protocol: TCP + networkPolicy.extraEgress[0].ports[0].port: 8443 + asserts: + - contains: + path: spec.policyTypes + content: Egress + - equal: + path: spec.egress[0].ports[0].port + value: 53 + - equal: + path: spec.egress[1].ports[0].port + value: 443 + - equal: + path: spec.egress[2].ports[0].port + value: 8443 diff --git a/charts/notediscovery/tests/podlabels-selector-instance-values.yaml b/charts/notediscovery/tests/podlabels-selector-instance-values.yaml new file mode 100644 index 00000000..5a3999b7 --- /dev/null +++ b/charts/notediscovery/tests/podlabels-selector-instance-values.yaml @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 +podLabels: + app.kubernetes.io/instance: custom diff --git a/charts/notediscovery/tests/podlabels-selector-name-values.yaml b/charts/notediscovery/tests/podlabels-selector-name-values.yaml new file mode 100644 index 00000000..44e89508 --- /dev/null +++ b/charts/notediscovery/tests/podlabels-selector-name-values.yaml @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 +podLabels: + app.kubernetes.io/name: custom diff --git a/charts/notediscovery/templates/tests/test-connection.yaml b/charts/notediscovery/tests/test-connection.yaml similarity index 100% rename from charts/notediscovery/templates/tests/test-connection.yaml rename to charts/notediscovery/tests/test-connection.yaml diff --git a/charts/notediscovery/tests/validation_test.yaml b/charts/notediscovery/tests/validation_test.yaml index c3518b98..2b563c50 100644 --- a/charts/notediscovery/tests/validation_test.yaml +++ b/charts/notediscovery/tests/validation_test.yaml @@ -15,9 +15,27 @@ tests: asserts: - failedTemplate: errorMessage: "auth.secretKey and auth.password are required when auth.enabled=true unless auth.existingSecret is set" + - it: fails when ingress is enabled without hosts + set: + ingress.enabled: true + asserts: + - failedTemplate: + errorMessage: "ingress.hosts must contain at least one host when ingress.enabled=true" - it: fails when ExternalSecrets is enabled without items set: externalSecrets.enabled: true asserts: - failedTemplate: errorMessage: "externalSecrets.items must contain at least one item when externalSecrets.enabled=true" + - it: fails when podLabels override selector name + values: + - podlabels-selector-name-values.yaml + asserts: + - failedTemplate: + errorMessage: "podLabels must not override the selector label app.kubernetes.io/name" + - it: fails when podLabels override selector instance + values: + - podlabels-selector-instance-values.yaml + asserts: + - failedTemplate: + errorMessage: "podLabels must not override the selector label app.kubernetes.io/instance" diff --git a/charts/notediscovery/values.schema.json b/charts/notediscovery/values.schema.json index 042d4004..beb1ca01 100644 --- a/charts/notediscovery/values.schema.json +++ b/charts/notediscovery/values.schema.json @@ -171,7 +171,8 @@ "type": "object", "properties": { "enabled": { "type": "boolean", "default": false }, - "ingressFrom": { "type": "array", "items": { "type": "object" } } + "ingressFrom": { "type": "array", "items": { "type": "object" } }, + "extraEgress": { "type": "array", "items": { "type": "object" } } } } } diff --git a/charts/notediscovery/values.yaml b/charts/notediscovery/values.yaml index e6832473..abcd4339 100644 --- a/charts/notediscovery/values.yaml +++ b/charts/notediscovery/values.yaml @@ -186,6 +186,8 @@ networkPolicy: enabled: false # -- Custom ingress peers. Empty allows ingress from any namespace. ingressFrom: [] + # -- Additional egress rules. When set, the policy also isolates egress while preserving DNS and HTTPS access. + extraEgress: [] # -- Node selector for scheduling the pod. nodeSelector: {} From 0a8fc48b93a09e1cb88a3c96a0d401d6ca48f861 Mon Sep 17 00:00:00 2001 From: MergeCheck Date: Fri, 3 Jul 2026 17:36:50 -0300 Subject: [PATCH 2/3] fix(notediscovery): address networkpolicy test review --- .../{ => templates}/tests/test-connection.yaml | 0 .../networkpolicy-extra-egress-values.yaml | 14 ++++++++++++++ .../tests/networkpolicy_test.yaml | 6 +----- .../tests/test_connection_test.yaml | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 5 deletions(-) rename charts/notediscovery/{ => templates}/tests/test-connection.yaml (100%) create mode 100644 charts/notediscovery/tests/networkpolicy-extra-egress-values.yaml create mode 100644 charts/notediscovery/tests/test_connection_test.yaml diff --git a/charts/notediscovery/tests/test-connection.yaml b/charts/notediscovery/templates/tests/test-connection.yaml similarity index 100% rename from charts/notediscovery/tests/test-connection.yaml rename to charts/notediscovery/templates/tests/test-connection.yaml diff --git a/charts/notediscovery/tests/networkpolicy-extra-egress-values.yaml b/charts/notediscovery/tests/networkpolicy-extra-egress-values.yaml new file mode 100644 index 00000000..3623acec --- /dev/null +++ b/charts/notediscovery/tests/networkpolicy-extra-egress-values.yaml @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: Apache-2.0 +networkPolicy: + enabled: true + ingressFrom: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: ingress-system + extraEgress: + - to: + - ipBlock: + cidr: 10.0.0.0/8 + ports: + - protocol: TCP + port: 8443 diff --git a/charts/notediscovery/tests/networkpolicy_test.yaml b/charts/notediscovery/tests/networkpolicy_test.yaml index 279f37d2..baa457a1 100644 --- a/charts/notediscovery/tests/networkpolicy_test.yaml +++ b/charts/notediscovery/tests/networkpolicy_test.yaml @@ -19,11 +19,7 @@ tests: content: Egress - it: enables egress isolation when extraEgress is configured values: - - networkpolicy-values.yaml - set: - networkPolicy.extraEgress[0].to[0].ipBlock.cidr: 10.0.0.0/8 - networkPolicy.extraEgress[0].ports[0].protocol: TCP - networkPolicy.extraEgress[0].ports[0].port: 8443 + - networkpolicy-extra-egress-values.yaml asserts: - contains: path: spec.policyTypes diff --git a/charts/notediscovery/tests/test_connection_test.yaml b/charts/notediscovery/tests/test_connection_test.yaml new file mode 100644 index 00000000..e05d85b4 --- /dev/null +++ b/charts/notediscovery/tests/test_connection_test.yaml @@ -0,0 +1,18 @@ +# 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-notediscovery-test-connection + - equal: + path: metadata.annotations["helm.sh/hook"] + value: test From 7fa092422aa6f52b6345aba24c21fcbe599cba6e Mon Sep 17 00:00:00 2001 From: MergeCheck Date: Sun, 5 Jul 2026 16:30:35 -0300 Subject: [PATCH 3/3] test(notediscovery): cover hook delete policy --- charts/notediscovery/templates/_helpers.tpl | 7 +++---- charts/notediscovery/tests/test_connection_test.yaml | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/charts/notediscovery/templates/_helpers.tpl b/charts/notediscovery/templates/_helpers.tpl index c6f4fb66..40d80a3c 100644 --- a/charts/notediscovery/templates/_helpers.tpl +++ b/charts/notediscovery/templates/_helpers.tpl @@ -162,10 +162,9 @@ Validate chart values. {{- fail "externalSecrets.items must contain at least one item when externalSecrets.enabled=true" -}} {{- end -}} {{- $podLabels := .Values.podLabels | default dict -}} -{{- if hasKey $podLabels "app.kubernetes.io/name" -}} -{{- fail "podLabels must not override the selector label app.kubernetes.io/name" -}} +{{- range $key := (list "app.kubernetes.io/name" "app.kubernetes.io/instance") -}} +{{- if hasKey $podLabels $key -}} +{{- fail (printf "podLabels must not override the selector label %s" $key) -}} {{- end -}} -{{- if hasKey $podLabels "app.kubernetes.io/instance" -}} -{{- fail "podLabels must not override the selector label app.kubernetes.io/instance" -}} {{- end -}} {{- end -}} diff --git a/charts/notediscovery/tests/test_connection_test.yaml b/charts/notediscovery/tests/test_connection_test.yaml index e05d85b4..5bc22593 100644 --- a/charts/notediscovery/tests/test_connection_test.yaml +++ b/charts/notediscovery/tests/test_connection_test.yaml @@ -16,3 +16,6 @@ tests: - equal: path: metadata.annotations["helm.sh/hook"] value: test + - equal: + path: metadata.annotations["helm.sh/hook-delete-policy"] + value: before-hook-creation,hook-succeeded