[stable/zed] Bump helm-toolkit to 0.2.78 (#2270)

This is an automated cherry-pick of #2264
/assign mnaser
diff --git a/charts/ovn/charts/helm-toolkit/Chart.yaml b/charts/ovn/charts/helm-toolkit/Chart.yaml
index d4c0ea2..9d3aa1e 100644
--- a/charts/ovn/charts/helm-toolkit/Chart.yaml
+++ b/charts/ovn/charts/helm-toolkit/Chart.yaml
@@ -9,4 +9,4 @@
 sources:
 - https://opendev.org/openstack/openstack-helm-infra
 - https://opendev.org/openstack/openstack-helm
-version: 0.2.69
+version: 0.2.78
diff --git a/charts/ovn/charts/helm-toolkit/templates/endpoints/_host_and_port_endpoint_uri_lookup.tpl b/charts/ovn/charts/helm-toolkit/templates/endpoints/_host_and_port_endpoint_uri_lookup.tpl
index 6877b7b..728b994 100644
--- a/charts/ovn/charts/helm-toolkit/templates/endpoints/_host_and_port_endpoint_uri_lookup.tpl
+++ b/charts/ovn/charts/helm-toolkit/templates/endpoints/_host_and_port_endpoint_uri_lookup.tpl
@@ -14,7 +14,8 @@
 
 {{/*
 abstract: |
-  Resolves 'hostname:port' for an endpoint
+  Resolves 'hostname:port' for an endpoint, or several hostname:port pairs for statefulset e.g
+  'hostname1:port1,hostname2:port2,hostname3:port3',
 examples:
   - values: |
       endpoints:
@@ -46,6 +47,23 @@
       {{ tuple "oslo_db" "internal" "mysql" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }}
     return: |
       127.0.0.1:3306
+  - values: |
+      endpoints:
+        oslo_cache:
+          hosts:
+            default: memcached
+          host_fqdn_override:
+            default: null
+          statefulset:
+            name: openstack-memcached-memcached
+            replicas: 3
+          port:
+            memcache:
+              default: 11211
+    usage: |
+      {{ tuple "oslo_cache" "internal" "memcache" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }}
+    return: |
+      openstack-memcached-memcached-0:11211,openstack-memcached-memcached-1:11211,openstack-memcached-memcached-2:11211
 */}}
 
 {{- define "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" -}}
@@ -53,7 +71,19 @@
 {{- $endpoint := index . 1 -}}
 {{- $port := index . 2 -}}
 {{- $context := index . 3 -}}
-{{- $endpointPort := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.endpoint_port_lookup" }}
-{{- $endpointHostname := tuple $type $endpoint $context | include "helm-toolkit.endpoints.endpoint_host_lookup" }}
-{{- printf "%s:%s" $endpointHostname $endpointPort -}}
+{{- $ssMap := index $context.Values.endpoints ( $type | replace "-" "_" ) "statefulset" | default false -}}
+{{- $local := dict "endpointHosts" list -}}
+{{- $endpointPort := tuple $type $endpoint $port $context | include "helm-toolkit.endpoints.endpoint_port_lookup" -}}
+{{- if $ssMap -}}
+{{-   $endpointHostPrefix := $ssMap.name -}}
+{{-   $endpointHostSuffix := tuple $type $endpoint $context | include "helm-toolkit.endpoints.endpoint_host_lookup" }}
+{{-   range $podInt := until ( atoi (print $ssMap.replicas ) ) -}}
+{{-     $endpointHostname := printf "%s-%d.%s:%s" $endpointHostPrefix $podInt $endpointHostSuffix $endpointPort -}}
+{{-     $_ := set $local "endpointHosts" ( append $local.endpointHosts $endpointHostname ) -}}
+{{-   end -}}
+{{- else -}}
+{{-   $endpointHostname := tuple $type $endpoint $context | include "helm-toolkit.endpoints.endpoint_host_lookup" -}}
+{{-   $_ := set $local "endpointHosts" ( append $local.endpointHosts (printf "%s:%s" $endpointHostname $endpointPort) ) -}}
+{{- end -}}
+{{ include "helm-toolkit.utils.joinListWithComma" $local.endpointHosts }}
 {{- end -}}
diff --git a/charts/ovn/charts/helm-toolkit/templates/endpoints/_keystone_endpoint_path_lookup.tpl b/charts/ovn/charts/helm-toolkit/templates/endpoints/_keystone_endpoint_path_lookup.tpl
index b2ec648..24eb569 100644
--- a/charts/ovn/charts/helm-toolkit/templates/endpoints/_keystone_endpoint_path_lookup.tpl
+++ b/charts/ovn/charts/helm-toolkit/templates/endpoints/_keystone_endpoint_path_lookup.tpl
@@ -40,9 +40,9 @@
 {{- $context := index . 3 -}}
 {{- $endpointMap := index $context.Values.endpoints ( $type | replace "-" "_" ) }}
 {{- if kindIs "string" $endpointMap.path }}
-{{- printf "%s" $endpointMap.path | default "/" -}}
+{{- printf "%s" $endpointMap.path | default "" -}}
 {{- else -}}
-{{- $endpointPath := index $endpointMap.path $endpoint | default $endpointMap.path.default | default "/" }}
+{{- $endpointPath := index $endpointMap.path $endpoint | default $endpointMap.path.default | default "" }}
 {{- printf "%s" $endpointPath -}}
 {{- end -}}
 {{- end -}}
diff --git a/charts/ovn/charts/helm-toolkit/templates/manifests/_configmap-oslo-policy.tpl b/charts/ovn/charts/helm-toolkit/templates/manifests/_configmap-oslo-policy.tpl
new file mode 100644
index 0000000..332ca99
--- /dev/null
+++ b/charts/ovn/charts/helm-toolkit/templates/manifests/_configmap-oslo-policy.tpl
@@ -0,0 +1,51 @@
+{{/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+   http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+{{/*
+abstract: |
+  Renders out the configmap <service>-oslo-policy.
+values: |
+  conf:
+    policy.d:
+      file1:
+        foo: bar
+      file2:
+        foo: baz
+usage: |
+{{- include "helm-toolkit.manifests.configmap_oslo_policy" (dict "envAll" $envAll "serviceName" "keystone") }}
+return: |
+  ---
+  apiVersion: v1
+  kind: Secret
+  metadata:
+    name: keystone-oslo-policy
+  data:
+    file1: base64of(foo: bar)
+    file2: base64of(foo: baz)
+*/}}
+{{- define "helm-toolkit.manifests.configmap_oslo_policy" -}}
+{{- $envAll := index . "envAll" -}}
+{{- $serviceName := index . "serviceName" -}}
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ $serviceName }}-oslo-policy
+type: Opaque
+data:
+  {{- range $key, $value := index $envAll.Values.conf "policy.d" }}
+  {{- if $value }}
+  {{ $key }}: {{ toYaml $value | b64enc }}
+  {{- else }}
+  {{ $key }}: {{ "\n" | b64enc }}
+  {{- end }}
+  {{- end }}
+{{- end -}}
diff --git a/charts/ovn/charts/helm-toolkit/templates/manifests/_ingress.tpl b/charts/ovn/charts/helm-toolkit/templates/manifests/_ingress.tpl
index cacb4b8..792571c 100644
--- a/charts/ovn/charts/helm-toolkit/templates/manifests/_ingress.tpl
+++ b/charts/ovn/charts/helm-toolkit/templates/manifests/_ingress.tpl
@@ -708,6 +708,10 @@
 {{- range $v := without (index $endpointHost.tls "dnsNames" | default list) $hostNameFull }}
 {{- $vHosts = append $vHosts $v }}
 {{- end }}
+{{- if hasKey $envAll.Values.endpoints "alias_fqdn" }}
+{{- $alias_host := $envAll.Values.endpoints.alias_fqdn }}
+{{- $vHosts = append $vHosts $alias_host }}
+{{- end }}
 {{- $secretName := index $envAll.Values.secrets "tls" ( $backendServiceType | replace "-" "_" ) $backendService $endpoint }}
 {{- $_ := required "You need to specify a secret in your values for the endpoint" $secretName }}
   tls:
diff --git a/charts/ovn/charts/helm-toolkit/templates/scripts/_db-drop.py.tpl b/charts/ovn/charts/helm-toolkit/templates/scripts/_db-drop.py.tpl
index 1e28da9..c6a7521 100644
--- a/charts/ovn/charts/helm-toolkit/templates/scripts/_db-drop.py.tpl
+++ b/charts/ovn/charts/helm-toolkit/templates/scripts/_db-drop.py.tpl
@@ -33,6 +33,7 @@
     PARSER_OPTS = {"strict": False}
 import logging
 from sqlalchemy import create_engine
+from sqlalchemy import text
 
 # Create logger, console handler and formatter
 logger = logging.getLogger('OpenStack-Helm DB Drop')
@@ -125,7 +126,7 @@
 # Delete DB
 try:
     with root_engine.connect() as connection:
-        connection.execute("DROP DATABASE IF EXISTS {0}".format(database))
+        connection.execute(text("DROP DATABASE IF EXISTS {0}".format(database)))
         try:
             connection.commit()
         except AttributeError:
@@ -138,7 +139,7 @@
 # Delete DB User
 try:
     with root_engine.connect() as connection:
-        connection.execute("DROP USER IF EXISTS {0}".format(user))
+        connection.execute(text("DROP USER IF EXISTS {0}".format(user)))
         try:
             connection.commit()
         except AttributeError:
diff --git a/charts/ovn/charts/helm-toolkit/templates/scripts/_db-init.py.tpl b/charts/ovn/charts/helm-toolkit/templates/scripts/_db-init.py.tpl
index 110cd98..1917f78 100644
--- a/charts/ovn/charts/helm-toolkit/templates/scripts/_db-init.py.tpl
+++ b/charts/ovn/charts/helm-toolkit/templates/scripts/_db-init.py.tpl
@@ -33,6 +33,7 @@
     PARSER_OPTS = {"strict": False}
 import logging
 from sqlalchemy import create_engine
+from sqlalchemy import text
 
 # Create logger, console handler and formatter
 logger = logging.getLogger('OpenStack-Helm DB Init')
@@ -125,7 +126,7 @@
 # Create DB
 try:
     with root_engine.connect() as connection:
-        connection.execute("CREATE DATABASE IF NOT EXISTS {0}".format(database))
+        connection.execute(text("CREATE DATABASE IF NOT EXISTS {0}".format(database)))
         try:
             connection.commit()
         except AttributeError:
@@ -139,10 +140,10 @@
 try:
     with root_engine.connect() as connection:
         connection.execute(
-            "CREATE USER IF NOT EXISTS \'{0}\'@\'%%\' IDENTIFIED BY \'{1}\' {2}".format(
-                user, password, mysql_x509))
+            text("CREATE USER IF NOT EXISTS \'{0}\'@\'%%\' IDENTIFIED BY \'{1}\' {2}".format(
+                user, password, mysql_x509)))
         connection.execute(
-            "GRANT ALL ON `{0}`.* TO \'{1}\'@\'%%\'".format(database, user))
+            text("GRANT ALL ON `{0}`.* TO \'{1}\'@\'%%\'".format(database, user)))
         try:
             connection.commit()
         except AttributeError:
diff --git a/charts/ovn/charts/helm-toolkit/templates/scripts/_rabbit-init.sh.tpl b/charts/ovn/charts/helm-toolkit/templates/scripts/_rabbit-init.sh.tpl
index 3739f95..e6e9c6e 100644
--- a/charts/ovn/charts/helm-toolkit/templates/scripts/_rabbit-init.sh.tpl
+++ b/charts/ovn/charts/helm-toolkit/templates/scripts/_rabbit-init.sh.tpl
@@ -29,7 +29,9 @@
   awk -F'[//:]' '{print $4}')
 RABBITMQ_ADMIN_PASSWORD=$(echo "${RABBITMQ_ADMIN_CONNECTION}" | \
   awk -F'[@]' '{print $1}' | \
-  awk -F'[//:]' '{print $5}')
+  awk -F'[//:]' '{print $5}' | \
+  sed 's/%/\\x/g' | \
+  xargs -0 printf "%b")
 
 # Extract User creadential
 RABBITMQ_USERNAME=$(echo "${RABBITMQ_USER_CONNECTION}" | \
@@ -37,7 +39,9 @@
   awk -F'[//:]' '{print $4}')
 RABBITMQ_PASSWORD=$(echo "${RABBITMQ_USER_CONNECTION}" | \
   awk -F'[@]' '{print $1}' | \
-  awk -F'[//:]' '{print $5}')
+  awk -F'[//:]' '{print $5}' | \
+  sed 's/%/\\x/g' | \
+  xargs -0 printf "%b")
 
 # Extract User vHost
 RABBITMQ_VHOST=$(echo "${RABBITMQ_USER_CONNECTION}" | \
diff --git a/charts/ovn/charts/helm-toolkit/templates/snippets/_kubernetes_metadata_labels.tpl b/charts/ovn/charts/helm-toolkit/templates/snippets/_kubernetes_metadata_labels.tpl
index 48b53fa..5c2dedb 100644
--- a/charts/ovn/charts/helm-toolkit/templates/snippets/_kubernetes_metadata_labels.tpl
+++ b/charts/ovn/charts/helm-toolkit/templates/snippets/_kubernetes_metadata_labels.tpl
@@ -40,6 +40,9 @@
 release_group: {{ $envAll.Values.release_group | default $envAll.Release.Name }}
 application: {{ $application }}
 component: {{ $component }}
+app.kubernetes.io/name: {{ $application }}
+app.kubernetes.io/component: {{ $component }}
+app.kubernetes.io/instance: {{ $envAll.Values.release_group | default $envAll.Release.Name }}
 {{- if ($envAll.Values.pod).labels }}
 {{- if hasKey $envAll.Values.pod.labels $component }}
 {{ index $envAll.Values.pod "labels" $component | toYaml }}
diff --git a/charts/ovn/charts/helm-toolkit/templates/snippets/_service_params.tpl b/charts/ovn/charts/helm-toolkit/templates/snippets/_service_params.tpl
new file mode 100644
index 0000000..6233a93
--- /dev/null
+++ b/charts/ovn/charts/helm-toolkit/templates/snippets/_service_params.tpl
@@ -0,0 +1,61 @@
+{{/*
+Copyright 2017 The Openstack-Helm Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+{{/*
+abstract: |
+  Inserts kubernetes service parameters from values as is.
+values: |
+  network:
+    serviceExample:
+      service:
+        type: loadBalancer
+        loadBalancerIP: 1.1.1.1
+usage: |
+  ---
+  apiVersion: v1
+  kind: Service
+  metadata:
+    name: 'serviceExample'
+  spec:
+    ports:
+    - name: s-example
+      port: 1111
+  {{ .Values.network.serviceExample | include "helm-toolkit.snippets.service_params" | indent 2 }}
+return: |
+  type: loadBalancer
+  loadBalancerIP: 1.1.1.1
+*/}}
+
+{{- define "helm-toolkit.snippets.service_params" }}
+{{- $serviceParams := dict }}
+{{- if hasKey . "service" }}
+{{- $serviceParams = .service }}
+{{- end }}
+{{- if hasKey . "node_port" }}
+{{- if hasKey .node_port "enabled" }}
+{{- if .node_port.enabled }}
+{{- $_ := set $serviceParams "type" "NodePort" }}
+{{- end }}
+{{- end }}
+{{- end }}
+{{- if hasKey . "external_policy_local" }}
+{{- if .external_policy_local }}
+{{- $_ := set $serviceParams "externalTrafficPolicy" "Local" }}
+{{- end }}
+{{- end }}
+{{- if $serviceParams }}
+{{- $serviceParams | toYaml }}
+{{- end }}
+{{- end }}
diff --git a/charts/ovn/charts/helm-toolkit/templates/utils/_daemonset_overrides_root.tpl b/charts/ovn/charts/helm-toolkit/templates/utils/_daemonset_overrides_root.tpl
new file mode 100644
index 0000000..bdb28c3
--- /dev/null
+++ b/charts/ovn/charts/helm-toolkit/templates/utils/_daemonset_overrides_root.tpl
@@ -0,0 +1,279 @@
+{{/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/}}
+
+{{/*
+
+The helm-toolkit.utils.daemonset_overrides function have some limitations:
+
+ * it allows to override only conf values specifid in configmap-etc
+ * it doesn't allow to override values for daemonsets passed via env variables
+   or via damoenset definition. As result it is impossible to have mixed
+   deployment when one compute is configured with dpdk while other not.
+ * it is impossible to override interface names/other information stored in
+   <service>-bin configmap
+ * It allows to schedule on both hosts and labels, which adds some
+   uncertainty
+
+This implementation is intended to handle those limitations:
+
+ * it allows to schedule only based on labels
+ * it creates <service>-bin per daemonset override
+ * it allows to override values when rendering daemonsets
+
+ It picks data from the following structure:
+
+  .Values:
+    overrides:
+      mychart_mydaemonset:
+        labels:
+          label::value:
+            values:
+              override_root_option: override_root_value
+              conf:
+                ovs_dpdk:
+                  enabled: true
+                neutron:
+                  DEFAULT:
+                    foo: bar
+
+*/}}
+
+{{- define "helm-toolkit.utils.daemonset_overrides_root" }}
+  {{- $daemonset := index . 0 }}
+  {{- $daemonSetTemplateName := index . 1 }}
+  {{ $serviceAccountName := index . 2 }}
+  {{- $configmap_include := index . 3 }}
+  {{- $configmap_name := index . 4 }}
+  {{- $configbin_include := index . 5 }}
+  {{- $configbin_name := index . 6 }}
+  {{- $context := index . 7 }}
+
+  {{- $_ := unset $context ".Files" }}
+  {{- $daemonset_root_name := printf (print $context.Chart.Name "_" $daemonset) }}
+  {{- $_ := set $context.Values "__daemonset_list" list }}
+  {{- $_ := set $context.Values "__default" dict }}
+
+  {{- $default_enabled := true }}
+  {{- if hasKey $context.Values "overrides" }}
+    {{- range $key, $val := $context.Values.overrides }}
+
+      {{- if eq $key $daemonset_root_name }}
+        {{- range $type, $type_data := . }}
+          {{- if eq $type "overrides_default" }}
+            {{- $default_enabled = $type_data }}
+          {{- end }}
+
+          {{- if eq $type "labels" }}
+            {{- $_ := set $context.Values "__label_dict" . }}
+            {{- range $lname, $ldata := . }}
+              {{ $label_name := (split "::" $lname)._0 }}
+              {{ $label_value := (split "::" $lname)._1 }}
+              {{/* dictionary that will contain all info needed to generate this
+              iteration of the daemonset. */}}
+              {{- $_ := set $context.Values "__current_label" dict }}
+
+              {{/* set daemonset name */}}
+              {{- $_ := set $context.Values.__current_label "name" $label_name }}
+
+              {{/* set daemonset metadata annotation */}}
+              {{- $_ := set $context.Values.__current_label "daemonset_override" $lname  }}
+
+              {{/* apply overrides */}}
+
+
+              {{- $override_root_copy := $ldata.values }}
+              {{/* Deep copy to prevent https://storyboard.openstack.org/#!/story/2005936 */}}
+              {{- $root_copy := omit ($context.Values | toYaml | fromYaml) "overrides" }}
+              {{- $merged_dict := mergeOverwrite $root_copy $override_root_copy }}
+
+              {{- $root_conf_copy2 := dict "values" $merged_dict }}
+              {{- $context_values := omit (omit ($context.Values | toYaml | fromYaml) "values") "__daemonset_list" }}
+              {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2.values }}
+              {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }}
+              {{- $_ := set $context.Values.__current_label "nodeData" $root_conf_copy4 }}
+
+
+              {{/* Schedule to the provided label value(s) */}}
+              {{- $label_dict := dict "key" $label_name  }}
+              {{- $_ := set $label_dict "values" (list $label_value) }}
+              {{- $_ := set $label_dict "operator" "In" }}
+              {{- $list_aggregate := list $label_dict }}
+              {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }}
+
+              {{/* Do not schedule to other specified labels, with higher
+              precedence as the list position increases. Last defined label
+              is highest priority. */}}
+              {{- $other_labels :=  omit $context.Values.__label_dict $lname }}
+              {{- range $lname2, $ldata2 := $other_labels }}
+                {{ $label_name2 := (split "::" $lname2)._0 }}
+                {{ $label_value2 := (split "::" $lname2)._1 }}
+
+                {{- $label_dict := dict "key" $label_name2  }}
+                {{- $_ := set $label_dict "values" (list $label_value2) }}
+                {{- $_ := set $label_dict "operator" "NotIn" }}
+
+                {{- $list_aggregate := append $context.Values.__current_label.matchExpressions $label_dict }}
+                {{- $_ := set $context.Values.__current_label "matchExpressions" $list_aggregate }}
+              {{- end }}
+
+              {{/* store completed daemonset entry/info into global list */}}
+              {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__current_label }}
+              {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }}
+              {{- $_ := unset $context.Values "__current_label" }}
+
+            {{- end }}
+          {{- end }}
+        {{- end }}
+
+        {{/* scheduler exceptions for the default daemonset */}}
+        {{- $_ := set $context.Values.__default "matchExpressions" list }}
+
+        {{- range $type, $type_data := . }}
+          {{/* Do not schedule to other specified labels */}}
+          {{- if eq $type "labels" }}
+            {{- range $lname, $ldata := . }}
+              {{ $label_name := (split "::" $lname)._0 }}
+              {{ $label_value := (split "::" $lname)._1 }}
+
+              {{- $default_dict := dict "key" $label_name  }}
+              {{- $_ := set $default_dict "values" (list $label_value) }}
+              {{- $_ := set $default_dict "operator" "NotIn" }}
+
+              {{- $list_aggregate := append $context.Values.__default.matchExpressions $default_dict }}
+              {{- $_ := set $context.Values.__default "matchExpressions" $list_aggregate }}
+            {{- end }}
+          {{- end }}
+        {{- end }}
+      {{- end }}
+    {{- end }}
+  {{- end }}
+
+  {{/* generate the default daemonset */}}
+
+  {{/* set name */}}
+  {{- $_ := set $context.Values.__default "name" "default" }}
+
+  {{/* no overrides apply, so copy as-is */}}
+  {{- $root_conf_copy1 := omit $context.Values.conf "overrides" }}
+  {{- $root_conf_copy2 := dict "conf" $root_conf_copy1 }}
+  {{- $context_values := omit $context.Values "conf" }}
+  {{- $root_conf_copy3 := mergeOverwrite $context_values $root_conf_copy2 }}
+  {{- $root_conf_copy4 := dict "Values" $root_conf_copy3 }}
+  {{- $_ := set $context.Values.__default "nodeData" $root_conf_copy4 }}
+
+  {{/* add to global list */}}
+  {{- if $default_enabled }}
+    {{- $list_aggregate := append $context.Values.__daemonset_list $context.Values.__default }}
+    {{- $_ := set $context.Values "__daemonset_list" $list_aggregate }}
+  {{- end }}
+
+  {{- range $current_dict := $context.Values.__daemonset_list }}
+
+    {{- $context_novalues := omit $context "Values" }}
+    {{- $merged_dict := mergeOverwrite $context_novalues $current_dict.nodeData }}
+    {{- $_ := set $current_dict "nodeData" $merged_dict }}
+    {{/* Deep copy original daemonset_yaml */}}
+    {{- $daemonset_yaml := list $daemonset $configmap_name $serviceAccountName $merged_dict | include $daemonSetTemplateName | toString | fromYaml }}
+    {{- $_ := set $context.Values "__daemonset_yaml" ($daemonset_yaml | toYaml | fromYaml) }}
+
+    {{/* Use the following name format $daemonset_root_name + sha256summ($current_dict.matchExpressions)
+    as labels might be too long and contain wrong characters like / */}}
+    {{- $_ := set $current_dict "dns_1123_name" dict }}
+    {{- $name_format := "" }}
+    {{- if eq $current_dict.name "default" }}
+       {{- $name_format = (printf "%s-%s" $daemonset_root_name "default") | replace "_" "-" }}
+    {{- else }}
+       {{- $name_format = (printf "%s-%s" $daemonset_root_name ($current_dict.matchExpressions | quote | sha256sum | trunc 16)) | replace "_" "-" }}
+    {{- end }}
+    {{- $_ := set $current_dict "dns_1123_name" $name_format }}
+
+    {{/* set daemonset metadata name */}}
+    {{- if not $context.Values.__daemonset_yaml.metadata }}{{- $_ := set $context.Values.__daemonset_yaml "metadata" dict }}{{- end }}
+    {{- if not $context.Values.__daemonset_yaml.metadata.name }}{{- $_ := set $context.Values.__daemonset_yaml.metadata "name" dict }}{{- end }}
+    {{- $_ := set $context.Values.__daemonset_yaml.metadata "name" $current_dict.dns_1123_name }}
+
+    {{/* cross-reference configmap name to container volume definitions */}}
+    {{- $_ := set $context.Values "__volume_list" list }}
+    {{- range $current_volume := $context.Values.__daemonset_yaml.spec.template.spec.volumes }}
+      {{- $_ := set $context.Values "__volume" $current_volume }}
+      {{- if hasKey $context.Values.__volume "secret" }}
+        {{- if eq $context.Values.__volume.secret.secretName $configmap_name }}
+          {{- $_ := set $context.Values.__volume.secret "secretName" (printf "%s-etc" $current_dict.dns_1123_name) }}
+        {{- end }}
+      {{- end }}
+      {{- if hasKey $context.Values.__volume "configMap" }}
+        {{- if eq $context.Values.__volume.configMap.name $configbin_name }}
+          {{- $_ := set $context.Values.__volume.configMap "name" (printf "%s-bin" $current_dict.dns_1123_name) }}
+        {{- end }}
+      {{- end }}
+      {{- $updated_list := append $context.Values.__volume_list $context.Values.__volume }}
+      {{- $_ := set $context.Values "__volume_list" $updated_list }}
+    {{- end }}
+    {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "volumes" $context.Values.__volume_list }}
+
+
+    {{/* populate scheduling restrictions */}}
+    {{- if hasKey $current_dict "matchExpressions" }}
+      {{- $length := len $current_dict.matchExpressions }}
+      {{- if gt $length 0 }}
+        {{- if not $context.Values.__daemonset_yaml.spec.template.spec }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "spec" dict }}{{- end }}
+        {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec "affinity" dict }}{{- end }}
+        {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity "nodeAffinity" dict }}{{- end }}
+        {{- if not $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity "requiredDuringSchedulingIgnoredDuringExecution" dict }}{{- end }}
+
+        {{- $expressions_modified := list }}
+        {{- if hasKey $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution "nodeSelectorTerms" }}
+          {{- range $orig_expression := $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution.nodeSelectorTerms }}
+            {{- $match_expressions_modified := list }}
+            {{- $match_expressions_modified = concat $match_expressions_modified $current_dict.matchExpressions }}
+            {{- if hasKey $orig_expression "matchExpressions" }}
+              {{- $match_expressions_modified = concat $match_expressions_modified $orig_expression.matchExpressions }}
+              {{- $expressions_modified = append $expressions_modified (dict "matchExpressions" $match_expressions_modified) }}
+            {{- end }}
+          {{- end }}
+        {{- else }}
+          {{- $expressions_modified = (list (dict "matchExpressions" $current_dict.matchExpressions)) }}
+        {{- end }}
+        {{- $_ := set $context.Values.__daemonset_yaml.spec.template.spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution "nodeSelectorTerms" $expressions_modified }}
+      {{- end }}
+    {{- end }}
+
+    {{/* input value hash for current set of values overrides */}}
+    {{- if not $context.Values.__daemonset_yaml.spec }}{{- $_ := set $context.Values.__daemonset_yaml "spec" dict }}{{- end }}
+    {{- if not $context.Values.__daemonset_yaml.spec.template }}{{- $_ := set $context.Values.__daemonset_yaml.spec "template" dict }}{{- end }}
+    {{- if not $context.Values.__daemonset_yaml.spec.template.metadata }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template "metadata" dict }}{{- end }}
+    {{- if not $context.Values.__daemonset_yaml.spec.template.metadata.annotations }}{{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata "annotations" dict }}{{- end }}
+    {{- $cmap := list (printf "%s-etc" $current_dict.dns_1123_name) $current_dict.nodeData | include $configmap_include }}
+    {{- $cmap_bin := list (printf "%s-bin" $current_dict.dns_1123_name) $current_dict.nodeData | include $configbin_include }}
+    {{- $values_cmap_hash := $cmap | quote | sha256sum }}
+    {{- $values_cmap_bin_hash := $cmap_bin | quote | sha256sum }}
+    {{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata.annotations "configmap-etc-hash" $values_cmap_hash }}
+    {{- $_ := set $context.Values.__daemonset_yaml.spec.template.metadata.annotations "configmap-bin-hash" $values_cmap_bin_hash }}
+
+    {{/* Do not set override for default daemonset */}}
+    {{- if $current_dict.daemonset_override }}
+        {{- $_ := set $context.Values.__daemonset_yaml.metadata.annotations "daemonset_override" $current_dict.daemonset_override }}
+    {{- end }}
+
+{{/* generate configmap */}}
+---
+{{ $cmap }}
+    {{/* generate <service>-bin yaml */}}
+---
+{{ $cmap_bin }}
+    {{/* generate daemonset yaml */}}
+---
+{{ $context.Values.__daemonset_yaml | toYaml }}
+  {{- end }}
+{{- end }}
diff --git a/charts/ovn/requirements.lock b/charts/ovn/requirements.lock
index 4f63a87..b94dead 100644
--- a/charts/ovn/requirements.lock
+++ b/charts/ovn/requirements.lock
@@ -1,6 +1,6 @@
 dependencies:
 - name: helm-toolkit
   repository: https://tarballs.openstack.org/openstack-helm-infra
-  version: 0.2.69
-digest: sha256:f971f98746c97193da5ff7a44d2401ae7d91201a49ed9f23d52359a1b6e9d0ef
+  version: 0.2.78
+digest: sha256:760c5997580ac8d30a64dfe92d6a54052b783ddf90cacbc5a4c95c1330988742
 generated: "0001-01-01T00:00:00Z"
diff --git a/charts/ovn/requirements.yaml b/charts/ovn/requirements.yaml
index b3d5dcf..52e723e 100644
--- a/charts/ovn/requirements.yaml
+++ b/charts/ovn/requirements.yaml
@@ -1,4 +1,4 @@
 dependencies:
 - name: helm-toolkit
   repository: https://tarballs.openstack.org/openstack-helm-infra
-  version: 0.2.69
+  version: 0.2.78