NSX|P: Initial connectivity support
Not covered yet: DHCP, Switching Profiles, TZs, provider networks, GW, NAT Change-Id: I9f4163d8a233b0d3914363556ddf6ec0f375f99a
This commit is contained in:
parent
30e1395302
commit
4f6730911c
@ -482,7 +482,15 @@ nsx_v3_opts = nsx_v3_and_p + [
|
||||
|
||||
]
|
||||
|
||||
nsx_p_opts = nsx_v3_and_p + []
|
||||
nsx_p_opts = nsx_v3_and_p + [
|
||||
cfg.StrOpt('default_tier0_router',
|
||||
help=_("Name or UUID of the default tier0 router that will be "
|
||||
"used for connecting to tier1 logical routers and "
|
||||
"configuring external networks. If only one tier0 "
|
||||
" router is present on backend, it will be assumed "
|
||||
"as default unless this value is provided")),
|
||||
]
|
||||
|
||||
|
||||
DEFAULT_STATUS_CHECK_INTERVAL = 2000
|
||||
DEFAULT_MINIMUM_POOLED_EDGES = 1
|
||||
|
@ -24,6 +24,7 @@ from neutron.db import l3_attrs_db
|
||||
from neutron.db import l3_db
|
||||
from neutron.db import models_v2
|
||||
from neutron_lib.api.definitions import address_scope as ext_address_scope
|
||||
from neutron_lib.api.definitions import allowedaddresspairs as addr_apidef
|
||||
from neutron_lib.api.definitions import availability_zone as az_def
|
||||
from neutron_lib.api.definitions import external_net as extnet_apidef
|
||||
from neutron_lib.api.definitions import network as net_def
|
||||
@ -38,12 +39,14 @@ from neutron_lib.callbacks import resources
|
||||
from neutron_lib import constants
|
||||
from neutron_lib import context as n_context
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from neutron_lib.exceptions import allowedaddresspairs as addr_exc
|
||||
from neutron_lib.plugins import directory
|
||||
from neutron_lib.services.qos import constants as qos_consts
|
||||
from neutron_lib.utils import net
|
||||
|
||||
from vmware_nsx._i18n import _
|
||||
from vmware_nsx.common import exceptions as nsx_exc
|
||||
from vmware_nsx.common import utils
|
||||
from vmware_nsx.extensions import maclearning as mac_ext
|
||||
from vmware_nsx.extensions import secgroup_rule_local_ip_prefix as sg_prefix
|
||||
from vmware_nsx.services.qos.common import utils as qos_com_utils
|
||||
@ -567,6 +570,24 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
self._assert_on_vpn_port_change(original_port)
|
||||
self._assert_on_lb_port_fixed_ip_change(port_data, orig_dev_owner)
|
||||
|
||||
def _build_port_name(self, context, port_data):
|
||||
device_owner = port_data.get('device_owner')
|
||||
device_id = port_data.get('device_id')
|
||||
if device_owner == l3_db.DEVICE_OWNER_ROUTER_INTF and device_id:
|
||||
router = self._get_router(context, device_id)
|
||||
name = utils.get_name_and_uuid(
|
||||
router['name'] or 'router', port_data['id'], tag='port')
|
||||
elif device_owner == constants.DEVICE_OWNER_DHCP:
|
||||
network = self.get_network(context, port_data['network_id'])
|
||||
name = self._get_dhcp_port_name(network['name'],
|
||||
network['id'])
|
||||
elif device_owner.startswith(constants.DEVICE_OWNER_COMPUTE_PREFIX):
|
||||
name = utils.get_name_and_uuid(
|
||||
port_data['name'] or 'instance-port', port_data['id'])
|
||||
else:
|
||||
name = port_data['name']
|
||||
return name
|
||||
|
||||
def _process_extra_attr_router_create(self, context, router_db, r):
|
||||
for extra_attr in l3_attrs_db.get_attr_info().keys():
|
||||
if (extra_attr in r and
|
||||
@ -595,6 +616,38 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
sg_rule[sg_prefix.LOCAL_IP_PREFIX].startswith('0.0.0.0/')):
|
||||
sg_rule[sg_prefix.LOCAL_IP_PREFIX] = None
|
||||
|
||||
def _validate_interface_address_scope(self, context,
|
||||
router_db, interface_info):
|
||||
gw_network_id = (router_db.gw_port.network_id if router_db.gw_port
|
||||
else None)
|
||||
|
||||
subnet = self.get_subnet(context, interface_info['subnet_ids'][0])
|
||||
if not router_db.enable_snat and gw_network_id:
|
||||
self._validate_address_scope_for_router_interface(
|
||||
context.elevated(), router_db.id, gw_network_id, subnet['id'])
|
||||
|
||||
def _validate_ipv4_address_pairs(self, address_pairs):
|
||||
for pair in address_pairs:
|
||||
ip = pair.get('ip_address')
|
||||
if not utils.is_ipv4_ip_address(ip):
|
||||
raise nsx_exc.InvalidIPAddress(ip_address=ip)
|
||||
|
||||
# NSXv3 and Policy only
|
||||
def _create_port_address_pairs(self, context, port_data):
|
||||
(port_security, has_ip) = self._determine_port_security_and_has_ip(
|
||||
context, port_data)
|
||||
|
||||
address_pairs = port_data.get(addr_apidef.ADDRESS_PAIRS)
|
||||
if validators.is_attr_set(address_pairs):
|
||||
if not port_security:
|
||||
raise addr_exc.AddressPairAndPortSecurityRequired()
|
||||
else:
|
||||
self._validate_ipv4_address_pairs(address_pairs)
|
||||
self._process_create_allowed_address_pairs(context, port_data,
|
||||
address_pairs)
|
||||
else:
|
||||
port_data[addr_apidef.ADDRESS_PAIRS] = []
|
||||
|
||||
def get_housekeeper(self, context, name, fields=None):
|
||||
# run the job in readonly mode and get the results
|
||||
self.housekeeper.run(context, name, readonly=True)
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
import sys
|
||||
|
||||
import netaddr
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
from oslo_utils import excutils
|
||||
@ -30,6 +32,7 @@ from neutron.db import external_net_db
|
||||
from neutron.db import extradhcpopt_db
|
||||
from neutron.db import extraroute_db
|
||||
from neutron.db import l3_attrs_db
|
||||
from neutron.db import l3_db
|
||||
from neutron.db import l3_gwmode_db
|
||||
from neutron.db.models import l3 as l3_db_models
|
||||
from neutron.db.models import securitygroup as securitygroup_model # noqa
|
||||
@ -40,6 +43,7 @@ from neutron.db import securitygroups_db
|
||||
from neutron.db import vlantransparent_db
|
||||
from neutron.extensions import providernet
|
||||
from neutron.quota import resource_registry
|
||||
from neutron_lib.api.definitions import allowedaddresspairs as addr_apidef
|
||||
from neutron_lib.api.definitions import external_net
|
||||
from neutron_lib.api.definitions import l3 as l3_apidef
|
||||
from neutron_lib.api.definitions import port_security as psec
|
||||
@ -161,6 +165,7 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
self.cfg_group = 'nsx_p' # group name for nsx_p section in nsx.ini
|
||||
|
||||
self._init_default_config()
|
||||
self._prepare_default_rules()
|
||||
|
||||
# subscribe the init complete method last, so it will be called only
|
||||
@ -169,6 +174,38 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
resources.PROCESS,
|
||||
events.AFTER_INIT)
|
||||
|
||||
# NOTE(annak): we may need to generalize this for API calls
|
||||
# requiring path ids
|
||||
def _init_default_resource(self, resource_api, name_or_id):
|
||||
if not name_or_id:
|
||||
# If not specified, the system will auto-configure
|
||||
# in case only single resource is present
|
||||
resources = resource_api.list()
|
||||
if len(resources) == 1:
|
||||
return resources[0]['id']
|
||||
else:
|
||||
return None
|
||||
|
||||
try:
|
||||
resource_api.get(name_or_id)
|
||||
return name_or_id
|
||||
except nsx_lib_exc.ResourceNotFound:
|
||||
try:
|
||||
resource = resource_api.get_by_name(name_or_id)
|
||||
if resource:
|
||||
return resource['id']
|
||||
except nsx_lib_exc.ResourceNotFound:
|
||||
return None
|
||||
|
||||
def _init_default_config(self):
|
||||
self.default_tier0_router = self._init_default_resource(
|
||||
self.nsxpolicy.tier0,
|
||||
cfg.CONF.nsx_p.default_tier0_router)
|
||||
|
||||
if not self.default_tier0_router:
|
||||
raise cfg.RequiredOptError("default_tier0_router",
|
||||
group=cfg.OptGroup('nsx_p'))
|
||||
|
||||
def _validate_nsx_policy_version(self):
|
||||
self._nsx_version = self.nsxpolicy.get_version()
|
||||
LOG.info("NSX Version: %s", self._nsx_version)
|
||||
@ -219,8 +256,25 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
})
|
||||
|
||||
def _create_network_at_the_backend(self, context, net_data):
|
||||
#TODO(asarfaty): implement, using nsx-id the same as the neutron id
|
||||
pass
|
||||
# TODO(annak): provider network
|
||||
net_data['id'] = net_data.get('id') or uuidutils.generate_uuid()
|
||||
|
||||
net_name = utils.get_name_and_uuid(net_data['name'] or 'network',
|
||||
net_data['id'])
|
||||
tags = self.nsxpolicy.build_v3_tags_payload(
|
||||
net_data, resource_type='os-neutron-net-id',
|
||||
project_name=context.tenant_name)
|
||||
|
||||
# TODO(annak): admin state config is missing on policy
|
||||
# should we not create networks that are down?
|
||||
# alternative - configure status on manager for time being
|
||||
# admin_state = net_data.get('admin_state_up', True)
|
||||
|
||||
self.nsxpolicy.segment.create_or_overwrite(
|
||||
net_name,
|
||||
segment_id=net_data['id'],
|
||||
description=net_data.get('description'),
|
||||
tags=tags)
|
||||
|
||||
def _validate_external_net_create(self, net_data):
|
||||
#TODO(asarfaty): implement
|
||||
@ -255,7 +309,7 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
# Create the backend NSX network
|
||||
if not is_external_net:
|
||||
try:
|
||||
self._create_network_at_the_backend(context, net_data)
|
||||
self._create_network_at_the_backend(context, created_net)
|
||||
except Exception as e:
|
||||
LOG.exception("Failed to create NSX network network: %s", e)
|
||||
with excutils.save_and_reraise_exception():
|
||||
@ -272,11 +326,10 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
def delete_network(self, context, network_id):
|
||||
with db_api.context_manager.writer.using(context):
|
||||
self._process_l3_delete(context, network_id)
|
||||
return super(NsxPolicyPlugin, self).delete_network(
|
||||
super(NsxPolicyPlugin, self).delete_network(
|
||||
context, network_id)
|
||||
if not self._network_is_external(context, network_id):
|
||||
# TODO(asarfaty) delete the NSX logical network
|
||||
pass
|
||||
self.nsxpolicy.segment.delete(network_id)
|
||||
|
||||
def update_network(self, context, id, network):
|
||||
original_net = super(NsxPolicyPlugin, self).get_network(context, id)
|
||||
@ -352,13 +405,51 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
return updated_subnet
|
||||
|
||||
def _build_address_bindings(self, port):
|
||||
address_bindings = []
|
||||
for fixed_ip in port['fixed_ips']:
|
||||
if netaddr.IPNetwork(fixed_ip['ip_address']).version != 4:
|
||||
#TODO(annak): enable when IPv6 is supported
|
||||
continue
|
||||
binding = self.nsxpolicy.segment_port.build_address_binding(
|
||||
fixed_ip['ip_address'], port['mac_address'])
|
||||
address_bindings.append(binding)
|
||||
|
||||
for pair in port.get(addr_apidef.ADDRESS_PAIRS):
|
||||
binding = self.nsxpolicy.segment_port.build_address_binding(
|
||||
pair['ip_address'], pair['mac_address'])
|
||||
address_bindings.append(binding)
|
||||
|
||||
return address_bindings
|
||||
|
||||
def _create_port_at_the_backend(self, context, port_data):
|
||||
#TODO(asarfaty): implement
|
||||
pass
|
||||
# TODO(annak): admin_state not supported by policy
|
||||
# TODO(annak): handle exclude list
|
||||
# TODO(annak): switching profiles when supported
|
||||
name = self._build_port_name(context, port_data)
|
||||
psec, has_ip = self._determine_port_security_and_has_ip(context,
|
||||
port_data)
|
||||
address_bindings = (self._build_address_bindings(port_data)
|
||||
if psec else None)
|
||||
device_owner = port_data.get('device_owner')
|
||||
vif_id = None
|
||||
if device_owner and device_owner != l3_db.DEVICE_OWNER_ROUTER_INTF:
|
||||
vif_id = port_data['id']
|
||||
|
||||
self.nsxpolicy.segment_port.create_or_overwrite(
|
||||
port_data['network_id'],
|
||||
port_data['id'],
|
||||
name,
|
||||
description=port_data.get('description'),
|
||||
address_bindings=address_bindings,
|
||||
vif_id=vif_id)
|
||||
|
||||
def _cleanup_port(self, context, port_id, lport_id):
|
||||
super(NsxPolicyPlugin, self).delete_port(context, port_id)
|
||||
#TODO(asarfaty): Delete the NSX logical port
|
||||
|
||||
port_data = self.get_port(context, port_id)
|
||||
self.nsxpolicy.segment_port.delete(
|
||||
port_data['network_id'], port_data['id'])
|
||||
|
||||
def base_create_port(self, context, port):
|
||||
neutron_db = super(NsxPolicyPlugin, self).create_port(context, port)
|
||||
@ -380,6 +471,8 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
neutron_db = self.base_create_port(context, port)
|
||||
port["port"].update(neutron_db)
|
||||
|
||||
self._create_port_address_pairs(context, port_data)
|
||||
|
||||
if not is_external_net:
|
||||
try:
|
||||
self._create_port_at_the_backend(context, port_data)
|
||||
@ -403,10 +496,15 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
l3_port_check=True, l2gw_port_check=True,
|
||||
force_delete_dhcp=False,
|
||||
force_delete_vpn=False):
|
||||
port = self.get_port(context, port_id)
|
||||
if not self._network_is_external(context, port['network_id']):
|
||||
#TODO(asarfaty): Delete the NSX logical port
|
||||
pass
|
||||
port_data = self.get_port(context, port_id)
|
||||
if not self._network_is_external(context, port_data['network_id']):
|
||||
try:
|
||||
self.nsxpolicy.segment_port.delete(
|
||||
port_data['network_id'], port_data['id'])
|
||||
except Exception as ex:
|
||||
LOG.error("Failed to delete port %(id)s on NSX backend "
|
||||
"due to %(e)s",
|
||||
{'id': port_data['id'], 'e': ex})
|
||||
|
||||
self.disassociate_floatingips(context, port_id)
|
||||
|
||||
@ -510,7 +608,22 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
context, router)
|
||||
router_db = self._get_router(context, router['id'])
|
||||
self._process_extra_attr_router_create(context, router_db, r)
|
||||
#TODO(asarfaty): Create the NSX logical router and add DB mapping
|
||||
|
||||
router_name = utils.get_name_and_uuid(router['name'] or 'router',
|
||||
router['id'])
|
||||
#TODO(annak): handle GW
|
||||
try:
|
||||
self.nsxpolicy.tier1.create_or_overwrite(
|
||||
router_name, router['id'],
|
||||
tier0=self.default_tier0_router)
|
||||
#TODO(annak): narrow down the exception
|
||||
except Exception as ex:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error('Failed to create router %(id)s '
|
||||
'on NSX backend. Exception: %(e)s',
|
||||
{'id': router['id'], 'e': ex})
|
||||
self.delete_router(context, router['id'])
|
||||
|
||||
LOG.debug("Created router %s: %s. GW info %s",
|
||||
router['id'], r, gw_info)
|
||||
return self.get_router(context, router['id'])
|
||||
@ -519,13 +632,14 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
router = self.get_router(context, router_id)
|
||||
if router.get(l3_apidef.EXTERNAL_GW_INFO):
|
||||
self._update_router_gw_info(context, router_id, {})
|
||||
nsx_router_id = nsx_db.get_nsx_router_id(
|
||||
context.session, router_id)
|
||||
ret_val = super(NsxPolicyPlugin, self).delete_router(
|
||||
context, router_id)
|
||||
if nsx_router_id:
|
||||
#TODO(asarfaty): delete the NSX logical router
|
||||
pass
|
||||
|
||||
try:
|
||||
self.nsxpolicy.tier1.delete(router_id)
|
||||
except Exception as ex:
|
||||
LOG.error("Failed to delete NSX T1 router %(id)s: %(e)s", {
|
||||
'e': ex, 'id': router_id})
|
||||
|
||||
return ret_val
|
||||
|
||||
@ -557,7 +671,23 @@ class NsxPolicyPlugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
info = super(NsxPolicyPlugin, self).add_router_interface(
|
||||
context, router_id, interface_info)
|
||||
|
||||
#TODO(asarfaty) Update the NSX logical router ports
|
||||
self._validate_interface_address_scope(context, router_db, info)
|
||||
subnet = self.get_subnet(context, info['subnet_ids'][0])
|
||||
|
||||
# TODO(annak): Validate TZ
|
||||
try:
|
||||
# This is always an overwrite call
|
||||
# NOTE: Connecting network to multiple routers is not supported
|
||||
self.nsxpolicy.segment.create_or_overwrite(network_id,
|
||||
tier1_id=router_id)
|
||||
except Exception as ex:
|
||||
with excutils.save_and_reraise_exception():
|
||||
LOG.error('Failed to create router interface for subnet '
|
||||
'%(id)s on NSX backend. Exception: %(e)s',
|
||||
{'id': subnet['id'], 'e': ex})
|
||||
self.remove_router_interface(
|
||||
context, router_id, interface_info)
|
||||
|
||||
return info
|
||||
|
||||
def remove_router_interface(self, context, router_id, interface_info):
|
||||
|
@ -1727,7 +1727,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
LOG.debug("Created logical DHCP server %(server)s for network "
|
||||
"%(network)s",
|
||||
{'server': dhcp_server['id'], 'network': network['id']})
|
||||
name = self._get_port_name(context, port_data)
|
||||
name = self._build_port_name(context, port_data)
|
||||
nsx_port = self.nsxlib.logical_port.create(
|
||||
nsx_net_id, dhcp_server['id'], tags=port_tags, name=name,
|
||||
attachment_type=nsxlib_consts.ATTACHMENT_DHCP,
|
||||
@ -2226,24 +2226,6 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
net_name or 'network'),
|
||||
net_id)
|
||||
|
||||
def _get_port_name(self, context, port_data):
|
||||
device_owner = port_data.get('device_owner')
|
||||
device_id = port_data.get('device_id')
|
||||
if device_owner == l3_db.DEVICE_OWNER_ROUTER_INTF and device_id:
|
||||
router = self._get_router(context, device_id)
|
||||
name = utils.get_name_and_uuid(
|
||||
router['name'] or 'router', port_data['id'], tag='port')
|
||||
elif device_owner == const.DEVICE_OWNER_DHCP:
|
||||
network = self.get_network(context, port_data['network_id'])
|
||||
name = self._get_dhcp_port_name(network['name'],
|
||||
network['id'])
|
||||
elif device_owner.startswith(const.DEVICE_OWNER_COMPUTE_PREFIX):
|
||||
name = utils.get_name_and_uuid(
|
||||
port_data['name'] or 'instance-port', port_data['id'])
|
||||
else:
|
||||
name = port_data['name']
|
||||
return name
|
||||
|
||||
def _get_qos_profile_id(self, context, policy_id):
|
||||
switch_profile_id = nsx_db.get_switch_profile_by_qos_policy(
|
||||
context.session, policy_id)
|
||||
@ -2378,7 +2360,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
profiles.append(self._mac_learning_profile)
|
||||
profiles.append(self._no_switch_security)
|
||||
|
||||
name = self._get_port_name(context, port_data)
|
||||
name = self._build_port_name(context, port_data)
|
||||
nsx_net_id = self._get_network_nsx_id(context, port_data['network_id'])
|
||||
try:
|
||||
result = self.nsxlib.logical_port.create(
|
||||
@ -2412,12 +2394,6 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
return result
|
||||
|
||||
def _validate_address_pairs(self, address_pairs):
|
||||
for pair in address_pairs:
|
||||
ip = pair.get('ip_address')
|
||||
if not utils.is_ipv4_ip_address(ip):
|
||||
raise nsx_exc.InvalidIPAddress(ip_address=ip)
|
||||
|
||||
def _provider_sgs_specified(self, port_data):
|
||||
# checks if security groups were updated adding/modifying
|
||||
# security groups, port security is set and port has ip
|
||||
@ -2462,18 +2438,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
context, port_data, neutron_db)
|
||||
|
||||
# allowed address pair checks
|
||||
address_pairs = port_data.get(addr_apidef.ADDRESS_PAIRS)
|
||||
if validators.is_attr_set(address_pairs):
|
||||
if not port_security:
|
||||
raise addr_exc.AddressPairAndPortSecurityRequired()
|
||||
else:
|
||||
self._validate_address_pairs(address_pairs)
|
||||
self._process_create_allowed_address_pairs(
|
||||
context, neutron_db,
|
||||
address_pairs)
|
||||
else:
|
||||
# remove ATTR_NOT_SPECIFIED
|
||||
port_data[addr_apidef.ADDRESS_PAIRS] = []
|
||||
self._create_port_address_pairs(context, port_data)
|
||||
|
||||
if port_security and has_ip:
|
||||
self._ensure_default_security_group_on_port(context, port)
|
||||
@ -3147,7 +3112,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
raise addr_exc.AddressPairAndPortSecurityRequired()
|
||||
|
||||
if delete_addr_pairs or has_addr_pairs:
|
||||
self._validate_address_pairs(
|
||||
self._validate_ipv4_address_pairs(
|
||||
updated_port[addr_apidef.ADDRESS_PAIRS])
|
||||
# delete address pairs and read them in
|
||||
self._delete_allowed_address_pairs(context, id)
|
||||
@ -3245,7 +3210,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
attachment_type = None
|
||||
vif_uuid = None
|
||||
|
||||
name = self._get_port_name(context, updated_port)
|
||||
name = self._build_port_name(context, updated_port)
|
||||
|
||||
# Update exclude list if necessary
|
||||
updated_ps = updated_port.get('port_security_enabled')
|
||||
@ -4333,9 +4298,7 @@ class NsxV3Plugin(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||
|
||||
# If it is a no-snat router, interface address scope must be the
|
||||
# same as the gateways
|
||||
if not router_db.enable_snat and gw_network_id:
|
||||
self._validate_address_scope_for_router_interface(
|
||||
context.elevated(), router_id, gw_network_id, subnet['id'])
|
||||
self._validate_interface_address_scope(context, router_db, info)
|
||||
|
||||
nsx_router_id = nsx_db.get_nsx_router_id(context.session,
|
||||
router_id)
|
||||
|
@ -37,11 +37,16 @@ class NsxPPluginTestCaseMixin(
|
||||
ext_mgr=ext_mgr)
|
||||
|
||||
def _mock_nsx_policy_backend_calls(self):
|
||||
resource_list_result = {'results': [{'id': 'test',
|
||||
'display_name': 'test'}]}
|
||||
mock.patch(
|
||||
"vmware_nsxlib.v3.NsxPolicyLib.get_version",
|
||||
return_value=nsx_constants.NSX_VERSION_2_4_0).start()
|
||||
mock.patch(
|
||||
"vmware_nsxlib.v3.client.RESTClient.get").start()
|
||||
mock.patch(
|
||||
"vmware_nsxlib.v3.client.RESTClient.list",
|
||||
return_value=resource_list_result).start()
|
||||
mock.patch(
|
||||
"vmware_nsxlib.v3.client.RESTClient.patch").start()
|
||||
mock.patch(
|
||||
|
Loading…
Reference in New Issue
Block a user