Browse Source

Add loadbalancer commands to client

This patch Implements the loadbalancer create,
show, set, delete, and list commands within
the OpenStack client.

Co-Authored-By: Jude Cross <jcross@godaddy.com>
Change-Id: I7f75a1319bca5865be71a3380e0866e87a13e37b
changes/16/454516/30
Ankur Gupta 5 years ago
committed by Michael Johnson
parent
commit
1940793da1
  1. 8
      doc/source/data/lbaas.csv
  2. 145
      doc/source/usage/osc/v2/load-balancer.rst
  3. 21
      octaviaclient/api/constants.py
  4. 74
      octaviaclient/api/load_balancer_v2.py
  5. 39
      octaviaclient/osc/v2/constants.py
  6. 237
      octaviaclient/osc/v2/load_balancer.py
  7. 138
      octaviaclient/osc/v2/utils.py
  8. 58
      octaviaclient/tests/unit/api/test_load_balancer.py
  9. 5
      octaviaclient/tests/unit/osc/v2/fakes.py
  10. 161
      octaviaclient/tests/unit/osc/v2/test_load_balancer.py
  11. 31
      requirements.txt
  12. 4
      setup.cfg
  13. 1
      test-requirements.txt

8
doc/source/data/lbaas.csv

@ -18,14 +18,14 @@ lbaas-listener-delete,,LBaaS v2 Delete a given listener.
lbaas-listener-list,,LBaaS v2 List listeners that belong to a given tenant.
lbaas-listener-show,,LBaaS v2 Show information of a given listener.
lbaas-listener-update,,LBaaS v2 Update a given listener.
lbaas-loadbalancer-create,,LBaaS v2 Create a loadbalancer.
lbaas-loadbalancer-delete,,LBaaS v2 Delete a given loadbalancer.
lbaas-loadbalancer-create,loadbalancer create,LBaaS v2 Create a loadbalancer.
lbaas-loadbalancer-delete,loadbalancer delete,LBaaS v2 Delete a given loadbalancer.
lbaas-loadbalancer-list,loadbalancer list,LBaaS v2 List loadbalancers that belong to a given tenant.
lbaas-loadbalancer-list-on-agent,,List the loadbalancers on a loadbalancer v2 agent.
lbaas-loadbalancer-show,,LBaaS v2 Show information of a given loadbalancer.
lbaas-loadbalancer-show,loadbalancer show,LBaaS v2 Show information of a given loadbalancer.
lbaas-loadbalancer-stats,,Retrieve stats for a given loadbalancer.
lbaas-loadbalancer-status,,Retrieve status for a given loadbalancer.
lbaas-loadbalancer-update,,LBaaS v2 Update a given loadbalancer.
lbaas-loadbalancer-update,loadbalancer set,LBaaS v2 Update a given loadbalancer.
lbaas-member-create,,LBaaS v2 Create a member.
lbaas-member-delete,,LBaaS v2 Delete a given member.
lbaas-member-list,,LBaaS v2 List members that belong to a given pool.

145
doc/source/usage/osc/v2/load-balancer.rst

@ -11,3 +11,148 @@ List load balancers
.. code:: bash
openstack loadbalancer list
[--name <name>]
[--enable | --disable]
[--project <project-id>]
.. option:: --name <name>
List load balancers according to their name.
.. option:: --enable
List enabled load balancers.
.. option:: --disable
List disabled load balancers.
.. option:: --project <project-id>
List load balancers according to their project (name or ID).
loadbalancer show
-----------------
Show the details for a single load balancer
.. program:: loadbalancer show
.. code:: bash
openstack loadbalancer show
<loadbalancer>
.. _loadbalancer_show-loadbalancer:
.. describe:: <load_balancer>
Name or UUID of the load balancer.
loadbalancer create
-------------------
Create a load balancer
.. program:: loadbalancer create
.. code:: bash
openstack loadbalancer create
[--name <name>]
[--description <description>]
[--vip-address <vip_address>]
[--vip-port-id <vip_port_id>]
[--vip-subnet-id <vip_subnet_id>]
[--vip-network-id <vip_network_id>]
[--project <project>]
[--enable | --disable]
.. option:: --name <name>
New load balancer name.
.. option:: --description <description>
Set load balancer description.
.. option:: --vip-address <vip_address>
Set the VIP IP Address.
.. option:: --vip-port-id <vip_port_id>
Set Port for the load balancer (name or ID).
.. option:: --vip-subnet-id <vip_subnet_id>
Set subnet for the load balancer (name or ID).
.. option:: --vip-network-id <vip_network_id>
Set network for the load balancer (name or ID).
.. option:: --project <project>
Project for the load balancer (name or ID).
.. option:: --enable
Enable load balancer (default).
.. option:: --disable
Disable load balancer.
loadbalancer set
----------------
Update a load balancer
.. program:: loadbalancer set
.. code:: bash
openstack loadbalancer set
[--enable | --disable]
[--name <name>]
[--description <description>]
<load_balancer>
.. _loadbalancer_set-loadbalancer:
.. describe:: <load_balancer>
Name or UUID of the load balancer to update.
.. option:: --enable
Enable load balancer.
.. option:: --disable
Disable load balancer.
.. option:: --name <name>
Set load balancer name.
.. option:: --description <description>
Set load balancer description.
loadbalancer delete
-------------------
Delete a load balancer
.. program:: loadbalancer delete
.. code:: bash
openstack loadbalancer delete
[--cascade]
<load_balancer>
.. _loadbalancer_delete-loadbalancer:
.. describe:: <loadbalancer>
Load balancers to delete (name or ID).
.. option:: --cascade
Cascade the delete to all child elements of the load balancer.

21
octaviaclient/api/constants.py

@ -0,0 +1,21 @@
# 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.
#
BASE_LOADBALANCER_URL = '/loadbalancers'
BASE_SINGLE_LB_URL = BASE_LOADBALANCER_URL + '/{uuid}'
BASE_LISTENER_URL = '/listeners'
BASE_SINGLE_LISTENER_URL = BASE_LISTENER_URL + '/{uuid}'
BASE_POOL_URL = '/pools'
BASE_SINGLE_POOL_URL = BASE_POOL_URL + '/{uuid}'

74
octaviaclient/api/load_balancer_v2.py

@ -15,6 +15,8 @@
from osc_lib.api import api
from octaviaclient.api import constants as const
class APIv2(api.BaseAPI):
"""Load Balancer v2 API"""
@ -30,11 +32,71 @@ class APIv2(api.BaseAPI):
if not self.endpoint.endswith(self._endpoint_suffix):
self.endpoint = self.endpoint + self._endpoint_suffix
def load_balancer_list(
self,
**filter
):
url = '/loadbalancers'
load_balancer_list = self.list(url, **filter)['loadbalancers']
def load_balancer_list(self, **params):
"""List all load balancers
:param params:
Parameters to filter on (not implemented)
:return:
List of load balancers and their settings
"""
url = const.BASE_LOADBALANCER_URL
load_balancer_list = self.list(url, **params)
return load_balancer_list
def load_balancer_show(self, lb_id):
"""Show a load balancer
:param string lb_id:
ID of the load balancer to show
:return:
A dict of the specified load balancer's settings
"""
load_balancer = self.find(path=const.BASE_LOADBALANCER_URL,
value=lb_id)
return load_balancer
def load_balancer_create(self, **params):
"""Create a load balancer
:param params:
Paramaters to create the load balancer with (expects json=)
:return:
A dict of the created load balancer's settings
"""
url = const.BASE_LOADBALANCER_URL
load_balancer = self.create(url, **params)
return load_balancer
def load_balancer_delete(self, lb_id, **params):
"""Delete a load balancer
:param string lb_id:
The ID of the load balancer to delete
:param params:
A dict of url parameters
:return:
Response Code from the API
"""
url = const.BASE_SINGLE_LB_URL.format(uuid=lb_id)
load_balancer = self.delete(url, params=params)
return load_balancer
def load_balancer_set(self, lb_id, **params):
"""Update a load balancer's settings
:param string lb_id:
The ID of the load baalancer to update
:param params:
A dict of arguments to update a loadbalancer
:return:
A dict of the updated load balancer's settings
"""
url = const.BASE_SINGLE_LB_URL.format(uuid=lb_id)
load_balancer = self.create(url, method='PUT', **params)
return load_balancer

39
octaviaclient/osc/v2/constants.py

@ -0,0 +1,39 @@
# 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.
#
LOAD_BALANCER_ROWS = (
'admin_state_up',
'created_at',
'description',
'flavor',
'id',
'listeners',
'name',
'operating_status',
'pools',
'project_id',
'provider',
'provisioning_status',
'updated_at',
'vip_Address',
'vip_network_id',
'vip_port_id',
'vip_subnet_id')
LOAD_BALANCER_COLUMNS = (
'id',
'name',
'project_id',
'vip_address',
'provisioning_status',
'provider')

237
octaviaclient/osc/v2/load_balancer.py

@ -15,27 +15,244 @@
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 CreateLoadBalancer(command.ShowOne):
"""Create a load balancer"""
def get_parser(self, prog_name):
parser = super(CreateLoadBalancer, self).get_parser(prog_name)
parser.add_argument(
'--name',
metavar='<name>',
help="New load balancer name"
)
parser.add_argument(
'--description',
metavar='<description>',
help="Set load balancer description"
)
parser.add_argument(
'--vip-address',
metavar='<vip_address>',
help="Set IP Address"
)
parser.add_argument(
'--vip-port-id',
metavar='<vip_port_id>',
help="Set Port for the load balancer (name or ID)"
)
parser.add_argument(
'--vip-subnet-id',
metavar='<vip_subnet_id>',
help="Set subnet for the load balancer (name or ID)"
)
parser.add_argument(
'--vip-network-id',
metavar='<vip_network_id>',
help="Set network for the load balancer (name or ID)"
)
parser.add_argument(
'--project',
metavar='<project>',
help="Project for the load balancer (name or ID)"
)
admin_group = parser.add_mutually_exclusive_group()
admin_group.add_argument(
'--enable',
action='store_true',
default=True,
help="Enable load balancer (default)"
)
admin_group.add_argument(
'--disable',
action='store_true',
default=None,
help="Disable load balancer"
)
return parser
def take_action(self, parsed_args):
rows = const.LOAD_BALANCER_ROWS
attrs = v2_utils.get_loadbalancer_attrs(self.app.client_manager,
parsed_args)
v2_utils.check_loadbalancer_attrs(attrs)
body = {'loadbalancer': attrs}
data = self.app.client_manager.load_balancer.load_balancer_create(
json=body)
formatters = {
'listeners': v2_utils.format_list,
'pools': v2_utils.format_list,
'l7policies': v2_utils.format_list
}
return (rows, (utils.get_dict_properties(
data['loadbalancer'], rows, formatters=formatters)))
class DeleteLoadBalancer(command.Command):
"""Delete a load balancer"""
def get_parser(self, prog_name):
parser = super(DeleteLoadBalancer, self).get_parser(prog_name)
parser.add_argument(
'loadbalancer',
metavar='<load_balancer>',
help="Load balancers to delete (name or ID)"
)
parser.add_argument(
'--cascade',
action='store_true',
default=None,
help="Cascade the delete to all child elements of the load "
"balancer."
)
return parser
def take_action(self, parsed_args):
attrs = v2_utils.get_loadbalancer_attrs(self.app.client_manager,
parsed_args)
lb_id = attrs.pop('loadbalancer_id')
self.app.client_manager.load_balancer.\
load_balancer_delete(lb_id=lb_id, **attrs)
class ListLoadBalancer(lister.Lister):
"""List load balancers"""
def parsed_args(self, prog_name):
def get_parser(self, prog_name):
parser = super(ListLoadBalancer, self).get_parser(prog_name)
parser.add_argument(
'--name',
metavar='<name>',
help="List load balancers according to their name"
)
admin_state_group = parser.add_mutually_exclusive_group()
admin_state_group.add_argument(
'--enable',
action='store_true',
default=None,
help="List load balancers according to their name"
)
admin_state_group.add_argument(
'--disable',
action='store_true',
default=None,
help="List disabled load balancers"
)
parser.add_argument(
'--project',
metavar='<project-id>',
help="List load balancers according to their project (name or ID)"
)
return parser
def take_action(self, parsed_args):
columns = (
'ID',
'Name',
'Project ID',
'VIP Address',
'Provisioning Status',)
data = self.app.client_manager.load_balancer.load_balancer_list()
columns = const.LOAD_BALANCER_COLUMNS
attrs = v2_utils.get_loadbalancer_attrs(self.app.client_manager,
parsed_args)
data = self.app.client_manager.load_balancer.load_balancer_list(
**attrs)
return (columns,
(utils.get_dict_properties(
s, columns,
formatters={},
) for s in data))
) for s in data['loadbalancers']))
class ShowLoadBalancer(command.ShowOne):
"""Show the details for a single load balancer"""
def get_parser(self, prog_name):
parser = super(ShowLoadBalancer, 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):
rows = const.LOAD_BALANCER_ROWS
attrs = v2_utils.get_loadbalancer_attrs(self.app.client_manager,
parsed_args)
lb_id = attrs.pop('loadbalancer_id')
data = self.app.client_manager.load_balancer.load_balancer_show(
lb_id=lb_id
)
formatters = {
'listeners': v2_utils.format_list,
'pools': v2_utils.format_list,
'l7policies': v2_utils.format_list
}
return (rows, (utils.get_dict_properties(
data, rows, formatters=formatters)))
class SetLoadBalancer(command.Command):
"""Update a load balancer"""
def get_parser(self, prog_name):
parser = super(SetLoadBalancer, self).get_parser(prog_name)
parser.add_argument(
'loadbalancer',
metavar='<load_balancer>',
help='Name or UUID of the load balancer'
)
admin_group = parser.add_mutually_exclusive_group()
admin_group.add_argument(
'--enable',
action='store_true',
default=None,
help="Enable load balancer (default)"
)
admin_group.add_argument(
'--disable',
action='store_true',
default=None,
help="Disable load balancer"
)
parser.add_argument(
'--name',
metavar='<name>',
help="Set load balancer name"
)
parser.add_argument(
'--description',
metavar='<description>',
help="Set load balancer description"
)
return parser
def take_action(self, parsed_args):
attrs = v2_utils.get_loadbalancer_attrs(self.app.client_manager,
parsed_args)
lb_id = attrs.pop('loadbalancer_id')
body = {'loadbalancer': attrs}
self.app.client_manager.load_balancer.load_balancer_set(
lb_id, json=body)

138
octaviaclient/osc/v2/utils.py

@ -0,0 +1,138 @@
# 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.
#
from osc_lib import exceptions
from openstackclient.identity import common as identity_common
def get_resource_id(resource, resource_name, name):
"""Converts a resource name into a UUID for consumption for the API
:param callable resource:
A client_manager callable
:param resource_name:
The resource key name for the dictonary returned
:param name:
The name of the resource to convert to UUID
:return:
The UUID of the found resource
"""
try:
if resource_name == 'project':
if name != 'non-uuid':
project_id = identity_common.find_project(
resource,
name
).id
return project_id
else:
return 'non-uuid'
else:
names = [re for re in resource()[resource_name]
if re.get('name') == name or re.get('id') == name]
if len(names) > 1:
msg = ("{0} {1} found with name or ID of {2}. Please try "
"again with UUID".format(len(names), resource_name,
name))
raise exceptions.CommandError(msg)
else:
return names[0].get('id')
except IndexError:
msg = "Unable to locate {0} in {1}".format(name, resource_name)
raise exceptions.CommandError(msg)
def get_loadbalancer_attrs(client_manager, parsed_args):
attr_map = {
'name': ('name', str),
'description': ('description', str),
'protocol': ('protocol', str),
'loadbalancer': (
'loadbalancer_id',
'loadbalancers',
client_manager.load_balancer.load_balancer_list
),
'connection_limit': ('connection_limit', str),
'protocol_port': ('protocol_port', int),
'default_pool': ('default_pool_id', str),
'project': (
'project_id',
'project',
client_manager.identity
),
'vip_address': ('vip_address', str),
'vip_port_id': (
'vip_port_id',
'ports',
client_manager.neutronclient.list_ports
),
'vip_subnet_id': (
'vip_subnet_id',
'subnets',
client_manager.neutronclient.list_subnets
),
'vip_network_id': (
'vip_network_id',
'networks',
client_manager.neutronclient.list_networks
),
'enable': ('admin_state_up', lambda x: True),
'disable': ('admin_state_up', lambda x: False),
'cascade': ('cascade', lambda x: True)
}
_attrs = vars(parsed_args)
attrs = _map_attrs(_attrs, attr_map)
return attrs
def check_loadbalancer_attrs(attrs):
verify_args = ['vip_subnet_id', 'vip_network_id', 'vip_port_id']
if not any(i in attrs.keys() for i in verify_args):
msg = "Missing required argument: Requires one of " \
"--vip-subnet-id, --vip-network-id or --vip-port-id"
raise exceptions.CommandError(msg)
elif 'vip_port_id' in attrs:
if any(i in attrs.keys() for i in ['vip_subnet_id', 'vip_address']):
msg = "Argument error: --port-id can not be used with " \
"--vip-network-id or --vip-subnet-id"
raise exceptions.CommandError(msg)
def format_headers(headers):
formatted_headers = {}
headers = headers.split(',')
for header in headers:
k, v = header.split('=')
formatted_headers[k] = v
return formatted_headers
def format_list(data):
return '\n'.join(i['id'] for i in data)
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():
if len(attr_map[k]) < 3:
mapped_attrs[attr_map[k][0]] = attr_map[k][1](v)
else:
mapped_attrs[attr_map[k][0]] = get_resource_id(
attr_map[k][2], attr_map[k][1], v)
return mapped_attrs

58
octaviaclient/tests/unit/api/test_load_balancer.py

@ -14,6 +14,7 @@
"""Load Balancer v2 API Library Tests"""
from keystoneauth1 import session
from oslo_utils import uuidutils
from requests_mock.contrib import fixture
from octaviaclient.api import load_balancer_v2 as lb
@ -23,12 +24,18 @@ FAKE_ACCOUNT = 'q12we34r'
FAKE_AUTH = '11223344556677889900'
FAKE_URL = 'http://example.com/v2.0/lbaas/'
FAKE_LB = 'rainbarrel'
FAKE_LB = uuidutils.generate_uuid()
LIST_LB_RESP = [
{'name': 'lb1'},
{'name': 'lb2'},
]
LIST_LB_RESP = {
'loadbalancers':
[{'name': 'lb1'},
{'name': 'lb2'}]
}
SINGLE_LB_RESP = {'loadbalancer': {'id': FAKE_LB, 'name': 'lb1'}}
SINGLE_LB_UPDATE = {"loadbalancer": {"admin_state_up": False}}
SINGLE_LB_UPDATE_INVALID = {"loadbalancer": {"id": 'invalid_param'}}
class TestLoadBalancerv2(utils.TestCase):
@ -46,8 +53,47 @@ class TestLoadBalancer(TestLoadBalancerv2):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'loadbalancers',
json={'loadbalancers': LIST_LB_RESP},
json=LIST_LB_RESP,
status_code=200,
)
ret = self.api.load_balancer_list()
self.assertEqual(LIST_LB_RESP, ret)
def test_show_load_balancer(self):
self.requests_mock.register_uri(
'GET',
FAKE_URL + 'loadbalancers/' + FAKE_LB,
json=SINGLE_LB_RESP,
status_code=200
)
ret = self.api.load_balancer_show(FAKE_LB)
self.assertEqual(SINGLE_LB_RESP['loadbalancer'], ret)
def test_create_load_balancer(self):
self.requests_mock.register_uri(
'POST',
FAKE_URL + 'loadbalancers',
json=SINGLE_LB_RESP,
status_code=200
)
ret = self.api.load_balancer_create(json=SINGLE_LB_RESP)
self.assertEqual(SINGLE_LB_RESP, ret)
def test_set_load_balancer(self):
self.requests_mock.register_uri(
'PUT',
FAKE_URL + 'loadbalancers/' + FAKE_LB,
json=SINGLE_LB_UPDATE,
status_code=200
)
ret = self.api.load_balancer_set(FAKE_LB, json=SINGLE_LB_UPDATE)
self.assertEqual(SINGLE_LB_UPDATE, ret)
def test_delete_load_balancer(self):
self.requests_mock.register_uri(
'DELETE',
FAKE_URL + 'loadbalancers/' + FAKE_LB,
status_code=200
)
ret = self.api.load_balancer_delete(FAKE_LB)
self.assertEqual(200, ret.status_code)

5
octaviaclient/tests/unit/osc/v2/fakes.py

@ -25,6 +25,7 @@ LOADBALANCER = {
'project_id': 'dummyproject',
'vip_address': '192.0.2.2',
'provisioning_status': 'ONLINE',
'provider': 'octavia'
}
@ -66,8 +67,10 @@ class FakeLoadBalancer(object):
'id': str(uuid.uuid4()),
'name': 'lb-name-' + uuid.uuid4().hex,
'project_id': uuid.uuid4().hex,
'vip_address': '192.0.2.2',
'vip_address': '192.0.2.124',
'vip_network_id': uuid.uuid4().hex,
'provisioning_status': 'ONLINE',
'provider': 'octavia'
}
lb_info.update(attrs)

161
octaviaclient/tests/unit/osc/v2/test_load_balancer.py

@ -14,6 +14,8 @@
import copy
import mock
from osc_lib import exceptions
from octaviaclient.osc.v2 import load_balancer as load_balancer
from octaviaclient.tests.unit.osc.v2 import fakes as lb_fakes
@ -23,22 +25,15 @@ AUTH_URL = "http://192.0.2.2"
class TestLoadBalancer(lb_fakes.TestLoadBalancerv2):
def setUp(self):
super(TestLoadBalancer, self).setUp()
self.lb_mock = self.app.client_manager.load_balancer.load_balancers
self.lb_mock.reset_mock()
class TestLoadBalancerList(TestLoadBalancer):
_lb = lb_fakes.FakeLoadBalancer.create_one_load_balancer()
columns = (
'ID',
'Name',
'Project ID',
'VIP Address',
'Provisioning Status',
'id',
'name',
'project_id',
'vip_address',
'provisioning_status',
'provider'
)
datalist = (
@ -48,25 +43,39 @@ class TestLoadBalancerList(TestLoadBalancer):
_lb.project_id,
_lb.vip_address,
_lb.provisioning_status,
_lb.provider
),
)
info = {
'id': _lb.id,
'name': _lb.name,
'project_id': _lb.project_id,
'vip_address': _lb.vip_address,
'provisioning_status': _lb.provisioning_status,
'loadbalancers':
[{'id': _lb.id,
'name': _lb.name,
'project_id': _lb.project_id,
'vip_address': _lb.vip_address,
'vip_network_id': _lb.vip_network_id,
'provisioning_status': _lb.provisioning_status,
'provider': _lb.provider
}]
}
lb_info = copy.deepcopy(info)
def setUp(self):
super(TestLoadBalancerList, self).setUp()
super(TestLoadBalancer, self).setUp()
self.lb_mock = self.app.client_manager.load_balancer.load_balancers
self.lb_mock.reset_mock()
self.api_mock = mock.Mock()
self.api_mock.load_balancer_list.return_value = [self.lb_info]
self.api_mock.load_balancer_list.return_value = self.lb_info
lb_client = self.app.client_manager
lb_client.load_balancer = self.api_mock
lb_client.neutronclient = mock.MagicMock()
class TestLoadBalancerList(TestLoadBalancer):
def setUp(self):
super(TestLoadBalancerList, self).setUp()
self.cmd = load_balancer.ListLoadBalancer(self.app, None)
def test_load_balancer_list_no_options(self):
@ -79,3 +88,115 @@ class TestLoadBalancerList(TestLoadBalancer):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
def test_load_balancer_list_with_options(self):
arglist = ['--name', 'rainbarrel']
verifylist = [('name', 'rainbarrel')]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.load_balancer_list.assert_called_with(name='rainbarrel')
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
class TestLoadBalancerDelete(TestLoadBalancer):
def setUp(self):
super(TestLoadBalancerDelete, self).setUp()
self.cmd = load_balancer.DeleteLoadBalancer(self.app, None)
def test_load_balancer_delete(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_delete.assert_called_with(
lb_id=self._lb.id)
def test_load_balancer_delete_failure(self):
arglist = ['unknown_lb']
verifylist = [
('loadbalancer', 'unknown_lb')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
self.assertNotCalled(self.api_mock.load_balancer_delete)
class TestLoadBalancerCreate(TestLoadBalancer):
def setUp(self):
super(TestLoadBalancerCreate, self).setUp()
self.api_mock = mock.Mock()
self.api_mock.load_balancer_create.return_value = {
'loadbalancer': self.lb_info['loadbalancers'][0]
}
lb_client = self.app.client_manager
lb_client.load_balancer = self.api_mock
self.cmd = load_balancer.CreateLoadBalancer(self.app, None)
@mock.patch('octaviaclient.osc.v2.utils.get_loadbalancer_attrs')
def test_load_balancer_create(self, mock_client):
mock_client.return_value = self.lb_info['loadbalancers'][0]
arglist = ['--name', self._lb.name,
'--vip-network-id', self._lb.vip_network_id,
'--project', self._lb.project_id]
verifylist = [
('name', self._lb.name),
('vip_network_id', self._lb.vip_network_id),
('project', self._lb.project_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.api_mock.load_balancer_create.assert_called_with(
json={'loadbalancer': self.lb_info['loadbalancers'][0]})
class TestLoadBalancerShow(TestLoadBalancer):
def setUp(self):
super(TestLoadBalancerShow, self).setUp()
self.api_mock = mock.Mock()
self.api_mock.load_balancer_list.return_value = self.lb_info
self.api_mock.load_balancer_show.return_value = {
'loadbalancer': self.lb_info['loadbalancers'][0]}
lb_client = self.app.client_manager
lb_client.load_balancer = self.api_mock
self.cmd = load_balancer.ShowLoadBalancer(self.app, None)
def test_load_balancer_show(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_show.assert_called_with(lb_id=self._lb.id)
class TestLoadBalancerSet(TestLoadBalancer):
def setUp(self):
super(TestLoadBalancerSet, self).setUp()
self.cmd = load_balancer.SetLoadBalancer(self.app, None)
def test_load_balancer_set(self):
arglist = [self._lb.id, '--name', 'new_name']
verifylist = [
('loadbalancer', self._lb.id),
('name', 'new_name')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.api_mock.load_balancer_set.assert_called_with(
self._lb.id, json={'loadbalancer': {'name': 'new_name'}})

31
requirements.txt

@ -2,4 +2,33 @@
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
pbr!=2.1.0,>=2.0.0 # Apache-2.0
appdirs>=1.3.0 # MIT License
Babel>=2.3.4,!=2.4.0 # BSD
cliff>=2.6.0 # Apache-2.0
cmd2>=0.6.7 # MIT
debtcollector>=1.2.0 # Apache-2.0
funcsigs>=0.4;python_version=='2.7' or python_version=='2.6' # Apache-2.0
iso8601>=0.1.11 # MIT
keystoneauth1>=2.20.0 # Apache-2.0
monotonic>=0.6 # Apache-2.0
netaddr>=0.7.13,!=0.7.16 # BSD
netifaces>=0.10.4 # MIT
python-neutronclient>=6.3.0 # Apache-2.0
python-openstackclient>=3.3.0,!=3.10.0 # Apache-2.0
os-client-config>=1.27.0 # Apache-2.0
osc-lib>=1.5.1 # Apache-2.0
oslo.i18n!=3.15.2,>=2.1.0 # Apache-2.0
oslo.utils>=3.20.0 # Apache-2.0
pbr>=2.0.0,!=2.1.0 # Apache-2.0
positional>=1.1.1 # Apache-2.0
PrettyTable>=0.7.1,<0.8 # BSD
pyparsing>=2.1.0 # MIT
pytz>=2013.6 # MIT
PyYAML>=3.10.0 # MIT
requests>=2.10.0,!=2.12.2,!=2.13.0 # Apache-2.0
requestsexceptions>=1.2.0 # Apache-2.0
simplejson>=2.2.0 # MIT
six>=1.9.0 # MIT
stevedore>=1.20.0 # Apache-2.0
unicodecsv>=0.8.0;python_version<'3.0' # BSD
wrapt>=1.7.0 # BSD License

4
setup.cfg

@ -27,7 +27,11 @@ openstack.cli.extension =
load_balancer = octaviaclient.osc.plugin
openstack.load_balancer.v2 =
loadbalancer_create = octaviaclient.osc.v2.load_balancer:CreateLoadBalancer
loadbalancer_list = octaviaclient.osc.v2.load_balancer:ListLoadBalancer
loadbalancer_show = octaviaclient.osc.v2.load_balancer:ShowLoadBalancer
loadbalancer_delete = octaviaclient.osc.v2.load_balancer:DeleteLoadBalancer
loadbalancer_set = octaviaclient.osc.v2.load_balancer:SetLoadBalancer
[build_sphinx]
source-dir = doc/source

1
test-requirements.txt

@ -7,6 +7,7 @@ requests!=2.12.2,!=2.13.0,>=2.10.0 # Apache-2.0
requests-mock>=1.1 # Apache-2.0
coverage!=4.4,>=4.0 # Apache-2.0
mock>=2.0 # BSD
keystoneauth1>=2.20.0 # Apache-2.0
python-subunit>=0.0.18 # Apache-2.0/BSD
python-openstackclient!=3.10.0,>=3.3.0 # Apache-2.0
sphinx!=1.6.1,>=1.5.1 # BSD

Loading…
Cancel
Save