Merge "Add support for n-g-s ml2 plugin"
diff --git a/.kitchen.yml b/.kitchen.yml
index 23c6f61..78a4834 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -42,7 +42,7 @@
           - linux_repo_openstack
           - neutron
   pillars-from-files:
-    linux_repo_openstack.sls: tests/pillar/repo_mos9.sls
+    linux_repo_openstack.sls: tests/pillar/repo_<%= ENV['OS_VERSION'] || 'mos9' %>.sls
 
 verifier:
   name: inspec
@@ -60,145 +60,270 @@
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_dpdk.sls
+      pillars:
+        release.sls:
+          neutron:
+            compute:
+              version: <%= ENV['OS_VERSION'] || 'mitaka' %>
 
   - name: compute_dvr
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_dvr.sls
+      pillars:
+        release.sls:
+          neutron:
+            compute:
+              version: <%= ENV['OS_VERSION'] || 'pike' %>
 
   - name: compute_dvr_fwaas_v1
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_dvr_fwaas_v1.sls
+      pillars:
+        release.sls:
+          neutron:
+            compute:
+              version: <%= ENV['OS_VERSION'] || 'ocata' %>
 
   - name: compute_legacy
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_legacy.sls
+      pillars:
+        release.sls:
+          neutron:
+            compute:
+              version: <%= ENV['OS_VERSION'] || 'mitaka' %>
 
   - name: compute_nonexternal_dvr
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_nonexternal_dvr.sls
+      pillars:
+        release.sls:
+          neutron:
+            compute:
+              version: <%= ENV['OS_VERSION'] || 'mitaka' %>
 
   - name: compute_sriov
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_sriov.sls
+      pillars:
+        release.sls:
+          neutron:
+            compute:
+              version: <%= ENV['OS_VERSION'] || 'mitaka' %>
+
 
   - name: compute_qos_sriov
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_qos_sriov.sls
+      pillars:
+        release.sls:
+          neutron:
+            compute:
+              version: <%= ENV['OS_VERSION'] || 'ocata' %>
 
   - name: compute_qos
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_qos.sls
+      pillars:
+        release.sls:
+          neutron:
+            compute:
+              version: <%= ENV['OS_VERSION'] || 'ocata' %>
 
   - name: compute_ovn
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_ovn.sls
+      release.sls:
+        neutron:
+          compute:
+            version: <%= ENV['OS_VERSION'] || 'queens' %>
 
   - name: compute_bgpvpn
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/compute_bgpvpn.sls
+      release.sls:
+        neutron:
+          compute:
+            version: <%= ENV['OS_VERSION'] || 'pike' %>
 
   - name: control_cluster
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_cluster.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'mitaka' %>
 
   - name: control_dvr
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_dvr.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'pike' %>
 
   - name: control_nodvr
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_nodvr.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'mitaka' %>
 
   - name: control_lbaas_octavia
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_lbaas_octavia.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'ocata' %>
 
   - name: control_fwaas_v1
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_fwaas_v1.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'ocata' %>
 
   - name: control_l2gw
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_l2gw.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'pike' %>
 
   - name: control_opendaylight
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_opendaylight.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'pike' %>
 
   - name: control_single
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_single.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'mitaka' %>
 
   - name: control_qos
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_qos.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'ocata' %>
 
   - name: control_ovn
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_ovn.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'queens' %>
 
   - name: control_bgpvpn
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_bgpvpn.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'pike' %>
 
   - name: control_sfc
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_sfc.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'queens' %>
 
   - name: gateway_dvr
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/gateway_dvr.sls
+      release.sls:
+        neutron:
+          gateway:
+            version: <%= ENV['OS_VERSION'] || 'pike' %>
 
   - name: gateway_legacy
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/gateway_legacy.sls
+      release.sls:
+        neutron:
+          gateway:
+            version: <%= ENV['OS_VERSION'] || 'mitaka' %>
 
   - name: gateway_qos
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/gateway_qos.sls
+      release.sls:
+        neutron:
+          gateway:
+            version: <%= ENV['OS_VERSION'] || 'ocata' %>
 
   - name: gateway_legacy_fwaas_v1
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/gateway_legacy_fwaas_v1.sls
+      release.sls:
+        neutron:
+          gateway:
+            version: <%= ENV['OS_VERSION'] || 'ocata' %>
 
   - name: gateway_legacy_l2gw
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/gateway_legacy_l2gw.sls
+      release.sls:
+        neutron:
+          gateway:
+            version: <%= ENV['OS_VERSION'] || 'pike' %>
 
   - name: gateway_legacy_opendaylight
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/gateway_legacy_opendaylight.sls
+      release.sls:
+        neutron:
+          gateway:
+            version: <%= ENV['OS_VERSION'] || 'pike' %>
 
   - name: control_dns
     provisioner:
       pillars-from-files:
         neutron.sls: tests/pillar/control_dns.sls
+      release.sls:
+        neutron:
+          server:
+            version: <%= ENV['OS_VERSION'] || 'ocata' %>
 
 # vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git a/.travis.yml b/.travis.yml
index 6d4f0c2..0984d89 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,32 +15,32 @@
   - bundle install
 
 env:
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=compute-dpdk
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=compute-dvr-fwaas-v1
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=compute-nonexternal-dvr
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=compute-qos-sriov
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=compute-ovn
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=control-cluster
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=control-nodvr
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=control-fwaas-v1
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=control-opendaylight
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=control-qos
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=gateway-dvr
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=gateway-qos
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 SUITE=gateway-legacy-l2gw
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=compute-dvr
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=compute-legacy
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=compute-sriov
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=compute-qos
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=control-dvr
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=control-lbaas-octavia
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=control-l2gw
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=control-single
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=control-ovn
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=gateway-dvr
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=gateway-legacy
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=gateway-legacy-fwaas-v1
-    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 SUITE=gateway-legacy-opendaylight
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=compute-dpdk
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=ocata SUITE=compute-dvr-fwaas-v1
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=compute-nonexternal-dvr
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=compute-qos-sriov
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=queens SUITE=compute-ovn
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=control-cluster
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=control-nodvr
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=ocata SUITE=control-fwaas-v1
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=control-opendaylight
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=control-qos
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=gateway-dvr
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=gateway-qos
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19 OS_VERSION=pike SUITE=gateway-legacy-l2gw
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=compute-dvr
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=compute-legacy
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=compute-sriov
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=compute-qos
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=control-dvr
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=control-lbaas-octavia
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=control-l2gw
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=control-single
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=queens SUITE=control-ovn
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=gateway-dvr
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=gateway-legacy
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=ocata SUITE=gateway-legacy-fwaas-v1
+    - PLATFORM=docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19 OS_VERSION=pike SUITE=gateway-legacy-opendaylight
 
 before_script:
   - set -o pipefail
diff --git a/_modules/neutronv2/__init__.py b/_modules/neutronv2/__init__.py
index e275af6..74b6fb1 100644
--- a/_modules/neutronv2/__init__.py
+++ b/_modules/neutronv2/__init__.py
@@ -12,6 +12,7 @@
 from neutronv2 import subnets
 from neutronv2 import agents
 from neutronv2 import routers
+from neutronv2 import ports
 from neutronv2 import common
 
 
@@ -61,6 +62,13 @@
 router_interface_add = routers.router_interface_add
 router_interface_remove = routers.router_interface_remove
 
+port_list = lists.port_list
+port_create = ports.port_create
+port_delete = ports.port_delete
+port_update = ports.port_update
+port_get_details = ports.port_get_details
+
+
 wait_for_network_services = agents.wait_for_network_services
 
 wait_for_api_ready = common.wait_for_api_ready
@@ -79,6 +87,7 @@
     'dhcp_agent_network_remove', 'dhcp_agent_network_schedule',
     'router_list', 'router_create', 'router_delete', 'router_get_details',
     'router_interface_add', 'router_interface_remove', 'router_update',
+    'port_create', 'port_delete', 'port_update', 'port_list', 'port_get_details',
 )
 
 
diff --git a/_modules/neutronv2/arg_converter.py b/_modules/neutronv2/arg_converter.py
index f2bc76d..99cb8fe 100644
--- a/_modules/neutronv2/arg_converter.py
+++ b/_modules/neutronv2/arg_converter.py
@@ -18,6 +18,7 @@
     'subnetpool': lists.subnetpool_list,
     'agent': lists.agent_list,
     'router': lists.router_list,
+    'port': lists.port_list,
 }
 
 
@@ -27,6 +28,7 @@
     'subnetpool': 'subnetpools',
     'agent': 'agents',
     'router': 'routers',
+    'port': 'ports',
 }
 
 
diff --git a/_modules/neutronv2/common.py b/_modules/neutronv2/common.py
index 6f3f56c..699c6d9 100644
--- a/_modules/neutronv2/common.py
+++ b/_modules/neutronv2/common.py
@@ -92,7 +92,7 @@
                       url, connect_retries=connect_retries,
                       **request_kwargs)
                 except Exception as e:
-                    if hasattr(e, 'http_status') and (e.http_status >= 500
+                    if not hasattr(e, 'http_status') or (e.http_status >= 500
                         or e.http_status == 0):
                         msg = ("Got retriable exception when contacting "
                                "Neutron API. Sleeping for %ss. Attepmpts "
diff --git a/_modules/neutronv2/lists.py b/_modules/neutronv2/lists.py
index 1b56392..eea4a7a 100644
--- a/_modules/neutronv2/lists.py
+++ b/_modules/neutronv2/lists.py
@@ -34,3 +34,9 @@
 def router_list(**kwargs):
     url = '/routers?{}'.format(urlencode(kwargs))
     return url, {}
+
+
+@send('get')
+def port_list(**kwargs):
+    url = '/ports?{}'.format(urlencode(kwargs))
+    return url, {}
\ No newline at end of file
diff --git a/_modules/neutronv2/ports.py b/_modules/neutronv2/ports.py
new file mode 100644
index 0000000..ab9482b
--- /dev/null
+++ b/_modules/neutronv2/ports.py
@@ -0,0 +1,40 @@
+from neutronv2.common import send
+from neutronv2.arg_converter import get_by_name_or_uuid_multiple
+
+try:
+    from urllib.parse import urlencode
+except ImportError:
+    from urllib import urlencode
+
+
+@get_by_name_or_uuid_multiple([('port', 'port_id')])
+@send('get')
+def port_get_details(port_id, **kwargs):
+    url = '/ports/{}?{}'.format(port_id, urlencode(kwargs))
+    return url, {}
+
+
+@get_by_name_or_uuid_multiple([('port', 'port_id')])
+@send('put')
+def port_update(port_id, **kwargs):
+    url = '/ports/{}'.format(port_id)
+    json = {
+        'port': kwargs,
+    }
+    return url, {'json': json}
+
+
+@get_by_name_or_uuid_multiple([('port', 'port_id')])
+@send('delete')
+def port_delete(port_id, **kwargs):
+    url = '/port/{}'.format(port_id)
+    return url, {}
+
+
+@send('post')
+def port_create(**kwargs):
+    url = '/ports'
+    json = {
+        'port': kwargs,
+    }
+    return url, {'json': json}
diff --git a/_states/neutronv2.py b/_states/neutronv2.py
index b4fd30d..81c8fa4 100644
--- a/_states/neutronv2.py
+++ b/_states/neutronv2.py
@@ -12,7 +12,7 @@
     return __salt__['neutronv2.{}'.format(fname)](*args, **kwargs)
 
 
-def _resource_present(resource, name, changeable_params, cloud_name, **kwargs):
+def _try_get_resource(resource, name, cloud_name):
     try:
         method_name = '{}_get_details'.format(resource)
         exact_resource = _neutronv2_call(
@@ -20,35 +20,58 @@
         )[resource]
     except Exception as e:
         if 'ResourceNotFound' in repr(e):
-            try:
-                method_name = '{}_create'.format(resource)
-                resp = _neutronv2_call(
-                    method_name, name=name, cloud_name=cloud_name, **kwargs
-                )
-            except Exception as e:
-                log.exception('Neutron {0} create failed with {1}'.
-                    format(resource, e))
-                return _failed('create', name, resource)
-            return _succeeded('create', name, resource, resp)
-        elif 'MultipleResourcesFound' in repr(e):
-            return _failed('find', name, resource)
+            return None
         else:
             raise
+    return exact_resource
+
+def _resource_present(resource, resource_name, changeable_params, cloud_name,
+                      **kwargs):
+    exact_resource = None
+    try:
+        exact_resource = _try_get_resource(resource, resource_name, cloud_name)
+        if exact_resource is None:
+            # in case of rename - check if resource was already renamed
+            if kwargs.get('name') is not None and kwargs.get(
+                    'name') != resource_name:
+                exact_resource = _try_get_resource(resource,
+                                                   kwargs.get('name'),
+                                                   cloud_name)
+    except Exception as e:
+        if 'MultipleResourcesFound' in repr(e):
+            return _failed('find', resource_name, resource)
+        else:
+            raise
+    if exact_resource is None:
+        try:
+            method_name = '{}_create'.format(resource)
+            exact_resource_name = kwargs.pop('name', resource_name)
+            resp = _neutronv2_call(
+                method_name, name=exact_resource_name,
+                cloud_name=cloud_name, **kwargs)
+        except Exception as e:
+            log.exception('Neutron {0} create failed with {1}'.
+                format(resource, e))
+            return _failed('create', exact_resource_name, resource)
+        return _succeeded('create', exact_resource_name, resource, resp)
 
     to_update = {}
     for key in kwargs:
         if key in changeable_params and (key not in exact_resource
                 or kwargs[key] != exact_resource[key]):
             to_update[key] = kwargs[key]
-    try:
-        method_name = '{}_update'.format(resource)
-        resp = _neutronv2_call(
-            method_name, name, cloud_name=cloud_name, **to_update
-        )
-    except Exception as e:
-        log.exception('Neutron {0} update failed with {1}'.format(resource, e))
-        return _failed('update', name, resource)
-    return _succeeded('update', name, resource, resp)
+    if to_update:
+        try:
+            method_name = '{}_update'.format(resource)
+            resp = _neutronv2_call(
+                method_name, resource_name, cloud_name=cloud_name, **to_update
+            )
+        except Exception as e:
+            log.exception('Neutron {0} update failed with {1}'.format(resource, e))
+            return _failed('update', resource_name, resource)
+        return _succeeded('update', resource_name, resource, resp)
+    else:
+        return _succeeded('no_changes', resource_name, resource)
 
 
 def _resource_absent(resource, name, cloud_name):
@@ -237,6 +260,17 @@
     return _succeeded('resources_moved', name, 'L3 agent')
 
 
+def port_present(port_name, cloud_name, **kwargs):
+    changeable = (
+        'name', 'description', 'device_id', 'qos_policy',
+        'allowed_address_pair', 'fixed_ip',
+        'device_owner', 'admin_state_up', 'security_group', 'extra_dhcp_opt',
+    )
+
+    return _resource_present('port', port_name, changeable,
+                             cloud_name, **kwargs)
+
+
 def _succeeded(op, name, resource, changes=None):
     msg_map = {
         'create': '{0} {1} created',
diff --git a/neutron/files/queens/sriov_agent.ini b/neutron/files/queens/sriov_agent.ini
new file mode 100644
index 0000000..734c7bd
--- /dev/null
+++ b/neutron/files/queens/sriov_agent.ini
@@ -0,0 +1,165 @@
+{%- if pillar.neutron.gateway is defined %}
+{%- from "neutron/map.jinja" import gateway as neutron with context %}
+{%- else %}
+{%- from "neutron/map.jinja" import compute as neutron with context %}
+{%- endif %}
+[DEFAULT]
+
+#
+# From oslo.log
+#
+
+# If set to true, the logging level will be set to DEBUG instead of the default
+# INFO level. (boolean value)
+# Note: This option can be changed without restarting.
+#debug = false
+
+# DEPRECATED: If set to false, the logging level will be set to WARNING instead
+# of the default INFO level. (boolean value)
+# This option is deprecated for removal.
+# Its value may be silently ignored in the future.
+#verbose = true
+
+# The name of a logging configuration file. This file is appended to any
+# existing logging configuration files. For details about logging configuration
+# files, see the Python logging module documentation. Note that when logging
+# configuration files are used then all logging configuration is set in the
+# configuration file and other logging configuration options are ignored (for
+# example, logging_context_format_string). (string value)
+# Note: This option can be changed without restarting.
+# Deprecated group/name - [DEFAULT]/log_config
+#log_config_append = <None>
+
+# Defines the format string for %%(asctime)s in log records. Default:
+# %(default)s . This option is ignored if log_config_append is set. (string
+# value)
+#log_date_format = %Y-%m-%d %H:%M:%S
+
+# (Optional) Name of log file to send logging output to. If no default is set,
+# logging will go to stderr as defined by use_stderr. This option is ignored if
+# log_config_append is set. (string value)
+# Deprecated group/name - [DEFAULT]/logfile
+#log_file = <None>
+
+# (Optional) The base directory used for relative log_file  paths. This option
+# is ignored if log_config_append is set. (string value)
+# Deprecated group/name - [DEFAULT]/logdir
+#log_dir = <None>
+
+# Uses logging handler designed to watch file system. When log file is moved or
+# removed this handler will open a new log file with specified path
+# instantaneously. It makes sense only if log_file option is specified and
+# Linux platform is used. This option is ignored if log_config_append is set.
+# (boolean value)
+#watch_log_file = false
+
+# Use syslog for logging. Existing syslog format is DEPRECATED and will be
+# changed later to honor RFC5424. This option is ignored if log_config_append
+# is set. (boolean value)
+#use_syslog = false
+
+# Syslog facility to receive log lines. This option is ignored if
+# log_config_append is set. (string value)
+#syslog_log_facility = LOG_USER
+
+# Log output to standard error. This option is ignored if log_config_append is
+# set. (boolean value)
+#use_stderr = false
+
+# Format string to use for log messages with context. (string value)
+#logging_context_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s
+
+# Format string to use for log messages when context is undefined. (string
+# value)
+#logging_default_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s
+
+# Additional data to append to log message when logging level for the message
+# is DEBUG. (string value)
+#logging_debug_format_suffix = %(funcName)s %(pathname)s:%(lineno)d
+
+# Prefix each line of exception output with this format. (string value)
+#logging_exception_prefix = %(asctime)s.%(msecs)03d %(process)d ERROR %(name)s %(instance)s
+
+# Defines the format string for %(user_identity)s that is used in
+# logging_context_format_string. (string value)
+#logging_user_identity_format = %(user)s %(tenant)s %(domain)s %(user_domain)s %(project_domain)s
+
+# List of package logging levels in logger=LEVEL pairs. This option is ignored
+# if log_config_append is set. (list value)
+#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO
+
+# Enables or disables publication of error events. (boolean value)
+#publish_errors = false
+
+# The format for an instance that is passed with the log message. (string
+# value)
+#instance_format = "[instance: %(uuid)s] "
+
+# The format for an instance UUID that is passed with the log message. (string
+# value)
+#instance_uuid_format = "[instance: %(uuid)s] "
+
+# Interval, number of seconds, of log rate limiting. (integer value)
+#rate_limit_interval = 0
+
+# Maximum number of logged messages per rate_limit_interval. (integer value)
+#rate_limit_burst = 0
+
+# Log level name used by rate limiting: CRITICAL, ERROR, INFO, WARNING, DEBUG
+# or empty string. Logs with level greater or equal to rate_limit_except_level
+# are not filtered. An empty string means that all levels are filtered. (string
+# value)
+#rate_limit_except_level = CRITICAL
+
+# Enables or disables fatal status of deprecations. (boolean value)
+#fatal_deprecations = false
+
+
+[agent]
+
+#
+# From neutron.ml2.sriov.agent
+#
+
+# Extensions list to use (list value)
+{# Get neutron:backend:extension mapping and prepare tmp_ext_list list with extentions where enabled = True #}
+{%- set tmp_ext_list = [] %}
+
+{%- for ext_name, ext_params in neutron.backend.get('sriov_extension', {}).iteritems() %}
+{%- do tmp_ext_list.append(ext_name) if ext_params.get('enabled', False)  %}
+{%- endfor %}
+
+{%- for ext_name, ext_params in neutron.backend.get('extension', {}).iteritems() %}
+{%- do tmp_ext_list.append(ext_name) if ext_params.get('enabled', False) and ext_name != 'bagpipe_bgpvpn' and ext_name not in tmp_ext_list %}
+{%- endfor %}
+{# Below section is for backward compatible when extentions were separated properties without neutron:backend:extension pillar #}
+{%- do tmp_ext_list.append('qos') if neutron.get('qos', 'True') and 'qos' not in tmp_ext_list %}
+extensions={{ tmp_ext_list|join(',') }}
+
+
+[sriov_nic]
+
+#
+# From neutron.ml2.sriov.agent
+#
+
+# Comma-separated list of <physical_network>:<network_device> tuples mapping
+# physical network names to the agent's node-specific physical network device
+# interfaces of SR-IOV physical function to be used for VLAN networks. All
+# physical networks listed in network_vlan_ranges on the server should have
+# mappings to appropriate interfaces on each agent. (list value)
+#physical_device_mappings =
+physical_device_mappings = {%- for nic_name, sriov in neutron.backend.sriov.iteritems() %}{{ sriov.physical_network }}:{{ sriov.devname }}{% if not loop.last %},{% endif %}{%- endfor %}
+
+# Comma-separated list of <network_device>:<vfs_to_exclude> tuples, mapping
+# network_device to the agent's node-specific list of virtual functions that
+# should not be used for virtual networking. vfs_to_exclude is a semicolon-
+# separated list of virtual functions to exclude from network_device. The
+# network_device in the mapping should appear in the physical_device_mappings
+# list. (list value)
+#exclude_devices =
+
+{%- if pillar.neutron.compute is defined %}
+[securitygroup]
+firewall_driver = neutron.agent.firewall.NoopFirewallDriver
+{%- endif %}
diff --git a/neutron/upgrade/upgrade/init.sls b/neutron/upgrade/upgrade/init.sls
index 4ca8dea..9a58255 100644
--- a/neutron/upgrade/upgrade/init.sls
+++ b/neutron/upgrade/upgrade/init.sls
@@ -5,7 +5,6 @@
     - text: "Running neutron.upgrade.upgrade"
 
 include:
- - neutron.upgrade.upgrade.pre
  - neutron.upgrade.service_stopped
  - neutron.upgrade.pkgs_latest
  - neutron.upgrade.render_config
@@ -13,4 +12,3 @@
  - neutron.db.offline_sync
 {%- endif %}
  - neutron.upgrade.service_running
- - neutron.upgrade.upgrade.post
diff --git a/tests/pillar/compute_ovn.sls b/tests/pillar/compute_ovn.sls
index 487faa3..f3fbaf1 100644
--- a/tests/pillar/compute_ovn.sls
+++ b/tests/pillar/compute_ovn.sls
@@ -13,11 +13,4 @@
       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_bgpvpn.sls b/tests/pillar/control_bgpvpn.sls
index d7b4d16..b8926fd 100644
--- a/tests/pillar/control_bgpvpn.sls
+++ b/tests/pillar/control_bgpvpn.sls
@@ -7,11 +7,3 @@
     bgp_vpn:
       enabled: true
       driver: bagpipe
-linux:
-  system:
-    enabled: true
-    repo:
-      mirantis_openstack_pike:
-        source: "deb http://mirror.fuel-infra.org/mcp-repos/pike/xenial pike main"
-        architectures: amd64
-        key_url: "http://mirror.fuel-infra.org/mcp-repos/pike/xenial/archive-mcppike.key"
\ No newline at end of file
diff --git a/tests/pillar/control_l2gw.sls b/tests/pillar/control_l2gw.sls
index b1c2065..30e5b72 100644
--- a/tests/pillar/control_l2gw.sls
+++ b/tests/pillar/control_l2gw.sls
@@ -53,12 +53,4 @@
       'create_network:shared':
     version: pike
     l2gw:
-      enabled: true
-linux:
-  system:
-    enabled: true
-    repo:
-      mirantis_openstack_pike:
-        source: "deb http://mirror.fuel-infra.org/mcp-repos/pike/xenial pike main"
-        architectures: amd64
-        key_url: "http://mirror.fuel-infra.org/mcp-repos/pike/xenial/archive-mcppike.key"
+      enabled: true
\ No newline at end of file
diff --git a/tests/pillar/control_opendaylight.sls b/tests/pillar/control_opendaylight.sls
index 76a4c90..86310e9 100644
--- a/tests/pillar/control_opendaylight.sls
+++ b/tests/pillar/control_opendaylight.sls
@@ -61,11 +61,3 @@
         ovs:
           driver: opendaylight
           order: 77
-linux:
-  system:
-    enabled: true
-    repo:
-      mirantis_openstack_pike:
-        source: "deb http://mirror.fuel-infra.org/mcp-repos/pike/xenial pike main"
-        architectures: amd64
-        key_url: "http://mirror.fuel-infra.org/mcp-repos/pike/xenial/archive-mcppike.key"
diff --git a/tests/pillar/control_ovn.sls b/tests/pillar/control_ovn.sls
index f5348fa..e891cb4 100644
--- a/tests/pillar/control_ovn.sls
+++ b/tests/pillar/control_ovn.sls
@@ -57,11 +57,3 @@
       db-nb-create-insecure-remote: 'yes'
       db-sb-create-insecure-remote: 'yes'
 
-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_sfc.sls b/tests/pillar/control_sfc.sls
index 81a4bc2..c460274 100644
--- a/tests/pillar/control_sfc.sls
+++ b/tests/pillar/control_sfc.sls
@@ -10,12 +10,3 @@
         - ovs
       flow_classifier_drivers:
         - ovs
-
-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/gateway_legacy_l2gw.sls b/tests/pillar/gateway_legacy_l2gw.sls
index d3cd4a8..df45399 100644
--- a/tests/pillar/gateway_legacy_l2gw.sls
+++ b/tests/pillar/gateway_legacy_l2gw.sls
@@ -27,11 +27,4 @@
       enabled: true
       ovsdb_hosts:
         ovsdbx: 10.164.5.33:6632
-linux:
-  system:
-    enabled: true
-    repo:
-      mirantis_openstack_pike:
-        source: "deb http://mirror.fuel-infra.org/mcp-repos/pike/xenial pike main"
-        architectures: amd64
-        key_url: "http://mirror.fuel-infra.org/mcp-repos/pike/xenial/archive-mcppike.key"
+
diff --git a/tests/pillar/gateway_legacy_opendaylight.sls b/tests/pillar/gateway_legacy_opendaylight.sls
index 2f43676..948955b 100644
--- a/tests/pillar/gateway_legacy_opendaylight.sls
+++ b/tests/pillar/gateway_legacy_opendaylight.sls
@@ -31,11 +31,3 @@
       ovsdb_odl_iface: tcp:127.0.0.1:6640
       tunnel_ip: 10.1.0.110
       provider_mappings: physnet1:br-floating
-linux:
-  system:
-    enabled: true
-    repo:
-      mirantis_openstack_pike:
-        source: "deb http://mirror.fuel-infra.org/mcp-repos/pike/xenial pike main"
-        architectures: amd64
-        key_url: "http://mirror.fuel-infra.org/mcp-repos/pike/xenial/archive-mcppike.key"
diff --git a/tests/pillar/repo_mitaka.sls b/tests/pillar/repo_mitaka.sls
new file mode 100644
index 0000000..625210a
--- /dev/null
+++ b/tests/pillar/repo_mitaka.sls
@@ -0,0 +1,8 @@
+linux:
+  system:
+    enabled: true
+    repo:
+      mirantis_openstack:
+        source: "deb http://mirror.fuel-infra.org/mcp-repos/mitaka/xenial/ mitaka main"
+        architectures: amd64
+        key_url: "http://mirror.fuel-infra.org/mcp-repos/mitaka/xenial/archive-mcpmitaka.key"
\ No newline at end of file
diff --git a/tests/pillar/repo_newton.sls b/tests/pillar/repo_newton.sls
new file mode 100644
index 0000000..e11cb18
--- /dev/null
+++ b/tests/pillar/repo_newton.sls
@@ -0,0 +1,8 @@
+linux:
+  system:
+    enabled: true
+    repo:
+      mirantis_openstack:
+        source: "deb http://mirror.fuel-infra.org/mcp-repos/newton/xenial/ newton main"
+        architectures: amd64
+        key_url: "http://mirror.fuel-infra.org/mcp-repos/newton/xenial/archive-mcpnewton.key"
\ No newline at end of file
diff --git a/tests/pillar/repo_ocata.sls b/tests/pillar/repo_ocata.sls
new file mode 100644
index 0000000..41d42d1
--- /dev/null
+++ b/tests/pillar/repo_ocata.sls
@@ -0,0 +1,8 @@
+linux:
+  system:
+    enabled: true
+    repo:
+      mirantis_openstack:
+        source: "deb http://mirror.fuel-infra.org/mcp-repos/ocata/xenial ocata main"
+        architectures: amd64
+        key_url: "http://mirror.fuel-infra.org/mcp-repos/ocata/xenial/archive-mcpocata.key"
\ No newline at end of file
diff --git a/tests/pillar/repo_pike.sls b/tests/pillar/repo_pike.sls
new file mode 100644
index 0000000..bc006ea
--- /dev/null
+++ b/tests/pillar/repo_pike.sls
@@ -0,0 +1,8 @@
+linux:
+  system:
+    enabled: true
+    repo:
+      mirantis_openstack_repo:
+        source: "deb http://mirror.mirantis.com/stable/openstack-pike/xenial xenial main"
+        architectures: amd64
+        key_url: "http://mirror.mirantis.com/stable/openstack-pike/xenial/archive-pike.key"
diff --git a/tests/pillar/repo_queens.sls b/tests/pillar/repo_queens.sls
new file mode 100644
index 0000000..46f7bd9
--- /dev/null
+++ b/tests/pillar/repo_queens.sls
@@ -0,0 +1,8 @@
+linux:
+  system:
+    enabled: true
+    repo:
+      mirantis_openstack_queens:
+        source: "deb http://mirror.mirantis.com/stable/openstack-queens/xenial xenial main"
+        architectures: amd64
+        key_url: "http://mirror.mirantis.com/stable/openstack-queens/xenial/archive-queens.key"
\ No newline at end of file