[ATMOSPHERE-492] chore: Bump neutron to 0.3.47 (#2005)

This is an automated cherry-pick of #1957
/assign ricolin
Depends-On: #2028
diff --git a/.charts.yml b/.charts.yml
index 4c3e371..c1d443e 100644
--- a/.charts.yml
+++ b/.charts.yml
@@ -139,13 +139,13 @@
     repository: *openstack_helm_infra_repository
     dependencies: *openstack_helm_dependencies
   - name: neutron
-    version: 0.3.42
+    version: 0.3.47
     repository: *openstack_helm_repository
     dependencies: *openstack_helm_dependencies
     patches:
       gerrit:
         review.opendev.org:
-          - 916862
+          - 931781
   - name: node-feature-discovery
     version: 0.15.4
     repository:
diff --git a/charts/neutron/Chart.yaml b/charts/neutron/Chart.yaml
index c30e7af..6ca7ef0 100644
--- a/charts/neutron/Chart.yaml
+++ b/charts/neutron/Chart.yaml
@@ -9,4 +9,4 @@
 sources:
 - https://opendev.org/openstack/neutron
 - https://opendev.org/openstack/openstack-helm
-version: 0.3.42
+version: 0.3.47
diff --git a/charts/neutron/templates/bin/_neutron-ovn-vpn-agent-init.sh.tpl b/charts/neutron/templates/bin/_neutron-ovn-vpn-agent-init.sh.tpl
new file mode 100644
index 0000000..5b6ce43
--- /dev/null
+++ b/charts/neutron/templates/bin/_neutron-ovn-vpn-agent-init.sh.tpl
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+{{/*
+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.
+*/}}
+
+set -ex
+
+chown ${NEUTRON_USER_UID} /var/lib/neutron/openstack-helm
+
+{{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }}
+mkdir -p /tmp/pod-shared
+tee > /tmp/pod-shared/neutron-agent.ini << EOF
+[DEFAULT]
+host = $(hostname --fqdn)
+EOF
+{{- end }}
diff --git a/charts/neutron/templates/bin/_neutron-ovn-vpn-agent.sh.tpl b/charts/neutron/templates/bin/_neutron-ovn-vpn-agent.sh.tpl
new file mode 100644
index 0000000..3a248bf
--- /dev/null
+++ b/charts/neutron/templates/bin/_neutron-ovn-vpn-agent.sh.tpl
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+{{/*
+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.
+*/}}
+
+set -x
+
+exec neutron-ovn-vpn-agent \
+      --config-file /etc/neutron/neutron.conf \
+      --config-file /etc/neutron/neutron_vpnaas.conf \
+      --config-file /etc/neutron/neutron_ovn_vpn_agent.ini \
+{{- if and ( empty .Values.conf.neutron.DEFAULT.host ) ( .Values.pod.use_fqdn.neutron_agent ) }}
+  --config-file /tmp/pod-shared/neutron-agent.ini \
+{{- end }}
+      --config-file /tmp/pod-shared/ovn.ini
+
diff --git a/charts/neutron/templates/configmap-bin.yaml b/charts/neutron/templates/configmap-bin.yaml
index b6ad4af..2032b15 100644
--- a/charts/neutron/templates/configmap-bin.yaml
+++ b/charts/neutron/templates/configmap-bin.yaml
@@ -111,6 +111,10 @@
 {{ tuple "bin/_neutron-ovn-metadata-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
   neutron-ovn-init.sh: |
 {{ tuple "bin/_neutron-ovn-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
+  neutron-ovn-vpn-agent-init.sh: |
+{{ tuple "bin/_neutron-ovn-vpn-agent-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
+  neutron-ovn-vpn-agent.sh: |
+{{ tuple "bin/_neutron-ovn-vpn-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
 {{- else }}
   neutron-metadata-agent.sh: |
 {{ tuple "bin/_neutron-metadata-agent.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }}
diff --git a/charts/neutron/templates/configmap-etc.yaml b/charts/neutron/templates/configmap-etc.yaml
index bd52753..82865c0 100644
--- a/charts/neutron/templates/configmap-etc.yaml
+++ b/charts/neutron/templates/configmap-etc.yaml
@@ -265,6 +265,9 @@
 {{- if empty .Values.conf.neutron.ironic.password -}}
 {{- $_ := set .Values.conf.neutron.ironic "password" .Values.endpoints.identity.auth.ironic.password -}}
 {{- end -}}
+{{- if empty $envAll.Values.conf.neutron.ironic.auth_url -}}
+{{- $_ := tuple "identity" "internal" "api" . | include "helm-toolkit.endpoints.keystone_endpoint_uri_lookup"| set $envAll.Values.conf.neutron.ironic "auth_url" -}}
+{{- end }}
 {{- end -}}
 
 {{- if ( has "tungstenfabric" .Values.network.backend ) -}}
@@ -327,12 +330,14 @@
   neutron_sudoers: {{ $envAll.Values.conf.neutron_sudoers | b64enc }}
   rootwrap.conf: {{ $envAll.Values.conf.rootwrap | b64enc }}
   auto_bridge_add: {{ toJson $envAll.Values.conf.auto_bridge_add | b64enc }}
+  neutron_vpnaas.conf: {{ default "\"\"" (include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.neutron_vpnaas | b64enc) }}
 {{- if .Values.conf.netoffload.enabled }}
   netoffload: {{ toJson $envAll.Values.conf.netoffload | b64enc }}
 {{- end }}
   dpdk.conf: {{ toJson $envAll.Values.conf.ovs_dpdk | b64enc }}
   update_dpdk_bond_config: {{ $envAll.Values.conf.ovs_dpdk.update_dpdk_bond_config | toString | b64enc }}
 {{- if ( has "ovn" .Values.network.backend ) }}
+  neutron_ovn_vpn_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.ovn_vpn_agent | b64enc }}
   ovn_metadata_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.ovn_metadata_agent | b64enc }}
 {{- else }}
   metadata_agent.ini: {{ include "helm-toolkit.utils.to_oslo_conf" $envAll.Values.conf.metadata_agent | b64enc }}
diff --git a/charts/neutron/templates/daemonset-neutron-ovn-vpn-agent.yaml b/charts/neutron/templates/daemonset-neutron-ovn-vpn-agent.yaml
new file mode 100644
index 0000000..fc6d805
--- /dev/null
+++ b/charts/neutron/templates/daemonset-neutron-ovn-vpn-agent.yaml
@@ -0,0 +1,261 @@
+{{/*
+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.
+*/}}
+
+{{- define "ovnVPNAgentReadinessProbeTemplate" }}
+exec:
+  command:
+    - python
+    - /tmp/health-probe.py
+    - --config-file
+    - /etc/neutron/neutron.conf
+    - --config-file
+    - /etc/neutron/neutron_vpnaas.conf
+    - --config-file
+    - /etc/neutron/neutron_ovn_vpn_agent.ini
+{{- if .Values.pod.use_fqdn.neutron_agent }}
+    - --use-fqdn
+{{- end }}
+{{- end }}
+{{- define "ovnVPNAgentLivenessProbeTemplate" }}
+exec:
+  command:
+    - python
+    - /tmp/health-probe.py
+    - --config-file
+    - /etc/neutron/neutron.conf
+    - --config-file
+    - /etc/neutron/neutron_vpnaas.conf
+    - --config-file
+    - /etc/neutron/neutron_ovn_vpn_agent.ini
+    - --liveness-probe
+{{- if .Values.pod.use_fqdn.neutron_agent }}
+    - --use-fqdn
+{{- end }}
+{{- end }}
+
+{{- define "neutron.ovn_vpn_agent.daemonset" }}
+{{- $daemonset := index . 0 }}
+{{- $configMapName := index . 1 }}
+{{- $serviceAccountName := index . 2 }}
+{{- $envAll := index . 3 }}
+{{- with $envAll }}
+
+{{- $mounts_ovn_vpn_agent := .Values.pod.mounts.ovn_vpn_agent.ovn_vpn_agent }}
+{{- $mounts_ovn_vpn_agent_init := .Values.pod.mounts.ovn_vpn_agent.init_container }}
+
+---
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  name: neutron-ovn-vpn-agent
+  annotations:
+    {{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" }}
+  labels:
+{{ tuple $envAll "neutron" "ovn-vpn-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }}
+spec:
+  selector:
+    matchLabels:
+{{ tuple $envAll "neutron" "ovn-vpn-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }}
+{{ tuple $envAll "ovn_vpn_agent" | include "helm-toolkit.snippets.kubernetes_upgrades_daemonset" | indent 2 }}
+  template:
+    metadata:
+      labels:
+{{ tuple $envAll "neutron" "ovn-vpn-agent" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }}
+      annotations:
+{{ tuple $envAll | include "helm-toolkit.snippets.release_uuid" | indent 8 }}
+        configmap-bin-hash: {{ tuple "configmap-bin.yaml" . | include "helm-toolkit.utils.hash" }}
+        configmap-etc-hash: {{ tuple "configmap-etc.yaml" . | include "helm-toolkit.utils.hash" }}
+    spec:
+{{ dict "envAll" $envAll "application" "ovn_vpn_agent" | include "helm-toolkit.snippets.kubernetes_pod_security_context" | indent 6 }}
+      serviceAccountName: {{ $serviceAccountName }}
+{{ if $envAll.Values.pod.tolerations.neutron.enabled }}
+{{ tuple $envAll "neutron" | include "helm-toolkit.snippets.kubernetes_tolerations" | indent 6 }}
+{{ end }}
+      nodeSelector:
+        {{ .Values.labels.agent.ovn_vpn.node_selector_key }}: {{ .Values.labels.agent.ovn_vpn.node_selector_value }}
+      dnsPolicy: ClusterFirstWithHostNet
+      hostNetwork: true
+      {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "10" ) }}
+      shareProcessNamespace: true
+      {{- else }}
+      hostPID: true
+      {{- end }}
+      initContainers:
+{{ tuple $envAll "pod_dependency" $mounts_ovn_vpn_agent_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }}
+        - name: ovn-vpn-agent-init
+{{ tuple $envAll "neutron_ovn_vpn" | include "helm-toolkit.snippets.image" | indent 10 }}
+{{ tuple $envAll $envAll.Values.pod.resources.agent.ovn_vpn | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+{{ dict "envAll" $envAll "application" "ovn_vpn_agent" "container" "ovn_vpn_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
+          env:
+            - name: NEUTRON_USER_UID
+              value: "{{ .Values.pod.security_context.ovn_vpn_agent.pod.runAsUser }}"
+          command:
+            - /tmp/neutron-ovn-vpn-agent-init.sh
+          volumeMounts:
+            - name: pod-tmp
+              mountPath: /tmp
+            - name: neutron-bin
+              mountPath: /tmp/neutron-ovn-vpn-agent-init.sh
+              subPath: neutron-ovn-vpn-agent-init.sh
+              readOnly: true
+            - name: neutron-etc
+              mountPath: /etc/neutron/neutron.conf
+              subPath: neutron.conf
+              readOnly: true
+            - name: socket
+              mountPath: /var/lib/neutron/openstack-helm
+        - name: ovn-neutron-init
+{{ tuple $envAll "neutron_ovn_vpn" | include "helm-toolkit.snippets.image" | indent 10 }}
+{{ tuple $envAll $envAll.Values.pod.resources.agent.ovn_vpn | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+{{ dict "envAll" $envAll "application" "ovn_vpn_agent" "container" "ovn_vpn_agent_init" | include "helm-toolkit.snippets.kubernetes_container_security_context" | indent 10 }}
+          command:
+            - /tmp/neutron-ovn-init.sh
+          volumeMounts:
+            - name: pod-tmp
+              mountPath: /tmp
+            - name: neutron-bin
+              mountPath: /tmp/neutron-ovn-init.sh
+              subPath: neutron-ovn-init.sh
+              readOnly: true
+      containers:
+        - name: neutron-ovn-vpn-agent
+{{ tuple $envAll "neutron_ovn_vpn" | include "helm-toolkit.snippets.image" | indent 10 }}
+{{ tuple $envAll $envAll.Values.pod.resources.agent.ovn_vpn | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }}
+          env:
+            - name: RPC_PROBE_TIMEOUT
+              value: "{{ .Values.pod.probes.rpc_timeout }}"
+            - name: RPC_PROBE_RETRIES
+              value: "{{ .Values.pod.probes.rpc_retries }}"
+{{ dict "envAll" $envAll "component" "ovn_vpn_agent" "container" "ovn_vpn_agent" "type" "readiness" "probeTemplate" (include "ovnVPNAgentReadinessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }}
+{{ dict "envAll" $envAll "component" "ovn_vpn_agent" "container" "ovn_vpn_agent" "type" "liveness" "probeTemplate" (include "ovnVPNAgentLivenessProbeTemplate" $envAll | fromYaml) | include "helm-toolkit.snippets.kubernetes_probe" | indent 10 }}
+          securityContext:
+            privileged: true
+          command:
+            - /tmp/neutron-ovn-vpn-agent.sh
+          volumeMounts:
+            - name: run
+              mountPath: /run
+            - name: pod-tmp
+              mountPath: /tmp
+            - name: pod-var-neutron
+              mountPath: {{ .Values.conf.neutron.DEFAULT.state_path }}
+            - name: neutron-bin
+              mountPath: /tmp/neutron-ovn-vpn-agent.sh
+              subPath: neutron-ovn-vpn-agent.sh
+              readOnly: true
+            - name: neutron-bin
+              mountPath: /tmp/health-probe.py
+              subPath: health-probe.py
+              readOnly: true
+            - name: neutron-etc
+              mountPath: /etc/neutron/neutron.conf
+              subPath: neutron.conf
+              readOnly: true
+            {{- if .Values.conf.neutron.DEFAULT.log_config_append }}
+            - name: neutron-etc
+              mountPath: {{ .Values.conf.neutron.DEFAULT.log_config_append }}
+              subPath: {{ base .Values.conf.neutron.DEFAULT.log_config_append }}
+              readOnly: true
+            {{- end }}
+            - name: neutron-etc
+              mountPath: /etc/neutron/plugins/ml2/ml2_conf.ini
+              subPath: ml2_conf.ini
+              readOnly: true
+            {{- if ( has "openvswitch" .Values.network.backend ) }}
+            - name: neutron-etc
+              mountPath: /etc/neutron/plugins/ml2/openvswitch_agent.ini
+              subPath: openvswitch_agent.ini
+              readOnly: true
+            {{- end }}
+            - name: neutron-etc
+              mountPath: /etc/neutron/neutron_vpnaas.conf
+              subPath: neutron_vpnaas.conf
+              readOnly: true
+            - name: neutron-etc
+              mountPath: /etc/neutron/neutron_ovn_vpn_agent.ini
+              subPath: neutron_ovn_vpn_agent.ini
+              readOnly: true
+            - name: neutron-etc
+              # NOTE (Portdirect): We mount here to override Kollas
+              # custom sudoers file when using Kolla images, this
+              # location will also work fine for other images.
+              mountPath: /etc/sudoers.d/kolla_neutron_sudoers
+              subPath: neutron_sudoers
+              readOnly: true
+            - name: neutron-etc
+              mountPath: /etc/neutron/rootwrap.conf
+              subPath: rootwrap.conf
+              readOnly: true
+            {{- range $key, $value := $envAll.Values.conf.rootwrap_filters }}
+            {{- if ( has "ovn_vpn_agent" $value.pods ) }}
+            {{- $filePrefix := replace "_" "-"  $key }}
+            {{- $rootwrapFile := printf "/etc/neutron/rootwrap.d/%s.filters" $filePrefix }}
+            - name: neutron-etc
+              mountPath: {{ $rootwrapFile }}
+              subPath: {{ base $rootwrapFile }}
+              readOnly: true
+            {{- end }}
+            {{- end }}
+            - name: socket
+              mountPath: /var/lib/neutron/openstack-helm
+            {{- if .Values.network.share_namespaces }}
+            - name: host-run-netns
+              mountPath: /run/netns
+              mountPropagation: Bidirectional
+            {{- end }}
+{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }}
+{{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal "path" "/etc/rabbitmq/certs" | include "helm-toolkit.snippets.tls_volume_mount" | indent 12 }}
+{{ if $mounts_ovn_vpn_agent.volumeMounts }}{{ toYaml $mounts_ovn_vpn_agent.volumeMounts | indent 12 }}{{ end }}
+      volumes:
+        - name: pod-tmp
+          emptyDir: {}
+        - name: pod-var-neutron
+          emptyDir: {}
+        - name: run
+          hostPath:
+            path: /run
+        - name: neutron-bin
+          configMap:
+            name: neutron-bin
+            defaultMode: 0555
+        - name: neutron-etc
+          secret:
+            secretName: {{ $configMapName }}
+            defaultMode: 0444
+        - name: socket
+          hostPath:
+            path: /var/lib/neutron/openstack-helm
+        {{- if .Values.network.share_namespaces }}
+        - name: host-run-netns
+          hostPath:
+            path: /run/netns
+        {{- end }}
+{{- dict "enabled" .Values.manifests.certificates "name" .Values.secrets.tls.compute_metadata.metadata.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }}
+{{- dict "enabled" $envAll.Values.manifests.certificates "name" $envAll.Values.endpoints.oslo_messaging.auth.admin.secret.tls.internal | include "helm-toolkit.snippets.tls_volume" | indent 8 }}
+{{ if $mounts_ovn_vpn_agent.volumes }}{{ toYaml $mounts_ovn_vpn_agent.volumes | indent 8 }}{{ end }}
+{{- end }}
+{{- end }}
+
+{{- if .Values.manifests.daemonset_ovn_vpn_agent }}
+{{- $envAll := . }}
+{{- $daemonset := "ovn-vpn-agent" }}
+{{- $configMapName := "neutron-etc" }}
+{{- $serviceAccountName := "neutron-ovn-vpn-agent" }}
+{{- $dependencyOpts := dict "envAll" $envAll "dependencyMixinParam" $envAll.Values.network.backend "dependencyKey" "ovn_vpn_agent" -}}
+{{- $_ := include "helm-toolkit.utils.dependency_resolver" $dependencyOpts | toString | fromYaml }}
+{{ tuple $envAll "pod_dependency" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }}
+{{- $daemonset_yaml := list $daemonset $configMapName $serviceAccountName . | include "neutron.ovn_vpn_agent.daemonset" | toString | fromYaml }}
+{{- $configmap_yaml := "neutron.configmap.etc" }}
+{{- list $daemonset $daemonset_yaml $configmap_yaml $configMapName . | include "helm-toolkit.utils.daemonset_overrides" }}
+{{- end }}
diff --git a/charts/neutron/values.yaml b/charts/neutron/values.yaml
index cd3889b..819d785 100644
--- a/charts/neutron/values.yaml
+++ b/charts/neutron/values.yaml
@@ -37,6 +37,7 @@
     neutron_dhcp: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
     neutron_metadata: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
     neutron_ovn_metadata: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
+    neutron_ovn_vpn: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
     neutron_l3: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
     neutron_l2gw: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
     neutron_openvswitch_agent: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
@@ -47,7 +48,7 @@
     neutron_bgp_dragent: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
     neutron_ironic_agent: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
     neutron_netns_cleanup_cron: docker.io/openstackhelm/neutron:2024.1-ubuntu_jammy
-    dep_check: quay.io/airshipit/kubernetes-entrypoint:v1.0.0
+    dep_check: quay.io/airshipit/kubernetes-entrypoint:latest-ubuntu_focal
     image_repo_sync: docker.io/docker:17.07.0
   pull_policy: "IfNotPresent"
   local_registry:
@@ -70,6 +71,9 @@
     l2gw:
       node_selector_key: openstack-control-plane
       node_selector_value: enabled
+    ovn_vpn:
+      node_selector_key: openstack-control-plane
+      node_selector_value: enabled
   job:
     node_selector_key: openstack-control-plane
     node_selector_value: enabled
@@ -305,6 +309,17 @@
           service: compute_metadata
         - endpoint: internal
           service: network
+    ovn_vpn_agent:
+      pod:
+        - requireSameNode: true
+          labels:
+            application: ovn
+            component: ovn-controller
+      services:
+        - endpoint: internal
+          service: oslo_messaging
+        - endpoint: internal
+          service: network
     ovs_agent:
       jobs:
         - neutron-rabbit-init
@@ -426,6 +441,20 @@
             initialDelaySeconds: 120
             periodSeconds: 600
             timeoutSeconds: 580
+    ovn_vpn_agent:
+      ovn_vpn_agent:
+        readiness:
+          enabled: true
+          params:
+            initialDelaySeconds: 30
+            periodSeconds: 190
+            timeoutSeconds: 185
+        liveness:
+          enabled: true
+          params:
+            initialDelaySeconds: 120
+            periodSeconds: 600
+            timeoutSeconds: 580
     ovn_metadata_agent:
       ovn_metadata_agent:
         readiness:
@@ -586,6 +615,13 @@
         neutron_ovn_metadata_agent_init:
           runAsUser: 0
           readOnlyRootFilesystem: true
+    ovn_vpn_agent:
+      pod:
+        runAsUser: 42424
+      container:
+        ovn_vpn_agent_init:
+          runAsUser: 0
+          readOnlyRootFilesystem: true
     neutron_ovs_agent:
       pod:
         runAsUser: 42424
@@ -707,6 +743,11 @@
       neutron_ovn_metadata_agent:
         volumeMounts:
         volumes:
+    ovn_vpn_agent:
+      init_container: null
+      ovn_vpn_agent:
+        volumeMounts:
+        volumes:
     neutron_ovs_agent:
       init_container: null
       neutron_ovs_agent:
@@ -794,6 +835,10 @@
           enabled: true
           min_ready_seconds: 0
           max_unavailable: 1
+        ovn_vpn_agent:
+          enabled: true
+          min_ready_seconds: 0
+          max_unavailable: 1
         ovs_agent:
           enabled: true
           min_ready_seconds: 0
@@ -854,6 +899,13 @@
         limits:
           memory: "1024Mi"
           cpu: "2000m"
+      ovn_vpn:
+        requests:
+          memory: "128Mi"
+          cpu: "100m"
+        limits:
+          memory: "1024Mi"
+          cpu: "2000m"
       ovs:
         requests:
           memory: "128Mi"
@@ -1422,6 +1474,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
       content: |
@@ -1450,6 +1503,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
       content: |
@@ -1476,6 +1530,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
       content: |
@@ -1498,6 +1553,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
       content: |
@@ -1589,6 +1645,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
         - netns_cleanup_cron
@@ -1612,6 +1669,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
         - netns_cleanup_cron
@@ -1662,6 +1720,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
       content: |
@@ -1683,6 +1742,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
       content: |
@@ -1720,6 +1780,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
       content: |
@@ -1758,6 +1819,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
       content: |
@@ -1796,6 +1858,7 @@
         - lb_agent
         - metadata_agent
         - ovn_metadata_agent
+        - ovn_vpn_agent
         - ovs_agent
         - sriov_agent
         - netns_cleanup_cron
@@ -1939,6 +2002,8 @@
       endpoint_type: internal
       allow_reverse_dns_lookup: true
     ironic:
+      auth_type: password
+      auth_version: v3
       endpoint_type: internal
     keystone_authtoken:
       service_token_roles: service
@@ -2097,6 +2162,14 @@
       #dhcp-option=3,10.10.10.1
       #dhcp-option-force=26,1450
 
+  neutron_vpnaas: null
+  ovn_vpn_agent:
+    DEFAULT:
+      interface_driver: openvswitch
+    vpnagent:
+      vpn_device_driver: neutron_vpnaas.services.vpn.device_drivers.ovn_ipsec.OvnStrongSwanDriver
+    ovs:
+      ovsdb_connection: unix:/run/openvswitch/db.sock
   l3_agent:
     DEFAULT:
       # (NOTE)portdirect: if unset this is populated dyanmicly from the value in
@@ -2614,6 +2687,8 @@
   daemonset_bagpipe_bgp: false
   daemonset_bgp_dragent: false
   daemonset_netns_cleanup_cron: true
+  daemonset_ovn_metadata_agent: false
+  daemonset_ovn_vpn_agent: false
   deployment_ironic_agent: false
   deployment_server: true
   deployment_rpc_server: true
diff --git a/charts/patches/neutron/0001-fix-role-for-user.patch b/charts/patches/neutron/0001-fix-role-for-user.patch
deleted file mode 100644
index 0a05416..0000000
--- a/charts/patches/neutron/0001-fix-role-for-user.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git b/neutron/values.yaml a/charts/neutron/values.yaml
-index 747baa53..8d5e9446 100644
---- b/neutron/values.yaml
-+++ a/neutron/values.yaml
-@@ -2316,7 +2316,7 @@ endpoints:
-         user_domain_name: default
-         project_domain_name: default
-       neutron:
--        role: admin
-+        role: admin,service
-         region_name: RegionOne
-         username: neutron
-         password: password
diff --git a/roles/defaults/vars/main.yml b/roles/defaults/vars/main.yml
index 5835207..4afe501 100644
--- a/roles/defaults/vars/main.yml
+++ b/roles/defaults/vars/main.yml
@@ -151,6 +151,7 @@
   neutron_netns_cleanup_cron: "registry.atmosphere.dev/library/neutron:{{ atmosphere_release }}"
   neutron_openvswitch_agent: "registry.atmosphere.dev/library/neutron:{{ atmosphere_release }}"
   neutron_ovn_metadata: "registry.atmosphere.dev/library/neutron:{{ atmosphere_release }}"
+  neutron_ovn_vpn: "registry.atmosphere.dev/library/neutron:{{ atmosphere_release }}"
   neutron_server: "registry.atmosphere.dev/library/neutron:{{ atmosphere_release }}"
   neutron_rpc_server: "registry.atmosphere.dev/library/neutron:{{ atmosphere_release }}"
   neutron_sriov_agent_init: "registry.atmosphere.dev/library/neutron:{{ atmosphere_release }}"
diff --git a/roles/neutron/vars/main.yml b/roles/neutron/vars/main.yml
index d205166..8b6c043 100644
--- a/roles/neutron/vars/main.yml
+++ b/roles/neutron/vars/main.yml
@@ -32,6 +32,7 @@
         dhcp_agents_per_network: 3
         log_config_append: null
         rpc_workers: 8
+        rpc_response_timeout: 600
         service_plugins: qos,router,segments,trunk,vpnaas
         external_dns_driver: "{{ _neutron_external_dns_driver | default(omit) }}"
       cors:
@@ -87,12 +88,22 @@
   conf:
     neutron:
       DEFAULT:
-        service_plugins: qos,ovn-router,segments,trunk,log
+        service_plugins: qos,ovn-router,segments,trunk,log,ovn-vpnaas
       ovn:
         ovn_emit_need_to_frag: true
+      service_providers:
+        service_provider: VPN:strongswan:neutron_vpnaas.services.vpn.service_drivers.ovn_ipsec.IPsecOvnVPNDriver:default
     ovn_metadata_agent:
       DEFAULT:
         metadata_proxy_shared_secret: "{{ openstack_helm_endpoints['compute_metadata']['secret'] }}"
+    ovn_vpn_agent:
+      AGENT:
+        extensions: vpnaas
+      vpnagent:
+        vpn_device_driver: neutron_vpnaas.services.vpn.device_drivers.ovn_ipsec.OvnStrongSwanDriver
+    neutron_vpnaas:
+      service_providers:
+        service_provider: VPN:strongswan:neutron_vpnaas.services.vpn.service_drivers.ovn_ipsec.IPsecOvnVPNDriver:default
     plugins:
       ml2_conf:
         agent:
@@ -105,6 +116,7 @@
     daemonset_l3_agent: false
     daemonset_metadata_agent: false
     daemonset_ovn_metadata_agent: true
+    daemonset_ovn_vpn_agent: true
     daemonset_ovs_agent: false
     deployment_rpc_server: false
 
diff --git a/roles/tempest/vars/main.yml b/roles/tempest/vars/main.yml
index 39eb424..ea508f9 100644
--- a/roles/tempest/vars/main.yml
+++ b/roles/tempest/vars/main.yml
@@ -190,3 +190,5 @@
             - tag
             - trunk
             - trunk-details
+            - vpnaas
+            - vpn-endpoint-groups