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
|
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,
|
def add_neutron_nsx_port_mapping(session, neutron_id,
|
||||||
nsx_switch_id, nsx_port_id):
|
nsx_switch_id, nsx_port_id):
|
||||||
session.begin(subtransactions=True)
|
session.begin(subtransactions=True)
|
||||||
|
@ -1496,21 +1496,21 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
return
|
return
|
||||||
providernet._raise_if_updates_provider_attributes(attrs)
|
providernet._raise_if_updates_provider_attributes(attrs)
|
||||||
|
|
||||||
def _update_vlan_network_dvs_ids(self, network, new_physical_network,
|
def _update_vlan_network_dvs_ids(self, context, network,
|
||||||
az_dvs):
|
new_physical_network, az_dvs):
|
||||||
"""Update the dvs ids of a vlan provider network
|
"""Update the dvs ids of a vlan provider network
|
||||||
|
|
||||||
The new values will be added to the current ones.
|
The new values will replace the old ones.
|
||||||
No support for removing dvs-ids.
|
|
||||||
|
|
||||||
Actions done in this function:
|
Actions done in this function:
|
||||||
- Create a backend network for each new dvs
|
- 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
|
- Return the relevant information in order to later also update
|
||||||
the spoofguard policy, qos, network object and DB
|
the spoofguard policy, qos, network object and DB
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
- dvs_list_changed True/False
|
- 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 = {}
|
dvs_pg_mappings = {}
|
||||||
|
|
||||||
@ -1518,15 +1518,32 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
network[pnet.PHYSICAL_NETWORK], az_dvs))
|
network[pnet.PHYSICAL_NETWORK], az_dvs))
|
||||||
new_dvs_ids = set(self._get_dvs_ids(
|
new_dvs_ids = set(self._get_dvs_ids(
|
||||||
new_physical_network, az_dvs))
|
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
|
return False, dvs_pg_mappings
|
||||||
|
|
||||||
# create all the new ones
|
self._convert_to_transport_zones_dict(network)
|
||||||
for dvs_id in additinal_dvs_ids:
|
# 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:
|
try:
|
||||||
self._convert_to_transport_zones_dict(network)
|
|
||||||
net_moref = self._create_vlan_network_at_backend(
|
net_moref = self._create_vlan_network_at_backend(
|
||||||
dvs_id=dvs_id,
|
dvs_id=dvs_id,
|
||||||
net_data=network)
|
net_data=network)
|
||||||
@ -1585,12 +1602,12 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin,
|
|||||||
c_utils.NsxVNetworkTypes.VLAN):
|
c_utils.NsxVNetworkTypes.VLAN):
|
||||||
(updated_morefs,
|
(updated_morefs,
|
||||||
new_dvs_pg_mappings) = self._update_vlan_network_dvs_ids(
|
new_dvs_pg_mappings) = self._update_vlan_network_dvs_ids(
|
||||||
|
context,
|
||||||
orig_net,
|
orig_net,
|
||||||
net_attrs[pnet.PHYSICAL_NETWORK],
|
net_attrs[pnet.PHYSICAL_NETWORK],
|
||||||
az_dvs)
|
az_dvs)
|
||||||
if updated_morefs:
|
if updated_morefs:
|
||||||
new_dvs = list(new_dvs_pg_mappings.values())
|
net_morefs = list(new_dvs_pg_mappings.values())
|
||||||
net_morefs.extend(new_dvs)
|
|
||||||
|
|
||||||
with db_api.context_manager.writer.using(context):
|
with db_api.context_manager.writer.using(context):
|
||||||
net_res = super(NsxVPluginV2, self).update_network(context, id,
|
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._process_l3_update(context, net_res, net_attrs)
|
||||||
self._extend_network_dict_provider(context, net_res)
|
self._extend_network_dict_provider(context, net_res)
|
||||||
if updated_morefs:
|
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
|
# Save netmoref to dvs id mappings for VLAN network
|
||||||
# type for future access.
|
# 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):
|
for dvs_id, netmoref in six.iteritems(new_dvs_pg_mappings):
|
||||||
nsx_db.add_neutron_nsx_network_mapping(
|
nsx_db.add_neutron_nsx_network_mapping(
|
||||||
session=context.session,
|
session=context.session,
|
||||||
neutron_id=id,
|
neutron_id=id,
|
||||||
nsx_switch_id=netmoref,
|
nsx_switch_id=netmoref,
|
||||||
dvs_id=dvs_id)
|
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
|
net_res[pnet.PHYSICAL_NETWORK] = all_dvs
|
||||||
vlan_id = net_res.get(pnet.SEGMENTATION_ID)
|
vlan_id = net_res.get(pnet.SEGMENTATION_ID)
|
||||||
nsxv_db.update_network_binding_phy_uuid(
|
nsxv_db.update_network_binding_phy_uuid(
|
||||||
|
@ -502,7 +502,7 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
|||||||
# physical network attribute.
|
# physical network attribute.
|
||||||
self.assertEqual(2, vlan_net_call.call_count)
|
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'
|
name = 'multi-dvs-vlan-net'
|
||||||
providernet_args = {pnet.NETWORK_TYPE: 'vlan',
|
providernet_args = {pnet.NETWORK_TYPE: 'vlan',
|
||||||
pnet.SEGMENTATION_ID: 100,
|
pnet.SEGMENTATION_ID: 100,
|
||||||
@ -510,7 +510,7 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
|||||||
p = directory.get_plugin()
|
p = directory.get_plugin()
|
||||||
with mock.patch.object(
|
with mock.patch.object(
|
||||||
p, '_create_vlan_network_at_backend',
|
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:
|
side_effect=[_uuid(), _uuid(), _uuid()]) as vlan_net_call:
|
||||||
with self.network(name=name,
|
with self.network(name=name,
|
||||||
providernet_args=providernet_args,
|
providernet_args=providernet_args,
|
||||||
@ -524,7 +524,8 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
|||||||
self.assertEqual('dvs-1, dvs-2',
|
self.assertEqual('dvs-1, dvs-2',
|
||||||
net['network'][pnet.PHYSICAL_NETWORK])
|
net['network'][pnet.PHYSICAL_NETWORK])
|
||||||
# Add another dvs
|
# 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,
|
req = self.new_update_request('networks', data,
|
||||||
net['network']['id'])
|
net['network']['id'])
|
||||||
res = self.deserialize('json', req.get_response(self.api))
|
res = self.deserialize('json', req.get_response(self.api))
|
||||||
@ -539,7 +540,6 @@ class TestNetworksV2(test_plugin.TestNetworksV2, NsxVPluginV2TestCase):
|
|||||||
res['network'][pnet.PHYSICAL_NETWORK])
|
res['network'][pnet.PHYSICAL_NETWORK])
|
||||||
|
|
||||||
# update again - with no real change
|
# update again - with no real change
|
||||||
data = {'network': {pnet.PHYSICAL_NETWORK: 'dvs-3'}}
|
|
||||||
req = self.new_update_request('networks', data,
|
req = self.new_update_request('networks', data,
|
||||||
net['network']['id'])
|
net['network']['id'])
|
||||||
res = self.deserialize('json', req.get_response(self.api))
|
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',
|
self.assertEqual('dvs-1, dvs-2, dvs-3',
|
||||||
res['network'][pnet.PHYSICAL_NETWORK])
|
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):
|
def test_get_dvs_ids_for_multiple_dvs_vlan_network(self):
|
||||||
p = directory.get_plugin()
|
p = directory.get_plugin()
|
||||||
default_dvs = 'fake_dvs_id'
|
default_dvs = 'fake_dvs_id'
|
||||||
|
Loading…
Reference in New Issue
Block a user