Add support to regenerate port mac_address
Passing 'null' (None) as the mac address in a port update request causes the port's mac address to be re-generated using the base MAC address Neutron uses for VIFs. This change implementes a temporary lib api definition with a new converter that will generate valid mac if the data provided is None. APIImpact: Port mac_addr regenerated if None passed on update. Closes-Bug: #1768690 Change-Id: I7d04beea4810718c3b745de8ea97897b1323267e
This commit is contained in:
parent
9cb68ce777
commit
8f3a066b20
59
neutron/extensions/_port_mac_address_regenerate_lib.py
Normal file
59
neutron/extensions/_port_mac_address_regenerate_lib.py
Normal file
@ -0,0 +1,59 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
"""
|
||||
TODO(hjensas): This module should be deleted once neutron-lib containing
|
||||
Change-Id: Ibfcf179c2051d2bf47d4d1e62e8146cbee29fd64 is released.
|
||||
"""
|
||||
|
||||
from neutron_lib.api.definitions import port as port_def
|
||||
from neutron_lib import constants
|
||||
from neutron_lib.utils import net as net_utils
|
||||
from oslo_config import cfg
|
||||
|
||||
|
||||
def convert_to_mac_if_none(data):
|
||||
"""Convert to a random mac address if data is None
|
||||
|
||||
:param data: The data value
|
||||
:return: Random mac address if data is None, else return data.
|
||||
"""
|
||||
if data is None:
|
||||
return net_utils.get_random_mac(cfg.CONF.base_mac.split(':'))
|
||||
|
||||
return data
|
||||
|
||||
|
||||
NAME = 'Neutron Port MAC address regenerate'
|
||||
ALIAS = 'port-mac-address-regenerate'
|
||||
DESCRIPTION = "Network port MAC address regenerate"
|
||||
UPDATED_TIMESTAMP = "2018-05-03T10:00:00-00:00"
|
||||
|
||||
RESOURCE_ATTRIBUTE_MAP = {
|
||||
port_def.COLLECTION_NAME: {
|
||||
'mac_address': {'allow_post': True, 'allow_put': True,
|
||||
'default': constants.ATTR_NOT_SPECIFIED,
|
||||
'convert_to': convert_to_mac_if_none,
|
||||
'validate': {'type:mac_address': None},
|
||||
'enforce_policy': True,
|
||||
'is_visible': True},
|
||||
}
|
||||
}
|
||||
|
||||
IS_SHIM_EXTENSION = False
|
||||
IS_STANDARD_ATTR_EXTENSION = False
|
||||
SUB_RESOURCE_ATTRIBUTE_MAP = {}
|
||||
ACTION_MAP = {}
|
||||
REQUIRED_EXTENSIONS = []
|
||||
OPTIONAL_EXTENSIONS = []
|
||||
ACTION_STATUS = {}
|
24
neutron/extensions/port_mac_address_regenerate.py
Normal file
24
neutron/extensions/port_mac_address_regenerate.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# TODO(hjensas) When we have neutron-lib release, use it.
|
||||
# from neutron_lib.api.definitions import port_mac_address_regenerate as apidef
|
||||
|
||||
from neutron.extensions import _port_mac_address_regenerate_lib as apidef
|
||||
from neutron_lib.api import extensions as api_extensions
|
||||
|
||||
|
||||
class Port_mac_address_regenerate(api_extensions.APIExtensionDescriptor):
|
||||
"""Extension to support port MAC address regeneration"""
|
||||
|
||||
api_definition = apidef
|
@ -159,7 +159,8 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
"subnet-service-types",
|
||||
"ip-substring-filtering",
|
||||
"port-security-groups-filtering",
|
||||
"empty-string-filtering"]
|
||||
"empty-string-filtering",
|
||||
"port-mac-address-regenerate"]
|
||||
|
||||
@property
|
||||
def supported_extension_aliases(self):
|
||||
|
@ -40,6 +40,7 @@ NETWORK_API_EXTENSIONS+=",rbac-policies"
|
||||
NETWORK_API_EXTENSIONS+=",router"
|
||||
NETWORK_API_EXTENSIONS+=",router_availability_zone"
|
||||
NETWORK_API_EXTENSIONS+=",security-group"
|
||||
NETWORK_API_EXTENSIONS+=",port-mac-address-regenerate"
|
||||
NETWORK_API_EXTENSIONS+=",port-security-groups-filtering"
|
||||
NETWORK_API_EXTENSIONS+=",segment"
|
||||
NETWORK_API_EXTENSIONS+=",service-type"
|
||||
|
@ -962,6 +962,29 @@ class TestMl2PortsV2(test_plugin.TestPortsV2, Ml2PluginV2TestCase):
|
||||
host_arg={portbindings.HOST_ID: HOST},
|
||||
arg_list=(portbindings.HOST_ID,))
|
||||
|
||||
def test_update_port_regenerate_mac(self):
|
||||
ctx = context.get_admin_context()
|
||||
plugin = directory.get_plugin()
|
||||
data = {'port': {'mac_address': None}}
|
||||
with self.port() as port:
|
||||
current_mac = port['port']['mac_address']
|
||||
req = self.new_update_request('ports', data, port['port']['id'])
|
||||
self.assertEqual(200, req.get_response(self.api).status_int)
|
||||
new_mac = plugin.get_port(ctx, port['port']['id'])['mac_address']
|
||||
self.assertNotEqual(current_mac, new_mac)
|
||||
self.assertTrue(netaddr.valid_mac(new_mac))
|
||||
|
||||
def test_update_port_mac_does_not_change(self):
|
||||
ctx = context.get_admin_context()
|
||||
plugin = directory.get_plugin()
|
||||
data = {'port': {'description': 'Port Description'}}
|
||||
with self.port() as port:
|
||||
current_mac = port['port']['mac_address']
|
||||
req = self.new_update_request('ports', data, port['port']['id'])
|
||||
self.assertEqual(200, req.get_response(self.api).status_int)
|
||||
new_mac = plugin.get_port(ctx, port['port']['id'])['mac_address']
|
||||
self.assertEqual(current_mac, new_mac)
|
||||
|
||||
def test_update_non_existent_port(self):
|
||||
ctx = context.get_admin_context()
|
||||
plugin = directory.get_plugin()
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds api extenstion ``port-mac-address-regenerate``. When passing
|
||||
``'null'`` (``None``) as the ``mac_address`` on port update a converter
|
||||
will generate a new mac address that will be assigned to the port.
|
||||
`RFE: #1768690 <https://bugs.launchpad.net/neutron/+bug/1768690>`_.
|
Loading…
Reference in New Issue
Block a user