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
This commit is contained in:
Harald Jensås 2018-11-09 15:42:32 +01:00
parent 9dd732a695
commit 360dafe232
2 changed files with 7 additions and 55 deletions

View File

@ -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)

View File

@ -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)