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
This commit is contained in:
parent
39b500ef61
commit
1940793da1
|
@ -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.
|
||||
|
|
|
|
@ -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.
|
||||
|
|
|
@ -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}'
|
|
@ -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
|
||||
|
|
|
@ -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')
|
|
@ -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',)
|
||||
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)
|
||||
|
||||
data = self.app.client_manager.load_balancer.load_balancer_list()
|
||||
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)
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
'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'}})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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…
Reference in New Issue