The change implements LBaaS CLI commands.
Implements: blueprint lbaas-cli New commands: * Vip: lb-vip-create, lb-vip-list, lb-vip-show, lb-vip-update, lb-vip-delete * Pool: lb-pool-create, lb-pool-list, lb-pool-show, lb-pool-update, lb-pool-delete, lb-pool-stats * Member: lb-member-create, lb-member-list, lb-member-show, lb-member-update, lb-member-delete * Health Monitor: lb-healthmonitor-create, lb-healthmonitor-list, lb-healthmonitor-show, lb-healthmonitor-update, lb-healthmonitor-delete, lb-healthmonitor-associate, lb-healthmonitor-disassociate Change-Id: Idaa569024c24955886a836e3dfedd009fed87007
This commit is contained in:
@@ -141,7 +141,10 @@ def parse_args_to_dict(values_specs):
|
||||
current_arg = _options[_item]
|
||||
_item = _temp
|
||||
elif _item.startswith('type='):
|
||||
if current_arg is not None:
|
||||
if current_arg is None:
|
||||
raise exceptions.CommandError(
|
||||
"invalid values_specs %s" % ' '.join(values_specs))
|
||||
if 'type' not in current_arg:
|
||||
_type_str = _item.split('=', 2)[1]
|
||||
current_arg.update({'type': eval(_type_str)})
|
||||
if _type_str == 'bool':
|
||||
@@ -149,9 +152,6 @@ def parse_args_to_dict(values_specs):
|
||||
elif _type_str == 'dict':
|
||||
current_arg.update({'type': utils.str2dict})
|
||||
continue
|
||||
else:
|
||||
raise exceptions.CommandError(
|
||||
"invalid values_specs %s" % ' '.join(values_specs))
|
||||
elif _item == 'list=true':
|
||||
_list_flag = True
|
||||
continue
|
||||
@@ -212,6 +212,12 @@ def _merge_args(qCmd, parsed_args, _extra_values, value_specs):
|
||||
_extra_values.pop(key)
|
||||
|
||||
|
||||
def update_dict(obj, dict, attributes):
|
||||
for attribute in attributes:
|
||||
if hasattr(obj, attribute) and getattr(obj, attribute):
|
||||
dict[attribute] = getattr(obj, attribute)
|
||||
|
||||
|
||||
class QuantumCommand(command.OpenStackCommand):
|
||||
api = 'network'
|
||||
log = logging.getLogger(__name__ + '.QuantumCommand')
|
||||
|
||||
16
quantumclient/quantum/v2_0/lb/__init__.py
Normal file
16
quantumclient/quantum/v2_0/lb/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# Copyright 2013 OpenStack LLC.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
172
quantumclient/quantum/v2_0/lb/healthmonitor.py
Normal file
172
quantumclient/quantum/v2_0/lb/healthmonitor.py
Normal file
@@ -0,0 +1,172 @@
|
||||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# @author: Ilya Shakhat, Mirantis Inc.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import logging
|
||||
|
||||
from quantumclient.quantum import v2_0 as quantumv20
|
||||
|
||||
|
||||
class ListHealthMonitor(quantumv20.ListCommand):
|
||||
"""List healthmonitors that belong to a given tenant."""
|
||||
|
||||
resource = 'health_monitor'
|
||||
log = logging.getLogger(__name__ + '.ListHealthMonitor')
|
||||
list_columns = ['id', 'type', 'admin_state_up', 'status']
|
||||
_formatters = {}
|
||||
|
||||
|
||||
class ShowHealthMonitor(quantumv20.ShowCommand):
|
||||
"""Show information of a given healthmonitor."""
|
||||
|
||||
resource = 'health_monitor'
|
||||
log = logging.getLogger(__name__ + '.ShowHealthMonitor')
|
||||
|
||||
|
||||
class CreateHealthMonitor(quantumv20.CreateCommand):
|
||||
"""Create a healthmonitor"""
|
||||
|
||||
resource = 'health_monitor'
|
||||
log = logging.getLogger(__name__ + '.CreateHealthMonitor')
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--admin-state-down',
|
||||
default=True, action='store_false',
|
||||
help='set admin state up to false')
|
||||
parser.add_argument(
|
||||
'--delay',
|
||||
required=True,
|
||||
help='the minimum time in seconds between regular connections '
|
||||
'of the member.')
|
||||
parser.add_argument(
|
||||
'--expected-codes',
|
||||
help='the list of HTTP status codes expected in '
|
||||
'response from the member to declare it healthy. This '
|
||||
'attribute can contain one value, '
|
||||
'or a list of values separated by comma, '
|
||||
'or a range of values (e.g. "200-299"). If this attribute '
|
||||
'is not specified, it defaults to "200". ')
|
||||
parser.add_argument(
|
||||
'--http-method',
|
||||
help='the HTTP method used for requests by the monitor of type '
|
||||
'HTTP.')
|
||||
parser.add_argument(
|
||||
'--max-retries',
|
||||
required=True,
|
||||
help='number of permissible connection failures before changing '
|
||||
'the member status to INACTIVE.')
|
||||
parser.add_argument(
|
||||
'--timeout',
|
||||
required=True,
|
||||
help='maximum number of seconds for a monitor to wait for a '
|
||||
'connection to be established before it times out. The '
|
||||
'value must be less than the delay value.')
|
||||
parser.add_argument(
|
||||
'--type',
|
||||
required=True,
|
||||
help='one of predefined health monitor types, e.g. RoundRobin')
|
||||
parser.add_argument(
|
||||
'--url-path',
|
||||
help='the HTTP path used in the HTTP request used by the monitor'
|
||||
' to test a member health. This must be a string '
|
||||
'beginning with a / (forward slash)')
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {
|
||||
self.resource: {
|
||||
'admin_state_up': parsed_args.admin_state_down,
|
||||
'delay': parsed_args.delay,
|
||||
'max_retries': parsed_args.max_retries,
|
||||
'timeout': parsed_args.timeout,
|
||||
'type': parsed_args.type,
|
||||
},
|
||||
}
|
||||
quantumv20.update_dict(parsed_args, body[self.resource],
|
||||
['expected_codes', 'http_method', 'url_path',
|
||||
'tenant_id'])
|
||||
return body
|
||||
|
||||
|
||||
class UpdateHealthMonitor(quantumv20.UpdateCommand):
|
||||
"""Update a given healthmonitor."""
|
||||
|
||||
resource = 'health_monitor'
|
||||
log = logging.getLogger(__name__ + '.UpdateHealthMonitor')
|
||||
|
||||
|
||||
class DeleteHealthMonitor(quantumv20.DeleteCommand):
|
||||
"""Delete a given healthmonitor."""
|
||||
|
||||
resource = 'health_monitor'
|
||||
log = logging.getLogger(__name__ + '.DeleteHealthMonitor')
|
||||
|
||||
|
||||
class AssociateHealthMonitor(quantumv20.QuantumCommand):
|
||||
"""Create a mapping between a health monitor and a pool."""
|
||||
|
||||
log = logging.getLogger(__name__ + '.AssociateHealthMonitor')
|
||||
resource = 'health_monitor'
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(AssociateHealthMonitor, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'health_monitor_id',
|
||||
help='Health monitor to associate')
|
||||
parser.add_argument(
|
||||
'pool_id',
|
||||
help='ID of the pool to be associated with the health monitor')
|
||||
return parser
|
||||
|
||||
def run(self, parsed_args):
|
||||
quantum_client = self.get_client()
|
||||
quantum_client.format = parsed_args.request_format
|
||||
body = {'health_monitor': {'id': parsed_args.health_monitor_id}}
|
||||
pool_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
quantum_client, 'pool', parsed_args.pool_id)
|
||||
quantum_client.associate_health_monitor(pool_id, body)
|
||||
print >>self.app.stdout, (_('Associated health monitor '
|
||||
'%s') % parsed_args.health_monitor_id)
|
||||
|
||||
|
||||
class DisassociateHealthMonitor(quantumv20.QuantumCommand):
|
||||
"""Remove a mapping from a health monitor to a pool."""
|
||||
|
||||
log = logging.getLogger(__name__ + '.DisassociateHealthMonitor')
|
||||
resource = 'health_monitor'
|
||||
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DisassociateHealthMonitor, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'health_monitor_id',
|
||||
help='Health monitor to associate')
|
||||
parser.add_argument(
|
||||
'pool_id',
|
||||
help='ID of the pool to be associated with the health monitor')
|
||||
return parser
|
||||
|
||||
def run(self, parsed_args):
|
||||
quantum_client = self.get_client()
|
||||
quantum_client.format = parsed_args.request_format
|
||||
pool_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
quantum_client, 'pool', parsed_args.pool_id)
|
||||
quantum_client.disassociate_health_monitor(pool_id,
|
||||
parsed_args
|
||||
.health_monitor_id)
|
||||
print >>self.app.stdout, (_('Disassociated health monitor '
|
||||
'%s') % parsed_args.health_monitor_id)
|
||||
93
quantumclient/quantum/v2_0/lb/member.py
Normal file
93
quantumclient/quantum/v2_0/lb/member.py
Normal file
@@ -0,0 +1,93 @@
|
||||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# @author: Ilya Shakhat, Mirantis Inc.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import logging
|
||||
|
||||
from quantumclient.quantum import v2_0 as quantumv20
|
||||
|
||||
|
||||
class ListMember(quantumv20.ListCommand):
|
||||
"""List members that belong to a given tenant."""
|
||||
|
||||
resource = 'member'
|
||||
log = logging.getLogger(__name__ + '.ListMember')
|
||||
list_columns = ['id', 'address', 'port', 'admin_state_up', 'status']
|
||||
_formatters = {}
|
||||
|
||||
|
||||
class ShowMember(quantumv20.ShowCommand):
|
||||
"""Show information of a given member."""
|
||||
|
||||
resource = 'member'
|
||||
log = logging.getLogger(__name__ + '.ShowMember')
|
||||
|
||||
|
||||
class CreateMember(quantumv20.CreateCommand):
|
||||
"""Create a member"""
|
||||
|
||||
resource = 'member'
|
||||
log = logging.getLogger(__name__ + '.CreateMember')
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'pool_id', metavar='pool',
|
||||
help='Pool id or name this vip belongs to')
|
||||
parser.add_argument(
|
||||
'--address',
|
||||
required=True,
|
||||
help='IP address of the pool member on the pool network. ')
|
||||
parser.add_argument(
|
||||
'--admin-state-down',
|
||||
default=True, action='store_false',
|
||||
help='set admin state up to false')
|
||||
parser.add_argument(
|
||||
'--port',
|
||||
required=True,
|
||||
help='port on which the pool member listens for requests or '
|
||||
'connections. ')
|
||||
parser.add_argument(
|
||||
'--weight',
|
||||
help='weight of pool member in the pool')
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
_pool_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
self.get_client(), 'pool', parsed_args.pool_id)
|
||||
body = {
|
||||
self.resource: {
|
||||
'pool_id': _pool_id,
|
||||
'admin_state_up': parsed_args.admin_state_down,
|
||||
},
|
||||
}
|
||||
quantumv20.update_dict(parsed_args, body[self.resource],
|
||||
['address', 'port', 'weight', 'tenant_id'])
|
||||
return body
|
||||
|
||||
|
||||
class UpdateMember(quantumv20.UpdateCommand):
|
||||
"""Update a given member."""
|
||||
|
||||
resource = 'member'
|
||||
log = logging.getLogger(__name__ + '.UpdateMember')
|
||||
|
||||
|
||||
class DeleteMember(quantumv20.DeleteCommand):
|
||||
"""Delete a given member."""
|
||||
|
||||
resource = 'member'
|
||||
log = logging.getLogger(__name__ + '.DeleteMember')
|
||||
120
quantumclient/quantum/v2_0/lb/pool.py
Normal file
120
quantumclient/quantum/v2_0/lb/pool.py
Normal file
@@ -0,0 +1,120 @@
|
||||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# @author: Ilya Shakhat, Mirantis Inc.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import logging
|
||||
|
||||
from quantumclient.quantum import v2_0 as quantumv20
|
||||
|
||||
|
||||
class ListPool(quantumv20.ListCommand):
|
||||
"""List pools that belong to a given tenant."""
|
||||
|
||||
resource = 'pool'
|
||||
log = logging.getLogger(__name__ + '.ListPool')
|
||||
list_columns = ['id', 'name', 'lb_method', 'protocol',
|
||||
'admin_state_up', 'status']
|
||||
_formatters = {}
|
||||
|
||||
|
||||
class ShowPool(quantumv20.ShowCommand):
|
||||
"""Show information of a given pool."""
|
||||
|
||||
resource = 'pool'
|
||||
log = logging.getLogger(__name__ + '.ShowPool')
|
||||
|
||||
|
||||
class CreatePool(quantumv20.CreateCommand):
|
||||
"""Create a pool"""
|
||||
|
||||
resource = 'pool'
|
||||
log = logging.getLogger(__name__ + '.CreatePool')
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--admin-state-down',
|
||||
default=True, action='store_false',
|
||||
help='set admin state up to false')
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help='description of the pool')
|
||||
parser.add_argument(
|
||||
'--lb-method',
|
||||
required=True,
|
||||
help='the algorithm used to distribute load between the members '
|
||||
'of the pool')
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
required=True,
|
||||
help='the name of the pool')
|
||||
parser.add_argument(
|
||||
'--protocol',
|
||||
required=True,
|
||||
help='protocol for balancing')
|
||||
parser.add_argument(
|
||||
'--subnet-id',
|
||||
required=True,
|
||||
help='the subnet on which the members of the pool will be located')
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
body = {
|
||||
self.resource: {
|
||||
'admin_state_up': parsed_args.admin_state_down,
|
||||
},
|
||||
}
|
||||
quantumv20.update_dict(parsed_args, body[self.resource],
|
||||
['description', 'lb_method', 'name',
|
||||
'subnet_id', 'protocol', 'tenant_id'])
|
||||
return body
|
||||
|
||||
|
||||
class UpdatePool(quantumv20.UpdateCommand):
|
||||
"""Update a given pool."""
|
||||
|
||||
resource = 'pool'
|
||||
log = logging.getLogger(__name__ + '.UpdatePool')
|
||||
|
||||
|
||||
class DeletePool(quantumv20.DeleteCommand):
|
||||
"""Delete a given pool."""
|
||||
|
||||
resource = 'pool'
|
||||
log = logging.getLogger(__name__ + '.DeletePool')
|
||||
|
||||
|
||||
class RetrievePoolStats(quantumv20.ShowCommand):
|
||||
"""Retrieve stats for a given pool."""
|
||||
|
||||
resource = 'pool'
|
||||
log = logging.getLogger(__name__ + '.RetrievePoolStats')
|
||||
|
||||
def get_data(self, parsed_args):
|
||||
self.log.debug('run(%s)' % parsed_args)
|
||||
quantum_client = self.get_client()
|
||||
quantum_client.format = parsed_args.request_format
|
||||
params = {}
|
||||
if parsed_args.fields:
|
||||
params = {'fields': parsed_args.fields}
|
||||
|
||||
data = quantum_client.retrieve_pool_stats(parsed_args.id, **params)
|
||||
self.format_output_data(data)
|
||||
stats = data['stats']
|
||||
if 'stats' in data:
|
||||
return zip(*sorted(stats.iteritems()))
|
||||
else:
|
||||
return None
|
||||
111
quantumclient/quantum/v2_0/lb/vip.py
Normal file
111
quantumclient/quantum/v2_0/lb/vip.py
Normal file
@@ -0,0 +1,111 @@
|
||||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# @author: Ilya Shakhat, Mirantis Inc.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import logging
|
||||
|
||||
from quantumclient.quantum import v2_0 as quantumv20
|
||||
|
||||
|
||||
class ListVip(quantumv20.ListCommand):
|
||||
"""List vips that belong to a given tenant."""
|
||||
|
||||
resource = 'vip'
|
||||
log = logging.getLogger(__name__ + '.ListVip')
|
||||
list_columns = ['id', 'name', 'algorithm', 'protocol',
|
||||
'admin_state_up', 'status']
|
||||
_formatters = {}
|
||||
|
||||
|
||||
class ShowVip(quantumv20.ShowCommand):
|
||||
"""Show information of a given vip."""
|
||||
|
||||
resource = 'vip'
|
||||
log = logging.getLogger(__name__ + '.ShowVip')
|
||||
|
||||
|
||||
class CreateVip(quantumv20.CreateCommand):
|
||||
"""Create a vip"""
|
||||
|
||||
resource = 'vip'
|
||||
log = logging.getLogger(__name__ + '.CreateVip')
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'pool_id', metavar='pool',
|
||||
help='Pool id or name this vip belongs to')
|
||||
parser.add_argument(
|
||||
'--address',
|
||||
help='IP address of the vip')
|
||||
parser.add_argument(
|
||||
'--admin-state-down',
|
||||
default=True, action='store_false',
|
||||
help='set admin state up to false')
|
||||
parser.add_argument(
|
||||
'--connection-limit',
|
||||
help='the maximum number of connections per second allowed for '
|
||||
'the vip')
|
||||
parser.add_argument(
|
||||
'--description',
|
||||
help='description of the vip')
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
required=True,
|
||||
help='name of the vip')
|
||||
parser.add_argument(
|
||||
'--port',
|
||||
required=True,
|
||||
help='TCP port on which to listen for client traffic that is '
|
||||
'associated with the vip address')
|
||||
parser.add_argument(
|
||||
'--protocol',
|
||||
required=True,
|
||||
help='protocol for balancing')
|
||||
parser.add_argument(
|
||||
'--subnet-id',
|
||||
required=True,
|
||||
help='the subnet on which to allocate the vip address')
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
_pool_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
self.get_client(), 'pool', parsed_args.pool_id)
|
||||
body = {
|
||||
self.resource: {
|
||||
'pool_id': _pool_id,
|
||||
'admin_state_up': parsed_args.admin_state_down,
|
||||
},
|
||||
}
|
||||
quantumv20.update_dict(parsed_args, body[self.resource],
|
||||
['address', 'connection_limit', 'description',
|
||||
'name', 'port', 'protocol', 'subnet_id',
|
||||
'tenant_id'])
|
||||
return body
|
||||
|
||||
|
||||
class UpdateVip(quantumv20.UpdateCommand):
|
||||
"""Update a given vip."""
|
||||
|
||||
resource = 'vip'
|
||||
log = logging.getLogger(__name__ + '.UpdateVip')
|
||||
|
||||
|
||||
class DeleteVip(quantumv20.DeleteCommand):
|
||||
"""Delete a given vip."""
|
||||
|
||||
resource = 'vip'
|
||||
log = logging.getLogger(__name__ + '.DeleteVip')
|
||||
@@ -145,6 +145,53 @@ COMMAND_V2 = {
|
||||
'quantumclient.quantum.v2_0.securitygroup.CreateSecurityGroupRule'),
|
||||
'security-group-rule-delete': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.securitygroup.DeleteSecurityGroupRule'),
|
||||
'lb-vip-list': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.vip.ListVip'),
|
||||
'lb-vip-show': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.vip.ShowVip'),
|
||||
'lb-vip-create': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.vip.CreateVip'),
|
||||
'lb-vip-update': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.vip.UpdateVip'),
|
||||
'lb-vip-delete': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.vip.DeleteVip'),
|
||||
'lb-pool-list': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.pool.ListPool'),
|
||||
'lb-pool-show': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.pool.ShowPool'),
|
||||
'lb-pool-create': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.pool.CreatePool'),
|
||||
'lb-pool-update': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.pool.UpdatePool'),
|
||||
'lb-pool-delete': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.pool.DeletePool'),
|
||||
'lb-pool-stats': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.pool.RetrievePoolStats'),
|
||||
'lb-member-list': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.member.ListMember'),
|
||||
'lb-member-show': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.member.ShowMember'),
|
||||
'lb-member-create': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.member.CreateMember'),
|
||||
'lb-member-update': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.member.UpdateMember'),
|
||||
'lb-member-delete': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.member.DeleteMember'),
|
||||
'lb-healthmonitor-list': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.healthmonitor.ListHealthMonitor'),
|
||||
'lb-healthmonitor-show': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.healthmonitor.ShowHealthMonitor'),
|
||||
'lb-healthmonitor-create': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.healthmonitor.CreateHealthMonitor'),
|
||||
'lb-healthmonitor-update': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.healthmonitor.UpdateHealthMonitor'),
|
||||
'lb-healthmonitor-delete': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.healthmonitor.DeleteHealthMonitor'),
|
||||
'lb-healthmonitor-associate': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.healthmonitor.AssociateHealthMonitor'),
|
||||
'lb-healthmonitor-disassociate': utils.import_class(
|
||||
'quantumclient.quantum.v2_0.lb.healthmonitor'
|
||||
'.DisassociateHealthMonitor'),
|
||||
}
|
||||
|
||||
COMMANDS = {'2.0': COMMAND_V2}
|
||||
|
||||
16
quantumclient/tests/unit/lb/__init__.py
Normal file
16
quantumclient/tests/unit/lb/__init__.py
Normal file
@@ -0,0 +1,16 @@
|
||||
# Copyright 2013 OpenStack LLC.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
189
quantumclient/tests/unit/lb/test_cli20_healthmonitor.py
Normal file
189
quantumclient/tests/unit/lb/test_cli20_healthmonitor.py
Normal file
@@ -0,0 +1,189 @@
|
||||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# @author: Ilya Shakhat, Mirantis Inc.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import sys
|
||||
|
||||
from mox import ContainsKeyValue
|
||||
|
||||
from quantumclient.quantum.v2_0.lb import healthmonitor
|
||||
from quantumclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbHealthmonitor(test_cli20.CLITestV20Base):
|
||||
def test_create_healthmonitor_with_all_params(self):
|
||||
"""lb-healthmonitor-create with mandatory params only"""
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
delay = '60'
|
||||
max_retries = '2'
|
||||
timeout = '10'
|
||||
type = 'tcp'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--admin-state-down',
|
||||
'--delay', delay,
|
||||
'--max-retries', max_retries,
|
||||
'--timeout', timeout,
|
||||
'--type', type,
|
||||
'--tenant-id', tenant_id]
|
||||
position_names = ['admin_state_up', 'delay', 'max_retries', 'timeout',
|
||||
'type', 'tenant_id']
|
||||
position_values = [True, delay, max_retries, timeout, type,
|
||||
tenant_id]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_healthmonitor_with_all_params(self):
|
||||
"""lb-healthmonitor-create with all params set"""
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.CreateHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
admin_state_up = False
|
||||
delay = '60'
|
||||
expected_codes = '200-202,204'
|
||||
http_method = 'HEAD'
|
||||
max_retries = '2'
|
||||
timeout = '10'
|
||||
type = 'tcp'
|
||||
tenant_id = 'my-tenant'
|
||||
url_path = '/health'
|
||||
my_id = 'my-id'
|
||||
args = ['--admin-state-down',
|
||||
'--delay', delay,
|
||||
'--expected-codes', expected_codes,
|
||||
'--http-method', http_method,
|
||||
'--max-retries', max_retries,
|
||||
'--timeout', timeout,
|
||||
'--type', type,
|
||||
'--tenant-id', tenant_id,
|
||||
'--url-path', url_path]
|
||||
position_names = ['admin_state_up', 'delay',
|
||||
'expected_codes', 'http_method',
|
||||
'max_retries', 'timeout',
|
||||
'type', 'tenant_id', 'url_path']
|
||||
position_values = [admin_state_up, delay,
|
||||
expected_codes, http_method,
|
||||
max_retries, timeout,
|
||||
type, tenant_id, url_path]
|
||||
self._test_create_resource(resource, cmd, '', my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_list_healthmonitors(self):
|
||||
"""lb-healthmonitor-list"""
|
||||
resources = "health_monitors"
|
||||
cmd = healthmonitor.ListHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_show_healthmonitor_id(self):
|
||||
"""lb-healthmonitor-show test_id"""
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.ShowHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_healthmonitor_id_name(self):
|
||||
"""lb-healthmonitor-show"""
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.ShowHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_health_monitor(self):
|
||||
"""lb-healthmonitor-update myid --name myname --tags a b."""
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.UpdateHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--timeout', '5'],
|
||||
{'timeout': '5', })
|
||||
|
||||
def test_delete_healthmonitor(self):
|
||||
"""lb-healthmonitor-delete my-id"""
|
||||
resource = 'health_monitor'
|
||||
cmd = healthmonitor.DeleteHealthMonitor(test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
def test_associate_healthmonitor(self):
|
||||
cmd = healthmonitor.AssociateHealthMonitor(
|
||||
test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
resource = 'health_monitor'
|
||||
health_monitor_id = 'hm-id'
|
||||
pool_id = 'p_id'
|
||||
args = [health_monitor_id, pool_id]
|
||||
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
|
||||
body = {resource: {'id': health_monitor_id}}
|
||||
result = {resource: {'id': health_monitor_id}, }
|
||||
result_str = self.client.serialize(result)
|
||||
|
||||
path = getattr(self.client,
|
||||
"associate_pool_health_monitors_path") % pool_id
|
||||
return_tup = (test_cli20.MyResp(200), result_str)
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path), 'POST',
|
||||
body=test_cli20.MyComparator(body, self.client),
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn(return_tup)
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser('test_' + resource)
|
||||
parsed_args = cmd_parser.parse_args(args)
|
||||
cmd.run(parsed_args)
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
|
||||
def test_disassociate_healthmonitor(self):
|
||||
cmd = healthmonitor.DisassociateHealthMonitor(
|
||||
test_cli20.MyApp(sys.stdout),
|
||||
None)
|
||||
resource = 'health_monitor'
|
||||
health_monitor_id = 'hm-id'
|
||||
pool_id = 'p_id'
|
||||
args = [health_monitor_id, pool_id]
|
||||
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
|
||||
path = getattr(self.client,
|
||||
"disassociate_pool_health_monitors_path") % \
|
||||
{'pool': pool_id, 'health_monitor': health_monitor_id}
|
||||
return_tup = (test_cli20.MyResp(204), None)
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path), 'DELETE',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn(return_tup)
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser('test_' + resource)
|
||||
parsed_args = cmd_parser.parse_args(args)
|
||||
cmd.run(parsed_args)
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
104
quantumclient/tests/unit/lb/test_cli20_member.py
Normal file
104
quantumclient/tests/unit/lb/test_cli20_member.py
Normal file
@@ -0,0 +1,104 @@
|
||||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# @author: Ilya Shakhat, Mirantis Inc.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import sys
|
||||
|
||||
from quantumclient.quantum.v2_0.lb import member
|
||||
from quantumclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbMember(test_cli20.CLITestV20Base):
|
||||
def test_create_member(self):
|
||||
"""lb-member-create with mandatory params only"""
|
||||
resource = 'member'
|
||||
cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None)
|
||||
address = '10.0.0.1'
|
||||
port = '8080'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
pool_id = 'pool-id'
|
||||
args = ['--address', address, '--port', port,
|
||||
'--tenant-id', tenant_id, pool_id]
|
||||
position_names = ['address', 'port', 'tenant_id', 'pool_id',
|
||||
'admin_state_up']
|
||||
position_values = [address, port, tenant_id, pool_id,
|
||||
True]
|
||||
self._test_create_resource(resource, cmd, None, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=None)
|
||||
|
||||
def test_create_member_all_params(self):
|
||||
"""lb-member-create with all available params"""
|
||||
resource = 'member'
|
||||
cmd = member.CreateMember(test_cli20.MyApp(sys.stdout), None)
|
||||
address = '10.0.0.1'
|
||||
admin_state_up = False
|
||||
port = '8080'
|
||||
weight = '1'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
pool_id = 'pool-id'
|
||||
args = ['--address', address, '--admin-state-down',
|
||||
'--port', port, '--weight', weight,
|
||||
'--tenant-id', tenant_id, pool_id]
|
||||
position_names = ['address', 'admin_state_up', 'port', 'weight',
|
||||
'tenant_id', 'pool_id']
|
||||
position_values = [address, admin_state_up, port, weight,
|
||||
tenant_id, pool_id]
|
||||
self._test_create_resource(resource, cmd, None, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=None)
|
||||
|
||||
def test_list_members(self):
|
||||
"""lb-member-list"""
|
||||
resources = "members"
|
||||
cmd = member.ListMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_show_member_id(self):
|
||||
"""lb-member-show test_id"""
|
||||
resource = 'member'
|
||||
cmd = member.ShowMember(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_member_id_name(self):
|
||||
"""lb-member-show"""
|
||||
resource = 'member'
|
||||
cmd = member.ShowMember(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_member(self):
|
||||
"""lb-member-update myid --name myname --tags a b."""
|
||||
resource = 'member'
|
||||
cmd = member.UpdateMember(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'myname',
|
||||
'--tags', 'a', 'b'],
|
||||
{'name': 'myname', 'tags': ['a', 'b'], })
|
||||
|
||||
def test_delete_member(self):
|
||||
"""lb-member-delete my-id"""
|
||||
resource = 'member'
|
||||
cmd = member.DeleteMember(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
145
quantumclient/tests/unit/lb/test_cli20_pool.py
Normal file
145
quantumclient/tests/unit/lb/test_cli20_pool.py
Normal file
@@ -0,0 +1,145 @@
|
||||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# @author: Ilya Shakhat, Mirantis Inc.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import sys
|
||||
|
||||
from mox import ContainsKeyValue
|
||||
|
||||
from quantumclient.quantum.v2_0.lb import pool
|
||||
from quantumclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbPool(test_cli20.CLITestV20Base):
|
||||
|
||||
def test_create_pool_with_mandatory_params(self):
|
||||
"""lb-pool-create with mandatory params only"""
|
||||
resource = 'pool'
|
||||
cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'my-name'
|
||||
lb_method = 'round-robin'
|
||||
protocol = 'http'
|
||||
subnet_id = 'subnet-id'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--lb-method', lb_method,
|
||||
'--name', name,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id]
|
||||
position_names = ['admin_state_up', 'lb_method', 'name',
|
||||
'protocol', 'subnet_id', 'tenant_id']
|
||||
position_values = [True, lb_method, name,
|
||||
protocol, subnet_id, tenant_id]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_pool_with_all_params(self):
|
||||
"""lb-pool-create with all params set"""
|
||||
resource = 'pool'
|
||||
cmd = pool.CreatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
name = 'my-name'
|
||||
description = 'my-desc'
|
||||
lb_method = 'round-robin'
|
||||
protocol = 'http'
|
||||
subnet_id = 'subnet-id'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--admin-state-down',
|
||||
'--description', description,
|
||||
'--lb-method', lb_method,
|
||||
'--name', name,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id]
|
||||
position_names = ['admin_state_up', 'description', 'lb_method', 'name',
|
||||
'protocol', 'subnet_id', 'tenant_id']
|
||||
position_values = [False, description, lb_method, name,
|
||||
protocol, subnet_id, tenant_id]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_list_pools(self):
|
||||
"""lb-pool-list"""
|
||||
resources = "pools"
|
||||
cmd = pool.ListPool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_show_pool_id(self):
|
||||
"""lb-pool-show test_id"""
|
||||
resource = 'pool'
|
||||
cmd = pool.ShowPool(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_pool_id_name(self):
|
||||
"""lb-pool-show"""
|
||||
resource = 'pool'
|
||||
cmd = pool.ShowPool(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_pool(self):
|
||||
"""lb-pool-update myid --name newname --tags a b."""
|
||||
resource = 'pool'
|
||||
cmd = pool.UpdatePool(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'newname'],
|
||||
{'name': 'newname', })
|
||||
|
||||
def test_delete_pool(self):
|
||||
"""lb-pool-delete my-id"""
|
||||
resource = 'pool'
|
||||
cmd = pool.DeletePool(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
def test_retrieve_pool_stats(self):
|
||||
"""lb-pool-stats test_id"""
|
||||
resource = 'pool'
|
||||
cmd = pool.RetrievePoolStats(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = self.test_id
|
||||
fields = ['bytes_in', 'bytes_out']
|
||||
args = ['--fields', 'bytes_in', '--fields', 'bytes_out', my_id]
|
||||
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
query = "&".join(["fields=%s" % field for field in fields])
|
||||
expected_res = {'stats': {'bytes_in': '1234', 'bytes_out': '4321'}}
|
||||
resstr = self.client.serialize(expected_res)
|
||||
path = getattr(self.client, "pool_path_stats")
|
||||
return_tup = (test_cli20.MyResp(200), resstr)
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path % my_id, query), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn(return_tup)
|
||||
self.mox.ReplayAll()
|
||||
|
||||
cmd_parser = cmd.get_parser("test_" + resource)
|
||||
parsed_args = cmd_parser.parse_args(args)
|
||||
cmd.run(parsed_args)
|
||||
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertTrue('bytes_in' in _str)
|
||||
self.assertTrue('bytes_out' in _str)
|
||||
185
quantumclient/tests/unit/lb/test_cli20_vip.py
Normal file
185
quantumclient/tests/unit/lb/test_cli20_vip.py
Normal file
@@ -0,0 +1,185 @@
|
||||
# Copyright 2013 Mirantis Inc.
|
||||
# All Rights Reserved
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
# @author: Ilya Shakhat, Mirantis Inc.
|
||||
#
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import sys
|
||||
|
||||
from quantumclient.quantum.v2_0.lb import vip
|
||||
from quantumclient.tests.unit import test_cli20
|
||||
|
||||
|
||||
class CLITestV20LbVip(test_cli20.CLITestV20Base):
|
||||
def test_create_vip_with_mandatory_params(self):
|
||||
"""lb-vip-create with all mandatory params"""
|
||||
resource = 'vip'
|
||||
cmd = vip.CreateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
pool_id = 'my-pool-id'
|
||||
name = 'my-name'
|
||||
subnet_id = 'subnet-id'
|
||||
port = '1000'
|
||||
protocol = 'tcp'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--name', name,
|
||||
'--port', port,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id,
|
||||
pool_id]
|
||||
position_names = ['pool_id', 'name', 'port', 'protocol',
|
||||
'subnet_id', 'tenant_id']
|
||||
position_values = [pool_id, name, port, protocol,
|
||||
subnet_id, tenant_id]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=True)
|
||||
|
||||
def test_create_vip_with_all_params(self):
|
||||
"""lb-vip-create with all params"""
|
||||
resource = 'vip'
|
||||
cmd = vip.CreateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
pool_id = 'my-pool-id'
|
||||
name = 'my-name'
|
||||
description = 'my-desc'
|
||||
address = '10.0.0.2'
|
||||
admin_state = False
|
||||
connection_limit = '1000'
|
||||
subnet_id = 'subnet-id'
|
||||
port = '80'
|
||||
protocol = 'tcp'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--name', name,
|
||||
'--description', description,
|
||||
'--address', address,
|
||||
'--admin-state-down',
|
||||
'--connection-limit', connection_limit,
|
||||
'--port', port,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id,
|
||||
pool_id]
|
||||
position_names = ['pool_id', 'name', 'description', 'address',
|
||||
'admin_state_up', 'connection_limit', 'port',
|
||||
'protocol', 'subnet_id',
|
||||
'tenant_id']
|
||||
position_values = [pool_id, name, description, address,
|
||||
admin_state, connection_limit, port,
|
||||
protocol, subnet_id,
|
||||
tenant_id]
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_vip_with_session_persistence_params(self):
|
||||
"""lb-vip-create with mandatory and session-persistence params"""
|
||||
resource = 'vip'
|
||||
cmd = vip.CreateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
pool_id = 'my-pool-id'
|
||||
name = 'my-name'
|
||||
subnet_id = 'subnet-id'
|
||||
port = '1000'
|
||||
protocol = 'tcp'
|
||||
tenant_id = 'my-tenant'
|
||||
my_id = 'my-id'
|
||||
args = ['--name', name,
|
||||
'--port', port,
|
||||
'--protocol', protocol,
|
||||
'--subnet-id', subnet_id,
|
||||
'--tenant-id', tenant_id,
|
||||
pool_id,
|
||||
'--session-persistence', 'type=dict',
|
||||
'type=cookie,cookie_name=pie',
|
||||
'--optional-param', 'any']
|
||||
position_names = ['pool_id', 'name', 'port', 'protocol',
|
||||
'subnet_id', 'tenant_id', 'optional_param']
|
||||
position_values = [pool_id, name, port, protocol,
|
||||
subnet_id, tenant_id, 'any']
|
||||
extra_body = {
|
||||
'session_persistence': {
|
||||
'type': 'cookie',
|
||||
'cookie_name': 'pie',
|
||||
},
|
||||
}
|
||||
self._test_create_resource(resource, cmd, name, my_id, args,
|
||||
position_names, position_values,
|
||||
admin_state_up=True, extra_body=extra_body)
|
||||
|
||||
def test_list_vips(self):
|
||||
"""lb-vip-list"""
|
||||
resources = "vips"
|
||||
cmd = vip.ListVip(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd, True)
|
||||
|
||||
def test_show_vip_id(self):
|
||||
"""lb-vip-show test_id"""
|
||||
resource = 'vip'
|
||||
cmd = vip.ShowVip(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||
|
||||
def test_show_vip_id_name(self):
|
||||
"""lb-vip-show"""
|
||||
resource = 'vip'
|
||||
cmd = vip.ShowVip(test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_update_vip(self):
|
||||
"""lb-vip-update myid --name myname --tags a b."""
|
||||
resource = 'vip'
|
||||
cmd = vip.UpdateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
['myid', '--name', 'myname',
|
||||
'--tags', 'a', 'b'],
|
||||
{'name': 'myname', 'tags': ['a', 'b'], })
|
||||
|
||||
def test_update_vip_with_session_persistence(self):
|
||||
resource = 'vip'
|
||||
cmd = vip.UpdateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
body = {
|
||||
'session_persistence': {
|
||||
'type': 'source',
|
||||
},
|
||||
}
|
||||
args = ['myid', '--session-persistence', 'type=dict',
|
||||
'type=source']
|
||||
self._test_update_resource(resource, cmd, 'myid', args, body)
|
||||
|
||||
def test_update_vip_with_session_persistence_and_name(self):
|
||||
resource = 'vip'
|
||||
cmd = vip.UpdateVip(test_cli20.MyApp(sys.stdout), None)
|
||||
body = {
|
||||
'name': 'newname',
|
||||
'session_persistence': {
|
||||
'type': 'cookie',
|
||||
'cookie_name': 'pie',
|
||||
},
|
||||
}
|
||||
args = ['myid', '--name', 'newname',
|
||||
'--session-persistence', 'type=dict',
|
||||
'type=cookie,cookie_name=pie']
|
||||
self._test_update_resource(resource, cmd, 'myid', args, body)
|
||||
|
||||
def test_delete_vip(self):
|
||||
"""lb-vip-delete my-id"""
|
||||
resource = 'vip'
|
||||
cmd = vip.DeleteVip(test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
@@ -53,6 +53,16 @@ class CLITestArgs(testtools.TestCase):
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
quantumV20.parse_args_to_dict, _specs)
|
||||
|
||||
def test_badarg_duplicate(self):
|
||||
_specs = ['--tag=t', '--arg1', 'value1', '--arg1', 'value1']
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
quantumV20.parse_args_to_dict, _specs)
|
||||
|
||||
def test_badarg_early_type_specification(self):
|
||||
_specs = ['type=dict', 'key=value']
|
||||
self.assertRaises(exceptions.CommandError,
|
||||
quantumV20.parse_args_to_dict, _specs)
|
||||
|
||||
def test_arg(self):
|
||||
_specs = ['--tag=t', '--arg1', 'value1']
|
||||
self.assertEqual('value1',
|
||||
@@ -64,6 +74,12 @@ class CLITestArgs(testtools.TestCase):
|
||||
self.assertEqual('value1', arg1['key1'])
|
||||
self.assertEqual('value2', arg1['key2'])
|
||||
|
||||
def test_dict_arg_with_attribute_named_type(self):
|
||||
_specs = ['--tag=t', '--arg1', 'type=dict', 'type=value1,key2=value2']
|
||||
arg1 = quantumV20.parse_args_to_dict(_specs)['arg1']
|
||||
self.assertEqual('value1', arg1['type'])
|
||||
self.assertEqual('value2', arg1['key2'])
|
||||
|
||||
def test_list_of_dict_arg(self):
|
||||
_specs = ['--tag=t', '--arg1', 'type=dict',
|
||||
'list=true', 'key1=value1,key2=value2']
|
||||
|
||||
@@ -135,7 +135,8 @@ class CLITestV20Base(testtools.TestCase):
|
||||
def _test_create_resource(self, resource, cmd,
|
||||
name, myid, args,
|
||||
position_names, position_values, tenant_id=None,
|
||||
tags=None, admin_state_up=True, shared=False):
|
||||
tags=None, admin_state_up=True, shared=False,
|
||||
extra_body=None):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
@@ -151,6 +152,8 @@ class CLITestV20Base(testtools.TestCase):
|
||||
body[resource].update({'tags': tags})
|
||||
if shared:
|
||||
body[resource].update({'shared': shared})
|
||||
if extra_body:
|
||||
body[resource].update(extra_body)
|
||||
|
||||
for i in xrange(len(position_names)):
|
||||
body[resource].update({position_names[i]: position_values[i]})
|
||||
|
||||
@@ -168,6 +168,18 @@ class Client(object):
|
||||
security_group_path = "/security-groups/%s"
|
||||
security_group_rules_path = "/security-group-rules"
|
||||
security_group_rule_path = "/security-group-rules/%s"
|
||||
vips_path = "/lb/vips"
|
||||
vip_path = "/lb/vips/%s"
|
||||
pools_path = "/lb/pools"
|
||||
pool_path = "/lb/pools/%s"
|
||||
pool_path_stats = "/lb/pools/%s/stats"
|
||||
members_path = "/lb/members"
|
||||
member_path = "/lb/members/%s"
|
||||
health_monitors_path = "/lb/health_monitors"
|
||||
health_monitor_path = "/lb/health_monitors/%s"
|
||||
associate_pool_health_monitors_path = "/lb/pools/%s/health_monitors"
|
||||
disassociate_pool_health_monitors_path = (
|
||||
"/lb/pools/%(pool)s/health_monitors/%(health_monitor)s")
|
||||
|
||||
@APIParamsCall
|
||||
def get_quotas_tenant(self, **_params):
|
||||
@@ -475,6 +487,175 @@ class Client(object):
|
||||
return self.get(self.security_group_rule_path % (security_group_rule),
|
||||
params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def list_vips(self, **_params):
|
||||
"""
|
||||
Fetches a list of all load balancer vips for a tenant
|
||||
"""
|
||||
# Pass filters in "params" argument to do_request
|
||||
return self.get(self.vips_path, params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def show_vip(self, vip, **_params):
|
||||
"""
|
||||
Fetches information of a certain load balancer vip
|
||||
"""
|
||||
return self.get(self.vip_path % (vip), params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def create_vip(self, body=None):
|
||||
"""
|
||||
Creates a new load balancer vip
|
||||
"""
|
||||
return self.post(self.vips_path, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def update_vip(self, vip, body=None):
|
||||
"""
|
||||
Updates a load balancer vip
|
||||
"""
|
||||
return self.put(self.vip_path % (vip), body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_vip(self, vip):
|
||||
"""
|
||||
Deletes the specified load balancer vip
|
||||
"""
|
||||
return self.delete(self.vip_path % (vip))
|
||||
|
||||
@APIParamsCall
|
||||
def list_pools(self, **_params):
|
||||
"""
|
||||
Fetches a list of all load balancer pools for a tenant
|
||||
"""
|
||||
# Pass filters in "params" argument to do_request
|
||||
return self.get(self.pools_path, params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def show_pool(self, pool, **_params):
|
||||
"""
|
||||
Fetches information of a certain load balancer pool
|
||||
"""
|
||||
return self.get(self.pool_path % (pool), params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def create_pool(self, body=None):
|
||||
"""
|
||||
Creates a new load balancer pool
|
||||
"""
|
||||
return self.post(self.pools_path, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def update_pool(self, pool, body=None):
|
||||
"""
|
||||
Updates a load balancer pool
|
||||
"""
|
||||
return self.put(self.pool_path % (pool), body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_pool(self, pool):
|
||||
"""
|
||||
Deletes the specified load balancer pool
|
||||
"""
|
||||
return self.delete(self.pool_path % (pool))
|
||||
|
||||
@APIParamsCall
|
||||
def retrieve_pool_stats(self, pool, **_params):
|
||||
"""
|
||||
Retrieves stats for a certain load balancer pool
|
||||
"""
|
||||
return self.get(self.pool_path_stats % (pool), params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def list_members(self, **_params):
|
||||
"""
|
||||
Fetches a list of all load balancer members for a tenant
|
||||
"""
|
||||
# Pass filters in "params" argument to do_request
|
||||
return self.get(self.members_path, params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def show_member(self, member, **_params):
|
||||
"""
|
||||
Fetches information of a certain load balancer member
|
||||
"""
|
||||
return self.get(self.member_path % (member), params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def create_member(self, body=None):
|
||||
"""
|
||||
Creates a new load balancer member
|
||||
"""
|
||||
return self.post(self.members_path, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def update_member(self, member, body=None):
|
||||
"""
|
||||
Updates a load balancer member
|
||||
"""
|
||||
return self.put(self.member_path % (member), body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_member(self, member):
|
||||
"""
|
||||
Deletes the specified load balancer member
|
||||
"""
|
||||
return self.delete(self.member_path % (member))
|
||||
|
||||
@APIParamsCall
|
||||
def list_health_monitors(self, **_params):
|
||||
"""
|
||||
Fetches a list of all load balancer health monitors for a tenant
|
||||
"""
|
||||
# Pass filters in "params" argument to do_request
|
||||
return self.get(self.health_monitors_path, params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def show_health_monitor(self, health_monitor, **_params):
|
||||
"""
|
||||
Fetches information of a certain load balancer health monitor
|
||||
"""
|
||||
return self.get(self.health_monitor_path % (health_monitor),
|
||||
params=_params)
|
||||
|
||||
@APIParamsCall
|
||||
def create_health_monitor(self, body=None):
|
||||
"""
|
||||
Creates a new load balancer health monitor
|
||||
"""
|
||||
return self.post(self.health_monitors_path, body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def update_health_monitor(self, health_monitor, body=None):
|
||||
"""
|
||||
Updates a load balancer health monitor
|
||||
"""
|
||||
return self.put(self.health_monitor_path % (health_monitor), body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def delete_health_monitor(self, health_monitor):
|
||||
"""
|
||||
Deletes the specified load balancer health monitor
|
||||
"""
|
||||
return self.delete(self.health_monitor_path % (health_monitor))
|
||||
|
||||
@APIParamsCall
|
||||
def associate_health_monitor(self, pool, body):
|
||||
"""
|
||||
Associate specified load balancer health monitor and pool
|
||||
"""
|
||||
return self.post(self.associate_pool_health_monitors_path % (pool),
|
||||
body=body)
|
||||
|
||||
@APIParamsCall
|
||||
def disassociate_health_monitor(self, pool, health_monitor):
|
||||
"""
|
||||
Disassociate specified load balancer health monitor and pool
|
||||
"""
|
||||
path = (self.disassociate_pool_health_monitors_path %
|
||||
{'pool': pool, 'health_monitor': health_monitor})
|
||||
return self.delete(path)
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
""" Initialize a new client for the Quantum v2.0 API. """
|
||||
super(Client, self).__init__()
|
||||
|
||||
Reference in New Issue
Block a user