NsxV3: external network support
external network is attached to default tier0 router by default, else attached to tier0 via --provider:physical_network DocImpact Change-Id: I3fa4e1a6955d47f68f86b36f214ce4a43daefe5b
This commit is contained in:
parent
f58351ade3
commit
7e2205e9ab
@ -106,6 +106,7 @@ function neutron_plugin_configure_service {
|
|||||||
else
|
else
|
||||||
die $LINENO "The VMware NSX plugin needs at least an NSX controller."
|
die $LINENO "The VMware NSX plugin needs at least an NSX controller."
|
||||||
fi
|
fi
|
||||||
|
_nsxv3_ini_set default_tier0_router_uuid $DEFAULT_TIER0_ROUTER_UUID
|
||||||
_nsxv3_ini_set nsx_manager $NSX_MANAGER "The VMWare NSX plugin needs a NSX manager."
|
_nsxv3_ini_set nsx_manager $NSX_MANAGER "The VMWare NSX plugin needs a NSX manager."
|
||||||
_nsxv3_ini_set nsx_user $NSX_USER
|
_nsxv3_ini_set nsx_user $NSX_USER
|
||||||
_nsxv3_ini_set nsx_password $NSX_PASSWORD
|
_nsxv3_ini_set nsx_password $NSX_PASSWORD
|
||||||
|
@ -323,3 +323,7 @@
|
|||||||
# If true, the NSX Manager server certificate is not verified. If false,
|
# If true, the NSX Manager server certificate is not verified. If false,
|
||||||
# then the default CA truststore is used for verification.
|
# then the default CA truststore is used for verification.
|
||||||
# insecure = True
|
# insecure = True
|
||||||
|
|
||||||
|
# UUID of the default tier0 router that will be used for connecting to
|
||||||
|
# tier1 logical routers and configuring external network
|
||||||
|
# default_tier0_router_uuid = 412983fd-9016-45e5-93f2-48ba2a931225
|
||||||
|
@ -195,6 +195,8 @@ nsx_v3_opts = [
|
|||||||
'verified. If false, then the default CA truststore is '
|
'verified. If false, then the default CA truststore is '
|
||||||
'used for verification. This option is ignored if '
|
'used for verification. This option is ignored if '
|
||||||
'"ca_file" is set.')),
|
'"ca_file" is set.')),
|
||||||
|
cfg.StrOpt('default_tier0_router_uuid',
|
||||||
|
help=_("Default tier0 router identifier"))
|
||||||
]
|
]
|
||||||
|
|
||||||
DEFAULT_STATUS_CHECK_INTERVAL = 2000
|
DEFAULT_STATUS_CHECK_INTERVAL = 2000
|
||||||
|
@ -24,6 +24,11 @@ from vmware_nsx.neutron.plugins.vmware.nsxlib.v3 import client
|
|||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def get_edge_cluster(edge_cluster_uuid):
|
||||||
|
resource = "edge-clusters/%s" % edge_cluster_uuid
|
||||||
|
return client.get_resource(resource)
|
||||||
|
|
||||||
|
|
||||||
def create_logical_switch(display_name, transport_zone_id, tags,
|
def create_logical_switch(display_name, transport_zone_id, tags,
|
||||||
replication_mode=nsx_constants.MTEP,
|
replication_mode=nsx_constants.MTEP,
|
||||||
admin_state=True, vlan_id=None):
|
admin_state=True, vlan_id=None):
|
||||||
@ -157,6 +162,11 @@ def create_logical_router(display_name, tags, edge_cluster_uuid=None,
|
|||||||
return client.create_resource(resource, body)
|
return client.create_resource(resource, body)
|
||||||
|
|
||||||
|
|
||||||
|
def get_logical_router(lrouter_id):
|
||||||
|
resource = 'logical-routers/%s' % lrouter_id
|
||||||
|
return client.get_resource(resource)
|
||||||
|
|
||||||
|
|
||||||
def delete_logical_router(lrouter_id):
|
def delete_logical_router(lrouter_id):
|
||||||
resource = 'logical-routers/%s/' % lrouter_id
|
resource = 'logical-routers/%s/' % lrouter_id
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ from neutron.api.rpc.agentnotifiers import dhcp_rpc_agent_api
|
|||||||
from neutron.api.rpc.handlers import dhcp_rpc
|
from neutron.api.rpc.handlers import dhcp_rpc
|
||||||
from neutron.api.rpc.handlers import metadata_rpc
|
from neutron.api.rpc.handlers import metadata_rpc
|
||||||
from neutron.api.v2 import attributes
|
from neutron.api.v2 import attributes
|
||||||
|
from neutron.extensions import external_net as ext_net_extn
|
||||||
from neutron.extensions import extra_dhcp_opt as edo_ext
|
from neutron.extensions import extra_dhcp_opt as edo_ext
|
||||||
from neutron.extensions import l3
|
from neutron.extensions import l3
|
||||||
from neutron.extensions import portbindings as pbin
|
from neutron.extensions import portbindings as pbin
|
||||||
@ -39,6 +40,7 @@ from neutron.common import topics
|
|||||||
from neutron.db import agents_db
|
from neutron.db import agents_db
|
||||||
from neutron.db import agentschedulers_db
|
from neutron.db import agentschedulers_db
|
||||||
from neutron.db import db_base_plugin_v2
|
from neutron.db import db_base_plugin_v2
|
||||||
|
from neutron.db import external_net_db
|
||||||
from neutron.db import extradhcpopt_db
|
from neutron.db import extradhcpopt_db
|
||||||
from neutron.db import l3_db
|
from neutron.db import l3_db
|
||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
@ -59,6 +61,7 @@ LOG = log.getLogger(__name__)
|
|||||||
|
|
||||||
class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||||
securitygroups_db.SecurityGroupDbMixin,
|
securitygroups_db.SecurityGroupDbMixin,
|
||||||
|
external_net_db.External_net_db_mixin,
|
||||||
l3_db.L3_NAT_dbonly_mixin,
|
l3_db.L3_NAT_dbonly_mixin,
|
||||||
portbindings_db.PortBindingMixin,
|
portbindings_db.PortBindingMixin,
|
||||||
agentschedulers_db.DhcpAgentSchedulerDbMixin,
|
agentschedulers_db.DhcpAgentSchedulerDbMixin,
|
||||||
@ -74,8 +77,9 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
"binding",
|
"binding",
|
||||||
"extra_dhcp_opt",
|
"extra_dhcp_opt",
|
||||||
"security-group",
|
"security-group",
|
||||||
"router",
|
"provider",
|
||||||
"provider"]
|
"external-net",
|
||||||
|
"router"]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(NsxV3Plugin, self).__init__()
|
super(NsxV3Plugin, self).__init__()
|
||||||
@ -87,6 +91,7 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
# TODO(rkukura): Replace with new VIF security details
|
# TODO(rkukura): Replace with new VIF security details
|
||||||
pbin.CAP_PORT_FILTER:
|
pbin.CAP_PORT_FILTER:
|
||||||
'security-group' in self.supported_extension_aliases}}
|
'security-group' in self.supported_extension_aliases}}
|
||||||
|
self.tier0_groups_dict = {}
|
||||||
self._setup_rpc()
|
self._setup_rpc()
|
||||||
|
|
||||||
def _setup_rpc(self):
|
def _setup_rpc(self):
|
||||||
@ -174,6 +179,73 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
|
|
||||||
return net_type, physical_net, vlan_id
|
return net_type, physical_net, vlan_id
|
||||||
|
|
||||||
|
def _validate_tier0(self, tier0_uuid):
|
||||||
|
if tier0_uuid in self.tier0_groups_dict:
|
||||||
|
return
|
||||||
|
err_msg = None
|
||||||
|
try:
|
||||||
|
lrouter = nsxlib.get_logical_router(tier0_uuid)
|
||||||
|
except nsx_exc.ResourceNotFound:
|
||||||
|
err_msg = _("Failed to validate tier0 router %s since it is "
|
||||||
|
"not found at the backend") % tier0_uuid
|
||||||
|
else:
|
||||||
|
edge_cluster_uuid = lrouter.get('edge_cluster_id')
|
||||||
|
if not edge_cluster_uuid:
|
||||||
|
err_msg = _("Failed to get edge cluster uuid from tier0 "
|
||||||
|
"router %s at the backend") % lrouter
|
||||||
|
else:
|
||||||
|
edge_cluster = nsxlib.get_edge_cluster(edge_cluster_uuid)
|
||||||
|
member_index_list = [member['member_index']
|
||||||
|
for member in edge_cluster['members']]
|
||||||
|
if not member_index_list:
|
||||||
|
err_msg = _("No edge members found in edge_cluster "
|
||||||
|
"%(cluster)s from tier0 router %(tier0)s") % {
|
||||||
|
'cluster': edge_cluster_uuid,
|
||||||
|
'tier0': tier0_uuid}
|
||||||
|
if err_msg:
|
||||||
|
raise n_exc.InvalidInput(error_message=err_msg)
|
||||||
|
else:
|
||||||
|
self.tier0_groups_dict[tier0_uuid] = {
|
||||||
|
'edge_cluster_uuid': edge_cluster_uuid,
|
||||||
|
'member_index_list': member_index_list}
|
||||||
|
|
||||||
|
def _validate_external_net_create(self, net_data):
|
||||||
|
is_provider_net = False
|
||||||
|
if not attributes.is_attr_set(net_data.get(pnet.PHYSICAL_NETWORK)):
|
||||||
|
tier0_uuid = cfg.CONF.nsx_v3.default_tier0_router_uuid
|
||||||
|
else:
|
||||||
|
tier0_uuid = net_data[pnet.PHYSICAL_NETWORK]
|
||||||
|
is_provider_net = True
|
||||||
|
self._validate_tier0(tier0_uuid)
|
||||||
|
return (is_provider_net, utils.NetworkTypes.L3_EXT, tier0_uuid, 0)
|
||||||
|
|
||||||
|
def _create_network_at_the_backend(self, context, net_data):
|
||||||
|
is_provider_net = any(
|
||||||
|
attributes.is_attr_set(net_data.get(f))
|
||||||
|
for f in (pnet.NETWORK_TYPE,
|
||||||
|
pnet.PHYSICAL_NETWORK,
|
||||||
|
pnet.SEGMENTATION_ID))
|
||||||
|
net_type, physical_net, vlan_id = self._validate_provider_create(
|
||||||
|
context, net_data)
|
||||||
|
net_name = net_data['name']
|
||||||
|
tags = utils.build_v3_tags_payload(net_data)
|
||||||
|
admin_state = net_data.get('admin_state_up', True)
|
||||||
|
|
||||||
|
# Create network on the backend
|
||||||
|
LOG.debug('create_network: %(net_name)s, %(physical_net)s, '
|
||||||
|
'%(tags)s, %(admin_state)s, %(vlan_id)s',
|
||||||
|
{'net_name': net_name,
|
||||||
|
'physical_net': physical_net,
|
||||||
|
'tags': tags,
|
||||||
|
'admin_state': admin_state,
|
||||||
|
'vlan_id': vlan_id})
|
||||||
|
result = nsxlib.create_logical_switch(net_name, physical_net, tags,
|
||||||
|
admin_state=admin_state,
|
||||||
|
vlan_id=vlan_id)
|
||||||
|
network_id = result['id']
|
||||||
|
net_data['id'] = network_id
|
||||||
|
return (is_provider_net, net_type, physical_net, vlan_id)
|
||||||
|
|
||||||
def _extend_network_dict_provider(self, context, network, bindings=None):
|
def _extend_network_dict_provider(self, context, network, bindings=None):
|
||||||
if not bindings:
|
if not bindings:
|
||||||
bindings = nsx_db.get_network_bindings(context.session,
|
bindings = nsx_db.get_network_bindings(context.session,
|
||||||
@ -186,58 +258,56 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
network[pnet.SEGMENTATION_ID] = bindings[0].vlan_id
|
network[pnet.SEGMENTATION_ID] = bindings[0].vlan_id
|
||||||
|
|
||||||
def create_network(self, context, network):
|
def create_network(self, context, network):
|
||||||
is_provider_net = any(attributes.is_attr_set(network['network'].get(f))
|
net_data = network['network']
|
||||||
for f in (pnet.NETWORK_TYPE,
|
external = net_data.get(ext_net_extn.EXTERNAL)
|
||||||
pnet.PHYSICAL_NETWORK,
|
if attributes.is_attr_set(external) and external:
|
||||||
pnet.SEGMENTATION_ID))
|
is_provider_net, net_type, physical_net, vlan_id = (
|
||||||
net_type, physical_net, vlan_id = self._validate_provider_create(
|
self._validate_external_net_create(net_data))
|
||||||
context, network['network'])
|
else:
|
||||||
net_name = network['network']['name']
|
is_provider_net, net_type, physical_net, vlan_id = (
|
||||||
tags = utils.build_v3_tags_payload(network['network'])
|
self._create_network_at_the_backend(context, net_data))
|
||||||
admin_state = network['network'].get('admin_state_up', True)
|
tenant_id = self._get_tenant_id_for_create(
|
||||||
|
context, net_data)
|
||||||
# Create network on the backend
|
|
||||||
LOG.debug('create_network: %(net_name)s, %(physical_net)s, %(tags)s, '
|
|
||||||
'%(admin_state)s, %(vlan_id)s',
|
|
||||||
{'net_name': net_name,
|
|
||||||
'physical_net': physical_net,
|
|
||||||
'tags': tags,
|
|
||||||
'admin_state': admin_state,
|
|
||||||
'vlan_id': vlan_id})
|
|
||||||
result = nsxlib.create_logical_switch(net_name, physical_net, tags,
|
|
||||||
admin_state=admin_state,
|
|
||||||
vlan_id=vlan_id)
|
|
||||||
net_id = result['id']
|
|
||||||
network['network']['id'] = net_id
|
|
||||||
tenant_id = self._get_tenant_id_for_create(context, network['network'])
|
|
||||||
|
|
||||||
self._ensure_default_security_group(context, tenant_id)
|
self._ensure_default_security_group(context, tenant_id)
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
# Create network in Neutron
|
# Create network in Neutron
|
||||||
try:
|
try:
|
||||||
created_net = super(NsxV3Plugin, self).create_network(context,
|
created_net = super(NsxV3Plugin, self).create_network(context,
|
||||||
network)
|
network)
|
||||||
|
self._process_l3_create(context, created_net, net_data)
|
||||||
except Exception:
|
except Exception:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
# Undo creation on the backend
|
# Undo creation on the backend
|
||||||
LOG.exception(_LE('Failed to create network %s'), net_id)
|
LOG.exception(_LE('Failed to create network %s'),
|
||||||
nsxlib.delete_logical_switch(net_id)
|
created_net['id'])
|
||||||
|
if net_type != utils.NetworkTypes.L3_EXT:
|
||||||
|
nsxlib.delete_logical_switch(created_net['id'])
|
||||||
|
|
||||||
if is_provider_net:
|
if is_provider_net:
|
||||||
# Save provider network fields, needed by get_network()
|
# Save provider network fields, needed by get_network()
|
||||||
nsx_db.add_network_binding(context.session, net_id, net_type,
|
net_bindings = [nsx_db.add_network_binding(
|
||||||
physical_net, vlan_id)
|
context.session, created_net['id'],
|
||||||
|
net_type, physical_net, vlan_id)]
|
||||||
|
self._extend_network_dict_provider(context, created_net,
|
||||||
|
bindings=net_bindings)
|
||||||
|
|
||||||
return created_net
|
return created_net
|
||||||
|
|
||||||
def delete_network(self, context, network_id):
|
def delete_network(self, context, network_id):
|
||||||
# First call DB operation for delete network as it will perform
|
# First call DB operation for delete network as it will perform
|
||||||
# checks on active ports
|
# checks on active ports
|
||||||
ret_val = super(NsxV3Plugin, self).delete_network(context, network_id)
|
with context.session.begin(subtransactions=True):
|
||||||
# TODO(salv-orlando): Handle backend failure, possibly without
|
self._process_l3_delete(context, network_id)
|
||||||
# requiring us to un-delete the DB object. For instance, ignore
|
ret_val = super(NsxV3Plugin, self).delete_network(
|
||||||
# failures occuring if logical switch is not found
|
context, network_id)
|
||||||
nsxlib.delete_logical_switch(network_id)
|
if not self._network_is_external(context, network_id):
|
||||||
|
# TODO(salv-orlando): Handle backend failure, possibly without
|
||||||
|
# requiring us to un-delete the DB object. For instance, ignore
|
||||||
|
# failures occuring if logical switch is not found
|
||||||
|
nsxlib.delete_logical_switch(network_id)
|
||||||
|
else:
|
||||||
|
# TODO(berlin): delete subnets public announce on the network
|
||||||
|
pass
|
||||||
return ret_val
|
return ret_val
|
||||||
|
|
||||||
def update_network(self, context, id, network):
|
def update_network(self, context, id, network):
|
||||||
@ -248,7 +318,8 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
updated_net = super(NsxV3Plugin, self).update_network(context, id,
|
updated_net = super(NsxV3Plugin, self).update_network(context, id,
|
||||||
network)
|
network)
|
||||||
|
|
||||||
if 'name' in net_data or 'admin_state_up' in net_data:
|
if (not self._network_is_external(context, id) and
|
||||||
|
'name' in net_data or 'admin_state_up' in net_data):
|
||||||
try:
|
try:
|
||||||
nsxlib.update_logical_switch(
|
nsxlib.update_logical_switch(
|
||||||
id, name=net_data.get('name'),
|
id, name=net_data.get('name'),
|
||||||
@ -265,6 +336,14 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
|
|
||||||
return updated_net
|
return updated_net
|
||||||
|
|
||||||
|
def create_subnet(self, context, subnet):
|
||||||
|
# TODO(berlin): public external subnet announcement
|
||||||
|
return super(NsxV3Plugin, self).create_subnet(context, subnet)
|
||||||
|
|
||||||
|
def delete_subnet(self, context, subnet_id):
|
||||||
|
# TODO(berlin): cancel public external subnet announcement
|
||||||
|
return super(NsxV3Plugin, self).delete_subnet(context, subnet_id)
|
||||||
|
|
||||||
def _build_address_bindings(self, port):
|
def _build_address_bindings(self, port):
|
||||||
address_bindings = []
|
address_bindings = []
|
||||||
for fixed_ip in port['fixed_ips']:
|
for fixed_ip in port['fixed_ips']:
|
||||||
@ -340,57 +419,70 @@ class NsxV3Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
|||||||
# self.get_port(context, parent_name)
|
# self.get_port(context, parent_name)
|
||||||
return parent_name, tag
|
return parent_name, tag
|
||||||
|
|
||||||
|
def _create_port_at_the_backend(self, context, neutron_db, port_data):
|
||||||
|
tags = utils.build_v3_tags_payload(port_data)
|
||||||
|
parent_name, tag = self._get_data_from_binding_profile(
|
||||||
|
context, port_data)
|
||||||
|
address_bindings = self._build_address_bindings(port_data)
|
||||||
|
# FIXME(arosen): we might need to pull this out of the
|
||||||
|
# transaction here later.
|
||||||
|
result = nsxlib.create_logical_port(
|
||||||
|
lswitch_id=port_data['network_id'],
|
||||||
|
vif_uuid=port_data['id'], name=port_data['name'], tags=tags,
|
||||||
|
admin_state=port_data['admin_state_up'],
|
||||||
|
address_bindings=address_bindings,
|
||||||
|
parent_name=parent_name, parent_tag=tag)
|
||||||
|
|
||||||
|
# TODO(salv-orlando): The logical switch identifier in the
|
||||||
|
# mapping object is not necessary anymore.
|
||||||
|
nsx_db.add_neutron_nsx_port_mapping(
|
||||||
|
context.session, neutron_db['id'],
|
||||||
|
neutron_db['network_id'], result['id'])
|
||||||
|
|
||||||
def create_port(self, context, port):
|
def create_port(self, context, port):
|
||||||
dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, [])
|
dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, [])
|
||||||
port_id = uuidutils.generate_uuid()
|
port_id = uuidutils.generate_uuid()
|
||||||
tags = utils.build_v3_tags_payload(port['port'])
|
|
||||||
port['port']['id'] = port_id
|
port['port']['id'] = port_id
|
||||||
|
|
||||||
self._ensure_default_security_group_on_port(context, port)
|
self._ensure_default_security_group_on_port(context, port)
|
||||||
# TODO(salv-orlando): Undo logical switch creation on failure
|
# TODO(salv-orlando): Undo logical switch creation on failure
|
||||||
with context.session.begin(subtransactions=True):
|
with context.session.begin(subtransactions=True):
|
||||||
parent_name, tag = self._get_data_from_binding_profile(
|
|
||||||
context, port['port'])
|
|
||||||
neutron_db = super(NsxV3Plugin, self).create_port(context, port)
|
neutron_db = super(NsxV3Plugin, self).create_port(context, port)
|
||||||
self._process_portbindings_create_and_update(context,
|
self._process_portbindings_create_and_update(context,
|
||||||
port['port'],
|
port['port'],
|
||||||
neutron_db)
|
neutron_db)
|
||||||
|
|
||||||
port["port"].update(neutron_db)
|
port["port"].update(neutron_db)
|
||||||
address_bindings = self._build_address_bindings(port['port'])
|
|
||||||
# FIXME(arosen): we might need to pull this out of the transaction
|
|
||||||
# here later.
|
|
||||||
result = nsxlib.create_logical_port(
|
|
||||||
lswitch_id=port['port']['network_id'],
|
|
||||||
vif_uuid=port_id, name=port['port']['name'], tags=tags,
|
|
||||||
admin_state=port['port']['admin_state_up'],
|
|
||||||
address_bindings=address_bindings,
|
|
||||||
parent_name=parent_name, parent_tag=tag)
|
|
||||||
|
|
||||||
# TODO(salv-orlando): The logical switch identifier in the mapping
|
if not self._network_is_external(
|
||||||
# object is not necessary anymore.
|
context, port['port']['network_id']):
|
||||||
nsx_db.add_neutron_nsx_port_mapping(
|
self._create_port_at_the_backend(
|
||||||
context.session, neutron_db['id'],
|
context, neutron_db, port['port'])
|
||||||
neutron_db['network_id'], result['id'])
|
|
||||||
self._process_portbindings_create_and_update(context,
|
self._process_portbindings_create_and_update(context,
|
||||||
port['port'],
|
port['port'],
|
||||||
neutron_db)
|
neutron_db)
|
||||||
|
|
||||||
neutron_db[pbin.VNIC_TYPE] = pbin.VNIC_NORMAL
|
neutron_db[pbin.VNIC_TYPE] = pbin.VNIC_NORMAL
|
||||||
if (pbin.PROFILE in port['port'] and
|
if (pbin.PROFILE in port['port'] and
|
||||||
attributes.is_attr_set(port['port'][pbin.PROFILE])):
|
attributes.is_attr_set(port['port'][pbin.PROFILE])):
|
||||||
neutron_db[pbin.PROFILE] = port['port'][pbin.PROFILE]
|
neutron_db[pbin.PROFILE] = port['port'][pbin.PROFILE]
|
||||||
sgids = self._get_security_groups_on_port(context, port)
|
sgids = self._get_security_groups_on_port(context, port)
|
||||||
self._process_port_create_security_group(
|
self._process_port_create_security_group(
|
||||||
context, neutron_db, sgids)
|
context, neutron_db, sgids)
|
||||||
self._process_port_create_extra_dhcp_opts(context, neutron_db,
|
self._process_port_create_extra_dhcp_opts(context, neutron_db,
|
||||||
dhcp_opts)
|
dhcp_opts)
|
||||||
|
|
||||||
return neutron_db
|
return neutron_db
|
||||||
|
|
||||||
def delete_port(self, context, port_id, l3_port_check=True):
|
def delete_port(self, context, port_id, l3_port_check=True):
|
||||||
_net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
|
# if needed, check to see if this is a port owned by
|
||||||
context.session, port_id)
|
# a l3 router. If so, we should prevent deletion here
|
||||||
nsxlib.delete_logical_port(nsx_port_id)
|
if l3_port_check:
|
||||||
|
self.prevent_l3_port_deletion(context, port_id)
|
||||||
|
port = self.get_port(context, port_id)
|
||||||
|
if not self._network_is_external(context, port['network_id']):
|
||||||
|
_net_id, nsx_port_id = nsx_db.get_nsx_switch_and_port_id(
|
||||||
|
context.session, port_id)
|
||||||
|
nsxlib.delete_logical_port(nsx_port_id)
|
||||||
ret_val = super(NsxV3Plugin, self).delete_port(context, port_id)
|
ret_val = super(NsxV3Plugin, self).delete_port(context, port_id)
|
||||||
|
|
||||||
return ret_val
|
return ret_val
|
||||||
|
@ -177,3 +177,19 @@ def update_logical_port(lport_id, name=None, admin_state=None):
|
|||||||
else:
|
else:
|
||||||
lport['admin_state'] = nsx_constants.ADMIN_STATE_DOWN
|
lport['admin_state'] = nsx_constants.ADMIN_STATE_DOWN
|
||||||
return lport
|
return lport
|
||||||
|
|
||||||
|
|
||||||
|
def get_edge_cluster(edge_cluster_uuid):
|
||||||
|
FAKE_CLUSTER = {
|
||||||
|
"id": edge_cluster_uuid,
|
||||||
|
"members": [
|
||||||
|
{"member_index": 0},
|
||||||
|
{"member_index": 1}]}
|
||||||
|
return FAKE_CLUSTER
|
||||||
|
|
||||||
|
|
||||||
|
def get_logical_router(lrouter_uuid):
|
||||||
|
FAKE_LROUTER = {
|
||||||
|
"id": lrouter_uuid,
|
||||||
|
"edge_cluster_uuid": uuidutils.generate_uuid()}
|
||||||
|
return FAKE_LROUTER
|
||||||
|
@ -46,6 +46,9 @@ class NsxPluginV3TestCase(test_plugin.NeutronDbPluginV2TestCase):
|
|||||||
nsxlib.delete_logical_port = mock.Mock()
|
nsxlib.delete_logical_port = mock.Mock()
|
||||||
nsxlib.get_logical_port = nsx_v3_mocks.get_logical_port
|
nsxlib.get_logical_port = nsx_v3_mocks.get_logical_port
|
||||||
nsxlib.update_logical_port = nsx_v3_mocks.update_logical_port
|
nsxlib.update_logical_port = nsx_v3_mocks.update_logical_port
|
||||||
|
# TODO(berlin): fill valid data
|
||||||
|
nsxlib.get_edge_cluster = nsx_v3_mocks.get_edge_cluster
|
||||||
|
nsxlib.get_logical_router = nsx_v3_mocks.get_logical_router
|
||||||
|
|
||||||
|
|
||||||
class TestNetworksV2(test_plugin.TestNetworksV2, NsxPluginV3TestCase):
|
class TestNetworksV2(test_plugin.TestNetworksV2, NsxPluginV3TestCase):
|
||||||
@ -63,6 +66,7 @@ class SecurityGroupsTestCase(ext_sg.SecurityGroupDBTestCase):
|
|||||||
ext_mgr=None):
|
ext_mgr=None):
|
||||||
nsxlib.create_logical_switch = nsx_v3_mocks.create_logical_switch
|
nsxlib.create_logical_switch = nsx_v3_mocks.create_logical_switch
|
||||||
nsxlib.create_logical_port = nsx_v3_mocks.create_logical_port
|
nsxlib.create_logical_port = nsx_v3_mocks.create_logical_port
|
||||||
|
nsxlib.update_logical_port = nsx_v3_mocks.update_logical_port
|
||||||
nsxlib.delete_logical_port = mock.Mock()
|
nsxlib.delete_logical_port = mock.Mock()
|
||||||
nsxlib.delete_logical_switch = mock.Mock()
|
nsxlib.delete_logical_switch = mock.Mock()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user