Make MAC address of port updatable

openstackclient does not allow the update of a port's MAC address.
However this is possible in neutron API (though by default policy
it is an admin-only operation). Allow it in openstackclient too.

Change-Id: Ibd9e0a6fbd1d0d461b8a8daee24dbb7c3f929df6
Closes-Bug: #1670707
This commit is contained in:
Bence Romsics 2017-03-07 15:54:31 +01:00 committed by Dean Troyer
parent b6f51cdfa0
commit f1345dc06f
5 changed files with 55 additions and 7 deletions

View File

@ -219,6 +219,7 @@ Set port properties
[--host <host-id>] [--host <host-id>]
[--enable | --disable] [--enable | --disable]
[--name <name>] [--name <name>]
[--mac-address <mac-address>]
[--security-group <security-group>] [--security-group <security-group>]
[--no-security-group] [--no-security-group]
[--enable-port-security | --disable-port-security] [--enable-port-security | --disable-port-security]
@ -285,6 +286,10 @@ Set port properties
Set port name Set port name
.. option:: --mac-address
Set port's MAC address (admin only)
.. option:: --security-group <security-group> .. option:: --security-group <security-group>
Security group to associate with this port (name or ID) Security group to associate with this port (name or ID)

View File

@ -130,6 +130,8 @@ def _get_attrs(client_manager, parsed_args):
attrs['binding:vnic_type'] = parsed_args.vnic_type attrs['binding:vnic_type'] = parsed_args.vnic_type
if parsed_args.host: if parsed_args.host:
attrs['binding:host_id'] = parsed_args.host attrs['binding:host_id'] = parsed_args.host
if parsed_args.mac_address is not None:
attrs['mac_address'] = parsed_args.mac_address
if parsed_args.dns_name is not None: if parsed_args.dns_name is not None:
attrs['dns_name'] = parsed_args.dns_name attrs['dns_name'] = parsed_args.dns_name
@ -138,8 +140,6 @@ def _get_attrs(client_manager, parsed_args):
attrs['name'] = str(parsed_args.name) attrs['name'] = str(parsed_args.name)
# The remaining options do not support 'port set' command, so they require # The remaining options do not support 'port set' command, so they require
# additional check # additional check
if 'mac_address' in parsed_args and parsed_args.mac_address is not None:
attrs['mac_address'] = parsed_args.mac_address
if 'network' in parsed_args and parsed_args.network is not None: if 'network' in parsed_args and parsed_args.network is not None:
attrs['network_id'] = parsed_args.network attrs['network_id'] = parsed_args.network
if 'project' in parsed_args and parsed_args.project is not None: if 'project' in parsed_args and parsed_args.project is not None:
@ -234,6 +234,11 @@ def _add_updatable_args(parser):
metavar='<device-id>', metavar='<device-id>',
help=argparse.SUPPRESS, help=argparse.SUPPRESS,
) )
parser.add_argument(
'--mac-address',
metavar='<mac-address>',
help=_("MAC address of this port (admin only)")
)
parser.add_argument( parser.add_argument(
'--device-owner', '--device-owner',
metavar='<device-owner>', metavar='<device-owner>',
@ -324,11 +329,6 @@ class CreatePort(command.ShowOne):
action='store_true', action='store_true',
help=_("Disable port") help=_("Disable port")
) )
parser.add_argument(
'--mac-address',
metavar='<mac-address>',
help=_("MAC address of this port")
)
parser.add_argument( parser.add_argument(
'--project', '--project',
metavar='<project>', metavar='<project>',

View File

@ -147,3 +147,22 @@ class PortTests(base.TestCase):
'port show -f json ' + self.NAME 'port show -f json ' + self.NAME
)) ))
self.assertEqual('', json_output.get('security_group_ids')) self.assertEqual('', json_output.get('security_group_ids'))
def test_port_admin_set(self):
"""Test create, set (as admin), show, delete"""
json_output = json.loads(self.openstack(
'port create -f json ' +
'--network ' + self.NETWORK_NAME + ' ' + self.NAME
))
id_ = json_output.get('id')
self.addCleanup(self.openstack, 'port delete ' + id_)
raw_output = self.openstack(
'--os-username admin '
+ 'port set --mac-address 11:22:33:44:55:66 '
+ self.NAME)
self.assertOutput('', raw_output)
json_output = json.loads(self.openstack(
'port show -f json ' + self.NAME
))
self.assertEqual(json_output.get('mac_address'), '11:22:33:44:55:66')

View File

@ -987,6 +987,25 @@ class TestSetPort(TestPort):
self.network.update_port.assert_called_once_with(_testport, **attrs) self.network.update_port.assert_called_once_with(_testport, **attrs)
self.assertIsNone(result) self.assertIsNone(result)
def test_overwrite_mac_address(self):
_testport = network_fakes.FakePort.create_one_port(
{'mac_address': '11:22:33:44:55:66'})
self.network.find_port = mock.Mock(return_value=_testport)
arglist = [
'--mac-address', '66:55:44:33:22:11',
_testport.name,
]
verifylist = [
('mac_address', '66:55:44:33:22:11'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
attrs = {
'mac_address': '66:55:44:33:22:11',
}
self.network.update_port.assert_called_once_with(_testport, **attrs)
self.assertIsNone(result)
def test_set_this(self): def test_set_this(self):
arglist = [ arglist = [
'--disable', '--disable',

View File

@ -0,0 +1,5 @@
---
fixes:
- |
Add ``--mac-address`` option to ``port set`` command.
[Bug `1670707 <https://launchpad.net/bugs/1670707>`_]