Merge "[bgpvpn] Install plugin before database sync"
diff --git a/.kitchen.yml b/.kitchen.yml
index 222d4e0..2b5e840 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -27,6 +27,9 @@
     - name: keystone
       repo: git
       source: https://github.com/salt-formulas/salt-formula-keystone
+    - name: oslo_templates
+      repo: git
+      source: https://github.com/salt-formulas/salt-formula-oslo-templates
   state_top:
     base:
       "*":
diff --git a/README.rst b/README.rst
index f108a5b..42ad76b 100644
--- a/README.rst
+++ b/README.rst
@@ -853,6 +853,7 @@
           ovn:
             ovn_l3_scheduler: leastloaded # valid options: chance, leastloaded
             neutron_sync_mode: repair # valid options: log, off, repair
+            metadata_enabled: True
         ovn_ctl_opts:
           db-nb-create-insecure-remote: 'yes'
           db-sb-create-insecure-remote: 'yes'
@@ -868,6 +869,13 @@
         external_access: false
         backend:
           engine: ovn
+          ovsdb_connection: tcp:127.0.0.1:6640
+        metadata:
+          enabled: true
+          ovsdb_server_iface: ptcp:6640:127.0.0.1
+          host: 10.1.0.101
+          password: unsegreto
+
 
 Neutron L2 Gateway
 ----------------
diff --git a/metadata/service/compute/ovn/single.yml b/metadata/service/compute/ovn/single.yml
index 4697876..1665ac8 100644
--- a/metadata/service/compute/ovn/single.yml
+++ b/metadata/service/compute/ovn/single.yml
@@ -18,6 +18,12 @@
       external_bridge: ${_param:ovn_external_bridge}
       backend:
         engine: ovn
+        ovsdb_connection: tcp:127.0.0.1:6640
+      metadata:
+        enabled: true
+        ovsdb_server_iface: ptcp:6640:127.0.0.1
+        host: ${_param:cluster_vip_address}
+        password: ${_param:metadata_password}
       logging:
         log_appender: ${_param:openstack_log_appender}
         log_handlers:
diff --git a/neutron/agents/ovn_metadata.sls b/neutron/agents/ovn_metadata.sls
new file mode 100644
index 0000000..f2e755b
--- /dev/null
+++ b/neutron/agents/ovn_metadata.sls
@@ -0,0 +1,38 @@
+{%- from "neutron/map.jinja" import compute with context %}
+{%- if compute.metadata.enabled|default(False) %}
+
+/lib/systemd/system/ovn-metadata-agent.service:
+  file.managed:
+  - source: salt://neutron/files/{{ compute.version }}/ovn/metadata-agent.systemd
+
+/etc/neutron/plugins/ovn/metadata-agent.ini:
+  file.managed:
+  - source: salt://neutron/files/{{ compute.version }}/ovn/metadata-agent.ini
+  - template: jinja
+  - makedirs: true
+  - require:
+    - pkg: ovn_packages
+
+/etc/neutron/neutron.conf:
+  file.managed:
+  - source: salt://neutron/files/{{ compute.version }}/neutron-generic.conf
+  - template: jinja
+  - require:
+    - pkg: ovn_packages
+
+{%- if not grains.get('noservices', False) %}
+
+ovs_set_manager:
+  cmd.run:
+  - name: 'ovs-vsctl set-manager {{ compute.metadata.ovsdb_server_iface }}'
+  - unless: 'ovs-vsctl get-manager | fgrep -qx {{ compute.metadata.ovsdb_server_iface }}'
+
+ovn-metadata-agent:
+  service.running:
+  - enable: true
+  - watch:
+    - file: /etc/neutron/plugins/ovn/metadata-agent.ini
+    - file: /etc/neutron/neutron.conf
+
+{%- endif %}
+{%- endif %}
diff --git a/neutron/compute.sls b/neutron/compute.sls
index c831a37..5b1e3cf 100644
--- a/neutron/compute.sls
+++ b/neutron/compute.sls
@@ -93,6 +93,10 @@
   - require:
     - pkg: ovn_packages
     - sls: neutron._ssl.rabbitmq
+
+      {%- if compute.metadata is defined %}
+        {%- include "neutron/agents/ovn_metadata.sls" %}
+      {%- endif %}
     {%- endif %}
 
   {%- endif %}
diff --git a/neutron/files/queens/ml2_conf.ini b/neutron/files/queens/ml2_conf.ini
index 9bc6906..53b118b 100644
--- a/neutron/files/queens/ml2_conf.ini
+++ b/neutron/files/queens/ml2_conf.ini
@@ -249,6 +249,7 @@
 ovn_nb_connection = tcp:{{ server.controller_vip }}:6641
 ovn_sb_connection = tcp:{{ server.controller_vip }}:6642
 ovn_l3_scheduler = {{ _ovn.ovn_l3_scheduler|default('leastloaded') }}
+ovn_metadata_enabled = {{ _ovn.metadata_enabled|default('false') }}
 neutron_sync_mode = {{ _ovn.neutron_sync_mode|default('repair') }}
 enable_distributed_floating_ip = {{ server.dvr|default('false') }}
 {%- endif %}
diff --git a/neutron/files/queens/neutron-generic.conf b/neutron/files/queens/neutron-generic.conf
index 9b8c819..6025078 100644
--- a/neutron/files/queens/neutron-generic.conf
+++ b/neutron/files/queens/neutron-generic.conf
@@ -323,8 +323,10 @@
 {%- endif %}
 
 
+{%- if neutron.message_queue|default(none) is not none %}
 {%- set _data = neutron.message_queue %}
 {%- include "oslo_templates/files/queens/oslo/messaging/_default.conf" %}
+{%- endif %}
 
 {%- set _data = {} %}
 {%- include "oslo_templates/files/queens/oslo/service/_wsgi_default.conf" %}
@@ -417,7 +419,7 @@
 {%- include "oslo_templates/files/queens/oslo/_concurrency.conf" %}
 
 
-{%- if neutron.message_queue is defined %}
+{%- if neutron.message_queue|default(none) is not none %}
 {%- set _data = neutron.message_queue %}
 {%- if _data.engine == 'rabbitmq' %}
     {%- set messaging_engine = 'rabbit' %}
diff --git a/neutron/files/queens/ovn/metadata-agent.ini b/neutron/files/queens/ovn/metadata-agent.ini
new file mode 100644
index 0000000..8a65292
--- /dev/null
+++ b/neutron/files/queens/ovn/metadata-agent.ini
@@ -0,0 +1,97 @@
+{%- from "neutron/map.jinja" import compute with context -%}
+[DEFAULT]
+
+#
+# From networking_ovn.metadata.agent
+#
+
+# Location for Metadata Proxy UNIX domain socket. (string value)
+#metadata_proxy_socket = $state_path/metadata_proxy
+
+# User (uid or name) running metadata proxy after its initialization
+# (if empty: agent effective user). (string value)
+#metadata_proxy_user =
+
+# Group (gid or name) running metadata proxy after its initialization
+# (if empty: agent effective group). (string value)
+#metadata_proxy_group =
+
+# Name of Open vSwitch bridge to use (string value)
+#ovs_integration_bridge = br-int
+
+# Certificate Authority public key (CA cert) file for ssl (string
+# value)
+#auth_ca_cert = <None>
+
+# IP address or DNS name of Nova metadata server. (unknown value)
+# Deprecated group/name - [DEFAULT]/nova_metadata_ip
+nova_metadata_host = {{ compute.metadata.host }}
+
+# TCP Port used by Nova metadata server. (port value)
+# Minimum value: 0
+# Maximum value: 65535
+#nova_metadata_port = 8775
+
+# When proxying metadata requests, Neutron signs the Instance-ID
+# header with a shared secret to prevent spoofing. You may select any
+# string for a secret, but it must match here and in the configuration
+# used by the Nova Metadata Server. NOTE: Nova uses the same config
+# key, but in [neutron] section. (string value)
+metadata_proxy_shared_secret = {{ compute.metadata.password }}
+
+# Protocol to access nova metadata, http or https (string value)
+# Possible values:
+# http - <No description provided>
+# https - <No description provided>
+#nova_metadata_protocol = http
+
+# Allow to perform insecure SSL (https) requests to nova metadata
+# (boolean value)
+#nova_metadata_insecure = false
+
+# Client certificate for nova metadata api server. (string value)
+#nova_client_cert =
+
+# Private key of client certificate. (string value)
+#nova_client_priv_key =
+
+# Metadata Proxy UNIX domain socket mode, 4 values allowed: 'deduce':
+# deduce mode from metadata_proxy_user/group values, 'user': set
+# metadata proxy socket mode to 0o644, to use when metadata_proxy_user
+# is agent effective user or root, 'group': set metadata proxy socket
+# mode to 0o664, to use when metadata_proxy_group is agent effective
+# group or root, 'all': set metadata proxy socket mode to 0o666, to
+# use otherwise. (string value)
+# Possible values:
+# deduce - <No description provided>
+# user - <No description provided>
+# group - <No description provided>
+# all - <No description provided>
+#metadata_proxy_socket_mode = deduce
+
+# Number of separate worker processes for metadata server (defaults to
+# half of the number of CPUs) (integer value)
+#metadata_workers = 16
+
+# Number of backlog requests to configure the metadata server socket
+# with (integer value)
+#metadata_backlog = 4096
+
+[ovs]
+
+#
+# From networking_ovn.metadata.agent
+#
+
+# The connection string for the native OVSDB backend.
+# Use tcp:IP:PORT for TCP connection.
+# Use unix:FILE for unix domain socket connection. (string value)
+#ovsdb_connection = unix:/usr/local/var/run/openvswitch/db.sock
+
+# Timeout in seconds for the OVSDB connection transaction (integer
+# value)
+#ovsdb_connection_timeout = 180
+
+[ovn]
+
+ovn_sb_connection = tcp:{{ compute.controller_vip }}:6642
diff --git a/neutron/files/queens/ovn/metadata-agent.systemd b/neutron/files/queens/ovn/metadata-agent.systemd
new file mode 100644
index 0000000..552f7d7
--- /dev/null
+++ b/neutron/files/queens/ovn/metadata-agent.systemd
@@ -0,0 +1,22 @@
+[Unit]
+Description=OpenStack Networking OVN Metadata Agent
+After=rsyslog.target networking.target openvswitch-switch.service
+Requires=openvswitch-switch.service
+
+[Service]
+Type=simple
+User=neutron
+Group=neutron
+PermissionsStartOnly=true
+WorkingDirectory=/var/lib/neutron
+ExecStartPre=/bin/mkdir -p /var/lock/neutron /var/log/neutron /var/lib/neutron
+ExecStartPre=/bin/chown neutron:neutron /var/lock/neutron /var/lib/neutron
+ExecStartPre=/bin/chown neutron:adm /var/log/neutron
+ExecStart=/usr/bin/networking-ovn-metadata-agent --config-file /etc/neutron/plugins/ovn/metadata-agent.ini --config-file /etc/neutron/neutron.conf --log-file /var/log/neutron/ovn-metadata-agent.log
+PrivateTmp=false
+KillMode=process
+Restart=on-failure
+TimeoutStopSec=15
+
+[Install]
+WantedBy=multi-user.target
diff --git a/neutron/map.jinja b/neutron/map.jinja
index d4004a1..8070183 100644
--- a/neutron/map.jinja
+++ b/neutron/map.jinja
@@ -6,11 +6,18 @@
     'enabled': false }
 %}
 
+{%- if grains.os_family == "Debian" %}
+{%- set compute_pkgs_ovn = ['ovn-common', 'ovn-host'] %}
+{%- if pillar.neutron.compute is defined and pillar.neutron.compute.metadata is defined %}
+{%- do compute_pkgs_ovn.extend(['neutron-common', 'python-networking-ovn', 'haproxy']) %}
+{%- endif %}
+{%- endif %}
+
 {% set compute = salt['grains.filter_by']({
     'BaseDefaults': default_params,
     'Debian': {
         'pkgs': ['neutron-openvswitch-agent', 'python-pycadf'],
-        'pkgs_ovn': ['ovn-common', 'ovn-host'],
+        'pkgs_ovn': compute_pkgs_ovn,
         'pkgs_bagpipe': ['python-networking-bagpipe'],
         'services': ['neutron-openvswitch-agent'],
         'services_ovn': ['ovn-host'],
diff --git a/tests/pillar/compute_ovn.sls b/tests/pillar/compute_ovn.sls
index 0f4b580..487faa3 100644
--- a/tests/pillar/compute_ovn.sls
+++ b/tests/pillar/compute_ovn.sls
@@ -1,9 +1,23 @@
 neutron:
   compute:
     enabled: true
-    version: ocata
+    version: queens
     local_ip: 10.2.0.105
     controller_vip: 10.1.0.101
     external_access: false
     backend:
       engine: ovn
+      ovsdb_connection: tcp:127.0.0.1:6640
+    metadata:
+      enabled: true
+      ovsdb_server_iface: ptcp:6640:127.0.0.1
+      host: 10.1.0.101
+      password: unsegreto
+linux:
+  system:
+    enabled: true
+    repo:
+      mirantis_openstack_queens:
+        source: "deb http://mirror.fuel-infra.org/mcp-repos/queens/xenial queens main"
+        architectures: amd64
+        key_url: "http://mirror.fuel-infra.org/mcp-repos/queens/xenial/archive-mcpqueens.key"
diff --git a/tests/pillar/control_ovn.sls b/tests/pillar/control_ovn.sls
index 9d4794b..f5348fa 100644
--- a/tests/pillar/control_ovn.sls
+++ b/tests/pillar/control_ovn.sls
@@ -1,7 +1,7 @@
 neutron:
   server:
     enabled: true
-    version: ocata
+    version: queens
     api_workers: 2
     rpc_workers: 2
     rpc_state_report_workers: 2
@@ -15,6 +15,7 @@
       ovn:
         ovn_l3_scheduler: chance
         neutron_sync_mode: off
+        metadata_enabled: true
     controller_vip: 172.16.10.101
     dvr: false
     l3_ha: false
@@ -60,7 +61,7 @@
   system:
     enabled: true
     repo:
-      mirantis_openstack_ocata:
-        source: "deb http://mirror.fuel-infra.org/mcp-repos/ocata/xenial ocata main"
+      mirantis_openstack_queens:
+        source: "deb http://mirror.fuel-infra.org/mcp-repos/queens/xenial queens main"
         architectures: amd64
-        key_url: "http://mirror.fuel-infra.org/mcp-repos/ocata/xenial/archive-mcpocata.key"
+        key_url: "http://mirror.fuel-infra.org/mcp-repos/queens/xenial/archive-mcpqueens.key"