From defb5481b0e7e2469405de98e6dd49ed239ef986 Mon Sep 17 00:00:00 2001 From: Yong Sheng Gong Date: Sun, 29 Jul 2012 02:56:43 +0800 Subject: [PATCH] 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 --- quantum_test.sh | 59 ++++++++ quantumclient/quantum/v2_0/__init__.py | 118 +++++++-------- quantumclient/quantum/v2_0/port.py | 28 +++- quantumclient/quantum/v2_0/subnet.py | 14 +- quantumclient/tests/unit/test_cli20.py | 51 ++----- .../tests/unit/test_cli20_network.py | 9 -- quantumclient/tests/unit/test_cli20_port.py | 9 -- quantumclient/tests/unit/test_cli20_subnet.py | 9 -- quantumclient/tests/unit/test_name_or_id.py | 140 ++++++++++++++++++ 9 files changed, 303 insertions(+), 134 deletions(-) create mode 100755 quantum_test.sh create mode 100644 quantumclient/tests/unit/test_name_or_id.py diff --git a/quantum_test.sh b/quantum_test.sh new file mode 100755 index 000000000..590d22690 --- /dev/null +++ b/quantum_test.sh @@ -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" diff --git a/quantumclient/quantum/v2_0/__init__.py b/quantumclient/quantum/v2_0/__init__.py index 92dc4963c..5de594bf2 100644 --- a/quantumclient/quantum/v2_0/__init__.py +++ b/quantumclient/quantum/v2_0/__init__.py @@ -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", - 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]} + _id = find_resourceid_by_name_or_id(quantum_client, self.resource, + parsed_args.id) + 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): diff --git a/quantumclient/quantum/v2_0/port.py b/quantumclient/quantum/v2_0/port.py index 9d6a91a5b..c0674e0be 100644 --- a/quantumclient/quantum/v2_0/port.py +++ b/quantumclient/quantum/v2_0/port.py @@ -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=,ip_address=, ' + help='desired IP for this port: ' + 'subnet_id=,ip_address=, ' '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 diff --git a/quantumclient/quantum/v2_0/subnet.py b/quantumclient/quantum/v2_0/subnet.py index a43ec2744..62c8ad33c 100644 --- a/quantumclient/quantum/v2_0/subnet.py +++ b/quantumclient/quantum/v2_0/subnet.py @@ -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=,end= ' '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: diff --git a/quantumclient/tests/unit/test_cli20.py b/quantumclient/tests/unit/test_cli20.py index b58d65cac..373706103 100644 --- a/quantumclient/tests/unit/test_cli20.py +++ b/quantumclient/tests/unit/test_cli20.py @@ -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)) diff --git a/quantumclient/tests/unit/test_cli20_network.py b/quantumclient/tests/unit/test_cli20_network.py index ad85dc652..16837b349 100644 --- a/quantumclient/tests/unit/test_cli20_network.py +++ b/quantumclient/tests/unit/test_cli20_network.py @@ -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' diff --git a/quantumclient/tests/unit/test_cli20_port.py b/quantumclient/tests/unit/test_cli20_port.py index 676aaea8d..14ae209c2 100644 --- a/quantumclient/tests/unit/test_cli20_port.py +++ b/quantumclient/tests/unit/test_cli20_port.py @@ -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' diff --git a/quantumclient/tests/unit/test_cli20_subnet.py b/quantumclient/tests/unit/test_cli20_subnet.py index 8783ed0ad..ad9ee2f77 100644 --- a/quantumclient/tests/unit/test_cli20_subnet.py +++ b/quantumclient/tests/unit/test_cli20_subnet.py @@ -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' diff --git a/quantumclient/tests/unit/test_name_or_id.py b/quantumclient/tests/unit/test_name_or_id.py new file mode 100644 index 000000000..d5947d809 --- /dev/null +++ b/quantumclient/tests/unit/test_name_or_id.py @@ -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)