Allow provider net attr in update if no change

If provider net attributes are in update request body,
do an additional check to see if the values are actually
different. Only raise exception if values are different.

This backport partially picks change:
I2595335d6fbc51562b070f14eaeaadf49cf7c418. Specifically
the refactoring replacing the neutron.extensions.providernet
_raise_if_updates_provider_attributes method with the
neutron.plugins.ml2.plugin _update_provider_network_attributes
method.

Conflicts:
        neutron/extensions/providernet.py
	neutron/plugins/ml2/plugin.py
	neutron/tests/unit/plugins/ml2/test_plugin.py

Closes-Bug: #1822100
Co-Authored-By: Rodolfo Alonso Hernandez <ralonsoh@redhat.com>

Change-Id: I4ac11299375d1d3a7d2013f1fdc1742920d884a9
(cherry picked from commit 20743350b9)
This commit is contained in:
Rodolfo Alonso Hernandez 2019-04-02 16:57:17 +01:00 committed by Harald Jensås
parent f6652f0ee6
commit 234fcd61aa
3 changed files with 35 additions and 18 deletions

View File

@ -15,22 +15,6 @@
from neutron_lib.api.definitions import provider_net
from neutron_lib.api import extensions
from neutron_lib.api import validators
from neutron_lib import exceptions as n_exc
from neutron._i18n import _
def _raise_if_updates_provider_attributes(attrs):
"""Raise exception if provider attributes are present.
This method is used for plugins that do not support
updating provider networks.
"""
if any(validators.is_attr_set(attrs.get(a))
for a in provider_net.ATTRIBUTES):
msg = _("Plugin does not support updating provider attributes")
raise n_exc.InvalidInput(error_message=msg)
class Providernet(extensions.APIExtensionDescriptor):

View File

@ -107,7 +107,6 @@ from neutron.db import segments_db
from neutron.db import subnet_service_type_mixin
from neutron.db import vlantransparent_db
from neutron.extensions import filter_validation
from neutron.extensions import providernet as provider
from neutron.extensions import vlantransparent
from neutron.ipam import exceptions as ipam_exc
from neutron.objects import base as base_obj
@ -797,6 +796,22 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
segment[api.SEGMENTATION_ID],
segment[api.PHYSICAL_NETWORK])
def _update_provider_network_attributes(self, context, network, net_data):
"""Raise exception if provider network attrs update are not supported.
This function will raise an exception if the provider network attribute
update is not supported.
"""
provider_net_attrs = set(provider_net.ATTRIBUTES)
requested_provider_net_attrs = set(net_data) & provider_net_attrs
for attr in requested_provider_net_attrs:
if (validators.is_attr_set(net_data.get(attr)) and
net_data.get(attr) != network[attr]):
msg = (_('Plugin does not support updating the following '
'provider network attributes: %s') %
', '.join(provider_net_attrs))
raise exc.InvalidInput(error_message=msg)
def _delete_objects(self, context, resource, objects):
delete_op = getattr(self, 'delete_%s' % resource)
for obj in objects:
@ -985,11 +1000,12 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
@db_api.retry_if_session_inactive()
def update_network(self, context, id, network):
net_data = network[net_def.RESOURCE_NAME]
provider._raise_if_updates_provider_attributes(net_data)
need_network_update_notify = False
with db_api.CONTEXT_WRITER.using(context):
original_network = super(Ml2Plugin, self).get_network(context, id)
self._update_provider_network_attributes(
context, original_network, net_data)
updated_network = super(Ml2Plugin, self).update_network(context,
id,
network)

View File

@ -419,6 +419,23 @@ class TestMl2NetworksV2(test_plugin.TestNetworksV2,
self.assertEqual(3, f.call_count)
retry_fixture.cleanUp()
def test__update_provider_network_attributes_update_attrs(self):
plugin = directory.get_plugin()
kwargs = {'arg_list': (pnet.NETWORK_TYPE, ),
pnet.NETWORK_TYPE: 'vlan'}
with self.network(**kwargs) as net:
for attribute in set(pnet.ATTRIBUTES):
net_data = {attribute: net['network'][attribute]}
self.assertIsNone(
plugin._update_provider_network_attributes(
self.context, net['network'], net_data))
net_data = {attribute: 'other_value'}
self.assertRaises(
exc.InvalidInput,
plugin._update_provider_network_attributes,
self.context, net['network'], net_data)
class TestExternalNetwork(Ml2PluginV2TestCase):