From 360dafe2328041c27afd4504c65379d826348013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Harald=20Jens=C3=A5s?= Date: Fri, 9 Nov 2018 15:42:32 +0100 Subject: [PATCH] Let neutron regenerate mac on port unbind Neutron change: I7d04beea4810718c3b745de8ea97897b1323267e added support in neutron to regenerate the mac address by passing None as the mac address on port update. Remove the _get_random_mac() method added in change: I11fff92e0a58ac68e795c003c14a336bceba6d89 and pass None in the port update request when unbinding ports instead. Story: #2004428 Task: #28090 Change-Id: I69a7ea0b1f86ceaa6912312460abee2ecdfca85b --- ironic/common/neutron.py | 25 +--------------- ironic/tests/unit/common/test_neutron.py | 37 ++++-------------------- 2 files changed, 7 insertions(+), 55 deletions(-) diff --git a/ironic/common/neutron.py b/ironic/common/neutron.py index 1486806496..609d832dfe 100644 --- a/ironic/common/neutron.py +++ b/ironic/common/neutron.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import random - from neutronclient.common import exceptions as neutron_exceptions from neutronclient.v2_0 import client as clientv20 from oslo_log import log @@ -40,26 +38,6 @@ PHYSNET_PARAM_NAME = 'provider:physical_network' SEGMENTS_PARAM_NAME = 'segments' """Name of the neutron network API segments parameter.""" -BASE_MAC = ['fa', '16', '3e', '00', '00', '00'] - - -def _get_random_mac(base_mac): - """Get a random MAC address string of the specified base format. - - The first 3 octets will remain unchanged. If the 4th octet is not - 00, it will also be used. The others will be randomly generated. - - :param base_mac: Base MAC address represented by an array of 6 strings/int - :returns: The MAC address string. - """ - - mac = [int(base_mac[0], 16), int(base_mac[1], 16), - int(base_mac[2], 16), random.getrandbits(8), - random.getrandbits(8), random.getrandbits(8)] - if base_mac[3] != '00': - mac[3] = int(base_mac[3], 16) - return ':'.join(["%02x" % x for x in mac]) - def _get_neutron_session(): global _NEUTRON_SESSION @@ -126,8 +104,7 @@ def unbind_neutron_port(port_id, client=None, context=None): body_unbind = {'port': {'binding:host_id': '', 'binding:profile': {}}} - body_reset_mac = {'port': { - 'mac_address': _get_random_mac(BASE_MAC)}} + body_reset_mac = {'port': {'mac_address': None}} try: client.update_port(port_id, body_unbind) diff --git a/ironic/tests/unit/common/test_neutron.py b/ironic/tests/unit/common/test_neutron.py index d871d5f219..f4a35601d7 100644 --- a/ironic/tests/unit/common/test_neutron.py +++ b/ironic/tests/unit/common/test_neutron.py @@ -10,8 +10,6 @@ # License for the specific language governing permissions and limitations # under the License. -import random - from keystoneauth1 import loading as kaloading import mock from neutronclient.common import exceptions as neutron_client_exc @@ -750,18 +748,14 @@ class TestUpdatePortAddress(base.TestCase): @mock.patch.object(neutron, 'get_client', autospec=True) -@mock.patch.object(neutron, '_get_random_mac', autospec=True) class TestUnbindPort(base.TestCase): def setUp(self): super(TestUnbindPort, self).setUp() self.context = context.RequestContext() - def test_unbind_neutron_port_client_passed(self, mock_random_mac, - mock_client): + def test_unbind_neutron_port_client_passed(self, mock_client): port_id = 'fake-port-id' - address = 'fe:54:00:77:07:d9' - mock_random_mac.return_value = address body_unbind = { 'port': { 'binding:host_id': '', @@ -770,7 +764,7 @@ class TestUnbindPort(base.TestCase): } body_reset_mac = { 'port': { - 'mac_address': address + 'mac_address': None } } update_calls = [ @@ -784,8 +778,7 @@ class TestUnbindPort(base.TestCase): mock_client.return_value.update_port.assert_has_calls(update_calls) @mock.patch.object(neutron, 'LOG', autospec=True) - def test_unbind_neutron_port_failure(self, mock_log, mock_random_mac, - mock_client): + def test_unbind_neutron_port_failure(self, mock_log, mock_client): mock_client.return_value.update_port.side_effect = ( neutron_client_exc.NeutronClientException()) body = { @@ -802,10 +795,8 @@ class TestUnbindPort(base.TestCase): body) mock_log.exception.assert_called_once() - def test_unbind_neutron_port(self, mock_random_mac, mock_client): + def test_unbind_neutron_port(self, mock_client): port_id = 'fake-port-id' - address = 'fe:54:00:77:07:d9' - mock_random_mac.return_value = address body_unbind = { 'port': { 'binding:host_id': '', @@ -814,7 +805,7 @@ class TestUnbindPort(base.TestCase): } body_reset_mac = { 'port': { - 'mac_address': address + 'mac_address': None } } update_calls = [ @@ -826,8 +817,7 @@ class TestUnbindPort(base.TestCase): mock_client.return_value.update_port.assert_has_calls(update_calls) @mock.patch.object(neutron, 'LOG', autospec=True) - def test_unbind_neutron_port_not_found(self, mock_log, mock_random_mac, - mock_client): + def test_unbind_neutron_port_not_found(self, mock_log, mock_client): port_id = 'fake-port-id' mock_client.return_value.update_port.side_effect = ( neutron_client_exc.PortNotFoundClient()) @@ -1068,18 +1058,3 @@ class TestGetPhysnetsByPortUUID(base.TestCase): fields=self.PORT_FIELDS) mock_gn.assert_called_once_with(self.client, network_uuid, fields=self.NETWORK_FIELDS) - - -class TestGetRandomMac(base.TestCase): - - @mock.patch.object(random, 'getrandbits', return_value=0xa2) - def test_first_4_octets_unchanged(self, mock_rnd): - mac = neutron._get_random_mac(['aa', 'bb', '00', 'dd', 'ee', 'ff']) - self.assertEqual('aa:bb:00:dd:a2:a2', mac) - mock_rnd.assert_called_with(8) - - @mock.patch.object(random, 'getrandbits', return_value=0xa2) - def test_first_4th_octet_generated(self, mock_rnd): - mac = neutron._get_random_mac(['aa', 'bb', 'cc', '00', 'ee', 'ff']) - self.assertEqual('aa:bb:cc:a2:a2:a2', mac) - mock_rnd.assert_called_with(8)