From b51310a4bb5997137a4b6c0cf3517f481e178474 Mon Sep 17 00:00:00 2001 From: Shashank Kumar Shankar Date: Mon, 28 Nov 2016 21:10:52 +0000 Subject: [PATCH] Introduce neutron flavor associate, disassociate to OSC This patch introduces network flavor associate and disassociate to OSC. The following neutron equivalent commands are implemented in OSC: - neutron flavor-associate - neutron flavor-disassociate Change-Id: Icba4dbf7300a36353142586359059cd6784049dc --- doc/source/command-objects/network-flavor.rst | 44 ++++++++++ openstackclient/network/v2/network_flavor.py | 57 +++++++++++++ .../network/v2/test_network_flavor.py | 51 +++++++++++ .../unit/network/v2/test_network_flavor.py | 84 +++++++++++++++++++ ...utron-client-flavors-81387171f67a3c82.yaml | 5 ++ setup.cfg | 2 + 6 files changed, 243 insertions(+) create mode 100644 releasenotes/notes/neutron-client-flavors-81387171f67a3c82.yaml diff --git a/doc/source/command-objects/network-flavor.rst b/doc/source/command-objects/network-flavor.rst index 0723eb12d..2d23bf056 100644 --- a/doc/source/command-objects/network-flavor.rst +++ b/doc/source/command-objects/network-flavor.rst @@ -8,6 +8,28 @@ service flavors. Network v2 +network flavor add profile +-------------------------- + +Add network flavor to service profile + +.. program:: network flavor add profile +.. code:: bash + + openstack network flavor add profile + + + +.. describe:: + + Flavor to which service profile is added. (Name or ID) + +.. describe:: + + Service profile to be added to flavor. (ID only) + +.. _network_flavor_add_profile: + network flavor create --------------------- @@ -85,6 +107,28 @@ List network flavors .. _network_flavor_list: +network flavor remove profile +----------------------------- + +Remove network flavor from service profile + +.. program:: network flavor remove profile +.. code:: bash + + openstack network flavor remove profile + + + +.. describe:: + + Flavor from which service profile is removed. (Name or ID) + +.. describe:: + + Service profile to be removed from flavor. (ID only) + +.. _network_flavor_remove_profile: + network flavor set ------------------ diff --git a/openstackclient/network/v2/network_flavor.py b/openstackclient/network/v2/network_flavor.py index 3a3324c09..c9d368bfc 100644 --- a/openstackclient/network/v2/network_flavor.py +++ b/openstackclient/network/v2/network_flavor.py @@ -58,6 +58,34 @@ def _get_attrs(client_manager, parsed_args): return attrs +class AddNetworkFlavorToProfile(command.Command): + _description = _("Add a service profile to a network flavor") + + def get_parser(self, prog_name): + parser = super( + AddNetworkFlavorToProfile, self).get_parser(prog_name) + parser.add_argument( + 'flavor', + metavar="", + help=_("Network flavor (name or ID)") + ) + parser.add_argument( + 'service_profile', + metavar="", + help=_("Service profile (ID only)") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + obj_flavor = client.find_flavor( + parsed_args.flavor, ignore_missing=False) + obj_service_profile = client.find_service_profile( + parsed_args.service_profile, ignore_missing=False) + client.associate_flavor_with_service_profile( + obj_flavor, obj_service_profile) + + # TODO(dasanind): Use the SDK resource mapped attribute names once the # OSC minimum requirements include SDK 1.0. class CreateNetworkFlavor(command.ShowOne): @@ -175,6 +203,35 @@ class ListNetworkFlavor(command.Lister): ) for s in data)) +class RemoveNetworkFlavorFromProfile(command.Command): + _description = _( + "Remove service profile from network flavor") + + def get_parser(self, prog_name): + parser = super( + RemoveNetworkFlavorFromProfile, self).get_parser(prog_name) + parser.add_argument( + 'flavor', + metavar="", + help=_("Network flavor (name or ID)") + ) + parser.add_argument( + 'service_profile', + metavar="", + help=_("Service profile (ID only)") + ) + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + obj_flavor = client.find_flavor( + parsed_args.flavor, ignore_missing=False) + obj_service_profile = client.find_service_profile( + parsed_args.service_profile, ignore_missing=False) + client.disassociate_flavor_from_service_profile( + obj_flavor, obj_service_profile) + + # TODO(dasanind): Use only the SDK resource mapped attribute names once the # OSC minimum requirements include SDK 1.0. class SetNetworkFlavor(command.Command): diff --git a/openstackclient/tests/functional/network/v2/test_network_flavor.py b/openstackclient/tests/functional/network/v2/test_network_flavor.py index b2fc2eaea..743407905 100644 --- a/openstackclient/tests/functional/network/v2/test_network_flavor.py +++ b/openstackclient/tests/functional/network/v2/test_network_flavor.py @@ -20,6 +20,57 @@ from openstackclient.tests.functional import base class NetworkFlavorTests(base.TestCase): """Functional tests for network flavor.""" + def test_add_remove_network_flavor_profile(self): + """Test add and remove network flavor to/from profile""" + + # Create Flavor + name1 = uuid.uuid4().hex + cmd_output1 = json.loads(self.openstack( + 'network flavor create -f json --description testdescription ' + '--enable --service-type L3_ROUTER_NAT ' + name1, + )) + flavor_id = cmd_output1.get('id') + + # Create Service Flavor + cmd_output2 = json.loads(self.openstack( + 'network flavor profile create -f json --description ' + + 'fakedescription' + ' --enable --metainfo ' + 'Extrainfo' + )) + service_profile_id = cmd_output2.get('id') + + self.addCleanup(self.openstack, 'network flavor delete ' + + flavor_id) + self.addCleanup(self.openstack, 'network flavor profile delete ' + + service_profile_id) + # Add flavor to service profile + self.openstack( + 'network flavor add profile ' + + flavor_id + ' ' + service_profile_id + ) + + cmd_output4 = json.loads(self.openstack( + 'network flavor show -f json ' + flavor_id + )) + service_profile_ids1 = cmd_output4.get('service_profile_ids') + + # Assert + self.assertIn(service_profile_id, service_profile_ids1) + + # Cleanup + # Remove flavor from service profile + self.openstack( + 'network flavor remove profile ' + + flavor_id + ' ' + service_profile_id + ) + + cmd_output6 = json.loads(self.openstack( + 'network flavor show -f json ' + flavor_id + )) + service_profile_ids2 = cmd_output6.get('service_profile_ids') + + # Assert + self.assertNotIn(service_profile_id, service_profile_ids2) + def test_network_flavor_delete(self): """Test create, delete multiple""" name1 = uuid.uuid4().hex diff --git a/openstackclient/tests/unit/network/v2/test_network_flavor.py b/openstackclient/tests/unit/network/v2/test_network_flavor.py index 11e27841d..896a17253 100644 --- a/openstackclient/tests/unit/network/v2/test_network_flavor.py +++ b/openstackclient/tests/unit/network/v2/test_network_flavor.py @@ -37,6 +37,48 @@ class TestNetworkFlavor(network_fakes.TestNetworkV2): self.domains_mock = self.app.client_manager.identity.domains +class TestAddNetworkFlavorToProfile(TestNetworkFlavor): + + network_flavor = \ + network_fakes.FakeNetworkFlavor.create_one_network_flavor() + service_profile = \ + network_fakes.FakeNetworkFlavorProfile.create_one_service_profile() + + def setUp(self): + super(TestAddNetworkFlavorToProfile, self).setUp() + self.network.find_flavor = mock.Mock(return_value=self.network_flavor) + self.network.find_service_profile = mock.Mock( + return_value=self.service_profile) + self.network.associate_flavor_with_service_profile = mock.Mock() + + self.cmd = network_flavor.AddNetworkFlavorToProfile( + self.app, self.namespace) + + def test_show_no_options(self): + arglist = [] + verifylist = [] + + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_add_flavor_to_service_profile(self): + arglist = [ + self.network_flavor.id, + self.service_profile.id + ] + verifylist = [ + ('flavor', self.network_flavor.id), + ('service_profile', self.service_profile.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + + self.network.associate_flavor_with_service_profile.\ + assert_called_once_with(self.network_flavor, self.service_profile) + + class TestCreateNetworkFlavor(TestNetworkFlavor): project = identity_fakes_v3.FakeProject.create_one_project() @@ -281,6 +323,48 @@ class TestListNetworkFlavor(TestNetworkFlavor): self.assertEqual(self.data, list(data)) +class TestRemoveNetworkFlavorFromProfile(TestNetworkFlavor): + + network_flavor = \ + network_fakes.FakeNetworkFlavor.create_one_network_flavor() + service_profile = \ + network_fakes.FakeNetworkFlavorProfile.create_one_service_profile() + + def setUp(self): + super(TestRemoveNetworkFlavorFromProfile, self).setUp() + self.network.find_flavor = mock.Mock(return_value=self.network_flavor) + self.network.find_service_profile = mock.Mock( + return_value=self.service_profile) + self.network.disassociate_flavor_from_service_profile = mock.Mock() + + self.cmd = network_flavor.RemoveNetworkFlavorFromProfile( + self.app, self.namespace) + + def test_show_no_options(self): + arglist = [] + verifylist = [] + + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_remove_flavor_from_service_profile(self): + arglist = [ + self.network_flavor.id, + self.service_profile.id + ] + verifylist = [ + ('flavor', self.network_flavor.id), + ('service_profile', self.service_profile.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + + self.network.disassociate_flavor_from_service_profile.\ + assert_called_once_with(self.network_flavor, self.service_profile) + + class TestShowNetworkFlavor(TestNetworkFlavor): # The network flavor to show. diff --git a/releasenotes/notes/neutron-client-flavors-81387171f67a3c82.yaml b/releasenotes/notes/neutron-client-flavors-81387171f67a3c82.yaml new file mode 100644 index 000000000..484393c9a --- /dev/null +++ b/releasenotes/notes/neutron-client-flavors-81387171f67a3c82.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Add ``network flavor add profile`` and ``network flavor remove profile`` commands. + [Blueprint :oscbp:`neutron-client-flavors`] diff --git a/setup.cfg b/setup.cfg index 3bd484ce9..d003e7d8d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -369,9 +369,11 @@ openstack.network.v2 = network_auto_allocated_topology_create = openstackclient.network.v2.network_auto_allocated_topology:CreateAutoAllocatedTopology network_auto_allocated_topology_delete = openstackclient.network.v2.network_auto_allocated_topology:DeleteAutoAllocatedTopology + network_flavor_add_profile = openstackclient.network.v2.network_flavor:AddNetworkFlavorToProfile network_flavor_create = openstackclient.network.v2.network_flavor:CreateNetworkFlavor network_flavor_delete = openstackclient.network.v2.network_flavor:DeleteNetworkFlavor network_flavor_list = openstackclient.network.v2.network_flavor:ListNetworkFlavor + network_flavor_remove_profile = openstackclient.network.v2.network_flavor:RemoveNetworkFlavorFromProfile network_flavor_set = openstackclient.network.v2.network_flavor:SetNetworkFlavor network_flavor_show = openstackclient.network.v2.network_flavor:ShowNetworkFlavor