From 17a284ee3607e5749cf131feb4670c57cc7ee162 Mon Sep 17 00:00:00 2001 From: yangjianfeng Date: Tue, 11 Dec 2018 14:50:22 +0800 Subject: [PATCH] Add provider command support This patch adds two commands about provider. 1. openstack loadbalancer provider list 2. openstack loadbalancer provider capability list Story: 1655768 Task: 28460 Depends-On: https://review.openstack.org/#/c/633829 Depends-On: Ia3d62acdc3b1af2e666f58d32a06d2238706dee6 Change-Id: Ifcfc534c14d4768ad33dd0d76ebae14c98a08d6a --- doc/source/cli/index.rst | 7 ++ octaviaclient/api/constants.py | 5 ++ octaviaclient/api/v2/octavia.py | 25 ++++++ octaviaclient/osc/v2/constants.py | 10 +++ octaviaclient/osc/v2/provider.py | 70 +++++++++++++++ octaviaclient/osc/v2/utils.py | 9 ++ octaviaclient/tests/unit/api/test_octavia.py | 34 +++++++ octaviaclient/tests/unit/osc/v2/constants.py | 10 +++ .../tests/unit/osc/v2/test_provider.py | 89 +++++++++++++++++++ ...support-for-provider-4e60045ea54f1d30.yaml | 4 + setup.cfg | 2 + 11 files changed, 265 insertions(+) create mode 100644 octaviaclient/osc/v2/provider.py create mode 100644 octaviaclient/tests/unit/osc/v2/test_provider.py create mode 100644 releasenotes/notes/add-support-for-provider-4e60045ea54f1d30.yaml diff --git a/doc/source/cli/index.rst b/doc/source/cli/index.rst index a37c3f2..2a4dd7b 100644 --- a/doc/source/cli/index.rst +++ b/doc/source/cli/index.rst @@ -87,3 +87,10 @@ amphora .. autoprogram-cliff:: openstack.load_balancer.v2 :command: loadbalancer amphora * + +======== +provider +======== + +.. autoprogram-cliff:: openstack.load_balancer.v2 + :command: loadbalancer provider * diff --git a/octaviaclient/api/constants.py b/octaviaclient/api/constants.py index 5e26de5..1556f4c 100644 --- a/octaviaclient/api/constants.py +++ b/octaviaclient/api/constants.py @@ -45,3 +45,8 @@ BASE_QUOTA_DEFAULT_URL = BASE_QUOTA_URL + '/defaults' BASE_AMPHORA_URL = BASE_OCTAVIA_ENDPOINT + "/amphorae" BASE_SINGLE_AMPHORA_URL = BASE_AMPHORA_URL + "/{uuid}" BASE_AMPHORA_FAILOVER_URL = BASE_SINGLE_AMPHORA_URL + '/failover' + +BASE_PROVIDER_URL = BASE_LBAAS_ENDPOINT + "/providers" +BASE_PROVIDER_FLAVOR_CAPABILITY_URL = (BASE_LBAAS_ENDPOINT + + "/providers/{provider}/" + "flavor_capabilities") diff --git a/octaviaclient/api/v2/octavia.py b/octaviaclient/api/v2/octavia.py index 3ba32cd..aa6c84a 100644 --- a/octaviaclient/api/v2/octavia.py +++ b/octaviaclient/api/v2/octavia.py @@ -727,6 +727,31 @@ class OctaviaAPI(api.BaseAPI): return response + def provider_list(self): + """List all providers + + :return: + A ``dict`` containing a list of provider + """ + url = const.BASE_PROVIDER_URL + response = self.list(path=url) + + return response + + def provider_capability_list(self, provider): + """Show the flavor capability of the specified provider. + + :param string provider: + The name of the provider to show + :return: + A ``dict`` containing the capabilicy of provider + """ + url = const.BASE_PROVIDER_FLAVOR_CAPABILITY_URL.format( + provider=provider) + response = self.list(url) + + return response + class OctaviaClientException(Exception): """The base exception class for all exceptions this library raises.""" diff --git a/octaviaclient/osc/v2/constants.py b/octaviaclient/osc/v2/constants.py index 2bc87d2..8e14152 100644 --- a/octaviaclient/osc/v2/constants.py +++ b/octaviaclient/osc/v2/constants.py @@ -264,3 +264,13 @@ AMPHORA_COLUMNS = ( 'lb_network_ip', 'ha_ip', ) + +PROVIDER_COLUMNS = ( + 'name', + 'description', +) + +PROVIDER_CAPABILICY_COLUMNS = ( + 'name', + 'description', +) diff --git a/octaviaclient/osc/v2/provider.py b/octaviaclient/osc/v2/provider.py new file mode 100644 index 0000000..f659396 --- /dev/null +++ b/octaviaclient/osc/v2/provider.py @@ -0,0 +1,70 @@ +# Copyright (c) 2018 China Telecom Corporation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +"""Octavia provider action implementation""" + +from cliff import lister +from osc_lib import utils + +from octaviaclient.osc.v2 import constants as const +from octaviaclient.osc.v2 import utils as v2_utils + + +class ListProvider(lister.Lister): + """List all providers""" + + def get_parser(self, prog_name): + parser = super(ListProvider, self).get_parser(prog_name) + + return parser + + def take_action(self, parsed_args): + columns = const.PROVIDER_COLUMNS + data = self.app.client_manager.load_balancer.provider_list() + + return (columns, + (utils.get_dict_properties( + s, columns, + formatters={}, + ) for s in data['providers'])) + + +class ListProviderFlavorCapability(lister.Lister): + """List specified provider driver's flavor capabilicies.""" + + def get_parser(self, prog_name): + parser = super(ListProviderFlavorCapability, + self).get_parser(prog_name) + + parser.add_argument( + 'provider', + metavar='', + help="Name of the provider driver." + ) + + return parser + + def take_action(self, parsed_args): + columns = const.PROVIDER_CAPABILICY_COLUMNS + attrs = v2_utils.get_provider_attrs(parsed_args) + provider = attrs.pop('provider_name') + client = self.app.client_manager + data = client.load_balancer.provider_capability_list( + provider=provider) + return (columns, + (utils.get_dict_properties( + s, columns, + formatters={}, + ) for s in data['flavor_capabilities'])) diff --git a/octaviaclient/osc/v2/utils.py b/octaviaclient/osc/v2/utils.py index c9c4f40..010dbfe 100644 --- a/octaviaclient/osc/v2/utils.py +++ b/octaviaclient/osc/v2/utils.py @@ -440,6 +440,15 @@ def get_amphora_attrs(client_manager, parsed_args): return _map_attrs(vars(parsed_args), attr_map) +def get_provider_attrs(parsed_args): + attr_map = { + 'provider': ('provider_name', str), + 'description': ('description', str), + } + + return _map_attrs(vars(parsed_args), attr_map) + + def format_list(data): return '\n'.join(i['id'] for i in data) diff --git a/octaviaclient/tests/unit/api/test_octavia.py b/octaviaclient/tests/unit/api/test_octavia.py index 3613114..9ef0c8b 100644 --- a/octaviaclient/tests/unit/api/test_octavia.py +++ b/octaviaclient/tests/unit/api/test_octavia.py @@ -36,6 +36,7 @@ FAKE_L7RU = uuidutils.generate_uuid() FAKE_HM = uuidutils.generate_uuid() FAKE_PRJ = uuidutils.generate_uuid() FAKE_AMP = uuidutils.generate_uuid() +FAKE_PROVIDER = 'fake_provider' LIST_LB_RESP = { @@ -95,6 +96,12 @@ LIST_AMP_RESP = { {'id': uuidutils.generate_uuid()}] } +LIST_PROVIDER_RESP = { + 'providers': + [{'name': 'provider1', 'description': 'description of provider1'}, + {'name': 'provider2', 'description': 'description of provider2'}] +} + SINGLE_LB_RESP = {'loadbalancer': {'id': FAKE_LB, 'name': 'lb1'}} SINGLE_LB_UPDATE = {"loadbalancer": {"admin_state_up": False}} SINGLE_LB_STATS_RESP = {'bytes_in': '0'} @@ -123,6 +130,11 @@ SINGLE_QT_RESP = {'quota': {'pool': -1}} SINGLE_QT_UPDATE = {'quota': {'pool': -1}} SINGLB_AMP_RESP = {'amphora': {'id': FAKE_AMP}} +SINGLE_PROVIDER_CAPABILITY_RESP = { + 'flavor_capabilities': + [{'some_capability': 'Capabilicy description'}] +} + class TestOctaviaClient(utils.TestCase): @@ -899,3 +911,25 @@ class TestLoadBalancer(TestOctaviaClient): self._error_message, self.api.amphora_failover, FAKE_AMP) + + def test_list_provider(self): + self.requests_mock.register_uri( + 'GET', + FAKE_LBAAS_URL + 'providers', + json=LIST_PROVIDER_RESP, + status_code=200, + ) + ret = self.api.provider_list() + self.assertEqual(LIST_PROVIDER_RESP, ret) + + def test_show_provider_capabilicy(self): + self.requests_mock.register_uri( + 'GET', + (FAKE_LBAAS_URL + 'providers/' + + FAKE_PROVIDER + '/flavor_capabilities'), + json=SINGLE_PROVIDER_CAPABILITY_RESP, + status_code=200 + ) + ret = self.api.provider_capability_list(FAKE_PROVIDER) + self.assertEqual( + SINGLE_PROVIDER_CAPABILITY_RESP, ret) diff --git a/octaviaclient/tests/unit/osc/v2/constants.py b/octaviaclient/tests/unit/osc/v2/constants.py index 460cc69..4dac733 100644 --- a/octaviaclient/tests/unit/osc/v2/constants.py +++ b/octaviaclient/tests/unit/osc/v2/constants.py @@ -153,3 +153,13 @@ QUOTA_ATTRS = { "pool": None, "project_id": uuidutils.generate_uuid(dashed=True), } + +PROVIDER_ATTRS = { + "name": "provider1", + "description": "Description of provider1." +} + +CAPABILITY_ATTRS = { + "name": "some_capabilicy", + "description": "Description of capabilicy." +} diff --git a/octaviaclient/tests/unit/osc/v2/test_provider.py b/octaviaclient/tests/unit/osc/v2/test_provider.py new file mode 100644 index 0000000..66e9b74 --- /dev/null +++ b/octaviaclient/tests/unit/osc/v2/test_provider.py @@ -0,0 +1,89 @@ +# Copyright (c) 2018 China Telecom Corporation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import copy +import mock + +from octaviaclient.osc.v2 import constants +from octaviaclient.osc.v2 import provider +from octaviaclient.tests.unit.osc.v2 import constants as attr_consts +from octaviaclient.tests.unit.osc.v2 import fakes + + +class TestProvider(fakes.TestOctaviaClient): + + def setUp(self): + super(TestProvider, self).setUp() + + self.columns = copy.deepcopy(constants.PROVIDER_COLUMNS) + + self.api_mock = mock.Mock() + self.api_mock.provider_list.return_value = copy.deepcopy( + {'providers': [attr_consts.PROVIDER_ATTRS]}) + lb_client = self.app.client_manager + lb_client.load_balancer = self.api_mock + + +class TestProviderList(TestProvider): + + def setUp(self): + super(TestProviderList, self).setUp() + self.datalist = (tuple( + attr_consts.PROVIDER_ATTRS[k] for k in self.columns),) + self.cmd = provider.ListProvider(self.app, None) + + def test_provider_list(self): + arglist = [] + verifylist = [] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.api_mock.provider_list.assert_called_with() + self.assertEqual(self.columns, columns) + self.assertEqual(self.datalist, tuple(data)) + + +class TestProviderCapability(fakes.TestOctaviaClient): + + def setUp(self): + super(TestProviderCapability, self).setUp() + + self.api_mock = mock.Mock() + self.api_mock.provider_capability_list.return_value = copy.deepcopy( + {'flavor_capabilities': [attr_consts.CAPABILITY_ATTRS]}) + lb_client = self.app.client_manager + lb_client.load_balancer = self.api_mock + + +class TestProviderCapabilityShow(TestProviderCapability): + + def setUp(self): + super(TestProviderCapabilityShow, self).setUp() + lb_client = self.app.client_manager + lb_client.load_balancer = self.api_mock + + self.cmd = provider.ListProviderFlavorCapability(self.app, None) + + def test_provider_capability_list(self): + arglist = ['provider1'] + verifylist = [ + ('provider', 'provider1'), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.cmd.take_action(parsed_args) + self.api_mock.provider_capability_list.assert_called_with( + provider='provider1') diff --git a/releasenotes/notes/add-support-for-provider-4e60045ea54f1d30.yaml b/releasenotes/notes/add-support-for-provider-4e60045ea54f1d30.yaml new file mode 100644 index 0000000..259e781 --- /dev/null +++ b/releasenotes/notes/add-support-for-provider-4e60045ea54f1d30.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Adds client support for loadbalancer provider. diff --git a/setup.cfg b/setup.cfg index 3d314b5..21158f5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -75,6 +75,8 @@ openstack.load_balancer.v2 = loadbalancer_amphora_list = octaviaclient.osc.v2.amphora:ListAmphora loadbalancer_amphora_show = octaviaclient.osc.v2.amphora:ShowAmphora loadbalancer_amphora_failover = octaviaclient.osc.v2.amphora:FailoverAmphora + loadbalancer_provider_list = octaviaclient.osc.v2.provider:ListProvider + loadbalancer_provider_capability_list = octaviaclient.osc.v2.provider:ListProviderFlavorCapability [build_sphinx] source-dir = doc/source