Merge "Add provider command support"
This commit is contained in:
commit
de248a5178
|
@ -87,3 +87,10 @@ amphora
|
||||||
|
|
||||||
.. autoprogram-cliff:: openstack.load_balancer.v2
|
.. autoprogram-cliff:: openstack.load_balancer.v2
|
||||||
:command: loadbalancer amphora *
|
:command: loadbalancer amphora *
|
||||||
|
|
||||||
|
========
|
||||||
|
provider
|
||||||
|
========
|
||||||
|
|
||||||
|
.. autoprogram-cliff:: openstack.load_balancer.v2
|
||||||
|
:command: loadbalancer provider *
|
||||||
|
|
|
@ -45,3 +45,8 @@ BASE_QUOTA_DEFAULT_URL = BASE_QUOTA_URL + '/defaults'
|
||||||
BASE_AMPHORA_URL = BASE_OCTAVIA_ENDPOINT + "/amphorae"
|
BASE_AMPHORA_URL = BASE_OCTAVIA_ENDPOINT + "/amphorae"
|
||||||
BASE_SINGLE_AMPHORA_URL = BASE_AMPHORA_URL + "/{uuid}"
|
BASE_SINGLE_AMPHORA_URL = BASE_AMPHORA_URL + "/{uuid}"
|
||||||
BASE_AMPHORA_FAILOVER_URL = BASE_SINGLE_AMPHORA_URL + '/failover'
|
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")
|
||||||
|
|
|
@ -727,6 +727,31 @@ class OctaviaAPI(api.BaseAPI):
|
||||||
|
|
||||||
return response
|
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):
|
class OctaviaClientException(Exception):
|
||||||
"""The base exception class for all exceptions this library raises."""
|
"""The base exception class for all exceptions this library raises."""
|
||||||
|
|
|
@ -264,3 +264,13 @@ AMPHORA_COLUMNS = (
|
||||||
'lb_network_ip',
|
'lb_network_ip',
|
||||||
'ha_ip',
|
'ha_ip',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
PROVIDER_COLUMNS = (
|
||||||
|
'name',
|
||||||
|
'description',
|
||||||
|
)
|
||||||
|
|
||||||
|
PROVIDER_CAPABILICY_COLUMNS = (
|
||||||
|
'name',
|
||||||
|
'description',
|
||||||
|
)
|
||||||
|
|
|
@ -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='<provider_name>',
|
||||||
|
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']))
|
|
@ -440,6 +440,15 @@ def get_amphora_attrs(client_manager, parsed_args):
|
||||||
return _map_attrs(vars(parsed_args), attr_map)
|
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):
|
def format_list(data):
|
||||||
return '\n'.join(i['id'] for i in data)
|
return '\n'.join(i['id'] for i in data)
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ FAKE_L7RU = uuidutils.generate_uuid()
|
||||||
FAKE_HM = uuidutils.generate_uuid()
|
FAKE_HM = uuidutils.generate_uuid()
|
||||||
FAKE_PRJ = uuidutils.generate_uuid()
|
FAKE_PRJ = uuidutils.generate_uuid()
|
||||||
FAKE_AMP = uuidutils.generate_uuid()
|
FAKE_AMP = uuidutils.generate_uuid()
|
||||||
|
FAKE_PROVIDER = 'fake_provider'
|
||||||
|
|
||||||
|
|
||||||
LIST_LB_RESP = {
|
LIST_LB_RESP = {
|
||||||
|
@ -95,6 +96,12 @@ LIST_AMP_RESP = {
|
||||||
{'id': uuidutils.generate_uuid()}]
|
{'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_RESP = {'loadbalancer': {'id': FAKE_LB, 'name': 'lb1'}}
|
||||||
SINGLE_LB_UPDATE = {"loadbalancer": {"admin_state_up": False}}
|
SINGLE_LB_UPDATE = {"loadbalancer": {"admin_state_up": False}}
|
||||||
SINGLE_LB_STATS_RESP = {'bytes_in': '0'}
|
SINGLE_LB_STATS_RESP = {'bytes_in': '0'}
|
||||||
|
@ -123,6 +130,11 @@ SINGLE_QT_RESP = {'quota': {'pool': -1}}
|
||||||
SINGLE_QT_UPDATE = {'quota': {'pool': -1}}
|
SINGLE_QT_UPDATE = {'quota': {'pool': -1}}
|
||||||
SINGLB_AMP_RESP = {'amphora': {'id': FAKE_AMP}}
|
SINGLB_AMP_RESP = {'amphora': {'id': FAKE_AMP}}
|
||||||
|
|
||||||
|
SINGLE_PROVIDER_CAPABILITY_RESP = {
|
||||||
|
'flavor_capabilities':
|
||||||
|
[{'some_capability': 'Capabilicy description'}]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestOctaviaClient(utils.TestCase):
|
class TestOctaviaClient(utils.TestCase):
|
||||||
|
|
||||||
|
@ -899,3 +911,25 @@ class TestLoadBalancer(TestOctaviaClient):
|
||||||
self._error_message,
|
self._error_message,
|
||||||
self.api.amphora_failover,
|
self.api.amphora_failover,
|
||||||
FAKE_AMP)
|
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)
|
||||||
|
|
|
@ -153,3 +153,13 @@ QUOTA_ATTRS = {
|
||||||
"pool": None,
|
"pool": None,
|
||||||
"project_id": uuidutils.generate_uuid(dashed=True),
|
"project_id": uuidutils.generate_uuid(dashed=True),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROVIDER_ATTRS = {
|
||||||
|
"name": "provider1",
|
||||||
|
"description": "Description of provider1."
|
||||||
|
}
|
||||||
|
|
||||||
|
CAPABILITY_ATTRS = {
|
||||||
|
"name": "some_capabilicy",
|
||||||
|
"description": "Description of capabilicy."
|
||||||
|
}
|
||||||
|
|
|
@ -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')
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds client support for loadbalancer provider.
|
|
@ -75,6 +75,8 @@ openstack.load_balancer.v2 =
|
||||||
loadbalancer_amphora_list = octaviaclient.osc.v2.amphora:ListAmphora
|
loadbalancer_amphora_list = octaviaclient.osc.v2.amphora:ListAmphora
|
||||||
loadbalancer_amphora_show = octaviaclient.osc.v2.amphora:ShowAmphora
|
loadbalancer_amphora_show = octaviaclient.osc.v2.amphora:ShowAmphora
|
||||||
loadbalancer_amphora_failover = octaviaclient.osc.v2.amphora:FailoverAmphora
|
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]
|
[build_sphinx]
|
||||||
source-dir = doc/source
|
source-dir = doc/source
|
||||||
|
|
Loading…
Reference in New Issue