Update charts to use service tokens
diff --git a/charts/cinder/Chart.yaml b/charts/cinder/Chart.yaml
index c00ca66..10c84ad 100644
--- a/charts/cinder/Chart.yaml
+++ b/charts/cinder/Chart.yaml
@@ -9,4 +9,4 @@
 sources:
 - https://opendev.org/openstack/cinder
 - https://opendev.org/openstack/openstack-helm
-version: 0.3.10
+version: 0.3.13
diff --git a/charts/cinder/charts/helm-toolkit/Chart.yaml b/charts/cinder/charts/helm-toolkit/Chart.yaml
index 7d3703e..e6aec81 100644
--- a/charts/cinder/charts/helm-toolkit/Chart.yaml
+++ b/charts/cinder/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.53
+version: 0.2.54
diff --git a/charts/cinder/charts/helm-toolkit/templates/utils/_dependency_resolver.tpl b/charts/cinder/charts/helm-toolkit/templates/utils/_dependency_resolver.tpl
index b99c00d..4a88dd8 100644
--- a/charts/cinder/charts/helm-toolkit/templates/utils/_dependency_resolver.tpl
+++ b/charts/cinder/charts/helm-toolkit/templates/utils/_dependency_resolver.tpl
@@ -27,10 +27,12 @@
 {{- else if kindIs "slice" $dependencyMixinParam }}
 {{- $_ := set $envAll.Values "__deps" ( index $envAll.Values.dependencies.static $dependencyKey ) }}
 {{- range $k, $v := $dependencyMixinParam -}}
+{{- if ( index $envAll.Values.dependencies.dynamic.targeted $v ) }}
 {{- $_ := include "helm-toolkit.utils.merge" (tuple $envAll.Values.pod_dependency $envAll.Values.__deps ( index $envAll.Values.dependencies.dynamic.targeted $v $dependencyKey ) ) -}}
 {{- $_ := set $envAll.Values "__deps" $envAll.Values.pod_dependency -}}
 {{- end }}
 {{- end }}
+{{- end }}
 {{- else -}}
 {{- $_ := set $envAll.Values "pod_dependency" ( index $envAll.Values.dependencies.static $dependencyKey ) -}}
 {{- end -}}
diff --git a/charts/cinder/requirements.lock b/charts/cinder/requirements.lock
index 55f5c36..e0ae56e 100644
--- a/charts/cinder/requirements.lock
+++ b/charts/cinder/requirements.lock
@@ -1,6 +1,6 @@
 dependencies:
 - name: helm-toolkit
   repository: file://../../openstack-helm-infra/helm-toolkit
-  version: 0.2.53
-digest: sha256:f8f4fbba6f638b79447f7e458933b07deb792ae30a14df5900bde542cf0e64a6
-generated: "2023-05-28T07:16:22.044422448Z"
+  version: 0.2.54
+digest: sha256:337a0f1ffb3eae591150b305c22293d85fb8c18abec78f56672de4f3ada2faae
+generated: "2023-09-01T14:09:20.122224919Z"
diff --git a/charts/cinder/values.yaml b/charts/cinder/values.yaml
index 07adee1..28c2dc6 100644
--- a/charts/cinder/values.yaml
+++ b/charts/cinder/values.yaml
@@ -826,6 +826,8 @@
     database:
       max_retries: -1
     keystone_authtoken:
+      service_token_roles: service
+      service_token_roles_required: true
       auth_version: v3
       auth_type: password
       memcache_security_strategy: ENCRYPT
@@ -848,7 +850,7 @@
       backend_url: file:///var/lib/cinder/coordination
     service_user:
       auth_type: password
-      send_service_user_token: false
+      send_service_user_token: true
   logging:
     loggers:
       keys:
@@ -1224,7 +1226,7 @@
         user_domain_name: default
         project_domain_name: default
       cinder:
-        role: admin
+        role: admin,service
         region_name: RegionOne
         username: cinder
         password: password
diff --git a/charts/neutron/templates/bin/_neutron-netns-cleanup-cron.py.tpl b/charts/neutron/templates/bin/_neutron-netns-cleanup-cron.py.tpl
new file mode 100644
index 0000000..f4913ed
--- /dev/null
+++ b/charts/neutron/templates/bin/_neutron-netns-cleanup-cron.py.tpl
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+
+import sys
+import os
+import time
+import socket
+from neutron.common import config
+from oslo_config import cfg
+from oslo_concurrency import processutils
+from neutron.agent.linux import dhcp
+from neutron.agent.l3 import namespaces
+from neutron.agent.l3 import dvr_snat_ns
+from neutron.agent.l3 import dvr_fip_ns
+from neutron.cmd.netns_cleanup import setup_conf
+from neutron.cmd.netns_cleanup import unplug_device
+from neutron.cmd.netns_cleanup import eligible_for_deletion
+from neutron.conf.agent import common as agent_config
+from neutron.agent.linux import ip_lib
+from keystoneauth1.identity import v3
+from keystoneauth1 import session
+from neutronclient.neutron import client as neutron_client
+NS_PREFIXES = {'l3': [namespaces.NS_PREFIX, dvr_snat_ns.SNAT_NS_PREFIX,
+                      dvr_fip_ns.FIP_NS_PREFIX]}
+DHCP_NS_PREFIX = dhcp.NS_PREFIX
+
+def get_neutron_creds():
+    opts = {'auth_url': os.getenv('OS_AUTH_URL', 'https://keystone-api.openstack.svc.cluster.local:5000/v3'),
+        'password': os.getenv('OS_PASSWORD','nopassword'),
+        'project_domain_name': os.getenv('OS_PROJECT_DOMAIN_NAME', 'default'),
+        'project_name': os.getenv('OS_PROJECT_NAME', 'admin'),
+        'user_domain_name': os.getenv('OS_USER_DOMAIN_NAME', 'default'),
+        'username': os.getenv('OS_USERNAME', 'admin'),
+        'cafile' : os.getenv('OS_CACERT','/var/lib/neutron/openstack-helm/openstack-helm.crt'),
+        'insecure' : os.getenv('NEUTRON_CLEANUP_INSECURE', 'true'),
+        'debug': os.getenv('NEUTRON_CLEANUP_DEBUG', 'true'),
+        'wait': os.getenv('NEUTRON_CLEANUP_TIMEOUT', '600')}
+    return opts
+
+def ldestroy_namespace(conf, namespace):
+    try:
+        ip = ip_lib.IPWrapper(namespace=namespace)
+        if ip.netns.exists(namespace):
+            cmd = ['ip', 'netns', 'pids', namespace]
+            output = processutils.execute(*cmd, run_as_root=True, root_helper=conf.AGENT.root_helper)
+            for pid in output[0].splitlines():
+                utils.kill_process(pid, signal.SIGTERM, run_as_root=True, root_helper=conf.AGENT.root_helper)
+            for device in ip.get_devices():
+                unplug_device(device)
+        ip.garbage_collect_namespace()
+    except Exception as e:
+        sys.stderr.write("Error - unable to destroy namespace: {} : {}\n".format(namespace, e))
+
+def net_list(neutron_get):
+    hosts = dict()
+    net_list = neutron_get.list_networks()
+    if net_list['networks']:
+        for item in net_list['networks']:
+            net_id=item['id']
+            dhcp_agents = neutron_get.list_dhcp_agent_hosting_networks(net_id)['agents']
+            agents = list()
+            if dhcp_agents:
+                 for agent in dhcp_agents:
+                     agents.append(agent['host'].split('.')[0])
+            hosts[net_id] = agents
+    return hosts
+
+def sort_ns(all_ns, dhcp_prefix):
+    dhcp_ns = list()
+    not_dhcp_ns = list()
+    for ns in  all_ns:
+        if ns[:len(dhcp_prefix)] == dhcp_prefix:
+            dhcp_ns.append(ns)
+        else:
+            not_dhcp_ns.append(ns)
+    return dhcp_ns, not_dhcp_ns
+
+def del_bad_dhcp(dhcp_ns, dhcp_hosts, conf, dhcp_prefix, debug):
+    for ns in dhcp_ns:
+        cut_ns_name = ns[len(dhcp_prefix):]
+        if cut_ns_name in dhcp_hosts:
+            if hostname not in dhcp_hosts[cut_ns_name]:
+                ldestroy_namespace(conf, ns)
+                if debug:
+                    sys.stderr.write("DEBUG: {} host {} deleted {} because host wrong\n"
+                                     .format(sys.argv[0], hostname, ns))
+            else:
+                if debug:
+                    sys.stderr.write("DEBUG: {} host {} {} looks ok\n"
+                                     .format(sys.argv[0], hostname, ns))
+        else:
+            ldestroy_namespace(conf, ns)
+            if debug:
+                sys.stderr.write("DEBUG: {} host {} deleted {} because no related network found\n"
+                                 .format(sys.argv[0], hostname, ns))
+
+def del_bad_not_dhcp(not_dhcp_ns, conf, debug):
+    for ns in not_dhcp_ns:
+        if eligible_for_deletion(conf, ns, conf.force):
+            ldestroy_namespace(conf, ns)
+            if debug:
+                sys.stderr.write("DEBUG: {} host {} deleted {} because no IP addr\n"
+                                 .format(sys.argv[0], hostname, ns))
+
+if __name__ == "__main__":
+
+    conf = setup_conf()
+    cfg.CONF(sys.argv[1:])
+    opts = get_neutron_creds()
+    debug = False
+    verify= False
+    if opts.pop('debug') in ('true', '1', 'True'):
+        debug = True
+    insecure = opts.pop('insecure')
+    cafile = opts.pop('cafile')
+    if insecure in ('false', '0', 'False'):
+        verify = cafile
+    timeout = int(opts.pop('wait'))
+    conf()
+    config.setup_logging()
+    agent_config.setup_privsep()
+    auth = v3.Password(**opts)
+    hostname = socket.gethostname().split('.')[0]
+
+    while True:
+        try:
+            all_ns = ip_lib.list_network_namespaces()
+            sess = session.Session(auth=auth, verify=verify)
+            neutron_get = neutron_client.Client('2.0', session=sess)
+            dhcp_hosts = net_list(neutron_get)
+            if all_ns:
+                dhcp_ns, not_dhcp_ns = sort_ns(all_ns, DHCP_NS_PREFIX)
+                if dhcp_ns:
+                    del_bad_dhcp(dhcp_ns, dhcp_hosts, conf, DHCP_NS_PREFIX, debug)
+                else:
+                    if debug:
+                        sys.stderr.write("DEBUG: {} host {} no dhcp ns found\n"
+                                         .format(sys.argv[0], hostname))
+                if not_dhcp_ns:
+                    del_bad_not_dhcp(not_dhcp_ns, conf, debug)
+                else:
+                    if debug:
+                        sys.stderr.write("DEBUG: {} host {} no not_dhcp ns found\n"
+                                         .format(sys.argv[0], hostname))
+            else:
+                if debug:
+                    sys.stderr.write("DEBUG: {} host {} no ns found at all\n"
+                                     .format(sys.argv[0], hostname))
+        except Exception as ex:
+            sys.stderr.write(
+                "Cleaning network namespaces caught an exception %s"
+                % str(ex))
+            time.sleep(30)
+        except:
+            sys.stderr.write(
+                "Cleaning network namespaces caught an exception")
+            time.sleep(30)
+        time.sleep(timeout)
\ No newline at end of file
diff --git a/charts/placement/Chart.yaml b/charts/placement/Chart.yaml
index 188ccfb..fa4c4c2 100644
--- a/charts/placement/Chart.yaml
+++ b/charts/placement/Chart.yaml
@@ -9,4 +9,4 @@
 sources:
 - https://opendev.org/openstack/placement
 - https://opendev.org/openstack/openstack-helm
-version: 0.3.2
+version: 0.3.7
diff --git a/charts/placement/charts/helm-toolkit/Chart.yaml b/charts/placement/charts/helm-toolkit/Chart.yaml
index 404f380..e6aec81 100644
--- a/charts/placement/charts/helm-toolkit/Chart.yaml
+++ b/charts/placement/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.52
+version: 0.2.54
diff --git a/charts/placement/charts/helm-toolkit/templates/scripts/_db-init.py.tpl b/charts/placement/charts/helm-toolkit/templates/scripts/_db-init.py.tpl
index 4294d40..6027b95 100644
--- a/charts/placement/charts/helm-toolkit/templates/scripts/_db-init.py.tpl
+++ b/charts/placement/charts/helm-toolkit/templates/scripts/_db-init.py.tpl
@@ -133,8 +133,10 @@
 # Create DB User
 try:
     root_engine.execute(
-        "GRANT ALL ON `{0}`.* TO \'{1}\'@\'%%\' IDENTIFIED BY \'{2}\' {3}".format(
-            database, user, password, mysql_x509))
+        "CREATE USER IF NOT EXISTS \'{0}\'@\'%%\' IDENTIFIED BY \'{1}\' {2}".format(
+            user, password, mysql_x509))
+    root_engine.execute(
+        "GRANT ALL ON `{0}`.* TO \'{1}\'@\'%%\'".format(database, user))
     logger.info("Created user {0} for {1}".format(user, database))
 except:
     logger.critical("Could not create user {0} for {1}".format(user, database))
diff --git a/charts/placement/charts/helm-toolkit/templates/utils/_dependency_resolver.tpl b/charts/placement/charts/helm-toolkit/templates/utils/_dependency_resolver.tpl
index b99c00d..4a88dd8 100644
--- a/charts/placement/charts/helm-toolkit/templates/utils/_dependency_resolver.tpl
+++ b/charts/placement/charts/helm-toolkit/templates/utils/_dependency_resolver.tpl
@@ -27,10 +27,12 @@
 {{- else if kindIs "slice" $dependencyMixinParam }}
 {{- $_ := set $envAll.Values "__deps" ( index $envAll.Values.dependencies.static $dependencyKey ) }}
 {{- range $k, $v := $dependencyMixinParam -}}
+{{- if ( index $envAll.Values.dependencies.dynamic.targeted $v ) }}
 {{- $_ := include "helm-toolkit.utils.merge" (tuple $envAll.Values.pod_dependency $envAll.Values.__deps ( index $envAll.Values.dependencies.dynamic.targeted $v $dependencyKey ) ) -}}
 {{- $_ := set $envAll.Values "__deps" $envAll.Values.pod_dependency -}}
 {{- end }}
 {{- end }}
+{{- end }}
 {{- else -}}
 {{- $_ := set $envAll.Values "pod_dependency" ( index $envAll.Values.dependencies.static $dependencyKey ) -}}
 {{- end -}}
diff --git a/charts/placement/requirements.lock b/charts/placement/requirements.lock
index cbe09c9..9824cb6 100644
--- a/charts/placement/requirements.lock
+++ b/charts/placement/requirements.lock
@@ -1,6 +1,6 @@
 dependencies:
 - name: helm-toolkit
   repository: file://../../openstack-helm-infra/helm-toolkit
-  version: 0.2.52
-digest: sha256:fa4cf6491d7d370591b9751dbc9e761b5ae4bd1fdfda954f0acc240b187e0551
-generated: "2023-03-20T23:06:01.180245043Z"
+  version: 0.2.54
+digest: sha256:337a0f1ffb3eae591150b305c22293d85fb8c18abec78f56672de4f3ada2faae
+generated: "2023-09-01T14:09:25.657734667Z"
diff --git a/charts/placement/values.yaml b/charts/placement/values.yaml
index ff33660..4a702ac 100644
--- a/charts/placement/values.yaml
+++ b/charts/placement/values.yaml
@@ -82,9 +82,12 @@
     placement_database:
       connection: null
     keystone_authtoken:
+      service_token_roles: service
+      service_token_roles_required: true
       auth_version: v3
       auth_type: password
       memcache_security_strategy: ENCRYPT
+      service_type: placement
   logging:
     loggers:
       keys:
@@ -319,6 +322,9 @@
       - key: node-role.kubernetes.io/master
         operator: Exists
         effect: NoSchedule
+      - key: node-role.kubernetes.io/control-plane
+        operator: Exists
+        effect: NoSchedule
   mounts:
     placement:
       init_container: null
diff --git a/charts/placement/values_overrides/2023.1-ubuntu_focal.yaml b/charts/placement/values_overrides/2023.1-ubuntu_focal.yaml
new file mode 100644
index 0000000..b5804f9
--- /dev/null
+++ b/charts/placement/values_overrides/2023.1-ubuntu_focal.yaml
@@ -0,0 +1,19 @@
+---
+images:
+  pull_policy: IfNotPresent
+  tags:
+    placement: "docker.io/openstackhelm/placement:2023.1-ubuntu_focal"
+    ks_user: "docker.io/openstackhelm/heat:2023.1-ubuntu_focal"
+    ks_service: "docker.io/openstackhelm/heat:2023.1-ubuntu_focal"
+    ks_endpoints: "docker.io/openstackhelm/heat:2023.1-ubuntu_focal"
+    db_init: "docker.io/openstackhelm/heat:2023.1-ubuntu_focal"
+    db_drop: "docker.io/openstackhelm/heat:2023.1-ubuntu_focal"
+    placement_db_sync: "docker.io/openstackhelm/placement:2023.1-ubuntu_focal"
+    dep_check: "quay.io/airshipit/kubernetes-entrypoint:v1.0.0"
+    image_repo_sync: "docker.io/docker:17.07.0"
+dependencies:
+  static:
+    db_sync:
+      jobs:
+        - placement-db-init
+...
diff --git a/charts/placement/values_overrides/zed-ubuntu_focal.yaml b/charts/placement/values_overrides/zed-ubuntu_focal.yaml
new file mode 100644
index 0000000..901bc96
--- /dev/null
+++ b/charts/placement/values_overrides/zed-ubuntu_focal.yaml
@@ -0,0 +1,19 @@
+---
+images:
+  pull_policy: IfNotPresent
+  tags:
+    placement: "docker.io/openstackhelm/placement:zed-ubuntu_focal"
+    ks_user: "docker.io/openstackhelm/heat:zed-ubuntu_focal"
+    ks_service: "docker.io/openstackhelm/heat:zed-ubuntu_focal"
+    ks_endpoints: "docker.io/openstackhelm/heat:zed-ubuntu_focal"
+    db_init: "docker.io/openstackhelm/heat:zed-ubuntu_focal"
+    db_drop: "docker.io/openstackhelm/heat:zed-ubuntu_focal"
+    placement_db_sync: "docker.io/openstackhelm/placement:zed-ubuntu_focal"
+    dep_check: "quay.io/airshipit/kubernetes-entrypoint:v1.0.0"
+    image_repo_sync: "docker.io/docker:17.07.0"
+dependencies:
+  static:
+    db_sync:
+      jobs:
+        - placement-db-init
+...