diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dd76df5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.debug diff --git a/charts/helm_lib/Chart.yaml b/charts/helm_lib/Chart.yaml index 9d1e306..ac355c4 100644 --- a/charts/helm_lib/Chart.yaml +++ b/charts/helm_lib/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 type: library name: deckhouse_lib_helm -version: 1.64.0 +version: 1.64.11 description: "Helm utils template definitions for Deckhouse modules." diff --git a/charts/helm_lib/README.md b/charts/helm_lib/README.md index e5120af..60d3b68 100644 --- a/charts/helm_lib/README.md +++ b/charts/helm_lib/README.md @@ -9,6 +9,8 @@ | **Api Version And Kind** | | [helm_lib_kind_exists](#helm_lib_kind_exists) | | [helm_lib_get_api_version_by_kind](#helm_lib_get_api_version_by_kind) | +| **Csi Controller** | +| [helm_lib_csi_image_with_common_fallback](#helm_lib_csi_image_with_common_fallback) | | **Enable Ds Eviction** | | [helm_lib_prevent_ds_eviction_annotation](#helm_lib_prevent_ds_eviction_annotation) | | **Envs For Proxy** | @@ -163,6 +165,23 @@ list: - Template context with .Values, .Chart, etc - Kind name portion +## Csi Controller + +### helm_lib_csi_image_with_common_fallback + + returns image name from storage foundation module if enabled, otherwise from common module + +#### Usage + +`{{ include "helm_lib_csi_image_with_common_fallback" (list . "" "") }} ` + +#### Arguments + +list: +- Template context with .Values, .Chart, etc +- Container raw name +- Kubernetes semantic version + ## Enable Ds Eviction ### helm_lib_prevent_ds_eviction_annotation @@ -650,16 +669,17 @@ list: ### helm_lib_module_container_security_context_pss_restricted_flexible - SecurityContext for Deckhouse UID/GID 64535, PSS Restricted + SecurityContext for Deckhouse UID/GID 64535 (or root), PSS Restricted Optional keys: .ro – bool, read-only root FS (default true) .caps – []string, capabilities.add (default empty) .uid – int, runAsUser/runAsGroup (default 64535) + .runAsNonRoot – bool, run as Deckhouse user when true, root when false (default true) .seccompProfile – bool, disable seccompProfile when false (default true) #### Usage -`include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" false "caps" (list "NET_ADMIN" "SYS_TIME") "uid" 1001 "seccompProfile" false) ` +`include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" false "caps" (list "NET_ADMIN" "SYS_TIME") "uid" 1001 "seccompProfile" false "runAsNonRoot" true) ` diff --git a/charts/helm_lib/templates/_csi_controller.tpl b/charts/helm_lib/templates/_csi_controller.tpl index 646c319..da0de1b 100644 --- a/charts/helm_lib/templates/_csi_controller.tpl +++ b/charts/helm_lib/templates/_csi_controller.tpl @@ -1,3 +1,43 @@ +{{- /* Usage: {{ include "helm_lib_csi_image_with_common_fallback" (list . "" "") }} */ -}} +{{- /* returns image name from storage foundation module if enabled, otherwise from common module */ -}} +{{- define "helm_lib_csi_image_with_common_fallback" }} + {{- $context := index . 0 }} {{- /* Template context with .Values, .Chart, etc */ -}} + {{- $rawContainerName := index . 1 | trimAll "\"" }} {{- /* Container raw name */ -}} + {{- $kubernetesSemVer := index . 2 }} {{- /* Kubernetes semantic version */ -}} + {{- $imageDigest := "" }} + {{- $registryBase := $context.Values.global.modulesImages.registry.base }} + {{- /* Try to get from storage foundation module if enabled */}} + {{- if $context.Values.global.enabledModules | has "storage-foundation" }} + {{- $registryBase = join "/" (list $registryBase "modules" "storage-foundation" ) }} + {{- $storageFoundationDigests := index $context.Values.global.modulesImages.digests "storageFoundation" | default dict }} + {{- $currentMinor := int $kubernetesSemVer.Minor }} + {{- $kubernetesMajor := int $kubernetesSemVer.Major }} + {{- /* Iterate from currentMinor down to 0: use offset from 0 to currentMinor, then calculate minorVersion = currentMinor - offset */}} + {{- range $offset := until (int (add $currentMinor 1)) }} + {{- if not $imageDigest }} + {{- $minorVersion := int (sub $currentMinor $offset) }} + {{- $containerName := join "" (list $rawContainerName "ForK8SGE" $kubernetesMajor $minorVersion) }} + {{- $digest := index $storageFoundationDigests $containerName | default "" }} + {{- if $digest }} + {{- $imageDigest = $digest }} + {{- end }} + {{- end }} + {{- end }} + {{- /* Fallback to base container name if no versioned image found (when minor reached 0) */}} + {{- if not $imageDigest }} + {{- $imageDigest = index $storageFoundationDigests $rawContainerName | default "" }} + {{- end }} + {{- /* Fallback to common module if storage foundation module is not enabled */}} + {{- else }} + {{- $containerName := join "" (list $rawContainerName $kubernetesSemVer.Major $kubernetesSemVer.Minor) }} + {{- $imageDigest = index $context.Values.global.modulesImages.digests "common" $containerName | default "" }} + {{- end }} + {{- if $imageDigest }} + {{- printf "%s@%s" $registryBase $imageDigest }} + {{- end }} +{{- end }} + + {{- define "attacher_resources" }} cpu: 10m memory: 25Mi @@ -74,26 +114,22 @@ memory: 50Mi {{- $customNodeSelector := $config.customNodeSelector }} {{- $additionalPullSecrets := $config.additionalPullSecrets }} {{- $forceCsiControllerPrivilegedContainer := $config.forceCsiControllerPrivilegedContainer | default false }} + {{- $dnsPolicy := $config.dnsPolicy | default "ClusterFirstWithHostNet" }} {{- $kubernetesSemVer := semver $context.Values.global.discovery.kubernetesVersion }} - {{- $provisionerImageName := join "" (list "csiExternalProvisioner" $kubernetesSemVer.Major $kubernetesSemVer.Minor) }} - {{- $provisionerImage := include "helm_lib_module_common_image_no_fail" (list $context $provisionerImageName) }} + {{- $provisionerImage := include "helm_lib_csi_image_with_common_fallback" (list $context "csiExternalProvisioner" $kubernetesSemVer) }} - {{- $attacherImageName := join "" (list "csiExternalAttacher" $kubernetesSemVer.Major $kubernetesSemVer.Minor) }} - {{- $attacherImage := include "helm_lib_module_common_image_no_fail" (list $context $attacherImageName) }} + {{- $attacherImage := include "helm_lib_csi_image_with_common_fallback" (list $context "csiExternalAttacher" $kubernetesSemVer) }} - {{- $resizerImageName := join "" (list "csiExternalResizer" $kubernetesSemVer.Major $kubernetesSemVer.Minor) }} - {{- $resizerImage := include "helm_lib_module_common_image_no_fail" (list $context $resizerImageName) }} + {{- $resizerImage := include "helm_lib_csi_image_with_common_fallback" (list $context "csiExternalResizer" $kubernetesSemVer) }} {{- $syncerImageName := join "" (list "csiVsphereSyncer" $kubernetesSemVer.Major $kubernetesSemVer.Minor) }} {{- $syncerImage := include "helm_lib_module_common_image_no_fail" (list $context $syncerImageName) }} - {{- $snapshotterImageName := join "" (list "csiExternalSnapshotter" $kubernetesSemVer.Major $kubernetesSemVer.Minor) }} - {{- $snapshotterImage := include "helm_lib_module_common_image_no_fail" (list $context $snapshotterImageName) }} + {{- $snapshotterImage := include "helm_lib_csi_image_with_common_fallback" (list $context "csiExternalSnapshotter" $kubernetesSemVer) }} - {{- $livenessprobeImageName := join "" (list "csiLivenessprobe" $kubernetesSemVer.Major $kubernetesSemVer.Minor) }} - {{- $livenessprobeImage := include "helm_lib_module_common_image_no_fail" (list $context $livenessprobeImageName) }} + {{- $livenessprobeImage := include "helm_lib_csi_image_with_common_fallback" (list $context "csiLivenessprobe" $kubernetesSemVer) }} {{- if $provisionerImage }} {{- if ($context.Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} @@ -187,7 +223,7 @@ metadata: spec: {{- if $csiControllerHaMode }} - {{- include "helm_lib_deployment_strategy_and_replicas_for_ha" $context | nindent 2 }} + {{- include "helm_lib_deployment_on_master_strategy_and_replicas_for_ha" $context | nindent 2 }} {{- else }} replicas: 1 strategy: @@ -217,7 +253,7 @@ spec: hostNetwork: {{ $csiControllerHostNetwork }} hostPID: {{ $csiControllerHostPID }} {{- if eq $csiControllerHostNetwork "true" }} - dnsPolicy: ClusterFirstWithHostNet + dnsPolicy: {{ $dnsPolicy | quote }} {{- end }} imagePullSecrets: - name: deckhouse-registry @@ -241,7 +277,7 @@ spec: automountServiceAccountToken: true containers: - name: provisioner - {{- include "helm_lib_module_container_security_context_read_only_root_filesystem" . | nindent 8 }} + {{- include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" true "seccompProfile" true) | nindent 8 }} image: {{ $provisionerImage | quote }} args: - "--timeout={{ $provisionerTimeout }}" @@ -294,7 +330,7 @@ spec: {{- include "provisioner_resources" $context | nindent 12 }} {{- end }} - name: attacher - {{- include "helm_lib_module_container_security_context_read_only_root_filesystem" . | nindent 8 }} + {{- include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" true "seccompProfile" true) | nindent 8 }} image: {{ $attacherImage | quote }} args: - "--timeout={{ $attacherTimeout }}" @@ -325,7 +361,7 @@ spec: {{- end }} {{- if $resizerEnabled }} - name: resizer - {{- include "helm_lib_module_container_security_context_read_only_root_filesystem" . | nindent 8 }} + {{- include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" true "seccompProfile" true) | nindent 8 }} image: {{ $resizerImage | quote }} args: - "--timeout={{ $resizerTimeout }}" @@ -357,7 +393,7 @@ spec: {{- end }} {{- if $syncerEnabled }} - name: syncer - {{- include "helm_lib_module_container_security_context_read_only_root_filesystem" . | nindent 8 }} + {{- include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" true "seccompProfile" true) | nindent 8 }} image: {{ $syncerImage | quote }} args: - "--leader-election" @@ -384,7 +420,7 @@ spec: {{- end }} {{- if $snapshotterEnabled }} - name: snapshotter - {{- include "helm_lib_module_container_security_context_read_only_root_filesystem" . | nindent 8 }} + {{- include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" true "seccompProfile" true) | nindent 8 }} image: {{ $snapshotterImage | quote }} args: - "--timeout={{ $snapshotterTimeout }}" @@ -418,7 +454,7 @@ spec: {{- end }} {{- end }} - name: livenessprobe - {{- include "helm_lib_module_container_security_context_read_only_root_filesystem" . | nindent 8 }} + {{- include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" true "seccompProfile" true) | nindent 8 }} image: {{ $livenessprobeImage | quote }} args: - "--csi-address=$(ADDRESS)" @@ -454,7 +490,7 @@ spec: {{- if $forceCsiControllerPrivilegedContainer }} {{- include "helm_lib_module_container_security_context_escalated_sys_admin_privileged" . | nindent 8 }} {{- else }} - {{- include "helm_lib_module_container_security_context_read_only_root_filesystem" . | nindent 8 }} + {{- include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" true "seccompProfile" true) | nindent 8 }} {{- end }} image: {{ $controllerImage | quote }} args: diff --git a/charts/helm_lib/templates/_csi_node.tpl b/charts/helm_lib/templates/_csi_node.tpl index 115a2ab..fb3d9b7 100644 --- a/charts/helm_lib/templates/_csi_node.tpl +++ b/charts/helm_lib/templates/_csi_node.tpl @@ -28,7 +28,7 @@ memory: 25Mi {{- $customNodeSelector := $config.customNodeSelector }} {{- $forceCsiNodeAndStaticNodesDepoloy := $config.forceCsiNodeAndStaticNodesDepoloy | default false }} {{- $setSysAdminCapability := $config.setSysAdminCapability | default false }} - {{- $additionalContainers := $config.additionalContainers }} + {{- $additionalContainers := $config.additionalContainers }} {{- $initContainers := $config.initContainers }} {{- $additionalPullSecrets := $config.additionalPullSecrets }} {{- $csiNodeLifecycle := $config.csiNodeLifecycle | default false }} @@ -36,9 +36,9 @@ memory: 25Mi {{- $additionalCsiNodePodAnnotations := $config.additionalCsiNodePodAnnotations | default false }} {{- $csiNodeHostNetwork := $config.csiNodeHostNetwork | default "true" }} {{- $csiNodeHostPID := $config.csiNodeHostPID | default "false" }} + {{- $dnsPolicy := $config.dnsPolicy | default "ClusterFirstWithHostNet" }} {{- $kubernetesSemVer := semver $context.Values.global.discovery.kubernetesVersion }} - {{- $driverRegistrarImageName := join "" (list "csiNodeDriverRegistrar" $kubernetesSemVer.Major $kubernetesSemVer.Minor) }} - {{- $driverRegistrarImage := include "helm_lib_module_common_image_no_fail" (list $context $driverRegistrarImageName) }} + {{- $driverRegistrarImage := include "helm_lib_csi_image_with_common_fallback" (list $context "csiNodeDriverRegistrar" $kubernetesSemVer) }} {{- if $driverRegistrarImage }} {{- if or $forceCsiNodeAndStaticNodesDepoloy (include "_helm_lib_cloud_or_hybrid_cluster" $context) }} {{- if ($context.Values.global.enabledModules | has "vertical-pod-autoscaler-crd") }} @@ -134,11 +134,11 @@ spec: hostNetwork: {{ $csiNodeHostNetwork }} hostPID: {{ $csiNodeHostPID }} {{- if eq $csiNodeHostNetwork "true" }} - dnsPolicy: ClusterFirstWithHostNet + dnsPolicy: {{ $dnsPolicy | quote }} {{- end }} containers: - name: node-driver-registrar - {{- include "helm_lib_module_container_security_context_read_only_root_filesystem" $context | nindent 8 }} + {{- include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" true "seccompProfile" true "uid" "0" "runAsNonRoot" false) | nindent 8 }} image: {{ $driverRegistrarImage | quote }} args: - "--v=5" @@ -182,6 +182,8 @@ spec: securityContext: privileged: true readOnlyRootFilesystem: true + seccompProfile: + type: RuntimeDefault {{- if $setSysAdminCapability }} capabilities: add: @@ -207,7 +209,7 @@ spec: port: {{ $livenessProbePort }} initialDelaySeconds: 5 timeoutSeconds: 5 - {{- end }} + {{- end }} volumeMounts: - name: kubelet-dir mountPath: /var/lib/kubelet diff --git a/charts/helm_lib/templates/_envs_for_proxy.tpl b/charts/helm_lib/templates/_envs_for_proxy.tpl index 60423cd..f052cff 100644 --- a/charts/helm_lib/templates/_envs_for_proxy.tpl +++ b/charts/helm_lib/templates/_envs_for_proxy.tpl @@ -17,7 +17,7 @@ - name: https_proxy value: {{ $context.Values.global.clusterConfiguration.proxy.httpsProxy | quote }} {{- end }} - {{- $noProxy := list "127.0.0.1" "169.254.169.254" $context.Values.global.clusterConfiguration.clusterDomain $context.Values.global.clusterConfiguration.podSubnetCIDR $context.Values.global.clusterConfiguration.serviceSubnetCIDR }} + {{- $noProxy := list "127.0.0.1" "169.254.169.254" "registry.d8-system.svc" $context.Values.global.clusterConfiguration.clusterDomain $context.Values.global.clusterConfiguration.podSubnetCIDR $context.Values.global.clusterConfiguration.serviceSubnetCIDR }} {{- if $context.Values.global.clusterConfiguration.proxy.noProxy }} {{- $noProxy = concat $noProxy $context.Values.global.clusterConfiguration.proxy.noProxy }} {{- end }} diff --git a/charts/helm_lib/templates/_module_image.tpl b/charts/helm_lib/templates/_module_image.tpl index 642824f..da797f5 100644 --- a/charts/helm_lib/templates/_module_image.tpl +++ b/charts/helm_lib/templates/_module_image.tpl @@ -19,7 +19,7 @@ {{- if index $context.Values $moduleName "registry" }} {{- if index $context.Values $moduleName "registry" "base" }} {{- $host := trimAll "/" (index $context.Values $moduleName "registry" "base") }} - {{- $path := trimAll "/" $moduleName }} + {{- $path := trimAll "/" (include "helm_lib_module_kebabcase_name" $rawModuleName) }} {{- $registryBase = join "/" (list $host $path) }} {{- end }} {{- end }} @@ -33,11 +33,10 @@ {{- define "helm_lib_module_image_no_fail" }} {{- $context := index . 0 }} {{- /* Template context with .Values, .Chart, etc */ -}} {{- $containerName := index . 1 | trimAll "\"" }} {{- /* Container name */ -}} - {{- $rawModuleName := $context.Chart.Name }} + {{- $moduleName := (include "helm_lib_module_camelcase_name" $context) }} {{- if ge (len .) 3 }} - {{- $rawModuleName = (index . 2) }} {{- /* Optional module name */ -}} + {{- $moduleName = (include "helm_lib_module_camelcase_name" (index . 2)) }} {{- /* Optional module name */ -}} {{- end }} - {{- $moduleName := (include "helm_lib_module_camelcase_name" $rawModuleName) }} {{- $imageDigest := index $context.Values.global.modulesImages.digests $moduleName $containerName }} {{- if $imageDigest }} {{- $registryBase := $context.Values.global.modulesImages.registry.base }} @@ -45,7 +44,7 @@ {{- if index $context.Values $moduleName "registry" }} {{- if index $context.Values $moduleName "registry" "base" }} {{- $host := trimAll "/" (index $context.Values $moduleName "registry" "base") }} - {{- $path := trimAll "/" $moduleName }} + {{- $path := trimAll "/" $context.Chart.Name }} {{- $registryBase = join "/" (list $host $path) }} {{- end }} {{- end }} @@ -102,12 +101,11 @@ {{- define "helm_lib_module_image_digest_no_fail" }} {{- $context := index . 0 }} {{- /* Template context with .Values, .Chart, etc */ -}} {{- $containerName := index . 1 | trimAll "\"" }} {{- /* Container name */ -}} - {{- $rawModuleName := $context.Chart.Name }} + {{- $moduleName := (include "helm_lib_module_camelcase_name" $context) }} {{- if ge (len .) 3 }} - {{- $rawModuleName = (index . 2) }} {{- /* Optional module name */ -}} + {{- $moduleName = (include "helm_lib_module_camelcase_name" (index . 2)) }} {{- /* Optional module name */ -}} {{- end }} - {{- $moduleName := (include "helm_lib_module_camelcase_name" $rawModuleName) }} {{- $moduleMap := index $context.Values.global.modulesImages.digests $moduleName | default dict }} {{- $imageDigest := index $moduleMap $containerName | default "" }} {{- printf "%s" $imageDigest }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/charts/helm_lib/templates/_module_security_context.tpl b/charts/helm_lib/templates/_module_security_context.tpl index bee7d89..1f51081 100644 --- a/charts/helm_lib/templates/_module_security_context.tpl +++ b/charts/helm_lib/templates/_module_security_context.tpl @@ -69,13 +69,14 @@ securityContext: {{- end }} -{{- /* SecurityContext for Deckhouse UID/GID 64535, PSS Restricted */ -}} +{{- /* SecurityContext for Deckhouse UID/GID 64535 (or root), PSS Restricted */ -}} {{- /* Optional keys: */ -}} {{- /* .ro – bool, read-only root FS (default true) */ -}} {{- /* .caps – []string, capabilities.add (default empty) */ -}} {{- /* .uid – int, runAsUser/runAsGroup (default 64535) */ -}} +{{- /* .runAsNonRoot – bool, run as Deckhouse user when true, root when false (default true) */ -}} {{- /* .seccompProfile – bool, disable seccompProfile when false (default true) */ -}} -{{- /* Usage: include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" false "caps" (list "NET_ADMIN" "SYS_TIME") "uid" 1001 "seccompProfile" false) */ -}} +{{- /* Usage: include "helm_lib_module_container_security_context_pss_restricted_flexible" (dict "ro" false "caps" (list "NET_ADMIN" "SYS_TIME") "uid" 1001 "seccompProfile" false "runAsNonRoot" true) */ -}} {{- define "helm_lib_module_container_security_context_pss_restricted_flexible" -}} {{- $ro := true -}} {{- if hasKey . "ro" -}} @@ -87,19 +88,26 @@ securityContext: {{- end -}} {{- $caps := default (list) .caps -}} {{- $uid := default 64535 .uid -}} +{{- $runAsNonRoot := true -}} +{{- if hasKey . "runAsNonRoot" -}} + {{- $runAsNonRoot = .runAsNonRoot -}} +{{- end -}} securityContext: readOnlyRootFilesystem: {{ $ro }} - allowPrivilegeEscalation: false + allowPrivilegeEscalation: {{ not $runAsNonRoot }} +{{- if $runAsNonRoot }} + privileged: false +{{- end }} capabilities: drop: - ALL {{- if $caps }} add: {{ $caps | toJson }} {{- end }} - runAsUser: {{ $uid }} - runAsGroup: {{ $uid }} - runAsNonRoot: true + runAsUser: {{ ternary $uid 0 $runAsNonRoot }} + runAsGroup: {{ ternary $uid 0 $runAsNonRoot }} + runAsNonRoot: {{ $runAsNonRoot }} {{- if $seccompProfile }} seccompProfile: type: RuntimeDefault diff --git a/charts/helm_lib/templates/_monitoring_prometheus_rules.tpl b/charts/helm_lib/templates/_monitoring_prometheus_rules.tpl index 794fe30..20cabef 100644 --- a/charts/helm_lib/templates/_monitoring_prometheus_rules.tpl +++ b/charts/helm_lib/templates/_monitoring_prometheus_rules.tpl @@ -42,12 +42,32 @@ {{- end }} - {{ $definition = $definitionStruct.Rules | toYaml }} - {{- $resourceName := (regexReplaceAllLiteral "\\.(yaml|tpl)$" $path "") }} {{- $resourceName = ($resourceName | replace " " "-" | replace "." "-" | replace "_" "-") }} {{- $resourceName = (slice ($resourceName | splitList "/") $folderNamesIndex | join "-") }} {{- $resourceName = (printf "%s-%s" $context.Chart.Name $resourceName) }} + {{- $propagated := contains "propagated-" $resourceName }} + {{- $hasObservabilityModule := has "observability" $context.Values.global.enabledModules }} + {{- $useObservabilityRules := has "observability.deckhouse.io/v1alpha1/ClusterObservabilityMetricsRulesGroup" $context.Values.global.discovery.apiVersions }} + {{- if and $hasObservabilityModule $useObservabilityRules }} + {{- range $idx, $group := $definitionStruct.Rules }} + {{- if $group.rules }} + {{- $_ := unset $group "name" }} + {{- $resourceName = $resourceName | replace "propagated-" "" }} + {{- $groupResourceName := printf "%s-%d" $resourceName $idx }} +--- +apiVersion: observability.deckhouse.io/v1alpha1 +kind: {{ $propagated | ternary "ClusterObservabilityPropagatedMetricsRulesGroup" "ClusterObservabilityMetricsRulesGroup" }} +metadata: + name: {{ $groupResourceName }} + {{- include "helm_lib_module_labels" (list $context (dict "app" "prometheus" "prometheus" "main" "component" "rules")) | nindent 2 }} +spec: + {{- $group | toYaml | nindent 2 }} + {{- end }} + {{- end }} + {{- else }} + {{- if $definitionStruct.Rules }} + {{- $definition := $definitionStruct.Rules | toYaml }} --- apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule @@ -58,6 +78,8 @@ metadata: spec: groups: {{- $definition | nindent 4 }} + {{- end }} + {{- end }} {{- end }} {{- $subDirs := list }} diff --git a/tests/templates/helm_lib_csi_controller_value.yaml b/tests/templates/helm_lib_csi_controller_value.yaml new file mode 100644 index 0000000..7afa49e --- /dev/null +++ b/tests/templates/helm_lib_csi_controller_value.yaml @@ -0,0 +1 @@ +{{ include "helm_lib_csi_controller_manifests" (list . .Values._testvalues) }} diff --git a/tests/templates/helm_lib_csi_image_with_common_fallback.yaml b/tests/templates/helm_lib_csi_image_with_common_fallback.yaml new file mode 100644 index 0000000..dc031e6 --- /dev/null +++ b/tests/templates/helm_lib_csi_image_with_common_fallback.yaml @@ -0,0 +1,21 @@ +storageFoundationEnabledWithVersion: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalProvisioner" (semver "1.25.0")) }} +--- +storageFoundationEnabledWithoutVersion: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalAttacher" (semver "1.25.0")) }} +--- +storageFoundationEnabledNotFound: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalResizer" (semver "1.25.0")) }} +--- +storageFoundationDisabledUseCommon: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalSnapshotter" (semver "1.25.0")) }} +--- +storageFoundationVersionFallback: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiLivenessprobe" (semver "1.34.0")) }} +--- +storageFoundationK8s126: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalProvisioner" (semver "1.26.0")) }} +--- +commonFallbackDifferentVersion: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalSnapshotter" (semver "1.24.0")) }} +--- +storageFoundationVersionIteration: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalProvisioner" (semver "1.34.0")) }} +--- +commonNotFound: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalProvisioner" (semver "1.25.0")) }} +--- +otherModulesEnabled: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalProvisioner" (semver "1.25.0")) }} +--- +emptyStorageFoundationDigests: {{ include "helm_lib_csi_image_with_common_fallback" (list . "csiExternalProvisioner" (semver "1.25.0")) }} diff --git a/tests/templates/helm_lib_prometheus_rules_recursion.yaml b/tests/templates/helm_lib_prometheus_rules_recursion.yaml new file mode 100644 index 0000000..f94593b --- /dev/null +++ b/tests/templates/helm_lib_prometheus_rules_recursion.yaml @@ -0,0 +1 @@ +{{- include "helm_lib_prometheus_rules_recursion" (list . "d8-observability" "testdata/monitoring") }} \ No newline at end of file diff --git a/tests/testdata/monitoring/deadbeef/propagated-ingress-nginx.yaml b/tests/testdata/monitoring/deadbeef/propagated-ingress-nginx.yaml new file mode 100644 index 0000000..19462d0 --- /dev/null +++ b/tests/testdata/monitoring/deadbeef/propagated-ingress-nginx.yaml @@ -0,0 +1,13 @@ +- name: kubernetes.ingress-nginx.group-one + rules: + - alert: NginxIngressSslWillExpire + expr: vector(1) + - alert: NginxIngressSslExpired + expr: vector(1) +- name: kubernetes.ingress-nginx.group-two + rules: + - alert: NginxIngress5xxErrors + expr: vector(1) + - alert: NginxIngress5xxErrors + expr: vector(1) + diff --git a/tests/tests/helm_lib_csi_controller_test.yaml b/tests/tests/helm_lib_csi_controller_test.yaml new file mode 100644 index 0000000..0a252ed --- /dev/null +++ b/tests/tests/helm_lib_csi_controller_test.yaml @@ -0,0 +1,155 @@ +suite: helm_lib_csi_controller_value definition +templates: + - helm_lib_csi_controller_value.yaml +tests: + - it: renders csi controller manifests + + set: + global: + modules: + placement: {} + modulesImages: + registry: + base: "deckhouse.io/deckhouse/ce" + digests: + common: + csiExternalAttacher125: csiControllerAttacher125 + csiExternalProvisioner125: csiControllerProvisioner125 + csiExternalResizer125: csiControllerResizer125 + csiExternalSnapshotter125: csiControllerSnapshotter125 + csiVsphereSyncer125: csiControllerSyncer125 + csiLivenessprobe125: csiLivenessProbe125 + discovery: + kubernetesVersion: "1.25" + d8SpecificNodeCountByRole: {} + _testvalues: + controllerImage: controllerImage + syncerEnabled: "true" + + documentSelector: + path: kind + value: Deployment + + asserts: + - hasDocuments: + count: 2 + + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + name: csi-controller + namespace: d8-test-module + + - equal: + path: spec.template.spec.dnsPolicy + value: "ClusterFirstWithHostNet" + + - equal: + path: spec.template.spec.containers[0].image + value: "deckhouse.io/deckhouse/ce@csiControllerProvisioner125" + + - equal: + path: spec.template.spec.containers[1].image + value: "deckhouse.io/deckhouse/ce@csiControllerAttacher125" + + - equal: + path: spec.template.spec.containers[2].image + value: "deckhouse.io/deckhouse/ce@csiControllerResizer125" + + - equal: + path: spec.template.spec.containers[3].image + value: "deckhouse.io/deckhouse/ce@csiControllerSyncer125" + + - equal: + path: spec.template.spec.containers[4].image + value: "deckhouse.io/deckhouse/ce@csiControllerSnapshotter125" + + - equal: + path: spec.template.spec.containers[5].image + value: "deckhouse.io/deckhouse/ce@csiLivenessProbe125" + + - equal: + path: spec.template.spec.containers[6].image + value: "controllerImage" + + - it: renders csi controller manifests with dnsPolicy defined + + set: + global: + modules: + placement: {} + modulesImages: + registry: + base: "deckhouse.io/deckhouse/ce" + digests: + common: + csiExternalAttacher125: csiControllerAttacher125 + csiExternalProvisioner125: csiControllerProvisioner125 + csiExternalResizer125: csiControllerResizer125 + csiExternalSnapshotter125: csiControllerSnapshotter125 + csiLivenessprobe125: csiLivenessProbe125 + discovery: + kubernetesVersion: "1.25" + d8SpecificNodeCountByRole: {} + _testvalues: + controllerImage: controllerImage + dnsPolicy: Default + + documentSelector: + path: kind + value: Deployment + + asserts: + - hasDocuments: + count: 2 + + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + name: csi-controller + namespace: d8-test-module + + - equal: + path: spec.template.spec.dnsPolicy + value: "Default" + + - it: renders csi controller manifests with no dnsPolicy when hostNetwork is false + + set: + global: + modules: + placement: {} + modulesImages: + registry: + base: "deckhouse.io/deckhouse/ce" + digests: + common: + csiExternalAttacher125: csiControllerAttacher125 + csiExternalProvisioner125: csiControllerProvisioner125 + csiExternalResizer125: csiControllerResizer125 + csiExternalSnapshotter125: csiControllerSnapshotter125 + csiLivenessprobe125: csiLivenessProbe125 + discovery: + kubernetesVersion: "1.25" + d8SpecificNodeCountByRole: {} + _testvalues: + controllerImage: controllerImage + csiControllerHostNetwork: "false" + dnsPolicy: Default + + documentSelector: + path: kind + value: Deployment + + asserts: + - hasDocuments: + count: 2 + + - containsDocument: + kind: Deployment + apiVersion: apps/v1 + name: csi-controller + namespace: d8-test-module + + - notExists: + path: spec.template.spec.dnsPolicy diff --git a/tests/tests/helm_lib_csi_image_with_common_fallback_test.yaml b/tests/tests/helm_lib_csi_image_with_common_fallback_test.yaml new file mode 100644 index 0000000..c597f35 --- /dev/null +++ b/tests/tests/helm_lib_csi_image_with_common_fallback_test.yaml @@ -0,0 +1,210 @@ +suite: helm_lib_csi_image_with_common_fallback definition +templates: + - helm_lib_csi_image_with_common_fallback.yaml +tests: + - it: should return image from storage-foundation when enabled and image found with version + documentIndex: 0 + set: + global: + enabledModules: + - storage-foundation + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiExternalProvisionerForK8SGE125: "sha256:storage-foundation-provisioner-125" + common: + csiExternalProvisioner125: "sha256:common-provisioner-125" + asserts: + - equal: + path: "storageFoundationEnabledWithVersion" + value: "registry.deckhouse.io/deckhouse/ce/modules/storage-foundation@sha256:storage-foundation-provisioner-125" + + - it: should return image from storage-foundation base name when versioned not found + documentIndex: 1 + set: + global: + enabledModules: + - storage-foundation + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiExternalAttacher: "sha256:storage-foundation-attacher-base" + common: + csiExternalAttacher125: "sha256:common-attacher-125" + asserts: + - equal: + path: "storageFoundationEnabledWithoutVersion" + value: "registry.deckhouse.io/deckhouse/ce/modules/storage-foundation@sha256:storage-foundation-attacher-base" + + - it: should return null when storage-foundation enabled but image not found + documentIndex: 2 + set: + global: + enabledModules: + - storage-foundation + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiExternalProvisionerForK8SGE125: "sha256:provisioner-125" + common: + csiExternalResizer125: "sha256:common-resizer-125" + asserts: + - equal: + path: "storageFoundationEnabledNotFound" + value: null + + - it: should use common module when storage-foundation disabled + documentIndex: 3 + set: + global: + enabledModules: [] + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiExternalSnapshotterForK8SGE125: "sha256:storage-foundation-snapshotter-125" + common: + csiExternalSnapshotter125: "sha256:common-snapshotter-125" + asserts: + - equal: + path: "storageFoundationDisabledUseCommon" + value: "registry.deckhouse.io/deckhouse/ce@sha256:common-snapshotter-125" + + - it: should fallback to lower minor version when exact version not found + documentIndex: 4 + set: + global: + enabledModules: + - storage-foundation + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiLivenessprobeForK8SGE133: "sha256:storage-foundation-livenessprobe-133" + common: + csiLivenessprobe134: "sha256:common-livenessprobe-134" + asserts: + - equal: + path: "storageFoundationVersionFallback" + value: "registry.deckhouse.io/deckhouse/ce/modules/storage-foundation@sha256:storage-foundation-livenessprobe-133" + + - it: should handle different Kubernetes versions correctly + documentIndex: 5 + set: + global: + enabledModules: + - storage-foundation + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiExternalProvisionerForK8SGE126: "sha256:storage-foundation-provisioner-126" + common: + csiExternalProvisioner126: "sha256:common-provisioner-126" + asserts: + - equal: + path: "storageFoundationK8s126" + value: "registry.deckhouse.io/deckhouse/ce/modules/storage-foundation@sha256:storage-foundation-provisioner-126" + + - it: should use common module with correct version format when storage-foundation disabled + documentIndex: 6 + set: + global: + enabledModules: [] + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiExternalSnapshotterForK8SGE124: "sha256:storage-foundation-snapshotter-124" + common: + csiExternalSnapshotter124: "sha256:common-snapshotter-124" + asserts: + - equal: + path: "commonFallbackDifferentVersion" + value: "registry.deckhouse.io/deckhouse/ce@sha256:common-snapshotter-124" + + - it: should iterate through minor versions from current down to 0 + documentIndex: 7 + set: + global: + enabledModules: + - storage-foundation + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiExternalProvisionerForK8SGE130: "sha256:storage-foundation-provisioner-130" + common: + csiExternalProvisioner134: "sha256:common-provisioner-134" + asserts: + - equal: + path: "storageFoundationVersionIteration" + value: "registry.deckhouse.io/deckhouse/ce/modules/storage-foundation@sha256:storage-foundation-provisioner-130" + + - it: should return null when common module image not found + documentIndex: 8 + set: + global: + enabledModules: [] + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiExternalProvisionerForK8SGE125: "sha256:storage-foundation-provisioner-125" + common: + csiExternalAttacher125: "sha256:common-attacher-125" + asserts: + - equal: + path: "commonNotFound" + value: null + + - it: should use common module when other modules enabled but not storage-foundation + documentIndex: 9 + set: + global: + enabledModules: + - monitoring + - ingress-nginx + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: + csiExternalProvisionerForK8SGE125: "sha256:storage-foundation-provisioner-125" + common: + csiExternalProvisioner125: "sha256:common-provisioner-125" + asserts: + - equal: + path: "otherModulesEnabled" + value: "registry.deckhouse.io/deckhouse/ce@sha256:common-provisioner-125" + + - it: should return null when storage-foundation enabled but digests empty + documentIndex: 10 + set: + global: + enabledModules: + - storage-foundation + modulesImages: + registry: + base: "registry.deckhouse.io/deckhouse/ce" + digests: + storageFoundation: {} + common: + csiExternalProvisioner125: "sha256:common-provisioner-125" + asserts: + - equal: + path: "emptyStorageFoundationDigests" + value: null + diff --git a/tests/tests/helm_lib_envs_for_proxy_test.yaml b/tests/tests/helm_lib_envs_for_proxy_test.yaml index 2f838f2..64adcf6 100644 --- a/tests/tests/helm_lib_envs_for_proxy_test.yaml +++ b/tests/tests/helm_lib_envs_for_proxy_test.yaml @@ -44,13 +44,13 @@ tests: value: "NO_PROXY" - equal: path: "proxyEnvs[4].value" - value: "127.0.0.1,169.254.169.254,cluster.local,10.0.0.0/16,10.1.0.0/16,example.com" + value: "127.0.0.1,169.254.169.254,registry.d8-system.svc,cluster.local,10.0.0.0/16,10.1.0.0/16,example.com" - equal: path: "proxyEnvs[5].name" value: "no_proxy" - equal: path: "proxyEnvs[5].value" - value: "127.0.0.1,169.254.169.254,cluster.local,10.0.0.0/16,10.1.0.0/16,example.com" + value: "127.0.0.1,169.254.169.254,registry.d8-system.svc,cluster.local,10.0.0.0/16,10.1.0.0/16,example.com" - it: should render proxy env vars with only http proxy set: @@ -79,13 +79,13 @@ tests: value: "NO_PROXY" - equal: path: "proxyEnvs[2].value" - value: "127.0.0.1,169.254.169.254,cluster.local,10.0.0.0/16,10.1.0.0/16" + value: "127.0.0.1,169.254.169.254,registry.d8-system.svc,cluster.local,10.0.0.0/16,10.1.0.0/16" - equal: path: "proxyEnvs[3].name" value: "no_proxy" - equal: path: "proxyEnvs[3].value" - value: "127.0.0.1,169.254.169.254,cluster.local,10.0.0.0/16,10.1.0.0/16" + value: "127.0.0.1,169.254.169.254,registry.d8-system.svc,cluster.local,10.0.0.0/16,10.1.0.0/16" - it: should not render proxy env vars when no proxy configured set: diff --git a/tests/tests/helm_lib_module_container_security_context_pss_restricted_flexible_test.yaml b/tests/tests/helm_lib_module_container_security_context_pss_restricted_flexible_test.yaml index 9b968c3..802b8ae 100644 --- a/tests/tests/helm_lib_module_container_security_context_pss_restricted_flexible_test.yaml +++ b/tests/tests/helm_lib_module_container_security_context_pss_restricted_flexible_test.yaml @@ -13,6 +13,7 @@ tests: drop: - ALL runAsUser: 64535 + privileged: false runAsGroup: 64535 runAsNonRoot: true seccompProfile: diff --git a/tests/tests/helm_lib_module_image_test.yaml b/tests/tests/helm_lib_module_image_test.yaml index 0dee152..313de51 100644 --- a/tests/tests/helm_lib_module_image_test.yaml +++ b/tests/tests/helm_lib_module_image_test.yaml @@ -39,13 +39,13 @@ tests: asserts: - equal: path: "externalModuleImage" - value: "registry.deckhouse.io/modules/testModule@sha321" + value: "registry.deckhouse.io/modules/test-module@sha321" - equal: path: "externalModuleImageWithOptionalName" - value: "registry.flant.com/modules/someModule@sha543" + value: "registry.flant.com/modules/some-module@sha543" - equal: path: "externalModuleKebabImageWithOptionalName" - value: "registry.flant.com/modules/someModule@sha543" + value: "registry.flant.com/modules/some-module@sha543" - it: should render external module image with trail slash documentIndex: 1 @@ -59,7 +59,7 @@ tests: asserts: - equal: path: "externalModuleImage" - value: "registry.deckhouse.io/modules/testModule@sha321" + value: "registry.deckhouse.io/modules/test-module@sha321" - it: should render external module image digest documentIndex: 2 @@ -115,4 +115,4 @@ tests: value: "registry.deckhouse.io/deckhouse/ce@sha999" - equal: path: "commonImageNoFailNotExist" - value: null \ No newline at end of file + value: null diff --git a/tests/tests/helm_lib_module_init_container_test.yaml b/tests/tests/helm_lib_module_init_container_test.yaml index 9312181..8314c33 100644 --- a/tests/tests/helm_lib_module_init_container_test.yaml +++ b/tests/tests/helm_lib_module_init_container_test.yaml @@ -97,6 +97,7 @@ tests: drop: - ALL readOnlyRootFilesystem: true + privileged: false runAsGroup: 64535 runAsNonRoot: true runAsUser: 64535 diff --git a/tests/tests/helm_lib_prometheus_rules_recursion_test.yaml b/tests/tests/helm_lib_prometheus_rules_recursion_test.yaml new file mode 100644 index 0000000..a6c7c3c --- /dev/null +++ b/tests/tests/helm_lib_prometheus_rules_recursion_test.yaml @@ -0,0 +1,37 @@ +suite: test helm_lib_prometheus_rules_recursion +templates: + - helm_lib_prometheus_rules_recursion.yaml +tests: + - it: should generate PrometheusRule + set: + global.enabledModules: ["observability"] + global.discovery.prometheusScrapeInterval: 30s + global.discovery.apiVersions: [] + asserts: + - equal: + path: kind + value: PrometheusRule + - equal: + path: metadata.name + value: test-module-deadbeef-propagated-ingress-nginx + - hasDocuments: + count: 1 + - it: should generate ClusterObservabilityPropagatedMetricsRulesGroup + set: + global.enabledModules: ["observability"] + global.discovery.prometheusScrapeInterval: 30s + global.discovery.apiVersions: ["observability.deckhouse.io/v1alpha1/ClusterObservabilityMetricsRulesGroup"] + asserts: + - equal: + path: kind + value: ClusterObservabilityPropagatedMetricsRulesGroup + - equal: + path: metadata.name + value: test-module-deadbeef-ingress-nginx-0 + documentIndex: 0 + - equal: + path: metadata.name + value: test-module-deadbeef-ingress-nginx-1 + documentIndex: 1 + - hasDocuments: + count: 2