with context.session.begin(subtransactions=True):
self._ensure_default_security_group_on_port(context, port)
sgids = self._get_security_groups_on_port(context, port)
- # set port status to pending. updated after rest call completes
- port['port']['status'] = const.PORT_STATUS_BUILD
+ # non-router port status is set to pending. it is then updated
+ # after the async rest call completes. router ports are synchronous
+ if port['port']['device_owner'] == l3_db.DEVICE_OWNER_ROUTER_INTF:
+ port['port']['status'] = const.PORT_STATUS_ACTIVE
+ else:
+ port['port']['status'] = const.PORT_STATUS_BUILD
dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, [])
new_port = super(NeutronRestProxyV2, self).create_port(context,
port)
# create on network ctrl
mapped_port = self._map_state_and_status(new_port)
- self.evpool.spawn_n(self.async_port_create, net["tenant_id"],
- new_port["network_id"], mapped_port)
+ # ports have to be created synchronously when creating a router
+ # port since adding router interfaces is a multi-call process
+ if mapped_port['device_owner'] == l3_db.DEVICE_OWNER_ROUTER_INTF:
+ self.servers.rest_create_port(net["tenant_id"],
+ new_port["network_id"],
+ mapped_port)
+ else:
+ self.evpool.spawn_n(self.async_port_create, net["tenant_id"],
+ new_port["network_id"], mapped_port)
self.notify_security_groups_member_updated(context, new_port)
return new_port
from oslo.config import cfg
import webob.exc
+from neutron.common import constants
from neutron import context
from neutron.extensions import portbindings
from neutron.manager import NeutronManager
super(TestBigSwitchProxyPortsV2,
self).setUp(self._plugin_name)
+ def test_router_port_status_active(self):
+ # router ports screw up port auto-deletion so it has to be
+ # disabled for this test
+ with self.network(do_delete=False) as net:
+ with self.subnet(network=net, do_delete=False) as sub:
+ with self.port(
+ subnet=sub,
+ no_delete=True,
+ device_owner=constants.DEVICE_OWNER_ROUTER_INTF
+ ) as port:
+ # router ports should be immediately active
+ self.assertEqual(port['port']['status'], 'ACTIVE')
+
def test_update_port_status_build(self):
+ # normal ports go into the pending build state for async creation
with self.port() as port:
self.assertEqual(port['port']['status'], 'BUILD')
self.assertEqual(self.port_create_status, 'BUILD')