Add name or id to quantum cli commands.
Bug #1030180 We first lookup the resource id via id if it looks like an id. If we cannot find it via id, we will look it up via name. All of the update/show/delete support reference resource via name or id. To create port/subnet, we can refercen network via network's name. Also in port creation, we support reference subnet in fixed_ip via its name. quantum_test.sh is added to test the command lines after running 'python setup.py install' Change-Id: I54b6912e2c4044ba70aaf604cd79520022de262f
This commit is contained in:
59
quantum_test.sh
Executable file
59
quantum_test.sh
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
set -x
|
||||
function die() {
|
||||
local exitcode=$?
|
||||
set +o xtrace
|
||||
echo $@
|
||||
exit $exitcode
|
||||
}
|
||||
|
||||
|
||||
# test the CRUD of network
|
||||
network=mynet1
|
||||
quantum net-create $network || die "fail to create network $network"
|
||||
temp=`quantum net-list -- --name $network --fields id | wc -l`
|
||||
echo $temp
|
||||
if [ $temp -ne 5 ]; then
|
||||
die "networks with name $network is not unique or found"
|
||||
fi
|
||||
network_id=`quantum net-list -- --name $network --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of network with name $network is $network_id"
|
||||
|
||||
quantum net-show $network || die "fail to show network $network"
|
||||
quantum net-show $network_id || die "fail to show network $network_id"
|
||||
|
||||
quantum net-update $network --admin_state_up False || die "fail to update network $network"
|
||||
quantum net-update $network_id --admin_state_up True || die "fail to update network $network_id"
|
||||
|
||||
# test the CRUD of subnet
|
||||
subnet=mysubnet1
|
||||
cidr=10.0.1.3/24
|
||||
quantum subnet-create $network $cidr --name $subnet || die "fail to create subnet $subnet"
|
||||
tempsubnet=`quantum subnet-list -- --name $subnet --fields id | wc -l`
|
||||
echo $tempsubnet
|
||||
if [ $tempsubnet -ne 5 ]; then
|
||||
die "subnets with name $subnet is not unique or found"
|
||||
fi
|
||||
subnet_id=`quantum subnet-list -- --name $subnet --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of subnet with name $subnet is $subnet_id"
|
||||
quantum subnet-show $subnet || die "fail to show subnet $subnet"
|
||||
quantum subnet-show $subnet_id || die "fail to show subnet $subnet_id"
|
||||
|
||||
quantum subnet-update $subnet --dns_namesevers host1 || die "fail to update subnet $subnet"
|
||||
quantum subnet-update $subnet_id --dns_namesevers host2 || die "fail to update subnet $subnet_id"
|
||||
|
||||
# test the crud of ports
|
||||
port=myport1
|
||||
quantum port-create $network --name $port || die "fail to create port $port"
|
||||
tempport=`quantum port-list -- --name $port --fields id | wc -l`
|
||||
echo $tempport
|
||||
if [ $tempport -ne 5 ]; then
|
||||
die "ports with name $port is not unique or found"
|
||||
fi
|
||||
port_id=`quantum port-list -- --name $port --fields id | tail -n 2 | head -n 1 | cut -d' ' -f 2`
|
||||
echo "ID of port with name $port is $port_id"
|
||||
quantum port-show $port || die "fail to show port $port"
|
||||
quantum port-show $port_id || die "fail to show port $port_id"
|
||||
|
||||
quantum port-update $port --device_id deviceid1 || die "fail to update port $port"
|
||||
quantum port-update $port_id --device_id deviceid2 || die "fail to update port $port_id"
|
@@ -26,6 +26,44 @@ from quantumclient.common import command
|
||||
from quantumclient.common import exceptions
|
||||
from quantumclient.common import utils
|
||||
|
||||
HEX_ELEM = '[0-9A-Fa-f]'
|
||||
UUID_PATTERN = '-'.join([HEX_ELEM + '{8}', HEX_ELEM + '{4}',
|
||||
HEX_ELEM + '{4}', HEX_ELEM + '{4}',
|
||||
HEX_ELEM + '{12}'])
|
||||
|
||||
|
||||
def find_resourceid_by_name_or_id(client, resource, name_or_id):
|
||||
obj_lister = getattr(client, "list_%ss" % resource)
|
||||
# perform search by id only if we are passing a valid UUID
|
||||
match = re.match(UUID_PATTERN, name_or_id)
|
||||
collection = resource + "s"
|
||||
if match:
|
||||
data = obj_lister(id=name_or_id, fields='id')
|
||||
if data and data[collection]:
|
||||
return data[collection][0]['id']
|
||||
return _find_resourceid_by_name(client, resource, name_or_id)
|
||||
|
||||
|
||||
def _find_resourceid_by_name(client, resource, name):
|
||||
obj_lister = getattr(client, "list_%ss" % resource)
|
||||
data = obj_lister(name=name, fields='id')
|
||||
collection = resource + "s"
|
||||
info = data[collection]
|
||||
if len(info) > 1:
|
||||
msg = (_("Multiple %(resource)s matches found for '%(name)s',"
|
||||
" use an ID to be more specific.") %
|
||||
{'resource': resource, 'name': name})
|
||||
raise exceptions.QuantumClientException(
|
||||
message=msg)
|
||||
elif len(info) == 0:
|
||||
not_found_message = (_("Unable to find %(resource)s with '%(name)s'") %
|
||||
{'resource': resource, 'name': name})
|
||||
# 404 is used to simulate server side behavior
|
||||
raise exceptions.QuantumClientException(
|
||||
message=not_found_message, status_code=404)
|
||||
else:
|
||||
return info[0]['id']
|
||||
|
||||
|
||||
def add_show_list_common_argument(parser):
|
||||
parser.add_argument(
|
||||
@@ -222,8 +260,8 @@ class UpdateCommand(QuantumCommand):
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(UpdateCommand, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'id', metavar='%s_id' % self.resource,
|
||||
help='ID of %s to update' % self.resource)
|
||||
'id', metavar=self.resource,
|
||||
help='ID or name of %s to update' % self.resource)
|
||||
add_extra_argument(parser, 'value_specs',
|
||||
'new values for the %s' % self.resource)
|
||||
return parser
|
||||
@@ -237,9 +275,12 @@ class UpdateCommand(QuantumCommand):
|
||||
raise exceptions.CommandError(
|
||||
"Must specify new values to update %s" % self.resource)
|
||||
data = {self.resource: parse_args_to_dict(value_specs)}
|
||||
_id = find_resourceid_by_name_or_id(quantum_client,
|
||||
self.resource,
|
||||
parsed_args.id)
|
||||
obj_updator = getattr(quantum_client,
|
||||
"update_%s" % self.resource)
|
||||
obj_updator(parsed_args.id, data)
|
||||
obj_updator(_id, data)
|
||||
print >>self.app.stdout, (
|
||||
_('Updated %(resource)s: %(id)s') %
|
||||
{'id': parsed_args.id, 'resource': self.resource})
|
||||
@@ -258,8 +299,8 @@ class DeleteCommand(QuantumCommand):
|
||||
def get_parser(self, prog_name):
|
||||
parser = super(DeleteCommand, self).get_parser(prog_name)
|
||||
parser.add_argument(
|
||||
'id', metavar='%s_id' % self.resource,
|
||||
help='ID of %s to delete' % self.resource)
|
||||
'id', metavar=self.resource,
|
||||
help='ID or name of %s to delete' % self.resource)
|
||||
return parser
|
||||
|
||||
def run(self, parsed_args):
|
||||
@@ -268,7 +309,10 @@ class DeleteCommand(QuantumCommand):
|
||||
quantum_client.format = parsed_args.request_format
|
||||
obj_deleter = getattr(quantum_client,
|
||||
"delete_%s" % self.resource)
|
||||
obj_deleter(parsed_args.id)
|
||||
_id = find_resourceid_by_name_or_id(quantum_client,
|
||||
self.resource,
|
||||
parsed_args.id)
|
||||
obj_deleter(_id)
|
||||
print >>self.app.stdout, (_('Deleted %(resource)s: %(id)s')
|
||||
% {'id': parsed_args.id,
|
||||
'resource': self.resource})
|
||||
@@ -327,10 +371,7 @@ class ShowCommand(QuantumCommand, show.ShowOne):
|
||||
"""Show information of a given resource
|
||||
|
||||
"""
|
||||
HEX_ELEM = '[0-9A-Fa-f]'
|
||||
UUID_PATTERN = '-'.join([HEX_ELEM + '{8}', HEX_ELEM + '{4}',
|
||||
HEX_ELEM + '{4}', HEX_ELEM + '{4}',
|
||||
HEX_ELEM + '{12}'])
|
||||
|
||||
api = 'network'
|
||||
resource = None
|
||||
log = None
|
||||
@@ -339,7 +380,7 @@ class ShowCommand(QuantumCommand, show.ShowOne):
|
||||
parser = super(ShowCommand, self).get_parser(prog_name)
|
||||
add_show_list_common_argument(parser)
|
||||
parser.add_argument(
|
||||
'id', metavar='%s_id' % self.resource,
|
||||
'id', metavar=self.resource,
|
||||
help='ID or name of %s to look up' % self.resource)
|
||||
return parser
|
||||
|
||||
@@ -353,57 +394,10 @@ class ShowCommand(QuantumCommand, show.ShowOne):
|
||||
params = {'verbose': 'True'}
|
||||
if parsed_args.fields:
|
||||
params = {'fields': parsed_args.fields}
|
||||
|
||||
data = None
|
||||
# Error message to be used in case both search by id and name are
|
||||
# unsuccessful (if list by name fails it does not return an error)
|
||||
not_found_message = "Unable to find resource:%s" % parsed_args.id
|
||||
|
||||
# perform search by id only if we are passing a valid UUID
|
||||
match = re.match(self.UUID_PATTERN, parsed_args.id)
|
||||
if match:
|
||||
try:
|
||||
obj_shower = getattr(quantum_client,
|
||||
"show_%s" % self.resource)
|
||||
data = obj_shower(parsed_args.id, **params)
|
||||
except exceptions.QuantumClientException as ex:
|
||||
logging.debug("Show operation failed with code:%s",
|
||||
ex.status_code)
|
||||
not_found_message = ex.message
|
||||
if ex.status_code != 404:
|
||||
logging.exception("Unable to perform show operation")
|
||||
raise
|
||||
|
||||
# If data is empty, then we got a 404. Try to interpret Id as a name
|
||||
if not data:
|
||||
logging.debug("Trying to interpret %s as a %s name",
|
||||
parsed_args.id,
|
||||
self.resource)
|
||||
# build search_opts for the name
|
||||
search_opts = parse_args_to_dict(["--name=%s" % parsed_args.id])
|
||||
search_opts.update(params)
|
||||
obj_lister = getattr(quantum_client,
|
||||
"list_%ss" % self.resource)
|
||||
data = obj_lister(**search_opts)
|
||||
info = []
|
||||
collection = self.resource + "s"
|
||||
if collection in data:
|
||||
info = data[collection]
|
||||
if len(info) > 1:
|
||||
logging.info("Multiple occurrences found for: %s",
|
||||
_id = find_resourceid_by_name_or_id(quantum_client, self.resource,
|
||||
parsed_args.id)
|
||||
_columns = ['id']
|
||||
# put all ids in a single string as formatter for show
|
||||
# command will print on record only
|
||||
id_string = "\n".join(utils.get_item_properties(
|
||||
s, _columns)[0] for s in info)
|
||||
return (_columns, (id_string, ), )
|
||||
elif len(info) == 0:
|
||||
#Nothing was found
|
||||
raise exceptions.QuantumClientException(
|
||||
message=not_found_message)
|
||||
else:
|
||||
data = {self.resource: info[0]}
|
||||
obj_shower = getattr(quantum_client, "show_%s" % self.resource)
|
||||
data = obj_shower(_id, **params)
|
||||
if self.resource in data:
|
||||
for k, v in data[self.resource].iteritems():
|
||||
if isinstance(v, list):
|
||||
|
@@ -18,6 +18,7 @@
|
||||
import logging
|
||||
|
||||
from quantumclient.common import utils
|
||||
from quantumclient.quantum import v2_0 as quantumv20
|
||||
from quantumclient.quantum.v2_0 import CreateCommand
|
||||
from quantumclient.quantum.v2_0 import DeleteCommand
|
||||
from quantumclient.quantum.v2_0 import ListCommand
|
||||
@@ -54,39 +55,52 @@ class CreatePort(CreateCommand):
|
||||
log = logging.getLogger(__name__ + '.CreatePort')
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
help='name of this port')
|
||||
parser.add_argument(
|
||||
'--admin_state_down',
|
||||
default=True, action='store_false',
|
||||
help='set admin state up to false')
|
||||
parser.add_argument(
|
||||
'--mac_address',
|
||||
help='mac address of port')
|
||||
help='mac address of this port')
|
||||
parser.add_argument(
|
||||
'--device_id',
|
||||
help='device id of this port')
|
||||
parser.add_argument(
|
||||
'--fixed_ip',
|
||||
action='append',
|
||||
help='desired Ip for this port: '
|
||||
'subnet_id=<id>,ip_address=<ip>, '
|
||||
help='desired IP for this port: '
|
||||
'subnet_id=<name_or_id>,ip_address=<ip>, '
|
||||
'can be repeated')
|
||||
parser.add_argument(
|
||||
'network_id',
|
||||
help='Network id this port belongs to')
|
||||
'network_id', metavar='network',
|
||||
help='Network id or name this port belongs to')
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
_network_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
self.get_client(), 'network', parsed_args.network_id)
|
||||
body = {'port': {'admin_state_up': parsed_args.admin_state_down,
|
||||
'network_id': parsed_args.network_id, }, }
|
||||
'network_id': _network_id, }, }
|
||||
if parsed_args.mac_address:
|
||||
body['port'].update({'mac_address': parsed_args.mac_address})
|
||||
if parsed_args.device_id:
|
||||
body['port'].update({'device_id': parsed_args.device_id})
|
||||
if parsed_args.tenant_id:
|
||||
body['port'].update({'tenant_id': parsed_args.tenant_id})
|
||||
if parsed_args.name:
|
||||
body['port'].update({'name': parsed_args.name})
|
||||
ips = []
|
||||
if parsed_args.fixed_ip:
|
||||
for ip_spec in parsed_args.fixed_ip:
|
||||
ips.append(utils.str2dict(ip_spec))
|
||||
ip_dict = utils.str2dict(ip_spec)
|
||||
if 'subnet_id' in ip_dict:
|
||||
subnet_name_id = ip_dict['subnet_id']
|
||||
_subnet_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
self.get_client(), 'subnet', subnet_name_id)
|
||||
ip_dict['subnet_id'] = _subnet_id
|
||||
ips.append(ip_dict)
|
||||
if ips:
|
||||
body['port'].update({'fixed_ips': ips})
|
||||
return body
|
||||
|
@@ -18,6 +18,7 @@
|
||||
import logging
|
||||
|
||||
from quantumclient.common import utils
|
||||
from quantumclient.quantum import v2_0 as quantumv20
|
||||
from quantumclient.quantum.v2_0 import CreateCommand
|
||||
from quantumclient.quantum.v2_0 import DeleteCommand
|
||||
from quantumclient.quantum.v2_0 import ListCommand
|
||||
@@ -55,6 +56,9 @@ class CreateSubnet(CreateCommand):
|
||||
log = logging.getLogger(__name__ + '.CreateSubnet')
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--name',
|
||||
help='name of this subnet')
|
||||
parser.add_argument('--ip_version', type=int,
|
||||
default=4, choices=[4, 6],
|
||||
help='IP version with default 4')
|
||||
@@ -68,20 +72,24 @@ class CreateSubnet(CreateCommand):
|
||||
'start=<ip_address>,end=<ip_address> '
|
||||
'can be repeated')
|
||||
parser.add_argument(
|
||||
'network_id',
|
||||
help='Network id this subnet belongs to')
|
||||
'network_id', metavar='network',
|
||||
help='Network id or name this subnet belongs to')
|
||||
parser.add_argument(
|
||||
'cidr', metavar='cidr',
|
||||
help='cidr of subnet to create')
|
||||
|
||||
def args2body(self, parsed_args):
|
||||
_network_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
self.get_client(), 'network', parsed_args.network_id)
|
||||
body = {'subnet': {'cidr': parsed_args.cidr,
|
||||
'network_id': parsed_args.network_id,
|
||||
'network_id': _network_id,
|
||||
'ip_version': parsed_args.ip_version, }, }
|
||||
if parsed_args.gateway:
|
||||
body['subnet'].update({'gateway_ip': parsed_args.gateway})
|
||||
if parsed_args.tenant_id:
|
||||
body['subnet'].update({'tenant_id': parsed_args.tenant_id})
|
||||
if parsed_args.name:
|
||||
body['subnet'].update({'name': parsed_args.name})
|
||||
ips = []
|
||||
if parsed_args.allocation_pool:
|
||||
for ip_spec in parsed_args.allocation_pool:
|
||||
|
@@ -22,6 +22,7 @@ import mox
|
||||
from mox import ContainsKeyValue
|
||||
from mox import Comparator
|
||||
|
||||
from quantumclient.quantum import v2_0 as quantumv20
|
||||
from quantumclient.v2_0.client import Client
|
||||
|
||||
API_VERSION = "2.0"
|
||||
@@ -55,6 +56,11 @@ class MyApp(object):
|
||||
self.stdout = _stdout
|
||||
|
||||
|
||||
def end_url(path, query=None):
|
||||
_url_str = ENDURL + "/v" + API_VERSION + path + "." + FORMAT
|
||||
return query and _url_str + "?" + query or _url_str
|
||||
|
||||
|
||||
class MyComparator(Comparator):
|
||||
def __init__(self, lhs, client):
|
||||
self.lhs = lhs
|
||||
@@ -109,9 +115,8 @@ class CLITestV20Base(unittest.TestCase):
|
||||
|
||||
test_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
||||
|
||||
def _url(self, path, query=None):
|
||||
_url_str = self.endurl + "/v" + API_VERSION + path + "." + FORMAT
|
||||
return query and _url_str + "?" + query or _url_str
|
||||
def _find_resourceid(self, client, resource, name_or_id):
|
||||
return name_or_id
|
||||
|
||||
def setUp(self):
|
||||
"""Prepare the test environment"""
|
||||
@@ -120,10 +125,13 @@ class CLITestV20Base(unittest.TestCase):
|
||||
self.client = Client(token=TOKEN, endpoint_url=self.endurl)
|
||||
self.fake_stdout = FakeStdout()
|
||||
sys.stdout = self.fake_stdout
|
||||
self.old_find_resourceid = quantumv20.find_resourceid_by_name_or_id
|
||||
quantumv20.find_resourceid_by_name_or_id = self._find_resourceid
|
||||
|
||||
def tearDown(self):
|
||||
"""Clear the test environment"""
|
||||
sys.stdout = sys.__stdout__
|
||||
quantumv20.find_resourceid_by_name_or_id = self.old_find_resourceid
|
||||
|
||||
def _test_create_resource(self, resource, cmd,
|
||||
name, myid, args,
|
||||
@@ -149,7 +157,7 @@ class CLITestV20Base(unittest.TestCase):
|
||||
# url method body
|
||||
path = getattr(self.client, resource + "s_path")
|
||||
self.client.httpclient.request(
|
||||
self._url(path), 'POST',
|
||||
end_url(path), 'POST',
|
||||
body=MyComparator(body, self.client),
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
TOKEN)).AndReturn((MyResp(200),
|
||||
@@ -205,7 +213,7 @@ class CLITestV20Base(unittest.TestCase):
|
||||
query = "fields=" + field
|
||||
path = getattr(self.client, resources + "_path")
|
||||
self.client.httpclient.request(
|
||||
self._url(path, query), 'GET',
|
||||
end_url(path, query), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
TOKEN)).AndReturn((MyResp(200), resstr))
|
||||
@@ -226,7 +234,7 @@ class CLITestV20Base(unittest.TestCase):
|
||||
body = {resource: extrafields}
|
||||
path = getattr(self.client, resource + "_path")
|
||||
self.client.httpclient.request(
|
||||
self._url(path % myid), 'PUT',
|
||||
end_url(path % myid), 'PUT',
|
||||
body=MyComparator(body, self.client),
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
TOKEN)).AndReturn((MyResp(204), None))
|
||||
@@ -251,7 +259,7 @@ class CLITestV20Base(unittest.TestCase):
|
||||
resstr = self.client.serialize(expected_res)
|
||||
path = getattr(self.client, resource + "_path")
|
||||
self.client.httpclient.request(
|
||||
self._url(path % myid, query), 'GET',
|
||||
end_url(path % myid, query), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
TOKEN)).AndReturn((MyResp(200), resstr))
|
||||
@@ -266,40 +274,13 @@ class CLITestV20Base(unittest.TestCase):
|
||||
self.assertTrue(myid in _str)
|
||||
self.assertTrue('myname' in _str)
|
||||
|
||||
def _test_show_resource_by_name(self, resource, cmd, name,
|
||||
args, fields=[]):
|
||||
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 = {"%ss" % resource:
|
||||
[{'id': 'some_id',
|
||||
'name': name, }], }
|
||||
resstr = self.client.serialize(expected_res)
|
||||
list_path = getattr(self.client, resource + "s_path")
|
||||
self.client.httpclient.request(
|
||||
self._url(list_path, "%s&name=%s" % (query, name)), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
TOKEN)).AndReturn((MyResp(200), resstr))
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("show_" + 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(name in _str)
|
||||
self.assertTrue('some_id' in _str)
|
||||
|
||||
def _test_delete_resource(self, resource, cmd, myid, args):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
path = getattr(self.client, resource + "_path")
|
||||
self.client.httpclient.request(
|
||||
self._url(path % myid), 'DELETE',
|
||||
end_url(path % myid), 'DELETE',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
TOKEN)).AndReturn((MyResp(204), None))
|
||||
|
@@ -129,15 +129,6 @@ class CLITestV20Network(CLITestV20Base):
|
||||
self._test_show_resource(resource, cmd, self.test_id, args,
|
||||
['id', 'name'])
|
||||
|
||||
def test_show_network_by_name(self):
|
||||
"""Show net: --fields id --fields name myname."""
|
||||
resource = 'network'
|
||||
cmd = ShowNetwork(MyApp(sys.stdout), None)
|
||||
myname = 'myname'
|
||||
args = ['--fields', 'id', '--fields', 'name', myname]
|
||||
self._test_show_resource_by_name(resource, cmd, myname,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_delete_network(self):
|
||||
"""Delete net: myid."""
|
||||
resource = 'network'
|
||||
|
@@ -128,15 +128,6 @@ class CLITestV20Port(CLITestV20Base):
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_show_port_by_name(self):
|
||||
"""Show port: --fields id --fields name myname."""
|
||||
resource = 'port'
|
||||
cmd = ShowPort(MyApp(sys.stdout), None)
|
||||
myname = 'myname'
|
||||
args = ['--fields', 'id', '--fields', 'name', myname]
|
||||
self._test_show_resource_by_name(resource, cmd, myname,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_delete_port(self):
|
||||
"""Delete port: myid."""
|
||||
resource = 'port'
|
||||
|
@@ -161,15 +161,6 @@ class CLITestV20Subnet(CLITestV20Base):
|
||||
self._test_show_resource(resource, cmd, self.test_id,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_show_subnet_by_name(self):
|
||||
"""Show subnet: --fields id --fields name myname."""
|
||||
resource = 'subnet'
|
||||
cmd = ShowSubnet(MyApp(sys.stdout), None)
|
||||
myname = 'myname'
|
||||
args = ['--fields', 'id', '--fields', 'name', myname]
|
||||
self._test_show_resource_by_name(resource, cmd, myname,
|
||||
args, ['id', 'name'])
|
||||
|
||||
def test_delete_subnet(self):
|
||||
"""Delete subnet: subnetid."""
|
||||
resource = 'subnet'
|
||||
|
140
quantumclient/tests/unit/test_name_or_id.py
Normal file
140
quantumclient/tests/unit/test_name_or_id.py
Normal file
@@ -0,0 +1,140 @@
|
||||
# Copyright 2012 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
|
||||
|
||||
import uuid
|
||||
|
||||
import mox
|
||||
from mox import ContainsKeyValue
|
||||
import unittest
|
||||
|
||||
from quantumclient.common import exceptions
|
||||
from quantumclient.quantum import v2_0 as quantumv20
|
||||
from quantumclient.tests.unit import test_cli20
|
||||
from quantumclient.v2_0.client import Client
|
||||
|
||||
|
||||
class CLITestNameorID(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""Prepare the test environment"""
|
||||
self.mox = mox.Mox()
|
||||
self.endurl = test_cli20.ENDURL
|
||||
self.client = Client(token=test_cli20.TOKEN, endpoint_url=self.endurl)
|
||||
|
||||
def tearDown(self):
|
||||
"""Clear the test environment"""
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
|
||||
def test_get_id_from_id(self):
|
||||
_id = str(uuid.uuid4())
|
||||
reses = {'networks': [{'id': _id, }, ], }
|
||||
resstr = self.client.serialize(reses)
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
path = getattr(self.client, "networks_path")
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path, "fields=id&id=" + _id), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn(
|
||||
(test_cli20.MyResp(200), resstr))
|
||||
self.mox.ReplayAll()
|
||||
returned_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
self.client, 'network', _id)
|
||||
self.assertEqual(_id, returned_id)
|
||||
|
||||
def test_get_id_from_id_then_name_empty(self):
|
||||
_id = str(uuid.uuid4())
|
||||
reses = {'networks': [{'id': _id, }, ], }
|
||||
resstr = self.client.serialize(reses)
|
||||
resstr1 = self.client.serialize({'networks': []})
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
path = getattr(self.client, "networks_path")
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path, "fields=id&id=" + _id), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn(
|
||||
(test_cli20.MyResp(200), resstr1))
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path, "fields=id&name=" + _id), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn(
|
||||
(test_cli20.MyResp(200), resstr))
|
||||
self.mox.ReplayAll()
|
||||
returned_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
self.client, 'network', _id)
|
||||
self.assertEqual(_id, returned_id)
|
||||
|
||||
def test_get_id_from_name(self):
|
||||
name = 'myname'
|
||||
_id = str(uuid.uuid4())
|
||||
reses = {'networks': [{'id': _id, }, ], }
|
||||
resstr = self.client.serialize(reses)
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
path = getattr(self.client, "networks_path")
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path, "fields=id&name=" + name), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn(
|
||||
(test_cli20.MyResp(200), resstr))
|
||||
self.mox.ReplayAll()
|
||||
returned_id = quantumv20.find_resourceid_by_name_or_id(
|
||||
self.client, 'network', name)
|
||||
self.assertEqual(_id, returned_id)
|
||||
|
||||
def test_get_id_from_name_multiple(self):
|
||||
name = 'myname'
|
||||
reses = {'networks': [{'id': str(uuid.uuid4())},
|
||||
{'id': str(uuid.uuid4())}]}
|
||||
resstr = self.client.serialize(reses)
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
path = getattr(self.client, "networks_path")
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path, "fields=id&name=" + name), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn(
|
||||
(test_cli20.MyResp(200), resstr))
|
||||
self.mox.ReplayAll()
|
||||
try:
|
||||
quantumv20.find_resourceid_by_name_or_id(
|
||||
self.client, 'network', name)
|
||||
except exceptions.QuantumClientException as ex:
|
||||
self.assertTrue('Multiple' in ex.message)
|
||||
|
||||
def test_get_id_from_name_notfound(self):
|
||||
name = 'myname'
|
||||
reses = {'networks': []}
|
||||
resstr = self.client.serialize(reses)
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
path = getattr(self.client, "networks_path")
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path, "fields=id&name=" + name), 'GET',
|
||||
body=None,
|
||||
headers=ContainsKeyValue('X-Auth-Token',
|
||||
test_cli20.TOKEN)).AndReturn(
|
||||
(test_cli20.MyResp(200), resstr))
|
||||
self.mox.ReplayAll()
|
||||
try:
|
||||
quantumv20.find_resourceid_by_name_or_id(
|
||||
self.client, 'network', name)
|
||||
except exceptions.QuantumClientException as ex:
|
||||
self.assertTrue('Unable to find' in ex.message)
|
||||
self.assertEqual(404, ex.status_code)
|
Reference in New Issue
Block a user