[NSX-P] Relax network update provider attribute validation
Allow updates in physical network id for network of type l3_ext in order to allow for re-wiring an external network to a different NSX Tier-0 GW router. Change-Id: I1e3dc1ed874c78d9db43a31ddf29f413e530a808
This commit is contained in:
parent
302cdd51a2
commit
425de96fec
|
@ -875,6 +875,30 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
||||||
if nsx_id in NET_NSX_2_NEUTRON_ID_CACHE:
|
if nsx_id in NET_NSX_2_NEUTRON_ID_CACHE:
|
||||||
del NET_NSX_2_NEUTRON_ID_CACHE[nsx_id]
|
del NET_NSX_2_NEUTRON_ID_CACHE[nsx_id]
|
||||||
|
|
||||||
|
def _raise_if_updates_provider_attributes(self, original_net, net_data):
|
||||||
|
# Neutron does not support changing provider network values
|
||||||
|
# except for chaging provider physical network on networks whose
|
||||||
|
# provider network_type is l3_ext
|
||||||
|
try:
|
||||||
|
utils.raise_if_updates_provider_attributes(net_data)
|
||||||
|
# No provider update
|
||||||
|
except n_exc.InvalidInput as e:
|
||||||
|
# if we end here provider attributes were specified
|
||||||
|
original_net_type = original_net.get(pnet_apidef.NETWORK_TYPE)
|
||||||
|
if original_net_type == utils.NetworkTypes.L3_EXT:
|
||||||
|
if (not validators.is_attr_set(net_data.get(
|
||||||
|
pnet_apidef.SEGMENTATION_ID)) and validators.is_attr_set(
|
||||||
|
net_data.get(pnet_apidef.PHYSICAL_NETWORK))):
|
||||||
|
# Ensure valid T0 router
|
||||||
|
self._validate_external_net_create(
|
||||||
|
net_data, None, self._tier0_validator)
|
||||||
|
LOG.info("Allowing update of l3_ext provider network "
|
||||||
|
"%s with physical network %s",
|
||||||
|
original_net['id'],
|
||||||
|
net_data.get(pnet_apidef.PHYSICAL_NETWORK))
|
||||||
|
return net_data.get(pnet_apidef.PHYSICAL_NETWORK)
|
||||||
|
raise e
|
||||||
|
|
||||||
def update_network(self, context, network_id, network):
|
def update_network(self, context, network_id, network):
|
||||||
original_net = super(NsxPolicyPlugin, self).get_network(
|
original_net = super(NsxPolicyPlugin, self).get_network(
|
||||||
context, network_id)
|
context, network_id)
|
||||||
|
@ -885,21 +909,45 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
||||||
net_data)
|
net_data)
|
||||||
self._assert_on_resource_admin_state_down(net_data)
|
self._assert_on_resource_admin_state_down(net_data)
|
||||||
|
|
||||||
# Neutron does not support changing provider network values
|
# Physical network for l3_ext can be changed
|
||||||
utils.raise_if_updates_provider_attributes(net_data)
|
new_provider_phy_net = self._raise_if_updates_provider_attributes(
|
||||||
|
original_net, net_data)
|
||||||
extern_net = self._network_is_external(context, network_id)
|
extern_net = self._network_is_external(context, network_id)
|
||||||
is_nsx_net = self._network_is_nsx_net(context, network_id)
|
is_nsx_net = self._network_is_nsx_net(context, network_id)
|
||||||
|
|
||||||
# Update the neutron network
|
# Update the neutron network
|
||||||
updated_net = super(NsxPolicyPlugin, self).update_network(
|
with db_api.CONTEXT_WRITER.using(context):
|
||||||
context, network_id, network)
|
updated_net = super(NsxPolicyPlugin, self).update_network(
|
||||||
|
context, network_id, network)
|
||||||
|
if new_provider_phy_net:
|
||||||
|
# Save provider network fields, needed by get_network()
|
||||||
|
curr_bindings = nsx_db.get_network_bindings(
|
||||||
|
context.session, network_id)
|
||||||
|
if curr_bindings:
|
||||||
|
nsx_db.delete_network_bindings(
|
||||||
|
context.session, network_id)
|
||||||
|
net_type = curr_bindings[0].binding_type
|
||||||
|
vlan_id = curr_bindings[0].vlan_id
|
||||||
|
else:
|
||||||
|
# This should never happen. However safe defaults can be
|
||||||
|
# set easily
|
||||||
|
LOG.warning("Bindings for provider network %s not found. "
|
||||||
|
"Setting defaults", network_id)
|
||||||
|
net_type = utils.NetworkTypes.L3_EXT
|
||||||
|
vlan_id = 0
|
||||||
|
|
||||||
|
net_bindings = [nsx_db.add_network_binding(
|
||||||
|
context.session, network_id,
|
||||||
|
net_type, new_provider_phy_net, vlan_id)]
|
||||||
|
self._extend_network_dict_provider(context, updated_net,
|
||||||
|
bindings=net_bindings)
|
||||||
|
|
||||||
self._extension_manager.process_update_network(context, net_data,
|
self._extension_manager.process_update_network(context, net_data,
|
||||||
updated_net)
|
updated_net)
|
||||||
if psec.PORTSECURITY in net_data:
|
if psec.PORTSECURITY in net_data:
|
||||||
self._process_network_port_security_update(
|
self._process_network_port_security_update(
|
||||||
context, net_data, updated_net)
|
context, net_data, updated_net)
|
||||||
self._process_l3_update(context, updated_net, network['network'])
|
self._process_l3_update(context, updated_net, network['network'])
|
||||||
self._extend_network_dict_provider(context, updated_net)
|
|
||||||
|
|
||||||
if qos_consts.QOS_POLICY_ID in net_data:
|
if qos_consts.QOS_POLICY_ID in net_data:
|
||||||
# attach the policy to the network in neutron DB
|
# attach the policy to the network in neutron DB
|
||||||
|
|
|
@ -592,6 +592,70 @@ class NsxPTestNetworks(test_db_base_plugin_v2.TestNetworksV2,
|
||||||
network['id'], data)
|
network['id'], data)
|
||||||
self.assertEqual(False, res['port_security_enabled'])
|
self.assertEqual(False, res['port_security_enabled'])
|
||||||
|
|
||||||
|
def test_update_network_l3_ext_provider(self):
|
||||||
|
with self._create_l3_ext_network() as network:
|
||||||
|
net_data = network['network']
|
||||||
|
data = {'network': {'id': net_data['id'],
|
||||||
|
'provider:network_type': 'l3_ext',
|
||||||
|
'provider:physical_network': 'other'}}
|
||||||
|
res = self.plugin.update_network(context.get_admin_context(),
|
||||||
|
net_data['id'], data)
|
||||||
|
self.assertEqual('other', res['provider:physical_network'])
|
||||||
|
|
||||||
|
def test_update_network_l3_ext_provider_segmentation_id_fails(self):
|
||||||
|
with self._create_l3_ext_network() as network:
|
||||||
|
net_data = network['network']
|
||||||
|
data = {'network': {'id': net_data['id'],
|
||||||
|
'provider:network_type': 'l3_ext',
|
||||||
|
'provider:physical_network': 'other',
|
||||||
|
'provider:segmentation_id': 666}}
|
||||||
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
|
self.plugin.update_network,
|
||||||
|
context.get_admin_context(),
|
||||||
|
net_data['id'], data)
|
||||||
|
|
||||||
|
def test_update_network_l3_ext_provider_no_original_prov_fails(self):
|
||||||
|
with self.network(name='test_no_prov') as network:
|
||||||
|
net_data = network['network']
|
||||||
|
data = {'network': {'id': net_data['id'],
|
||||||
|
'provider:network_type': 'l3_ext',
|
||||||
|
'provider:physical_network': 'other',
|
||||||
|
'provider:segmentation_id': 666}}
|
||||||
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
|
self.plugin.update_network,
|
||||||
|
context.get_admin_context(),
|
||||||
|
net_data['id'], data)
|
||||||
|
|
||||||
|
def test_update_network_no_prov_does_not_update_bindings(self):
|
||||||
|
with mock.patch(
|
||||||
|
'vmware_nsx.db.db.delete_network_bindings') as mock_del_bindings,\
|
||||||
|
mock.patch(
|
||||||
|
'vmware_nsx.db.db.add_network_binding') as mock_add_bindings,\
|
||||||
|
self.network(name='test_no_prov') as network:
|
||||||
|
net_data = network['network']
|
||||||
|
data = {'network': {'id': net_data['id'],
|
||||||
|
'name': 'new_name'}}
|
||||||
|
res = self.plugin.update_network(context.get_admin_context(),
|
||||||
|
net_data['id'], data)
|
||||||
|
self.assertEqual('new_name', res['name'])
|
||||||
|
mock_del_bindings.assert_not_called()
|
||||||
|
mock_add_bindings.assert_not_called()
|
||||||
|
|
||||||
|
def test_update_network_l3_ext_provider_other_original_prov_fails(self):
|
||||||
|
providernet_args = {pnet.NETWORK_TYPE: 'geneve'}
|
||||||
|
with self.network(name='test_geneve_net',
|
||||||
|
providernet_args=providernet_args,
|
||||||
|
arg_list=(pnet.NETWORK_TYPE, )) as network:
|
||||||
|
net_data = network['network']
|
||||||
|
data = {'network': {'id': net_data['id'],
|
||||||
|
'provider:network_type': 'l3_ext',
|
||||||
|
'provider:physical_network': 'other',
|
||||||
|
'provider:segmentation_id': 666}}
|
||||||
|
self.assertRaises(n_exc.InvalidInput,
|
||||||
|
self.plugin.update_network,
|
||||||
|
context.get_admin_context(),
|
||||||
|
net_data['id'], data)
|
||||||
|
|
||||||
|
|
||||||
class NsxPTestPorts(common_v3.NsxV3TestPorts,
|
class NsxPTestPorts(common_v3.NsxV3TestPorts,
|
||||||
common_v3.NsxV3SubnetMixin,
|
common_v3.NsxV3SubnetMixin,
|
||||||
|
|
Loading…
Reference in New Issue