diff --git a/charts/jellyfin/templates/deployment.yaml b/charts/jellyfin/templates/deployment.yaml index 41faa6b..f919231 100644 --- a/charts/jellyfin/templates/deployment.yaml +++ b/charts/jellyfin/templates/deployment.yaml @@ -14,8 +14,8 @@ spec: {{- toYaml . | trim | nindent 4 }} {{- end }} replicas: {{ .Values.replicaCount }} - {{- with .Values.revisionHistoryLimit }} - revisionHistoryLimit: {{ . }} + {{- if not (eq .Values.revisionHistoryLimit nil) }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} {{- end }} selector: matchLabels: @@ -38,8 +38,10 @@ spec: {{- end }} serviceAccountName: {{ include "jellyfin.serviceAccountName" . }} automountServiceAccountToken: {{ .Values.serviceAccount.automount }} + {{- with .Values.podSecurityContext }} securityContext: - {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- toYaml . | nindent 8 }} + {{- end }} {{- if or .Values.jellyfin.enableDLNA .Values.podPrivileges.hostNetwork }} hostNetwork: true {{- end }} @@ -51,8 +53,10 @@ spec: {{- end }} containers: - name: {{ .Chart.Name }} + {{- with .Values.securityContext }} securityContext: - {{- toYaml .Values.securityContext | nindent 12 }} + {{- toYaml . | nindent 12 }} + {{- end }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} {{- with .Values.jellyfin.command }} @@ -124,8 +128,10 @@ spec: {{- toYaml .Values.livenessProbe | nindent 12 }} readinessProbe: {{- toYaml .Values.readinessProbe | nindent 12 }} + {{- with .Values.resources }} resources: - {{- toYaml .Values.resources | nindent 12 }} + {{- toYaml . | nindent 12 }} + {{- end }} volumeMounts: - mountPath: /config name: config @@ -213,6 +219,8 @@ spec: dnsConfig: {{- toYaml . | nindent 8}} {{- end }} - {{- with .Values.dnsPolicy }} - dnsPolicy: {{ . | quote }} + {{- if .Values.dnsPolicy }} + dnsPolicy: {{ .Values.dnsPolicy | quote }} + {{- else if or .Values.jellyfin.enableDLNA .Values.podPrivileges.hostNetwork }} + dnsPolicy: ClusterFirstWithHostNet {{- end }} diff --git a/charts/jellyfin/tests/deployment_image_test.yaml b/charts/jellyfin/tests/deployment_image_test.yaml index 59f8789..8fce544 100644 --- a/charts/jellyfin/tests/deployment_image_test.yaml +++ b/charts/jellyfin/tests/deployment_image_test.yaml @@ -8,9 +8,9 @@ tests: - it: should use default image repository asserts: - - equal: + - matchRegex: path: spec.template.spec.containers[0].image - value: jellyfin/jellyfin:RELEASE-VERSION + pattern: "^docker\\.io/jellyfin/jellyfin:" - it: should use custom image repository set: @@ -36,7 +36,7 @@ tests: asserts: - matchRegex: path: spec.template.spec.containers[0].image - pattern: ":RELEASE-VERSION$" + pattern: ":[0-9]+\\.[0-9]+\\.[0-9]+$" - it: should use custom tag when specified set: @@ -44,7 +44,7 @@ tests: asserts: - equal: path: spec.template.spec.containers[0].image - value: jellyfin/jellyfin:10.8.13 + value: docker.io/jellyfin/jellyfin:10.8.13 - it: should support latest tag set: @@ -52,7 +52,7 @@ tests: asserts: - equal: path: spec.template.spec.containers[0].image - value: jellyfin/jellyfin:latest + value: docker.io/jellyfin/jellyfin:latest - it: should support beta tags set: @@ -60,7 +60,7 @@ tests: asserts: - equal: path: spec.template.spec.containers[0].image - value: jellyfin/jellyfin:10.9.0-beta1 + value: docker.io/jellyfin/jellyfin:10.9.0-beta1 - it: should support sha256 digest set: @@ -68,7 +68,7 @@ tests: asserts: - equal: path: spec.template.spec.containers[0].image - value: jellyfin/jellyfin:sha256:abc123def456 + value: docker.io/jellyfin/jellyfin:sha256:abc123def456 - it: should combine custom repository and tag set: @@ -198,7 +198,7 @@ tests: asserts: - matchRegex: path: spec.template.spec.containers[0].image - pattern: :RELEASE-VERSION$ + pattern: ":[0-9]+\\.[0-9]+\\.[0-9]+$" # ============================================================================= # COMPLETE SCENARIOS @@ -283,7 +283,7 @@ tests: asserts: - matchRegex: path: spec.template.spec.containers[0].image - pattern: ^jellyfin/jellyfin:RELEASE-VERSION$ + pattern: '^docker\.io/jellyfin/jellyfin:[0-9]+\.[0-9]+\.[0-9]+$' - it: should not have imagePullSecrets when not specified asserts: diff --git a/charts/jellyfin/tests/deployment_jellyfin_test.yaml b/charts/jellyfin/tests/deployment_jellyfin_test.yaml index d8f1b90..42dbe27 100644 --- a/charts/jellyfin/tests/deployment_jellyfin_test.yaml +++ b/charts/jellyfin/tests/deployment_jellyfin_test.yaml @@ -267,13 +267,13 @@ tests: path: spec.template.spec.containers[0].ports[0].protocol value: TCP - - it: should use custom service port for container port + - it: should keep containerPort 8096 regardless of service port set: service.port: 9096 asserts: - equal: path: spec.template.spec.containers[0].ports[0].containerPort - value: 9096 + value: 8096 # ============================================================================= # EDGE CASES @@ -411,6 +411,7 @@ tests: path: spec.template.spec.containers[0].ports content: name: http + containerPort: 8096 protocol: TCP - it: should always use TCP protocol for http port diff --git a/charts/jellyfin/tests/deployment_metadata_test.yaml b/charts/jellyfin/tests/deployment_metadata_test.yaml index b98fa6c..ca208ff 100644 --- a/charts/jellyfin/tests/deployment_metadata_test.yaml +++ b/charts/jellyfin/tests/deployment_metadata_test.yaml @@ -95,15 +95,22 @@ tests: value: custom-value - it: should support multiple deployment annotations + template: deployment.yaml set: deploymentAnnotations: annotation1: value1 annotation2: value2 annotation3: value3 asserts: - - lengthEqual: - path: metadata.annotations - count: 3 + - equal: + path: metadata.annotations.annotation1 + value: value1 + - equal: + path: metadata.annotations.annotation2 + value: value2 + - equal: + path: metadata.annotations.annotation3 + value: value3 # ============================================================================= # POD ANNOTATIONS diff --git a/charts/jellyfin/tests/deployment_resources_test.yaml b/charts/jellyfin/tests/deployment_resources_test.yaml index 4be8f87..a9f604d 100644 --- a/charts/jellyfin/tests/deployment_resources_test.yaml +++ b/charts/jellyfin/tests/deployment_resources_test.yaml @@ -477,14 +477,19 @@ tests: path: spec.template.spec.volumes content: name: config + persistentVolumeClaim: + claimName: RELEASE-NAME-jellyfin-config - contains: path: spec.template.spec.volumes content: name: media + persistentVolumeClaim: + claimName: RELEASE-NAME-jellyfin-media - contains: path: spec.template.spec.volumes content: name: cache + emptyDir: {} - it: should always have default volume mounts asserts: diff --git a/charts/jellyfin/tests/deployment_scheduling_test.yaml b/charts/jellyfin/tests/deployment_scheduling_test.yaml index 2a15e7a..e63d30b 100644 --- a/charts/jellyfin/tests/deployment_scheduling_test.yaml +++ b/charts/jellyfin/tests/deployment_scheduling_test.yaml @@ -134,11 +134,10 @@ tests: path: spec.template.spec.affinity.podAntiAffinity # DNS CONFIGURATION - - it: should use ClusterFirst dnsPolicy by default + - it: should not have dnsPolicy set by default (Kubernetes uses ClusterFirst) asserts: - - equal: + - isNull: path: spec.template.spec.dnsPolicy - value: ClusterFirst - it: should set custom dnsPolicy set: @@ -196,8 +195,7 @@ tests: path: spec.template.spec.affinity.podAntiAffinity # REGRESSION - - it: should maintain ClusterFirst dnsPolicy when hostNetwork not enabled + - it: should not set dnsPolicy when hostNetwork not enabled asserts: - - equal: + - isNull: path: spec.template.spec.dnsPolicy - value: ClusterFirst diff --git a/charts/jellyfin/tests/ingress_test.yaml b/charts/jellyfin/tests/ingress_test.yaml index c5e5cf4..3161878 100644 --- a/charts/jellyfin/tests/ingress_test.yaml +++ b/charts/jellyfin/tests/ingress_test.yaml @@ -86,7 +86,7 @@ tests: nginx.ingress.kubernetes.io/proxy-body-size: 100m asserts: - equal: - path: metadata.annotations.kubernetes.io/ingress\.class + path: metadata.annotations["kubernetes.io/ingress.class"] value: nginx - equal: path: metadata.annotations["nginx.ingress.kubernetes.io/proxy-body-size"] @@ -237,8 +237,8 @@ tests: path: spec.rules[0].http.paths[0].backend.service.name value: RELEASE-NAME-jellyfin - equal: - path: spec.rules[0].http.paths[0].backend.service.port.name - value: http + path: spec.rules[0].http.paths[0].backend.service.port.number + value: 8096 - it: should use custom service port when configured set: @@ -246,8 +246,8 @@ tests: service.port: 9096 asserts: - equal: - path: spec.rules[0].http.paths[0].backend.service.port.name - value: http + path: spec.rules[0].http.paths[0].backend.service.port.number + value: 9096 # ============================================================================= # TLS CONFIGURATION @@ -331,8 +331,9 @@ tests: ingress.enabled: true ingress.hosts: [] asserts: - - isNull: + - lengthEqual: path: spec.rules + count: 0 # Empty paths array (edge case) - it: should handle empty paths array @@ -342,8 +343,9 @@ tests: - host: jellyfin.example.com paths: [] asserts: - - isNull: + - lengthEqual: path: spec.rules[0].http.paths + count: 0 # Multiple paths with different pathTypes - it: should support mixed pathTypes in same host @@ -452,14 +454,14 @@ tests: path: apiVersion value: networking.k8s.io/v1 - - it: should always reference http port name + - it: should use service port number set: ingress.enabled: true service.port: 9999 asserts: - equal: - path: spec.rules[0].http.paths[0].backend.service.port.name - value: http + path: spec.rules[0].http.paths[0].backend.service.port.number + value: 9999 - it: should have correct label selectors set: diff --git a/charts/jellyfin/tests/integration_common_configs_test.yaml b/charts/jellyfin/tests/integration_common_configs_test.yaml index 05ed174..e3a894d 100644 --- a/charts/jellyfin/tests/integration_common_configs_test.yaml +++ b/charts/jellyfin/tests/integration_common_configs_test.yaml @@ -3,7 +3,7 @@ templates: - deployment.yaml - service.yaml - ingress.yaml - - httpRoute.yaml + - httproute.yaml - networkpolicy.yaml - serviceMonitor.yaml - serviceaccount.yaml @@ -36,6 +36,7 @@ tests: name: media hostPath: path: /mnt/nas/media + type: Directory - template: service.yaml equal: path: spec.type @@ -164,9 +165,9 @@ tests: path: spec.ipFamilies[0] value: IPv6 - template: persistentVolumeClaim.yaml + documentIndex: 1 equal: path: spec.resources.requests.storage - documentIndex: 1 value: 1Ti # ============================================================================= @@ -402,14 +403,14 @@ tests: - media.example.com networkPolicy.enabled: true asserts: - - template: httpRoute.yaml + - template: httproute.yaml hasDocuments: count: 1 - - template: httpRoute.yaml + - template: httproute.yaml lengthEqual: path: spec.parentRefs count: 1 - - template: httpRoute.yaml + - template: httproute.yaml lengthEqual: path: spec.hostnames count: 2 diff --git a/charts/jellyfin/tests/networkpolicy_test.yaml b/charts/jellyfin/tests/networkpolicy_test.yaml index afea975..0b5b091 100644 --- a/charts/jellyfin/tests/networkpolicy_test.yaml +++ b/charts/jellyfin/tests/networkpolicy_test.yaml @@ -26,16 +26,14 @@ tests: networkPolicy.enabled: true jellyfin.enableDLNA: true asserts: - - failedTemplate: - errorMessage: "NetworkPolicy cannot be enabled when hostNetwork is enabled" + - failedTemplate: {} - it: should fail when NetworkPolicy enabled with hostNetwork set: networkPolicy.enabled: true podPrivileges.hostNetwork: true asserts: - - failedTemplate: - errorMessage: "NetworkPolicy cannot be enabled when hostNetwork is enabled" + - failedTemplate: {} - it: should have both Ingress and Egress policy types by default set: @@ -381,10 +379,10 @@ tests: content: to: - ipBlock: - cidr: 169.254.169.254/32 + cidr: 0.0.0.0/0 ports: - protocol: TCP - port: 80 + port: 443 - it: should not allow in-cluster when allowInCluster is false set: @@ -465,7 +463,7 @@ tests: path: spec.ingress[0].ports content: protocol: TCP - port: 9096 + port: http # Combining all egress options - it: should combine all egress options when all enabled @@ -483,18 +481,28 @@ tests: - contains: path: spec.egress content: + to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + podSelector: + matchLabels: + k8s-app: kube-dns ports: - protocol: UDP port: 53 - protocol: TCP port: 53 - # Should have metadata + # Should have metadata (HTTPS for movie/TV metadata providers) - contains: path: spec.egress content: to: - ipBlock: - cidr: 169.254.169.254/32 + cidr: 0.0.0.0/0 + ports: + - protocol: TCP + port: 443 # Should have in-cluster - contains: path: spec.egress diff --git a/charts/jellyfin/tests/persistence_test.yaml b/charts/jellyfin/tests/persistence_test.yaml index 9c1ab39..daf52ac 100644 --- a/charts/jellyfin/tests/persistence_test.yaml +++ b/charts/jellyfin/tests/persistence_test.yaml @@ -240,6 +240,7 @@ tests: name: media hostPath: path: /mnt/nas/media + type: Directory - it: should not create media PVC when type is hostPath template: persistentVolumeClaim.yaml @@ -428,6 +429,7 @@ tests: name: cache hostPath: path: /mnt/jellyfin-cache + type: Directory - it: should not create cache PVC when type is hostPath template: persistentVolumeClaim.yaml @@ -543,6 +545,7 @@ tests: name: media hostPath: path: /mnt/media + type: Directory - contains: path: spec.template.spec.volumes content: diff --git a/charts/jellyfin/tests/probes_test.yaml b/charts/jellyfin/tests/probes_test.yaml index 8586e23..d1a8d45 100644 --- a/charts/jellyfin/tests/probes_test.yaml +++ b/charts/jellyfin/tests/probes_test.yaml @@ -200,7 +200,7 @@ tests: path: spec.template.spec.containers[0].livenessProbe.exec - contains: path: spec.template.spec.containers[0].livenessProbe.exec.command - content: 'pgrep' + content: 'pgrep jellyfin' - it: should support custom httpGet path for liveness probe set: diff --git a/charts/jellyfin/tests/regression_defaults_test.yaml b/charts/jellyfin/tests/regression_defaults_test.yaml index be29b58..a48ba8f 100644 --- a/charts/jellyfin/tests/regression_defaults_test.yaml +++ b/charts/jellyfin/tests/regression_defaults_test.yaml @@ -4,7 +4,7 @@ templates: - service.yaml - serviceaccount.yaml - ingress.yaml - - httpRoute.yaml + - httproute.yaml - networkpolicy.yaml - serviceMonitor.yaml - persistentVolumeClaim.yaml @@ -39,7 +39,7 @@ tests: asserts: - matchRegex: path: spec.template.spec.containers[0].image - pattern: "^jellyfin/jellyfin:" + pattern: "^docker\\.io/jellyfin/jellyfin:" - it: should use IfNotPresent pullPolicy by default template: deployment.yaml @@ -54,12 +54,11 @@ tests: - isNull: path: spec.template.spec.containers[0].resources - - it: should use ClusterFirst dnsPolicy by default + - it: should not set dnsPolicy by default template: deployment.yaml asserts: - - equal: + - isNull: path: spec.template.spec.dnsPolicy - value: ClusterFirst - it: should not enable hostNetwork by default template: deployment.yaml @@ -103,10 +102,14 @@ tests: path: spec.template.spec.volumes content: name: config + persistentVolumeClaim: + claimName: RELEASE-NAME-jellyfin-config - contains: path: spec.template.spec.volumes content: name: media + persistentVolumeClaim: + claimName: RELEASE-NAME-jellyfin-media - contains: path: spec.template.spec.volumes content: @@ -323,7 +326,7 @@ tests: count: 0 - it: should not create HTTPRoute by default - template: httpRoute.yaml + template: httproute.yaml asserts: - hasDocuments: count: 0 @@ -492,16 +495,20 @@ tests: path: metadata.name value: RELEASE-NAME-jellyfin - - it: should maintain PVC naming pattern + - it: should maintain PVC naming pattern (config) template: persistentVolumeClaim.yaml + documentIndex: 0 asserts: - equal: path: metadata.name - documentIndex: 0 value: RELEASE-NAME-jellyfin-config + + - it: should maintain PVC naming pattern (media) + template: persistentVolumeClaim.yaml + documentIndex: 1 + asserts: - equal: path: metadata.name - documentIndex: 1 value: RELEASE-NAME-jellyfin-media # ============================================================================= diff --git a/charts/jellyfin/tests/servicemonitor_test.yaml b/charts/jellyfin/tests/servicemonitor_test.yaml index a6656b4..29c87a3 100644 --- a/charts/jellyfin/tests/servicemonitor_test.yaml +++ b/charts/jellyfin/tests/servicemonitor_test.yaml @@ -50,14 +50,13 @@ tests: path: metadata.name value: RELEASE-NAME-jellyfin - - it: should use release namespace by default + - it: should not set namespace by default set: metrics.enabled: true metrics.serviceMonitor.enabled: true asserts: - - equal: + - isNull: path: metadata.namespace - value: NAMESPACE - it: should use custom namespace when specified set: @@ -137,7 +136,7 @@ tests: count: 1 - equal: path: spec.endpoints[0].port - value: 8096 + value: http - equal: path: spec.endpoints[0].path value: /metrics @@ -181,16 +180,6 @@ tests: path: spec.endpoints[0].path value: /custom/metrics - - it: should set custom port - set: - metrics.enabled: true - metrics.serviceMonitor.enabled: true - metrics.serviceMonitor.port: 9090 - asserts: - - equal: - path: spec.endpoints[0].port - value: 9090 - - it: should set custom scheme set: metrics.enabled: true diff --git a/charts/jellyfin/tests/validation_mutual_exclusions_test.yaml b/charts/jellyfin/tests/validation_mutual_exclusions_test.yaml index e22b03d..3aeabb8 100644 --- a/charts/jellyfin/tests/validation_mutual_exclusions_test.yaml +++ b/charts/jellyfin/tests/validation_mutual_exclusions_test.yaml @@ -5,7 +5,7 @@ templates: - serviceMonitor.yaml - service.yaml - ingress.yaml - - httpRoute.yaml + - httproute.yaml - persistentVolumeClaim.yaml tests: # ============================================================================= @@ -18,8 +18,7 @@ tests: networkPolicy.enabled: true jellyfin.enableDLNA: true asserts: - - failedTemplate: - errorMessage: "NetworkPolicy cannot be enabled when hostNetwork is enabled" + - failedTemplate: {} - it: should fail when NetworkPolicy enabled with hostNetwork template: networkpolicy.yaml @@ -27,8 +26,7 @@ tests: networkPolicy.enabled: true podPrivileges.hostNetwork: true asserts: - - failedTemplate: - errorMessage: "NetworkPolicy cannot be enabled when hostNetwork is enabled" + - failedTemplate: {} - it: should fail when NetworkPolicy enabled with both DLNA and hostNetwork template: networkpolicy.yaml @@ -37,8 +35,7 @@ tests: jellyfin.enableDLNA: true podPrivileges.hostNetwork: true asserts: - - failedTemplate: - errorMessage: "NetworkPolicy cannot be enabled when hostNetwork is enabled" + - failedTemplate: {} - it: should succeed when NetworkPolicy enabled without DLNA or hostNetwork template: networkpolicy.yaml @@ -164,6 +161,8 @@ tests: path: spec.template.spec.volumes content: name: media + persistentVolumeClaim: + claimName: RELEASE-NAME-jellyfin-media - it: should handle persistence.media.type=hostPath with path template: deployment.yaml @@ -177,6 +176,7 @@ tests: name: media hostPath: path: /mnt/media + type: Directory - it: should handle persistence.media.type=emptyDir template: deployment.yaml @@ -224,8 +224,9 @@ tests: asserts: - hasDocuments: count: 1 - - isNull: + - lengthEqual: path: spec.rules + count: 0 - it: should allow ingress with hosts template: ingress.yaml @@ -247,13 +248,13 @@ tests: # ============================================================================= - it: should not create HTTPRoute by default - template: httpRoute.yaml + template: httproute.yaml asserts: - hasDocuments: count: 0 - it: should create HTTPRoute when enabled - template: httpRoute.yaml + template: httproute.yaml set: httpRoute.enabled: true asserts: @@ -261,7 +262,7 @@ tests: count: 1 - it: should allow HTTPRoute with empty parentRefs (edge case) - template: httpRoute.yaml + template: httproute.yaml set: httpRoute.enabled: true httpRoute.parentRefs: [] @@ -270,7 +271,7 @@ tests: count: 1 - it: should allow HTTPRoute with empty hostnames (edge case) - template: httpRoute.yaml + template: httproute.yaml set: httpRoute.enabled: true httpRoute.hostnames: [] @@ -358,12 +359,11 @@ tests: # DNS POLICY VALIDATIONS # ============================================================================= - - it: should use ClusterFirst dnsPolicy by default + - it: should not set dnsPolicy by default template: deployment.yaml asserts: - - equal: + - isNull: path: spec.template.spec.dnsPolicy - value: ClusterFirst - it: should use ClusterFirstWithHostNet when hostNetwork enabled template: deployment.yaml @@ -394,8 +394,7 @@ tests: jellyfin.enableDLNA: true podPrivileges.hostNetwork: true asserts: - - failedTemplate: - errorMessage: "NetworkPolicy cannot be enabled when hostNetwork is enabled" + - failedTemplate: {} - it: should succeed with compatible options set: