From 5ff2cfd042de7afc4323a3b306ff5be1882fba46 Mon Sep 17 00:00:00 2001 From: Ha Van Tu Date: Thu, 12 Jan 2017 09:57:53 +0700 Subject: [PATCH] Add "qos-policy" option to "port create" & "port set" This patch adds "qos-policy" option to "port create" command, and "qos-policy", "no-qos-policy" options to "port set" command and "qos-policy" option to "port unset". Change-Id: I78072e1ff0dd30a2e23a0fb833ce6ab5cf246016 Co-Authored-By: Nguyen Phuong An Co-Authored-By: Rodolfo Alonso Hernandez Partial-Bug: #1612136 Partially-Implements: blueprint network-commands-options --- doc/source/command-objects/port.rst | 15 +++++ openstackclient/network/v2/port.py | 32 +++++++++- .../tests/unit/network/v2/fakes.py | 2 + .../tests/unit/network/v2/test_port.py | 60 ++++++++++++++++++- .../notes/bug-1612136-ec240349a933db12.yaml | 6 ++ 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/bug-1612136-ec240349a933db12.yaml diff --git a/doc/source/command-objects/port.rst b/doc/source/command-objects/port.rst index ddfbb445b3..b3f4c7f9fd 100644 --- a/doc/source/command-objects/port.rst +++ b/doc/source/command-objects/port.rst @@ -30,6 +30,7 @@ Create new port [--security-group | --no-security-group] [--dns-name ] [--allowed-address ip-address=[,mac-address=]] + [--qos-policy ] [--project [--project-domain ]] [--enable-port-security | --disable-port-security] @@ -104,6 +105,10 @@ Create new port ip-address=[,mac-address=] (repeat option to set multiple allowed-address pairs) +.. option:: --qos-policy + + Attach QoS policy to this port (name or ID) + .. option:: --project Owner's project (name or ID) @@ -217,6 +222,7 @@ Set port properties [--binding-profile ] [--no-binding-profile] [--host ] + [--qos-policy ] [--enable | --disable] [--name ] [--mac-address ] @@ -274,6 +280,10 @@ Set port properties Allocate port on host ```` (ID only) +.. option:: --qos-policy + + Attach QoS policy to this port (name or ID) + .. option:: --enable Enable port @@ -359,6 +369,7 @@ Unset port properties [--binding-profile [...]] [--security-group [...]] [--allowed-address ip-address=[,mac-address=] [...]] + [--qos-policy] .. option:: --fixed-ip subnet=,ip-address= @@ -383,6 +394,10 @@ Unset port properties ip-address=[,mac-address=] (repeat option to unset multiple allowed-address pairs) +.. option:: --qos-policy + + Remove the QoS policy attached to the port + .. _port_unset-port: .. describe:: diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py index 9d598fabec..3a32916b78 100644 --- a/openstackclient/network/v2/port.py +++ b/openstackclient/network/v2/port.py @@ -155,6 +155,13 @@ def _get_attrs(client_manager, parsed_args): if parsed_args.enable_port_security: attrs['port_security_enabled'] = True + if 'no_qos_policy' in parsed_args and parsed_args.no_qos_policy: + attrs['qos_policy_id'] = None + + if parsed_args.qos_policy: + attrs['qos_policy_id'] = client_manager.network.find_qos_policy( + parsed_args.qos_policy, ignore_missing=False).id + return attrs @@ -337,7 +344,7 @@ class CreatePort(command.ShowOne): help=_("Name of this port") ) # TODO(singhj): Add support for extended options: - # qos,dhcp + # dhcp secgroups = parser.add_mutually_exclusive_group() secgroups.add_argument( '--security-group', @@ -353,6 +360,11 @@ class CreatePort(command.ShowOne): action='store_true', help=_("Associate no security groups with this port") ) + parser.add_argument( + '--qos-policy', + metavar='', + help=_("Attach QoS policy to this port (name or ID)") + ) port_security = parser.add_mutually_exclusive_group() port_security.add_argument( '--enable-port-security', @@ -403,6 +415,9 @@ class CreatePort(command.ShowOne): attrs['allowed_address_pairs'] = ( _convert_address_pairs(parsed_args)) + if parsed_args.qos_policy: + attrs['qos_policy_id'] = client.find_qos_policy( + parsed_args.qos_policy, ignore_missing=False).id obj = client.create_port(**attrs) display_columns, columns = _get_columns(obj) data = utils.get_item_properties(obj, columns, formatters=_formatters) @@ -619,6 +634,11 @@ class SetPort(command.Command): "Specify both --binding-profile and --no-binding-profile " "to overwrite the current binding:profile information.") ) + parser.add_argument( + '--qos-policy', + metavar='', + help=_("Attach QoS policy to this port (name or ID)") + ) parser.add_argument( 'port', metavar="", @@ -675,8 +695,8 @@ class SetPort(command.Command): client = self.app.client_manager.network _prepare_fixed_ips(self.app.client_manager, parsed_args) - attrs = _get_attrs(self.app.client_manager, parsed_args) obj = client.find_port(parsed_args.port, ignore_missing=False) + attrs = _get_attrs(self.app.client_manager, parsed_args) if parsed_args.no_binding_profile: attrs['binding:profile'] = {} @@ -794,6 +814,12 @@ class UnsetPort(command.Command): "[,mac-address=] (repeat option to set " "multiple allowed-address pairs)") ) + parser.add_argument( + '--qos-policy', + action='store_true', + default=False, + help=_("Remove the QoS policy attached to the port") + ) return parser @@ -843,6 +869,8 @@ class UnsetPort(command.Command): msg = _("Port does not contain allowed-address-pair %s") % addr raise exceptions.CommandError(msg) attrs['allowed_address_pairs'] = tmp_addr_pairs + if parsed_args.qos_policy: + attrs['qos_policy_id'] = None if attrs: client.update_port(obj, **attrs) diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py index d3685409a1..9a2899419c 100644 --- a/openstackclient/tests/unit/network/v2/fakes.py +++ b/openstackclient/tests/unit/network/v2/fakes.py @@ -572,6 +572,7 @@ class FakePort(object): 'security_group_ids': [], 'status': 'ACTIVE', 'tenant_id': 'project-id-' + uuid.uuid4().hex, + 'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex, } # Overwrite default attributes. @@ -590,6 +591,7 @@ class FakePort(object): port.is_port_security_enabled = port_attrs['port_security_enabled'] port.project_id = port_attrs['tenant_id'] port.security_group_ids = port_attrs['security_group_ids'] + port.qos_policy_id = port_attrs['qos_policy_id'] return port diff --git a/openstackclient/tests/unit/network/v2/test_port.py b/openstackclient/tests/unit/network/v2/test_port.py index 701af8790b..851bf25ad2 100644 --- a/openstackclient/tests/unit/network/v2/test_port.py +++ b/openstackclient/tests/unit/network/v2/test_port.py @@ -57,6 +57,7 @@ class TestPort(network_fakes.TestNetworkV2): 'network_id', 'port_security_enabled', 'project_id', + 'qos_policy_id', 'security_group_ids', 'status', ) @@ -82,6 +83,7 @@ class TestPort(network_fakes.TestNetworkV2): fake_port.network_id, fake_port.port_security_enabled, fake_port.project_id, + fake_port.qos_policy_id, utils.format_list(fake_port.security_group_ids), fake_port.status, ) @@ -422,6 +424,35 @@ class TestCreatePort(TestPort): self.assertEqual(ref_columns, columns) self.assertEqual(ref_data, data) + def test_create_port_with_qos(self): + qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy() + self.network.find_qos_policy = mock.Mock(return_value=qos_policy) + arglist = [ + '--network', self._port.network_id, + '--qos-policy', qos_policy.id, + 'test-port', + ] + verifylist = [ + ('network', self._port.network_id,), + ('enable', True), + ('qos_policy', qos_policy.id), + ('name', 'test-port'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_port.assert_called_once_with(**{ + 'admin_state_up': True, + 'network_id': self._port.network_id, + 'qos_policy_id': qos_policy.id, + 'name': 'test-port', + }) + + ref_columns, ref_data = self._get_common_cols_data(self._port) + self.assertEqual(ref_columns, columns) + self.assertEqual(ref_data, data) + def test_create_port_security_enabled(self): arglist = [ '--network', self._port.network_id, @@ -1316,6 +1347,30 @@ class TestSetPort(TestPort): 'port_security_enabled': False, }) + def test_set_port_with_qos(self): + qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy() + self.network.find_qos_policy = mock.Mock(return_value=qos_policy) + _testport = network_fakes.FakePort.create_one_port( + {'qos_policy_id': None}) + self.network.find_port = mock.Mock(return_value=_testport) + arglist = [ + '--qos-policy', qos_policy.id, + _testport.name, + ] + verifylist = [ + ('qos_policy', qos_policy.id), + ('port', _testport.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + attrs = { + 'qos_policy_id': qos_policy.id, + } + self.network.update_port.assert_called_once_with(_testport, **attrs) + self.assertIsNone(result) + class TestShowPort(TestPort): @@ -1379,6 +1434,7 @@ class TestUnsetPort(TestPort): '--fixed-ip', 'subnet=042eb10a-3a18-4658-ab-cf47c8d03152,ip-address=1.0.0.0', '--binding-profile', 'Superman', + '--qos-policy', self._testport.name, ] verifylist = [ @@ -1386,6 +1442,7 @@ class TestUnsetPort(TestPort): 'subnet': '042eb10a-3a18-4658-ab-cf47c8d03152', 'ip-address': '1.0.0.0'}]), ('binding_profile', ['Superman']), + ('qos_policy', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -1395,7 +1452,8 @@ class TestUnsetPort(TestPort): 'fixed_ips': [{ 'subnet_id': '042eb10a-3a18-4658-ab-cf47c8d03152', 'ip_address': '0.0.0.1'}], - 'binding:profile': {'batman': 'Joker'} + 'binding:profile': {'batman': 'Joker'}, + 'qos_policy_id': None } self.network.update_port.assert_called_once_with( self._testport, **attrs) diff --git a/releasenotes/notes/bug-1612136-ec240349a933db12.yaml b/releasenotes/notes/bug-1612136-ec240349a933db12.yaml new file mode 100644 index 0000000000..42872966b5 --- /dev/null +++ b/releasenotes/notes/bug-1612136-ec240349a933db12.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Add ``--qos-policy`` option to ``port create``, ``port set`` and + ``port unset`` commands. + [Bug `1612136 `_]