From cf91d7a2f46b4a8546169a4836cc64476fce44d8 Mon Sep 17 00:00:00 2001 From: LIU Yulong Date: Sun, 5 Nov 2017 12:05:09 +0800 Subject: [PATCH] Add floating IP qos_policy actions Now we can associate a qos policy to the floating IP, and dissociate it. The commands are: $ openstack floating ip create --qos-policy ... $ openstack floating ip set --qos-policy ... $ openstack floating ip set --no-qos-policy ... $ openstack floating ip unset --qos-policy These commands are based on the neutron change: I4efe9e49d268dffeb3df4de4ea1780152218633b Partially-Implements blueprint: floating-ip-rate-limit Change-Id: I932b32f78cc5a2b53926feaec1a0b392cf7e8b57 --- .../cli/command-objects/floating-ip.rst | 21 +++ openstackclient/network/v2/floating_ip.py | 42 +++++- .../tests/unit/network/v2/fakes.py | 1 + .../network/v2/test_floating_ip_network.py | 129 ++++++++++++++++++ ...oating-ip-rate-limit-8387c040a6fb9acd.yaml | 11 ++ 5 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 releasenotes/notes/bp-neutron-floating-ip-rate-limit-8387c040a6fb9acd.yaml diff --git a/doc/source/cli/command-objects/floating-ip.rst b/doc/source/cli/command-objects/floating-ip.rst index f2f101d3db..d9ed2307c3 100644 --- a/doc/source/cli/command-objects/floating-ip.rst +++ b/doc/source/cli/command-objects/floating-ip.rst @@ -18,6 +18,7 @@ Create floating IP [--floating-ip-address ] [--fixed-ip-address ] [--description ] + [--qos-policy ] [--project [--project-domain ]] @@ -46,6 +47,12 @@ Create floating IP Set floating IP description *Network version 2 only* +.. option:: --qos-policy + + QoS policy to attach to the floating IP (name or ID) + + *Network version 2 only* + .. option:: --project Owner's project (name or ID) @@ -154,6 +161,7 @@ Set floating IP properties openstack floating ip set --port [--fixed-ip-address ] + [--qos-policy | --no-qos-policy] .. option:: --port @@ -164,6 +172,14 @@ Set floating IP properties Fixed IP of the port (required only if port has multiple IPs) +.. option:: --qos-policy + + Attach QoS policy to the floating IP (name or ID) + +.. option:: --no-qos-policy + + Remove the QoS policy attached to the floating IP + .. _floating_ip_set-floating-ip: .. describe:: @@ -193,12 +209,17 @@ Unset floating IP Properties openstack floating ip unset --port + --qos-policy .. option:: --port Disassociate any port associated with the floating IP +.. option:: --qos-policy + + Remove the QoS policy attached to the floating IP + .. _floating_ip_unset-floating-ip: .. describe:: diff --git a/openstackclient/network/v2/floating_ip.py b/openstackclient/network/v2/floating_ip.py index 05b688a63d..181f88c054 100644 --- a/openstackclient/network/v2/floating_ip.py +++ b/openstackclient/network/v2/floating_ip.py @@ -67,6 +67,10 @@ def _get_attrs(client_manager, parsed_args): if parsed_args.fixed_ip_address: attrs['fixed_ip_address'] = parsed_args.fixed_ip_address + if parsed_args.qos_policy: + attrs['qos_policy_id'] = network_client.find_qos_policy( + parsed_args.qos_policy, ignore_missing=False).id + if parsed_args.description is not None: attrs['description'] = parsed_args.description @@ -169,6 +173,11 @@ class CreateFloatingIP(common.NetworkAndComputeShowOne): dest='fixed_ip_address', help=_("Fixed IP address mapped to the floating IP") ) + parser.add_argument( + '--qos-policy', + metavar='', + help=_("Attach QoS policy to the floating IP (name or ID)") + ) parser.add_argument( '--description', metavar='', @@ -462,6 +471,17 @@ class SetFloatingIP(command.Command): help=_("Fixed IP of the port " "(required only if port has multiple IPs)") ) + qos_policy_group = parser.add_mutually_exclusive_group() + qos_policy_group.add_argument( + '--qos-policy', + metavar='', + help=_("Attach QoS policy to the floating IP (name or ID)") + ) + qos_policy_group.add_argument( + '--no-qos-policy', + action='store_true', + help=_("Remove the QoS policy attached to the floating IP") + ) return parser def take_action(self, parsed_args): @@ -479,6 +499,13 @@ class SetFloatingIP(command.Command): if parsed_args.fixed_ip_address: attrs['fixed_ip_address'] = parsed_args.fixed_ip_address + if parsed_args.qos_policy: + attrs['qos_policy_id'] = client.find_qos_policy( + parsed_args.qos_policy, ignore_missing=False).id + + if 'no_qos_policy' in parsed_args and parsed_args.no_qos_policy: + attrs['qos_policy_id'] = None + client.update_ip(obj, **attrs) @@ -549,6 +576,12 @@ class UnsetFloatingIP(command.Command): default=False, help=_("Disassociate any port associated with the floating IP") ) + parser.add_argument( + '--qos-policy', + action='store_true', + default=False, + help=_("Remove the QoS policy attached to the floating IP") + ) return parser def take_action(self, parsed_args): @@ -559,8 +592,11 @@ class UnsetFloatingIP(command.Command): parsed_args.floating_ip, ignore_missing=False, ) + attrs = {} if parsed_args.port: - attrs = { - 'port_id': None, - } + attrs['port_id'] = None + if parsed_args.qos_policy: + attrs['qos_policy_id'] = None + + if attrs: client.update_ip(obj, **attrs) diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py index bdc1c1fb0e..a77cab8b5f 100644 --- a/openstackclient/tests/unit/network/v2/fakes.py +++ b/openstackclient/tests/unit/network/v2/fakes.py @@ -1378,6 +1378,7 @@ class FakeFloatingIP(object): 'port_id': 'port-id-' + uuid.uuid4().hex, 'tenant_id': 'project-id-' + uuid.uuid4().hex, 'description': 'floating-ip-description-' + uuid.uuid4().hex, + 'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex, } # Overwrite default attributes. diff --git a/openstackclient/tests/unit/network/v2/test_floating_ip_network.py b/openstackclient/tests/unit/network/v2/test_floating_ip_network.py index 4fbbc8227e..86f64ccd2e 100644 --- a/openstackclient/tests/unit/network/v2/test_floating_ip_network.py +++ b/openstackclient/tests/unit/network/v2/test_floating_ip_network.py @@ -62,6 +62,7 @@ class TestCreateFloatingIPNetwork(TestFloatingIPNetwork): 'id', 'port_id', 'project_id', + 'qos_policy_id', 'router_id', 'status', ) @@ -76,6 +77,7 @@ class TestCreateFloatingIPNetwork(TestFloatingIPNetwork): floating_ip.id, floating_ip.port_id, floating_ip.project_id, + floating_ip.qos_policy_id, floating_ip.router_id, floating_ip.status, ) @@ -197,6 +199,28 @@ class TestCreateFloatingIPNetwork(TestFloatingIPNetwork): self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) + def test_create_floating_ip_with_qos(self): + qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy() + self.network.find_qos_policy = mock.Mock(return_value=qos_policy) + arglist = [ + '--qos-policy', qos_policy.id, + self.floating_ip.floating_network_id, + ] + verifylist = [ + ('network', self.floating_ip.floating_network_id), + ('qos_policy', qos_policy.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.create_ip.assert_called_once_with(**{ + 'floating_network_id': self.floating_ip.floating_network_id, + 'qos_policy_id': qos_policy.id, + }) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + class TestDeleteFloatingIPNetwork(TestFloatingIPNetwork): @@ -538,6 +562,7 @@ class TestShowFloatingIPNetwork(TestFloatingIPNetwork): 'id', 'port_id', 'project_id', + 'qos_policy_id', 'router_id', 'status', ) @@ -552,6 +577,7 @@ class TestShowFloatingIPNetwork(TestFloatingIPNetwork): floating_ip.id, floating_ip.port_id, floating_ip.project_id, + floating_ip.qos_policy_id, floating_ip.router_id, floating_ip.status, ) @@ -677,6 +703,76 @@ class TestSetFloatingIP(TestFloatingIPNetwork): self.network.update_ip.assert_called_once_with( self.floating_ip, **attrs) + @mock.patch( + "openstackclient.tests.unit.network.v2.test_floating_ip_network." + + "fip._find_floating_ip" + ) + def test_port_and_qos_policy_option(self, find_floating_ip_mock): + qos_policy = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy() + self.network.find_qos_policy = mock.Mock(return_value=qos_policy) + find_floating_ip_mock.side_effect = [ + self.floating_ip, + ] + arglist = [ + "--qos-policy", qos_policy.id, + '--port', self.floating_ip.port_id, + self.floating_ip.id, + ] + verifylist = [ + ('qos_policy', qos_policy.id), + ('port', self.floating_ip.port_id), + ('floating_ip', self.floating_ip.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + attrs = { + 'qos_policy_id': qos_policy.id, + 'port_id': self.floating_ip.port_id, + } + find_floating_ip_mock.assert_called_once_with( + mock.ANY, + self.floating_ip.id, + ignore_missing=False, + ) + self.network.update_ip.assert_called_once_with( + self.floating_ip, **attrs) + + @mock.patch( + "openstackclient.tests.unit.network.v2.test_floating_ip_network." + + "fip._find_floating_ip" + ) + def test_port_and_no_qos_policy_option(self, find_floating_ip_mock): + find_floating_ip_mock.side_effect = [ + self.floating_ip, + ] + arglist = [ + "--no-qos-policy", + '--port', self.floating_ip.port_id, + self.floating_ip.id, + ] + verifylist = [ + ('no_qos_policy', True), + ('port', self.floating_ip.port_id), + ('floating_ip', self.floating_ip.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + + attrs = { + 'qos_policy_id': None, + 'port_id': self.floating_ip.port_id, + } + find_floating_ip_mock.assert_called_once_with( + mock.ANY, + self.floating_ip.id, + ignore_missing=False, + ) + self.network.update_ip.assert_called_once_with( + self.floating_ip, **attrs) + class TestUnsetFloatingIP(TestFloatingIPNetwork): @@ -732,3 +828,36 @@ class TestUnsetFloatingIP(TestFloatingIPNetwork): self.floating_ip, **attrs) self.assertIsNone(result) + + @mock.patch( + "openstackclient.tests.unit.network.v2.test_floating_ip_network." + + "fip._find_floating_ip" + ) + def test_floating_ip_unset_qos_policy(self, find_floating_ip_mock): + find_floating_ip_mock.side_effect = [ + self.floating_ip, + ] + arglist = [ + self.floating_ip.id, + "--qos-policy", + ] + verifylist = [ + ('floating_ip', self.floating_ip.id), + ('qos_policy', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + attrs = { + 'qos_policy_id': None, + } + find_floating_ip_mock.assert_called_once_with( + mock.ANY, + self.floating_ip.id, + ignore_missing=False, + ) + self.network.update_ip.assert_called_once_with( + self.floating_ip, **attrs) + + self.assertIsNone(result) diff --git a/releasenotes/notes/bp-neutron-floating-ip-rate-limit-8387c040a6fb9acd.yaml b/releasenotes/notes/bp-neutron-floating-ip-rate-limit-8387c040a6fb9acd.yaml new file mode 100644 index 0000000000..d0aa9cd121 --- /dev/null +++ b/releasenotes/notes/bp-neutron-floating-ip-rate-limit-8387c040a6fb9acd.yaml @@ -0,0 +1,11 @@ +--- +features: + - | + Add support for attaching and removing qos policy to floating IPs. + + Add option ``--qos-policy`` to the ``floating ip create`` and + ``floating ip set`` commands to add qos policy to a floating IP. + + Add option ``--no-qos-policy`` to the ``floating ip set`` and option + ``--qos-policy`` to the ``floating ip unset`` command to remove the + qos policy from a floating IP.