Complement Octavia client with a set of features

* Commands added: loadbalancer failover, loadbalancer amphora.
* Allow to filter 'list' calls.
e.g. list all pools that correspond with a given loadbalancer ID.
* Rename API internally, from load_balancer_v2 to Octavia.

Task: 5742
Story: 2001224

Change-Id: I7c38471073d8990de054def3d1d99f2c0524c26e
This commit is contained in:
Bar RH 2017-11-20 12:52:14 +02:00 committed by Michael Johnson
parent e3341ea625
commit 922edce32a
25 changed files with 700 additions and 175 deletions

View File

@ -26,6 +26,9 @@ loadbalancer
.. autoprogram-cliff:: openstack.load_balancer.v2
:command: loadbalancer stats show
.. autoprogram-cliff:: openstack.load_balancer.v2
:command: loadbalancer failover
========
listener
========
@ -74,3 +77,10 @@ quota
.. autoprogram-cliff:: openstack.load_balancer.v2
:command: loadbalancer quota *
=======
amphora
=======
.. autoprogram-cliff:: openstack.load_balancer.v2
:command: loadbalancer amphora *

View File

@ -11,27 +11,34 @@
# under the License.
#
BASE_LOADBALANCER_URL = '/loadbalancers'
BASE_LBAAS_ENDPOINT = '/lbaas'
BASE_OCTAVIA_ENDPOINT = '/octavia'
BASE_LOADBALANCER_URL = BASE_LBAAS_ENDPOINT + '/loadbalancers'
BASE_SINGLE_LB_URL = BASE_LOADBALANCER_URL + '/{uuid}'
BASE_LB_STATS_URL = BASE_SINGLE_LB_URL + '/stats'
BASE_LOADBALANCER_FAILOVER_URL = BASE_SINGLE_LB_URL + '/failover'
BASE_LISTENER_URL = '/listeners'
BASE_LISTENER_URL = BASE_LBAAS_ENDPOINT + '/listeners'
BASE_SINGLE_LISTENER_URL = BASE_LISTENER_URL + '/{uuid}'
BASE_POOL_URL = '/pools'
BASE_POOL_URL = BASE_LBAAS_ENDPOINT + '/pools'
BASE_SINGLE_POOL_URL = BASE_POOL_URL + '/{pool_id}'
BASE_MEMBER_URL = BASE_SINGLE_POOL_URL + '/members'
BASE_SINGLE_MEMBER_URL = BASE_MEMBER_URL + '/{member_id}'
BASE_HEALTH_MONITOR_URL = '/healthmonitors'
BASE_HEALTH_MONITOR_URL = BASE_LBAAS_ENDPOINT + '/healthmonitors'
BASE_SINGLE_HEALTH_MONITOR_URL = BASE_HEALTH_MONITOR_URL + '/{uuid}'
BASE_L7POLICY_URL = '/l7policies'
BASE_L7POLICY_URL = BASE_LBAAS_ENDPOINT + '/l7policies'
BASE_SINGLE_L7POLICY_URL = BASE_L7POLICY_URL + '/{policy_uuid}'
BASE_L7RULE_URL = BASE_SINGLE_L7POLICY_URL + '/rules'
BASE_SINGLE_L7RULE_URL = BASE_SINGLE_L7POLICY_URL + '/rules/{rule_uuid}'
BASE_QUOTA_URL = '/quotas'
BASE_QUOTA_URL = BASE_LBAAS_ENDPOINT + '/quotas'
BASE_SINGLE_QUOTA_URL = BASE_QUOTA_URL + '/{uuid}'
BASE_QUOTA_DEFAULT_URL = BASE_QUOTA_URL + '/defaults'
BASE_AMPHORA_URL = BASE_OCTAVIA_ENDPOINT + "/amphorae"
BASE_SINGLE_AMPHORA_URL = BASE_AMPHORA_URL + "/{amphora_id}"

View File

View File

@ -11,7 +11,7 @@
# under the License.
#
"""Load Balancer v2 API Library"""
"""Octavia API Library"""
from osc_lib.api import api
@ -40,13 +40,13 @@ def correct_return_codes(func):
return wrapper
class APIv2(api.BaseAPI):
"""Load Balancer v2 API"""
class OctaviaAPI(api.BaseAPI):
"""Octavia API"""
_endpoint_suffix = '/v2.0/lbaas'
_endpoint_suffix = '/v2.0'
def __init__(self, endpoint=None, **kwargs):
super(APIv2, self).__init__(endpoint=endpoint, **kwargs)
super(OctaviaAPI, self).__init__(endpoint=endpoint, **kwargs)
self.endpoint = self.endpoint.rstrip('/')
self._build_url()
@ -58,7 +58,7 @@ class APIv2(api.BaseAPI):
"""List all load balancers
:param params:
Parameters to filter on (not implemented)
Parameters to filter on
:return:
List of load balancers
"""
@ -114,7 +114,7 @@ class APIv2(api.BaseAPI):
"""Update a load balancer's settings
:param string lb_id:
The ID of the load baalancer to update
The ID of the load balancer to update
:param params:
A dict of arguments to update a loadbalancer
:return:
@ -138,11 +138,25 @@ class APIv2(api.BaseAPI):
return response
@correct_return_codes
def load_balancer_failover(self, lb_id):
"""Trigger load balancer failover
:param string lb_id:
ID of the load balancer to failover
:return:
Response Code from the API
"""
url = const.BASE_LOADBALANCER_FAILOVER_URL.format(uuid=lb_id)
response = self.create(url, method='PUT')
return response
def listener_list(self, **kwargs):
"""List all listeners
:param kwargs:
Parameters to filter on (not implemented)
Parameters to filter on
:return:
List of listeners
"""
@ -155,6 +169,7 @@ class APIv2(api.BaseAPI):
"""Show a listener
:param string listener_id:
ID of the listener to show
:return:
A dict of the specified listener's settings
"""
@ -210,7 +225,7 @@ class APIv2(api.BaseAPI):
"""List all pools
:param kwargs:
Parameters to filter on (not implemented)
Parameters to filter on
:return:
List of pools
"""
@ -363,7 +378,7 @@ class APIv2(api.BaseAPI):
"""List all l7policies
:param kwargs:
Parameters to filter on (not implemented)
Parameters to filter on
:return:
List of l7policies
"""
@ -432,7 +447,7 @@ class APIv2(api.BaseAPI):
"""List all l7rules for a l7policy
:param kwargs:
Parameters to filter on (not implemented)
Parameters to filter on
:return:
List of l7policies
"""
@ -512,7 +527,7 @@ class APIv2(api.BaseAPI):
"""List all health monitors
:param kwargs:
Parameters to filter on (not implemented)
Parameters to filter on
:return:
A dict containing a list of health monitors
"""
@ -646,6 +661,32 @@ class APIv2(api.BaseAPI):
return response
def amphora_show(self, amphora_id):
"""Show an amphora
:param string amphora_id:
ID of the amphora to show
:return:
A ``dict`` of the specified amphora's attributes
"""
url = const.BASE_AMPHORA_URL
response = self.find(path=url, value=amphora_id)
return response
def amphora_list(self, **kwargs):
"""List all amphorae
:param kwargs:
Parameters to filter on
:return:
A ``dict`` containing a list of amphorae
"""
url = const.BASE_AMPHORA_URL
response = self.list(path=url, **kwargs)
return response
class OctaviaClientException(Exception):
"""The base exception class for all exceptions this library raises."""

View File

@ -14,7 +14,7 @@
import logging
from octaviaclient.api import load_balancer_v2
from octaviaclient.api.v2 import octavia
from osc_lib import utils
LOG = logging.getLogger(__name__)
@ -24,7 +24,7 @@ API_VERSION_OPTION = 'os_loadbalancer_api_version'
API_NAME = 'load_balancer'
LOAD_BALANCER_API_TYPE = 'loadbalancer'
LOAD_BALANCER_API_VERSIONS = {
'2.0': 'octaviaclient.api.load_balancer_v2.APIv2',
'2.0': 'octaviaclient.api.v2.octavia.OctaviaAPI',
}
@ -35,7 +35,7 @@ def make_client(instance):
region_name=instance.region_name,
interface=instance.interface,
)
client = load_balancer_v2.APIv2(
client = octavia.OctaviaAPI(
session=instance.session,
service_type='load-balancer',
endpoint=endpoint,

View File

@ -0,0 +1,117 @@
# 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.
#
"""Amphora action implementation"""
from cliff import lister
from osc_lib.command import command
from osc_lib import utils
from octaviaclient.osc.v2 import constants as const
from octaviaclient.osc.v2 import utils as v2_utils
class ListAmphora(lister.Lister):
"""List amphorae"""
def get_parser(self, prog_name):
parser = super(ListAmphora, self).get_parser(prog_name)
parser.add_argument(
'--loadbalancer',
metavar='<loadbalancer>',
dest='loadbalancer',
help="Filter by load balancer (name or ID).",
)
parser.add_argument(
'--compute-id',
metavar='<compute-id>',
help="Filter by compute ID.",
)
role_choices = {'MASTER', 'BACKUP', 'STANDALONE'}
parser.add_argument(
'--role',
metavar='{' + ','.join(role_choices) + '}',
choices=role_choices,
type=lambda s: s.upper(), # case insensitive
help="Filter by role."
)
status_choices = {
'ALLOCATED', 'BOOTING', 'DELETED', 'ERROR',
'PENDING_CREATE', 'PENDING_DELETE', 'READY',
}
parser.add_argument(
'--status', '--provisioning-status',
dest='status',
metavar='{' + ','.join(status_choices) + '}',
choices=status_choices,
type=lambda s: s.upper(), # case insensitive
help="Filter by amphora provisioning status."
)
return parser
def take_action(self, parsed_args):
columns = const.AMPHORA_COLUMNS
attrs = v2_utils.get_amphora_attrs(self.app.client_manager,
parsed_args)
data = self.app.client_manager.load_balancer.amphora_list(**attrs)
formatters = {
'amphorae': v2_utils.format_list,
}
return (
columns,
(utils.get_dict_properties(
amp,
columns,
formatters=formatters,
) for amp in data['amphorae']),
)
class ShowAmphora(command.ShowOne):
"""Show the details of a single amphora"""
def get_parser(self, prog_name):
parser = super(ShowAmphora, self).get_parser(prog_name)
parser.add_argument(
'amphora_id',
metavar='<amphora-id>',
help='UUID of the amphora.',
)
return parser
def take_action(self, parsed_args):
attrs = v2_utils.get_amphora_attrs(self.app.client_manager,
parsed_args)
data = self.app.client_manager.load_balancer.amphora_show(
amphora_id=attrs.pop('amphora_id'),
)
rows = const.AMPHORA_ROWS
formatters = {
'loadbalancers': v2_utils.format_list,
'amphorae': v2_utils.format_list,
}
return (rows, utils.get_dict_properties(data, rows,
formatters=formatters))

View File

@ -29,7 +29,8 @@ LOAD_BALANCER_ROWS = (
'vip_address',
'vip_network_id',
'vip_port_id',
'vip_subnet_id')
'vip_subnet_id',
)
LOAD_BALANCER_COLUMNS = (
'id',
@ -212,7 +213,7 @@ QUOTA_ROWS = (
'listener',
'pool',
'health_monitor',
'member'
'member',
)
QUOTA_COLUMNS = (
@ -221,5 +222,33 @@ QUOTA_COLUMNS = (
'listener',
'pool',
'health_monitor',
'member'
'member',
)
AMPHORA_ROWS = (
'id',
'loadbalancer_id',
'compute_id',
'lb_network_ip',
'vrrp_ip',
'ha_ip',
'vrrp_port_id',
'ha_port_id',
'cert_expiration',
'cert_busy',
'role',
'status',
'vrrp_interface',
'vrrp_id',
'vrrp_priority',
'cached_zone',
)
AMPHORA_COLUMNS = (
'id',
'loadbalancer_id',
'status',
'role',
'lb_network_ip',
'ha_ip',
)

View File

@ -31,7 +31,7 @@ class CreateListener(command.ShowOne):
parser.add_argument(
'loadbalancer',
metavar='<load_balancer>',
metavar='<loadbalancer>',
help="Load balancer for the listener (name or ID)."
)
parser.add_argument(
@ -155,12 +155,17 @@ class ListListener(lister.Lister):
def get_parser(self, prog_name):
parser = super(ListListener, self).get_parser(prog_name)
# Filtering will soon be implemented to allow this
parser.add_argument(
'--name',
metavar='<name>',
help="List listeners by listener name."
)
parser.add_argument(
'--loadbalancer',
metavar='<loadbalancer>',
help="Filter by load balancer (name or ID).",
)
admin_group = parser.add_mutually_exclusive_group()
admin_group.add_argument(
'--enable',
@ -174,6 +179,7 @@ class ListListener(lister.Lister):
default=None,
help="List disabled listeners."
)
parser.add_argument(
'--project',
metavar='<project>',

View File

@ -81,6 +81,7 @@ class CreateLoadBalancer(command.ShowOne):
metavar='<project>',
help="Project for the load balancer (name or ID)."
)
admin_group = parser.add_mutually_exclusive_group()
admin_group.add_argument(
'--enable',
@ -148,6 +149,27 @@ class DeleteLoadBalancer(command.Command):
lb_id=lb_id, **attrs)
class FailoverLoadBalancer(command.Command):
"""Trigger load balancer failover"""
def get_parser(self, prog_name):
parser = super(FailoverLoadBalancer, self).get_parser(prog_name)
parser.add_argument(
'loadbalancer',
metavar='<load_balancer>',
help="Name or UUID of the load balancer."
)
return parser
def take_action(self, parsed_args):
attrs = v2_utils.get_loadbalancer_attrs(self.app.client_manager,
parsed_args)
self.app.client_manager.load_balancer.load_balancer_failover(
lb_id=attrs.pop('loadbalancer_id'))
class ListLoadBalancer(lister.Lister):
"""List load balancers"""
@ -250,6 +272,7 @@ class SetLoadBalancer(command.Command):
metavar='<description>',
help="Set load balancer description."
)
admin_group = parser.add_mutually_exclusive_group()
admin_group.add_argument(
'--enable',

View File

@ -127,12 +127,18 @@ class ListPool(lister.Lister):
def get_parser(self, prog_name):
parser = super(ListPool, self).get_parser(prog_name)
parser.add_argument(
'--loadbalancer',
metavar='<loadbalancer>',
help="Filter by load balancer (name or ID).",
)
return parser
def take_action(self, parsed_args):
columns = const.POOL_COLUMNS
data = self.app.client_manager.load_balancer.pool_list()
attrs = v2_utils.get_pool_attrs(self.app.client_manager, parsed_args)
data = self.app.client_manager.load_balancer.pool_list(**attrs)
formatters = {'loadbalancers': v2_utils.format_list,
'members': v2_utils.format_list,
'listeners': v2_utils.format_list}

View File

@ -17,6 +17,47 @@ from osc_lib import exceptions
from openstackclient.identity import common as identity_common
def _map_attrs(args, source_attr_map):
res = {}
for k, v in args.items():
if (v is None) or (k not in source_attr_map):
continue
source_val = source_attr_map[k]
# Attributes with 2 values map directly to a callable
if len(source_val) == 2:
res[source_val[0]] = source_val[1](v)
# Attributes with 3 values map directly to a resource
elif len(source_val) == 3:
if not isinstance(v, list):
res[source_val[0]] = get_resource_id(
source_val[2],
source_val[1],
v,
)
else:
res[source_val[0]] = [get_resource_id(
source_val[2],
source_val[1],
x,
) for x in v]
# Attributes with 4 values map to a resource with a parent
elif len(source_val) == 4:
parent = source_attr_map[source_val[2]]
parent_id = get_resource_id(
parent[2],
parent[1],
args[source_val[2]],
)
child = source_val
res[child[0]] = get_resource_id(
child[3],
child[1],
{child[0]: str(v), parent[0]: str(parent_id)},
)
return res
def get_resource_id(resource, resource_name, name):
"""Converts a resource name into a UUID for consumption for the API
@ -359,6 +400,26 @@ def get_quota_attrs(client_manager, parsed_args):
return attrs
def get_amphora_attrs(client_manager, parsed_args):
attr_map = {
'amphora_id': (
'amphora_id',
'amphorae',
client_manager.load_balancer.amphora_list,
),
'loadbalancer': (
'loadbalancer_id',
'loadbalancers',
client_manager.load_balancer.load_balancer_list,
),
'compute_id': ('compute_id', str),
'role': ('role', str),
'status': ('status', str),
}
return _map_attrs(vars(parsed_args), attr_map)
def format_list(data):
return '\n'.join(i['id'] for i in data)
@ -378,35 +439,3 @@ def _format_kv(data):
formatted_kv[k] = v
return formatted_kv
def _map_attrs(attrs, attr_map):
mapped_attrs = {}
for k, v in attrs.items():
if v is not None and k in attr_map.keys():
# Attributes with 2 values map directly to a callable
if len(attr_map[k]) is 2:
mapped_attrs[attr_map[k][0]] = attr_map[k][1](v)
# Attributes with 3 values map directly to a resource
elif len(attr_map[k]) is 3:
mapped_attrs[attr_map[k][0]] = get_resource_id(
attr_map[k][2],
attr_map[k][1],
v
)
# Attributes with 4 values map to a resource with a parent
else:
parent = attr_map[attr_map[k][2]]
parent_id = get_resource_id(
parent[2],
parent[1],
attrs[attr_map[k][2]]
)
child = attr_map[k]
mapped_attrs[child[0]] = get_resource_id(
child[3],
child[1],
{child[0]: str(v), parent[0]: str(parent_id)}
)
return mapped_attrs

View File

@ -17,12 +17,14 @@ from keystoneauth1 import session
from oslo_utils import uuidutils
from requests_mock.contrib import fixture
from octaviaclient.api import load_balancer_v2 as lb
from osc_lib.tests import utils
from octaviaclient.api.v2 import octavia
FAKE_ACCOUNT = 'q12we34r'
FAKE_AUTH = '11223344556677889900'
FAKE_URL = 'http://example.com/v2.0/lbaas/'
FAKE_URL = 'http://example.com/v2.0/'
FAKE_LBAAS_URL = FAKE_URL + 'lbaas/'
FAKE_LB = uuidutils.generate_uuid()
FAKE_LI = uuidutils.generate_uuid()
@ -111,23 +113,23 @@ SINGLE_QT_RESP = {'quota': {'pool': -1}}
SINGLE_QT_UPDATE = {'quota': {'pool': -1}}
class TestLoadBalancerv2(utils.TestCase):
class TestOctaviaClient(utils.TestCase):
def setUp(self):
super(TestLoadBalancerv2, self).setUp()
super(TestOctaviaClient, self).setUp()
sess = session.Session()
self.api = lb.APIv2(session=sess, endpoint=FAKE_URL)
self.api = octavia.OctaviaAPI(session=sess, endpoint=FAKE_URL)
self.requests_mock = self.useFixture(fixture.Fixture())
class TestLoadBalancer(TestLoadBalancerv2):
class TestLoadBalancer(TestOctaviaClient):
_error_message = ("Validation failure: Test message.")
def test_list_load_balancer_no_options(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'loadbalancers',
FAKE_LBAAS_URL + 'loadbalancers',
json=LIST_LB_RESP,
status_code=200,
)
@ -137,7 +139,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_show_load_balancer(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'loadbalancers/' + FAKE_LB,
FAKE_LBAAS_URL + 'loadbalancers/' + FAKE_LB,
json=SINGLE_LB_RESP,
status_code=200
)
@ -147,7 +149,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_load_balancer(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'loadbalancers',
FAKE_LBAAS_URL + 'loadbalancers',
json=SINGLE_LB_RESP,
status_code=200
)
@ -157,11 +159,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_load_balancer_error(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'loadbalancers',
FAKE_LBAAS_URL + 'loadbalancers',
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.load_balancer_create,
json=SINGLE_LB_RESP)
@ -169,7 +171,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_load_balancer(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'loadbalancers/' + FAKE_LB,
FAKE_LBAAS_URL + 'loadbalancers/' + FAKE_LB,
json=SINGLE_LB_UPDATE,
status_code=200
)
@ -179,20 +181,41 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_load_balancer_error(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'loadbalancers/' + FAKE_LB,
FAKE_LBAAS_URL + 'loadbalancers/' + FAKE_LB,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.load_balancer_set,
FAKE_LB,
json=SINGLE_LB_UPDATE)
def test_failover_load_balancer(self):
self.requests_mock.register_uri(
'PUT',
FAKE_LBAAS_URL + 'loadbalancers/' + FAKE_LB + '/failover',
status_code=202,
)
ret = self.api.load_balancer_failover(FAKE_LB)
self.assertEqual(202, ret.status_code)
def test_failover_load_balancer_error(self):
self.requests_mock.register_uri(
'PUT',
FAKE_LBAAS_URL + 'loadbalancers/' + FAKE_LB + '/failover',
text='{"faultstring": "%s"}' % self._error_message,
status_code=409,
)
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.load_balancer_failover,
FAKE_LB)
def test_delete_load_balancer(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'loadbalancers/' + FAKE_LB,
FAKE_LBAAS_URL + 'loadbalancers/' + FAKE_LB,
status_code=200
)
ret = self.api.load_balancer_delete(FAKE_LB)
@ -201,11 +224,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_load_balancer_error(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'loadbalancers/' + FAKE_LB,
FAKE_LBAAS_URL + 'loadbalancers/' + FAKE_LB,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.load_balancer_delete,
FAKE_LB)
@ -213,7 +236,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_stats_show_load_balancer(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'loadbalancers/' + FAKE_LB + '/stats',
FAKE_LBAAS_URL + 'loadbalancers/' + FAKE_LB + '/stats',
json=SINGLE_LB_STATS_RESP,
status_code=200,
)
@ -223,7 +246,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_list_listeners_no_options(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'listeners',
FAKE_LBAAS_URL + 'listeners',
json=LIST_LI_RESP,
status_code=200,
)
@ -233,7 +256,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_show_listener(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'listeners/' + FAKE_LI,
FAKE_LBAAS_URL + 'listeners/' + FAKE_LI,
json=SINGLE_LI_RESP,
status_code=200
)
@ -243,7 +266,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_listener(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'listeners',
FAKE_LBAAS_URL + 'listeners',
json=SINGLE_LI_RESP,
status_code=200
)
@ -253,11 +276,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_listener_error(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'listeners',
FAKE_LBAAS_URL + 'listeners',
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.listener_create,
json=SINGLE_LI_RESP)
@ -265,7 +288,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_listeners(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'listeners/' + FAKE_LI,
FAKE_LBAAS_URL + 'listeners/' + FAKE_LI,
json=SINGLE_LI_UPDATE,
status_code=200
)
@ -275,11 +298,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_listeners_error(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'listeners/' + FAKE_LI,
FAKE_LBAAS_URL + 'listeners/' + FAKE_LI,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.listener_set,
FAKE_LI, json=SINGLE_LI_UPDATE)
@ -287,7 +310,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_listener(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'listeners/' + FAKE_LI,
FAKE_LBAAS_URL + 'listeners/' + FAKE_LI,
status_code=200
)
ret = self.api.listener_delete(FAKE_LI)
@ -296,11 +319,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_listener_error(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'listeners/' + FAKE_LI,
FAKE_LBAAS_URL + 'listeners/' + FAKE_LI,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.listener_delete,
FAKE_LI)
@ -308,7 +331,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_list_pool_no_options(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'pools',
FAKE_LBAAS_URL + 'pools',
json=LIST_PO_RESP,
status_code=200,
)
@ -318,7 +341,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_show_pool(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'pools/' + FAKE_PO,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO,
json=SINGLE_PO_RESP,
status_code=200
)
@ -328,7 +351,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_pool(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'pools',
FAKE_LBAAS_URL + 'pools',
json=SINGLE_PO_RESP,
status_code=200
)
@ -338,11 +361,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_pool_error(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'pools',
FAKE_LBAAS_URL + 'pools',
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.pool_create,
json=SINGLE_PO_RESP)
@ -350,7 +373,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_pool(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'pools/' + FAKE_PO,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO,
json=SINGLE_PO_UPDATE,
status_code=200
)
@ -360,11 +383,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_pool_error(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'pools/' + FAKE_PO,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.pool_set,
FAKE_PO, json=SINGLE_PO_UPDATE)
@ -372,7 +395,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_pool(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'pools/' + FAKE_PO,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO,
status_code=200
)
ret = self.api.pool_delete(FAKE_PO)
@ -381,11 +404,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_pool_error(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'pools/' + FAKE_PO,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.pool_delete,
FAKE_PO)
@ -393,7 +416,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_list_member_no_options(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'pools/' + FAKE_PO + '/members',
FAKE_LBAAS_URL + 'pools/' + FAKE_PO + '/members',
json=LIST_ME_RESP,
status_code=200,
)
@ -403,7 +426,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_show_member(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
json=SINGLE_ME_RESP,
status_code=200
)
@ -413,7 +436,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_member(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'pools/' + FAKE_PO + '/members',
FAKE_LBAAS_URL + 'pools/' + FAKE_PO + '/members',
json=SINGLE_ME_RESP,
status_code=200
)
@ -423,11 +446,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_member_error(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'pools/' + FAKE_PO + '/members',
FAKE_LBAAS_URL + 'pools/' + FAKE_PO + '/members',
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.member_create,
json=SINGLE_ME_RESP, pool_id=FAKE_PO)
@ -435,7 +458,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_member(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
json=SINGLE_ME_UPDATE,
status_code=200
)
@ -446,11 +469,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_member_error(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.member_set,
pool_id=FAKE_PO, member_id=FAKE_ME,
@ -459,7 +482,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_member(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
status_code=200
)
ret = self.api.member_delete(pool_id=FAKE_PO, member_id=FAKE_ME)
@ -468,11 +491,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_member_error(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
FAKE_LBAAS_URL + 'pools/' + FAKE_PO + '/members/' + FAKE_ME,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.member_delete,
pool_id=FAKE_PO, member_id=FAKE_ME)
@ -480,7 +503,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_list_l7policy_no_options(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'l7policies',
FAKE_LBAAS_URL + 'l7policies',
json=LIST_L7PO_RESP,
status_code=200,
)
@ -490,7 +513,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_show_l7policy(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'l7policies/' + FAKE_L7PO,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO,
json=SINGLE_L7PO_RESP,
status_code=200
)
@ -500,7 +523,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_l7policy(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'l7policies',
FAKE_LBAAS_URL + 'l7policies',
json=SINGLE_L7PO_RESP,
status_code=200
)
@ -510,11 +533,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_l7policy_error(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'l7policies',
FAKE_LBAAS_URL + 'l7policies',
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.l7policy_create,
json=SINGLE_L7PO_RESP)
@ -522,7 +545,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_l7policy(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'l7policies/' + FAKE_L7PO,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO,
json=SINGLE_L7PO_UPDATE,
status_code=200
)
@ -532,11 +555,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_l7policy_error(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'l7policies/' + FAKE_L7PO,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.l7policy_set,
FAKE_L7PO, json=SINGLE_L7PO_UPDATE)
@ -544,7 +567,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_l7policy(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'l7policies/' + FAKE_L7PO,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO,
status_code=200
)
ret = self.api.l7policy_delete(FAKE_L7PO)
@ -553,11 +576,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_l7policy_error(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'l7policies/' + FAKE_L7PO,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.l7policy_delete,
FAKE_L7PO)
@ -565,7 +588,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_list_l7rule_no_options(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'l7policies/' + FAKE_L7PO + '/rules',
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO + '/rules',
json=LIST_L7RU_RESP,
status_code=200,
)
@ -575,7 +598,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_show_l7rule(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
json=SINGLE_L7RU_RESP,
status_code=200
)
@ -585,7 +608,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_l7rule(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'l7policies/' + FAKE_L7PO + '/rules',
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO + '/rules',
json=SINGLE_L7RU_RESP,
status_code=200
)
@ -595,11 +618,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_l7rule_error(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'l7policies/' + FAKE_L7PO + '/rules',
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO + '/rules',
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.l7rule_create,
FAKE_L7PO, json=SINGLE_L7RU_RESP)
@ -607,7 +630,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_l7rule(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
json=SINGLE_L7RU_UPDATE,
status_code=200
)
@ -621,11 +644,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_l7rule_error(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.l7rule_set,
l7rule_id=FAKE_L7RU,
@ -635,7 +658,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_l7rule(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
status_code=200
)
ret = self.api.l7rule_delete(
@ -647,11 +670,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_l7rule_error(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
FAKE_LBAAS_URL + 'l7policies/' + FAKE_L7PO + '/rules/' + FAKE_L7RU,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.l7rule_delete,
l7rule_id=FAKE_L7RU,
@ -660,7 +683,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_list_health_monitor_no_options(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'healthmonitors',
FAKE_LBAAS_URL + 'healthmonitors',
json=LIST_HM_RESP,
status_code=200,
)
@ -670,7 +693,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_show_health_monitor(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'healthmonitors/' + FAKE_HM,
FAKE_LBAAS_URL + 'healthmonitors/' + FAKE_HM,
json=SINGLE_HM_RESP,
status_code=200
)
@ -680,7 +703,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_health_monitor(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'healthmonitors',
FAKE_LBAAS_URL + 'healthmonitors',
json=SINGLE_HM_RESP,
status_code=200
)
@ -690,11 +713,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_create_health_monitor_error(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'healthmonitors',
FAKE_LBAAS_URL + 'healthmonitors',
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.health_monitor_create,
json=SINGLE_HM_RESP)
@ -702,7 +725,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_health_monitor(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'healthmonitors/' + FAKE_HM,
FAKE_LBAAS_URL + 'healthmonitors/' + FAKE_HM,
json=SINGLE_HM_UPDATE,
status_code=200
)
@ -712,11 +735,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_health_monitor_error(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'healthmonitors/' + FAKE_HM,
FAKE_LBAAS_URL + 'healthmonitors/' + FAKE_HM,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.health_monitor_set,
FAKE_HM, json=SINGLE_HM_UPDATE)
@ -724,7 +747,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_health_monitor(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'healthmonitors/' + FAKE_HM,
FAKE_LBAAS_URL + 'healthmonitors/' + FAKE_HM,
status_code=200
)
ret = self.api.health_monitor_delete(FAKE_HM)
@ -733,11 +756,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_delete_health_monitor_error(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'healthmonitors/' + FAKE_HM,
FAKE_LBAAS_URL + 'healthmonitors/' + FAKE_HM,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.health_monitor_delete,
FAKE_HM)
@ -745,7 +768,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_list_quota_no_options(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'quotas',
FAKE_LBAAS_URL + 'quotas',
json=LIST_QT_RESP,
status_code=200,
)
@ -755,7 +778,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_show_quota(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'quotas/' + FAKE_PRJ,
FAKE_LBAAS_URL + 'quotas/' + FAKE_PRJ,
json=SINGLE_QT_RESP,
status_code=200
)
@ -765,7 +788,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_quota(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'quotas/' + FAKE_PRJ,
FAKE_LBAAS_URL + 'quotas/' + FAKE_PRJ,
json=SINGLE_QT_UPDATE,
status_code=200
)
@ -775,11 +798,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_set_quota_error(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'quotas/' + FAKE_PRJ,
FAKE_LBAAS_URL + 'quotas/' + FAKE_PRJ,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.quota_set,
FAKE_PRJ, json=SINGLE_QT_UPDATE)
@ -787,7 +810,7 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_reset_quota(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'quotas/' + FAKE_PRJ,
FAKE_LBAAS_URL + 'quotas/' + FAKE_PRJ,
status_code=200
)
ret = self.api.quota_reset(FAKE_PRJ)
@ -796,11 +819,11 @@ class TestLoadBalancer(TestLoadBalancerv2):
def test_reset_quota_error(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'quotas/' + FAKE_PRJ,
FAKE_LBAAS_URL + 'quotas/' + FAKE_PRJ,
text='{"faultstring": "%s"}' % self._error_message,
status_code=400
)
self.assertRaisesRegex(lb.OctaviaClientException,
self.assertRaisesRegex(octavia.OctaviaClientException,
self._error_message,
self.api.quota_reset,
FAKE_PRJ)

View File

@ -28,7 +28,7 @@ LOADBALANCER = {
}
class FakeLoadBalancerv2Client(object):
class FakeOctaviaClient(object):
def __init__(self, **kwargs):
self.load_balancers = mock.Mock()
self.load_balancers.resource_class = fakes.FakeResource(None, {})
@ -36,11 +36,11 @@ class FakeLoadBalancerv2Client(object):
self.management_url = kwargs['endpoint']
class TestLoadBalancerv2(utils.TestCommand):
class TestOctaviaClient(utils.TestCommand):
def setUp(self):
super(TestLoadBalancerv2, self).setUp()
self.app.client_manager.load_balancer = FakeLoadBalancerv2Client(
super(TestOctaviaClient, self).setUp()
self.app.client_manager.load_balancer = FakeOctaviaClient(
endpoint=fakes.AUTH_URL,
token=fakes.AUTH_TOKEN,
)
@ -112,7 +112,7 @@ class FakeListener(object):
class FakePool(object):
"""Fake one or more pool."""
"""Fake one or more pools."""
@staticmethod
def create_one_pool(attrs=None):
@ -142,6 +142,7 @@ class FakePool(object):
class FakeMember(object):
"""Fake one or more members."""
@staticmethod
def create_member(attrs=None):
@ -170,7 +171,7 @@ class FakeMember(object):
class FakeL7Policy(object):
"""Fake one or more L7policy."""
"""Fake one or more L7policies."""
@staticmethod
def create_one_l7policy(attrs=None):
@ -199,7 +200,7 @@ class FakeL7Policy(object):
class FakeL7Rule(object):
"""Fake one or more L7policy."""
"""Fake one or more L7rules."""
@staticmethod
def create_one_l7rule(attrs=None):
@ -229,7 +230,7 @@ class FakeL7Rule(object):
class FakeHM(object):
"""Fake one or more L7policy."""
"""Fake one or more health monitors."""
@staticmethod
def create_one_health_monitor(attrs=None):
@ -289,3 +290,36 @@ class FakeQT(object):
loaded=True)
return qt
class FakeAmphora(object):
"""Fake one or more amphorae."""
@staticmethod
def create_one_amphora(attrs=None):
attrs = attrs or {}
amphora = {
"id": uuidutils.generate_uuid(dashed=True),
"loadbalancer_id": uuidutils.generate_uuid(dashed=True),
"compute_id": uuidutils.generate_uuid(dashed=True),
"lb_network_ip": "192.168.1.3",
"vrrp_ip": "192.168.1.6",
"ha_ip": "192.168.1.10",
"vrrp_port_id": uuidutils.generate_uuid(dashed=True),
"ha_port_id": uuidutils.generate_uuid(dashed=True),
"cert_expiration": "2019-09-19 00:34:51",
"cert_busy": 0,
"role": "BACKUP",
"status": "ALLOCATED",
"vrrp_interface": "eth1",
"vrrp_id": 1,
"vrrp_priority": 200,
"cached_zone": "zone2",
}
amphora.update(attrs)
return fakes.FakeResource(
info=copy.deepcopy(amphora),
loaded=True)

View File

@ -0,0 +1,175 @@
# 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
import osc_lib.tests.utils as osc_test_utils
from octaviaclient.osc.v2 import amphora
from octaviaclient.osc.v2 import constants
from octaviaclient.tests.unit.osc.v2 import fakes as amp_fakes
AUTH_TOKEN = "foobar"
AUTH_URL = "http://192.0.2.2"
class TestAmphora(amp_fakes.TestOctaviaClient):
_amp = amp_fakes.FakeAmphora.create_one_amphora()
columns = constants.AMPHORA_COLUMNS
rows = constants.AMPHORA_ROWS
data_show = (
(
_amp.id,
_amp.loadbalancer_id,
_amp.compute_id,
_amp.lb_network_ip,
_amp.vrrp_ip,
_amp.ha_ip,
_amp.vrrp_port_id,
_amp.ha_port_id,
_amp.cert_expiration,
_amp.cert_busy,
_amp.role,
_amp.status,
_amp.vrrp_interface,
_amp.vrrp_id,
_amp.vrrp_priority,
_amp.cached_zone,
),
)
info_show = {
'id': _amp.id,
'loadbalancer_id': _amp.loadbalancer_id,
'compute_id': _amp.compute_id,
'lb_network_ip': _amp.lb_network_ip,
'vrrp_ip': _amp.vrrp_ip,
'ha_ip': _amp.ha_ip,
'vrrp_port_id': _amp.vrrp_port_id,
'ha_port_id': _amp.ha_port_id,
'cert_expiration': _amp.cert_expiration,
'cert_busy': _amp.cert_busy,
'role': _amp.role,
'status': _amp.status,
'vrrp_interface': _amp.vrrp_interface,
'vrrp_id': _amp.vrrp_id,
'vrrp_priority': _amp.vrrp_priority,
'cached_zone': _amp.cached_zone,
}
data_list = (
(
_amp.id,
_amp.loadbalancer_id,
_amp.status,
_amp.role,
_amp.lb_network_ip,
_amp.ha_ip,
),
)
info_list = {
'amphorae':
[{
'id': _amp.id,
'loadbalancer_id': _amp.loadbalancer_id,
'status': _amp.status,
'role': _amp.role,
'lb_network_ip': _amp.lb_network_ip,
'ha_ip': _amp.ha_ip,
}],
}
amp_info = copy.deepcopy(info_list)
def setUp(self):
super(TestAmphora, self).setUp()
self.api_mock = mock.Mock()
self.api_mock.amphora_list.return_value = self.amp_info
self.api_mock.amphora_show.return_value = {
"amphora": self.amp_info['amphorae'][0],
}
lb_client = self.app.client_manager
lb_client.load_balancer = self.api_mock
class TestAmphoraList(TestAmphora):
def setUp(self):
super(TestAmphoraList, self).setUp()
self.cmd = amphora.ListAmphora(self.app, None)
def test_amphora_list_no_options(self):
arglist = []
verify_list = []
parsed_args = self.check_parser(self.cmd, arglist, verify_list)
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.amphora_list.assert_called_with()
self.assertEqual(self.columns, columns)
self.assertEqual(self.data_list, tuple(data))
@mock.patch('octaviaclient.osc.v2.utils.get_amphora_attrs')
def test_amphora_list_with_loadbalancer(self, mock_client):
mock_client.return_value = {
'loadbalancer_id': self._amp.loadbalancer_id,
'compute_id': self._amp.compute_id,
'role': self._amp.role,
'status': self._amp.status,
}
arglist = [
'--loadbalancer', self._amp.loadbalancer_id,
'--compute-id', self._amp.compute_id,
'--role', 'Master',
'--status', 'allocAted',
]
verify_list = [
('loadbalancer', self._amp.loadbalancer_id),
('compute_id', self._amp.compute_id),
('role', 'MASTER'),
('status', 'ALLOCATED'),
]
parsed_args = self.check_parser(self.cmd, arglist, verify_list)
columns, data = self.cmd.take_action(parsed_args)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data_list, tuple(data))
class TestAmphoraShow(TestAmphora):
def setUp(self):
super(TestAmphoraShow, self).setUp()
self.cmd = amphora.ShowAmphora(self.app, None)
def test_amphora_show_no_args(self):
self.assertRaises(
osc_test_utils.ParserException,
self.check_parser, self.cmd, [], [],
)
@mock.patch('octaviaclient.osc.v2.utils.get_amphora_attrs')
def test_amphora_show(self, mock_client):
mock_client.return_value = {'amphora_id': self._amp.id}
arglist = [self._amp.id]
verify_list = [('amphora_id', self._amp.id)]
parsed_args = self.check_parser(self.cmd, arglist, verify_list)
rows, data = self.cmd.take_action(parsed_args)
self.assertEqual(self.rows, rows)
self.api_mock.amphora_show.assert_called_with(amphora_id=self._amp.id)

View File

@ -23,7 +23,7 @@ AUTH_TOKEN = "foobar"
AUTH_URL = "http://192.0.2.2"
class TestHealthMonitor(hm_fakes.TestLoadBalancerv2):
class TestHealthMonitor(hm_fakes.TestOctaviaClient):
_hm = hm_fakes.FakeHM.create_one_health_monitor()

View File

@ -23,7 +23,7 @@ AUTH_TOKEN = "foobar"
AUTH_URL = "http://192.0.2.2"
class TestL7Policy(po_fakes.TestLoadBalancerv2):
class TestL7Policy(po_fakes.TestOctaviaClient):
_l7po = po_fakes.FakeL7Policy.create_one_l7policy()

View File

@ -21,7 +21,7 @@ AUTH_TOKEN = "foobar"
AUTH_URL = "http://192.0.2.2"
class TestL7Policy(ru_fakes.TestLoadBalancerv2):
class TestL7Policy(ru_fakes.TestOctaviaClient):
_l7ru = ru_fakes.FakeL7Rule.create_one_l7rule()
_l7po = ru_fakes.FakeL7Policy.create_one_l7policy()

View File

@ -23,7 +23,7 @@ AUTH_TOKEN = "foobar"
AUTH_URL = "http://192.0.2.2"
class TestListener(li_fakes.TestLoadBalancerv2):
class TestListener(li_fakes.TestOctaviaClient):
_li = li_fakes.FakeListener.create_one_listener()

View File

@ -24,7 +24,7 @@ AUTH_TOKEN = "foobar"
AUTH_URL = "http://192.0.2.2"
class TestLoadBalancer(lb_fakes.TestLoadBalancerv2):
class TestLoadBalancer(lb_fakes.TestOctaviaClient):
_lb = lb_fakes.FakeLoadBalancer.create_one_load_balancer()
@ -257,3 +257,21 @@ class TestLoadBalancerStats(TestLoadBalancer):
self.cmd.take_action(parsed_args)
self.api_mock.load_balancer_stats_show.assert_called_with(
lb_id=self._lb.id)
class TestLoadBalancerFailover(TestLoadBalancer):
def setUp(self):
super(TestLoadBalancerFailover, self).setUp()
self.cmd = load_balancer.FailoverLoadBalancer(self.app, None)
def test_load_balancer_failover(self):
arglist = [self._lb.id]
verifylist = [
('loadbalancer', self._lb.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.api_mock.load_balancer_failover.assert_called_with(
lb_id=self._lb.id)

View File

@ -17,10 +17,10 @@ import mock
from octaviaclient.osc.v2 import member
from octaviaclient.tests.unit.osc.v2 import fakes as mem_fakes
from osc_lib.tests.utils import ParserException
import osc_lib.tests.utils as osc_test_utils
class TestMember(mem_fakes.TestLoadBalancerv2):
class TestMember(mem_fakes.TestOctaviaClient):
mem = mem_fakes.FakeMember.create_member()
@ -84,7 +84,7 @@ class TestListMember(TestMember):
arglist = []
verifylist = []
self.assertRaises(ParserException,
self.assertRaises(osc_test_utils.ParserException,
self.check_parser, self.cmd, arglist, verifylist)
@mock.patch('octaviaclient.osc.v2.utils.get_member_attrs')

View File

@ -23,7 +23,7 @@ AUTH_TOKEN = "foobar"
AUTH_URL = "http://192.0.2.2"
class TestPool(po_fakes.TestLoadBalancerv2):
class TestPool(po_fakes.TestOctaviaClient):
_po = po_fakes.FakePool.create_one_pool()

View File

@ -23,7 +23,7 @@ AUTH_TOKEN = "foobar"
AUTH_URL = "http://192.0.2.2"
class TestQuota(qt_fakes.TestLoadBalancerv2):
class TestQuota(qt_fakes.TestOctaviaClient):
_qt = qt_fakes.FakeQT.create_one_quota()

View File

@ -19,10 +19,7 @@ import os
import testtools
from octaviaclient.tests import fakes
class ParserException(Exception):
pass
import osc_lib.tests.utils as osc_test_utils
class TestCase(testtools.TestCase):
@ -65,8 +62,10 @@ class TestCommand(TestCase):
cmd_parser = cmd.get_parser('check_parser')
try:
parsed_args = cmd_parser.parse_args(args)
except osc_test_utils.ParserException:
raise
except SystemExit:
raise ParserException("Argument parse failed")
raise osc_test_utils.ParserException("Argument parse failed")
for av in verify_args:
attr, value = av
if attr:

View File

@ -0,0 +1,5 @@
---
features:
- Loadbalancer failover command, which allows to trigger failover protocol.
- Amphora commands, to query amphorae by ID or by loadbalancer ID, etc.
- Filter 'list' calls by loadbalancer ID, for both listeners and pools.

View File

@ -33,6 +33,7 @@ openstack.load_balancer.v2 =
loadbalancer_delete = octaviaclient.osc.v2.load_balancer:DeleteLoadBalancer
loadbalancer_set = octaviaclient.osc.v2.load_balancer:SetLoadBalancer
loadbalancer_stats_show = octaviaclient.osc.v2.load_balancer:ShowLoadBalancerStats
loadbalancer_failover = octaviaclient.osc.v2.load_balancer:FailoverLoadBalancer
loadbalancer_listener_create = octaviaclient.osc.v2.listener:CreateListener
loadbalancer_listener_list = octaviaclient.osc.v2.listener:ListListener
loadbalancer_listener_show = octaviaclient.osc.v2.listener:ShowListener
@ -68,6 +69,8 @@ openstack.load_balancer.v2 =
loadbalancer_quota_defaults_show = octaviaclient.osc.v2.quota:ShowQuotaDefaults
loadbalancer_quota_reset = octaviaclient.osc.v2.quota:ResetQuota
loadbalancer_quota_set = octaviaclient.osc.v2.quota:SetQuota
loadbalancer_amphora_list = octaviaclient.osc.v2.amphora:ListAmphora
loadbalancer_amphora_show = octaviaclient.osc.v2.amphora:ShowAmphora
[build_sphinx]
source-dir = doc/source