Merge "NSX|V: Support add/remove dvs for VLAN provider networks"
This commit is contained in:
commit
de74d22fb7
@ -81,6 +81,11 @@ def add_neutron_nsx_network_mapping(session, neutron_id, nsx_switch_id,
|
||||
return mapping
|
||||
|
||||
|
||||
def delete_neutron_nsx_network_mapping(session, neutron_id):
|
||||
return (session.query(nsx_models.NeutronNsxNetworkMapping).
|
||||
filter_by(neutron_id=neutron_id).delete())
|
||||
|
||||
|
||||
def add_neutron_nsx_port_mapping(session, neutron_id,
|
||||
nsx_switch_id, nsx_port_id):
|
||||
session.begin(subtransactions=True)
|
||||
|
@ -1496,21 +1496,21 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
return
|
||||
providernet._raise_if_updates_provider_attributes(attrs)
|
||||
|
||||
def _update_vlan_network_dvs_ids(self, network, new_physical_network,
|
||||
az_dvs):
|
||||
def _update_vlan_network_dvs_ids(self, context, network,
|
||||
new_physical_network, az_dvs):
|
||||
"""Update the dvs ids of a vlan provider network
|
||||
|
||||
The new values will be added to the current ones.
|
||||
No support for removing dvs-ids.
|
||||
The new values will replace the old ones.
|
||||
|
||||
Actions done in this function:
|
||||
- Create a backend network for each new dvs
|
||||
- Delete the backend networks for the old ones.
|
||||
- Return the relevant information in order to later also update
|
||||
the spoofguard policy, qos, network object and DB
|
||||
|
||||
Returns:
|
||||
- dvs_list_changed True/False
|
||||
- dvs_pg_mappings - mapping of the new elements dvs->moref
|
||||
- dvs_pg_mappings - updated mapping of the elements dvs->moref
|
||||
"""
|
||||
dvs_pg_mappings = {}
|
||||
|
||||
@ -1518,15 +1518,32 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
network[pnet.PHYSICAL_NETWORK], az_dvs))
|
||||
new_dvs_ids = set(self._get_dvs_ids(
|
||||
new_physical_network, az_dvs))
|
||||
additinal_dvs_ids = new_dvs_ids - current_dvs_ids
|
||||
additional_dvs_ids = new_dvs_ids - current_dvs_ids
|
||||
removed_dvs_ids = current_dvs_ids - new_dvs_ids
|
||||
|
||||
if not additinal_dvs_ids:
|
||||
if not additional_dvs_ids and not removed_dvs_ids:
|
||||
# no changes in the list of DVS
|
||||
return False, dvs_pg_mappings
|
||||
|
||||
# create all the new ones
|
||||
for dvs_id in additinal_dvs_ids:
|
||||
self._convert_to_transport_zones_dict(network)
|
||||
# get the current mapping as in the DB
|
||||
db_mapping = nsx_db.get_nsx_network_mappings(
|
||||
context.session, network['id'])
|
||||
for db_map in db_mapping:
|
||||
dvs_pg_mappings[db_map.dvs_id] = db_map.nsx_id
|
||||
|
||||
# delete old backend networks
|
||||
for dvs_id in removed_dvs_ids:
|
||||
nsx_id = dvs_pg_mappings.get(dvs_id)
|
||||
if nsx_id:
|
||||
#Note(asarfaty) This may fail if there is a vm deployed, but
|
||||
# since the delete is done offline we will not catch it here
|
||||
self._delete_backend_network(nsx_id, dvs_id)
|
||||
del dvs_pg_mappings[dvs_id]
|
||||
|
||||
# create all the new backend networks
|
||||
for dvs_id in additional_dvs_ids:
|
||||
try:
|
||||
self._convert_to_transport_zones_dict(network)
|
||||
net_moref = self._create_vlan_network_at_backend(
|
||||
dvs_id=dvs_id,
|
||||
net_data=network)
|
||||
@ -1585,12 +1602,12 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
c_utils.NsxVNetworkTypes.VLAN):
|
||||
(updated_morefs,
|
||||
new_dvs_pg_mappings) = self._update_vlan_network_dvs_ids(
|
||||
context,
|
||||
orig_net,
|
||||
net_attrs[pnet.PHYSICAL_NETWORK],
|
||||
az_dvs)
|
||||
if updated_morefs:
|
||||
new_dvs = list(new_dvs_pg_mappings.values())
|
||||
net_morefs.extend(new_dvs)
|
||||
net_morefs = list(new_dvs_pg_mappings.values())
|
||||
|
||||
with db_api.context_manager.writer.using(context):
|
||||
net_res = super(NsxVPluginV2, self).update_network(context, id,
|
||||
@ -1602,16 +1619,21 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
||||
self._process_l3_update(context, net_res, net_attrs)
|
||||
self._extend_network_dict_provider(context, net_res)
|
||||
if updated_morefs:
|
||||
# delete old mapping before recreating all
|
||||
nsx_db.delete_neutron_nsx_network_mapping(
|
||||
session=context.session, neutron_id=id)
|
||||
|
||||
# Save netmoref to dvs id mappings for VLAN network
|
||||
# type for future access.
|
||||
all_dvs = net_res.get(pnet.PHYSICAL_NETWORK)
|
||||
dvs_ids = []
|
||||
for dvs_id, netmoref in six.iteritems(new_dvs_pg_mappings):
|
||||
nsx_db.add_neutron_nsx_network_mapping(
|
||||
session=context.session,
|
||||
neutron_id=id,
|
||||
nsx_switch_id=netmoref,
|
||||
dvs_id=dvs_id)
|
||||
all_dvs = '%s, %s' % (all_dvs, dvs_id)
|
||||
dvs_ids.append(dvs_id)
|
||||
all_dvs = ', '.join(sorted(dvs_ids))
|
||||
net_res[pnet.PHYSICAL_NETWORK] = all_dvs
|
||||
vlan_id = net_res.get(pnet.SEGMENTATION_ID)
|
||||
nsxv_db.update_network_binding_phy_uuid(
|
||||
|
@ -502,7 +502,7 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
||||
# physical network attribute.
|
||||
self.assertEqual(2, vlan_net_call.call_count)
|
||||
|
||||
def test_update_vlan_network_with_multiple_dvs(self):
|
||||
def test_update_vlan_network_add_dvs(self):
|
||||
name = 'multi-dvs-vlan-net'
|
||||
providernet_args = {pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.SEGMENTATION_ID: 100,
|
||||
@ -510,7 +510,7 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
||||
p = directory.get_plugin()
|
||||
with mock.patch.object(
|
||||
p, '_create_vlan_network_at_backend',
|
||||
# Return three netmorefs as side effect
|
||||
# Return 3 netmorefs as side effect
|
||||
side_effect=[_uuid(), _uuid(), _uuid()]) as vlan_net_call:
|
||||
with self.network(name=name,
|
||||
providernet_args=providernet_args,
|
||||
@ -524,7 +524,8 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
||||
self.assertEqual('dvs-1, dvs-2',
|
||||
net['network'][pnet.PHYSICAL_NETWORK])
|
||||
# Add another dvs
|
||||
data = {'network': {pnet.PHYSICAL_NETWORK: 'dvs-3'}}
|
||||
data = {'network': {pnet.PHYSICAL_NETWORK:
|
||||
'dvs-1, dvs-2, dvs-3'}}
|
||||
req = self.new_update_request('networks', data,
|
||||
net['network']['id'])
|
||||
res = self.deserialize('json', req.get_response(self.api))
|
||||
@ -539,7 +540,6 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
||||
res['network'][pnet.PHYSICAL_NETWORK])
|
||||
|
||||
# update again - with no real change
|
||||
data = {'network': {pnet.PHYSICAL_NETWORK: 'dvs-3'}}
|
||||
req = self.new_update_request('networks', data,
|
||||
net['network']['id'])
|
||||
res = self.deserialize('json', req.get_response(self.api))
|
||||
@ -547,6 +547,45 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
||||
self.assertEqual('dvs-1, dvs-2, dvs-3',
|
||||
res['network'][pnet.PHYSICAL_NETWORK])
|
||||
|
||||
def test_update_vlan_network_remove_dvs(self):
|
||||
name = 'multi-dvs-vlan-net'
|
||||
providernet_args = {pnet.NETWORK_TYPE: 'vlan',
|
||||
pnet.SEGMENTATION_ID: 100,
|
||||
pnet.PHYSICAL_NETWORK: 'dvs-1, dvs-2'}
|
||||
p = directory.get_plugin()
|
||||
with mock.patch.object(
|
||||
p, '_create_vlan_network_at_backend',
|
||||
# Return 2 netmorefs as side effect
|
||||
side_effect=[_uuid(), _uuid()]) as vlan_net_call,\
|
||||
mock.patch.object(
|
||||
p, '_delete_backend_network') as del_net:
|
||||
with self.network(name=name,
|
||||
providernet_args=providernet_args,
|
||||
arg_list=(pnet.NETWORK_TYPE,
|
||||
pnet.SEGMENTATION_ID,
|
||||
pnet.PHYSICAL_NETWORK)) as net:
|
||||
# _create_vlan_network_at_backend is expected to be called
|
||||
# 2 times since we have 2 DVS IDs in the physical
|
||||
# network attribute.
|
||||
self.assertEqual(2, vlan_net_call.call_count)
|
||||
self.assertEqual('dvs-1, dvs-2',
|
||||
net['network'][pnet.PHYSICAL_NETWORK])
|
||||
# Keep only dvs-1 (Remove dvs-2)
|
||||
data = {'network': {pnet.PHYSICAL_NETWORK: 'dvs-1'}}
|
||||
req = self.new_update_request('networks', data,
|
||||
net['network']['id'])
|
||||
res = self.deserialize('json', req.get_response(self.api))
|
||||
self.assertEqual(2, vlan_net_call.call_count)
|
||||
del_net.assert_called_once()
|
||||
self.assertEqual('dvs-1',
|
||||
res['network'][pnet.PHYSICAL_NETWORK])
|
||||
|
||||
# make sure it is updates also in the DB
|
||||
req = self.new_show_request('networks', net['network']['id'])
|
||||
res = self.deserialize('json', req.get_response(self.api))
|
||||
self.assertEqual('dvs-1',
|
||||
res['network'][pnet.PHYSICAL_NETWORK])
|
||||
|
||||
def test_get_dvs_ids_for_multiple_dvs_vlan_network(self):
|
||||
p = directory.get_plugin()
|
||||
default_dvs = 'fake_dvs_id'
|
||||
|
Loading…
Reference in New Issue
Block a user