Merge "Implement finding by name"
This commit is contained in:
commit
d67a087082
@ -76,11 +76,26 @@ def find_resource(manager, name_or_id):
|
|||||||
uuid.UUID(str(name_or_id))
|
uuid.UUID(str(name_or_id))
|
||||||
return manager.get(name_or_id)
|
return manager.get(name_or_id)
|
||||||
except (ValueError, exc.NotFound):
|
except (ValueError, exc.NotFound):
|
||||||
# This is temporary measure to prevent ugly errors on CLI.
|
pass
|
||||||
# Make this just 'pass' after we implement finding by name.
|
|
||||||
msg = "No %s with ID of '%s' exists." % \
|
# finally try to find the entity by name
|
||||||
|
resource = getattr(manager, 'resource_class', None)
|
||||||
|
attr = resource.NAME_ATTR if resource else 'name'
|
||||||
|
|
||||||
|
listing = manager.list()
|
||||||
|
matches = [obj for obj in listing if getattr(obj, attr) == name_or_id]
|
||||||
|
|
||||||
|
num_matches = len(matches)
|
||||||
|
if num_matches == 0:
|
||||||
|
msg = "No %s with name '%s' exists." % \
|
||||||
(manager.resource_class.__name__.lower(), name_or_id)
|
(manager.resource_class.__name__.lower(), name_or_id)
|
||||||
raise exc.CommandError(msg)
|
raise exc.CommandError(msg)
|
||||||
|
elif num_matches > 1:
|
||||||
|
msg = "Multiple instances of %s with name '%s' exist." % \
|
||||||
|
(manager.resource_class.__name__.lower(), name_or_id)
|
||||||
|
raise exc.CommandError(msg)
|
||||||
|
|
||||||
|
return matches[0]
|
||||||
|
|
||||||
|
|
||||||
def marshal_association(args, resource_dict, assoc_name):
|
def marshal_association(args, resource_dict, assoc_name):
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import mock
|
import mock
|
||||||
|
|
||||||
from tuskarclient.common import utils
|
from tuskarclient.common import utils
|
||||||
|
from tuskarclient.openstack.common.apiclient import exceptions as exc
|
||||||
from tuskarclient.tests import utils as test_utils
|
from tuskarclient.tests import utils as test_utils
|
||||||
|
|
||||||
|
|
||||||
@ -69,3 +70,52 @@ class MarshalAssociationTest(test_utils.TestCase):
|
|||||||
self.args.rack = None
|
self.args.rack = None
|
||||||
utils.marshal_association(self.args, self.dict, 'rack')
|
utils.marshal_association(self.args, self.dict, 'rack')
|
||||||
self.assertFalse('rack' in self.dict)
|
self.assertFalse('rack' in self.dict)
|
||||||
|
|
||||||
|
|
||||||
|
class FindResourceTest(test_utils.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(FindResourceTest, self).setUp()
|
||||||
|
|
||||||
|
self.overcloud1 = mock.Mock()
|
||||||
|
self.overcloud1.id = '1'
|
||||||
|
self.overcloud1.name = 'My Overcloud 1'
|
||||||
|
|
||||||
|
self.overcloud2 = mock.Mock()
|
||||||
|
self.overcloud2.id = '2'
|
||||||
|
self.overcloud2.name = 'My Overcloud 2'
|
||||||
|
|
||||||
|
self.overcloud3 = mock.Mock()
|
||||||
|
self.overcloud3.id = '3'
|
||||||
|
self.overcloud3.name = 'My Overcloud 2'
|
||||||
|
|
||||||
|
self.manager = mock.Mock()
|
||||||
|
self.manager.resource_class = None
|
||||||
|
self.manager.get.return_value = self.overcloud1
|
||||||
|
self.manager.resource_class = mock.Mock(__name__='Overcloud',
|
||||||
|
NAME_ATTR='name')
|
||||||
|
self.manager.list.return_value = [
|
||||||
|
self.overcloud1,
|
||||||
|
self.overcloud2,
|
||||||
|
self.overcloud3]
|
||||||
|
|
||||||
|
def test_with_id(self):
|
||||||
|
overcloud = utils.find_resource(self.manager, '1')
|
||||||
|
self.manager.get.assert_called_with(1)
|
||||||
|
self.assertEqual(self.overcloud1, overcloud)
|
||||||
|
|
||||||
|
def test_with_name(self):
|
||||||
|
overcloud = utils.find_resource(self.manager, 'My Overcloud 1')
|
||||||
|
self.assertEqual(self.overcloud1, overcloud)
|
||||||
|
|
||||||
|
def test_no_match(self):
|
||||||
|
self.assertRaises(exc.CommandError,
|
||||||
|
utils.find_resource,
|
||||||
|
self.manager,
|
||||||
|
'My Overcloud 3')
|
||||||
|
|
||||||
|
def test_multiple_matches(self):
|
||||||
|
self.assertRaises(exc.CommandError,
|
||||||
|
utils.find_resource,
|
||||||
|
self.manager,
|
||||||
|
'My Overcloud 2')
|
||||||
|
@ -92,7 +92,7 @@ tests = [
|
|||||||
'test_overcloud_role_delete_dashdash_help',
|
'test_overcloud_role_delete_dashdash_help',
|
||||||
'test_help_overcloud_role_delete'],
|
'test_help_overcloud_role_delete'],
|
||||||
'out_includes': [
|
'out_includes': [
|
||||||
'<ID> ID of Overcloud Role to show.',
|
'<ROLE> ID or name of the Overcloud Role to delete.',
|
||||||
],
|
],
|
||||||
'out_excludes': [
|
'out_excludes': [
|
||||||
'overcloud-role-list',
|
'overcloud-role-list',
|
||||||
@ -138,7 +138,7 @@ tests = [
|
|||||||
'test_overcloud_role_show_dashdash_help',
|
'test_overcloud_role_show_dashdash_help',
|
||||||
'test_help_overcloud_role_show'],
|
'test_help_overcloud_role_show'],
|
||||||
'out_includes': [
|
'out_includes': [
|
||||||
'<ID> ID of Overcloud Role to show.',
|
'<ROLE> ID or name of the Overcloud Role to show.',
|
||||||
],
|
],
|
||||||
'out_excludes': [
|
'out_excludes': [
|
||||||
'overcloud-role-list',
|
'overcloud-role-list',
|
||||||
@ -201,7 +201,7 @@ tests = [
|
|||||||
'test_overcloud_delete_dashdash_help',
|
'test_overcloud_delete_dashdash_help',
|
||||||
'test_help_overcloud_delete'],
|
'test_help_overcloud_delete'],
|
||||||
'out_includes': [
|
'out_includes': [
|
||||||
'<ID> ID of Overcloud to show.',
|
'<OVERCLOUD> ID or name of the Overcloud to delete.',
|
||||||
],
|
],
|
||||||
'out_excludes': [
|
'out_excludes': [
|
||||||
'overcloud-list',
|
'overcloud-list',
|
||||||
@ -247,7 +247,7 @@ tests = [
|
|||||||
'test_overcloud_show_dashdash_help',
|
'test_overcloud_show_dashdash_help',
|
||||||
'test_help_overcloud_show'],
|
'test_help_overcloud_show'],
|
||||||
'out_includes': [
|
'out_includes': [
|
||||||
'<ID> ID of Overcloud to show.',
|
'<OVERCLOUD> ID or name of the Overcloud to show.',
|
||||||
],
|
],
|
||||||
'out_excludes': [
|
'out_excludes': [
|
||||||
'overcloud-list',
|
'overcloud-list',
|
||||||
|
@ -45,7 +45,7 @@ class OvercloudRoleShellTest(tutils.TestCase):
|
|||||||
def test_overcloud_role_show(self, mock_print_detail, mock_find_resource):
|
def test_overcloud_role_show(self, mock_print_detail, mock_find_resource):
|
||||||
mock_find_resource.return_value = mock_overcloud()
|
mock_find_resource.return_value = mock_overcloud()
|
||||||
args = empty_args()
|
args = empty_args()
|
||||||
args.id = '5'
|
args.role = '5'
|
||||||
|
|
||||||
self.shell.do_overcloud_role_show(self.tuskar, args,
|
self.shell.do_overcloud_role_show(self.tuskar, args,
|
||||||
outfile=self.outfile)
|
outfile=self.outfile)
|
||||||
@ -93,7 +93,7 @@ class OvercloudRoleShellTest(tutils.TestCase):
|
|||||||
def test_overcloud_role_update(self, mock_print, mock_find_resource):
|
def test_overcloud_role_update(self, mock_print, mock_find_resource):
|
||||||
mock_find_resource.return_value = mock_overcloud()
|
mock_find_resource.return_value = mock_overcloud()
|
||||||
args = empty_args()
|
args = empty_args()
|
||||||
args.id = '5'
|
args.role = '5'
|
||||||
args.name = 'My Overcloud Role'
|
args.name = 'My Overcloud Role'
|
||||||
args.description = 'This is an Overcloud Role.'
|
args.description = 'This is an Overcloud Role.'
|
||||||
args.image_name = 'image'
|
args.image_name = 'image'
|
||||||
@ -117,7 +117,7 @@ class OvercloudRoleShellTest(tutils.TestCase):
|
|||||||
def test_overcloud_role_delete(self, mock_find_resource):
|
def test_overcloud_role_delete(self, mock_find_resource):
|
||||||
mock_find_resource.return_value = mock_overcloud()
|
mock_find_resource.return_value = mock_overcloud()
|
||||||
args = empty_args()
|
args = empty_args()
|
||||||
args.id = '5'
|
args.role = '5'
|
||||||
|
|
||||||
self.shell.do_overcloud_role_delete(self.tuskar, args,
|
self.shell.do_overcloud_role_delete(self.tuskar, args,
|
||||||
outfile=self.outfile)
|
outfile=self.outfile)
|
||||||
|
@ -50,7 +50,7 @@ class OvercloudShellTest(BaseOvercloudShellTest):
|
|||||||
def test_overcloud_show(self, mock_print_detail, mock_find_resource):
|
def test_overcloud_show(self, mock_print_detail, mock_find_resource):
|
||||||
mock_find_resource.return_value = mock_overcloud()
|
mock_find_resource.return_value = mock_overcloud()
|
||||||
args = empty_args()
|
args = empty_args()
|
||||||
args.id = '5'
|
args.overcloud = '5'
|
||||||
|
|
||||||
self.shell.do_overcloud_show(self.tuskar, args, outfile=self.outfile)
|
self.shell.do_overcloud_show(self.tuskar, args, outfile=self.outfile)
|
||||||
mock_find_resource.assert_called_with(self.tuskar.overclouds, '5')
|
mock_find_resource.assert_called_with(self.tuskar.overclouds, '5')
|
||||||
@ -89,7 +89,7 @@ class OvercloudShellTest(BaseOvercloudShellTest):
|
|||||||
def test_overcloud_update(self, mock_print_detail, mock_find_resource):
|
def test_overcloud_update(self, mock_print_detail, mock_find_resource):
|
||||||
mock_find_resource.return_value = mock_overcloud()
|
mock_find_resource.return_value = mock_overcloud()
|
||||||
args = empty_args()
|
args = empty_args()
|
||||||
args.id = '5'
|
args.overcloud = '5'
|
||||||
args.name = 'my_overcloud'
|
args.name = 'my_overcloud'
|
||||||
args.attributes = None
|
args.attributes = None
|
||||||
args.roles = None
|
args.roles = None
|
||||||
@ -108,7 +108,7 @@ class OvercloudShellTest(BaseOvercloudShellTest):
|
|||||||
def test_overcloud_delete(self, mock_find_resource):
|
def test_overcloud_delete(self, mock_find_resource):
|
||||||
mock_find_resource.return_value = mock_overcloud()
|
mock_find_resource.return_value = mock_overcloud()
|
||||||
args = empty_args()
|
args = empty_args()
|
||||||
args.id = '5'
|
args.overcloud = '5'
|
||||||
|
|
||||||
self.shell.do_overcloud_delete(self.tuskar, args, outfile=self.outfile)
|
self.shell.do_overcloud_delete(self.tuskar, args, outfile=self.outfile)
|
||||||
self.tuskar.overclouds.delete.assert_called_with('5')
|
self.tuskar.overclouds.delete.assert_called_with('5')
|
||||||
|
@ -18,10 +18,11 @@ import tuskarclient.common.formatting as fmt
|
|||||||
from tuskarclient.common import utils
|
from tuskarclient.common import utils
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('id', metavar="<ID>", help="ID of Overcloud Role to show.")
|
@utils.arg('role', metavar="<ROLE>",
|
||||||
|
help="ID or name of the Overcloud Role to show.")
|
||||||
def do_overcloud_role_show(tuskar, args, outfile=sys.stdout):
|
def do_overcloud_role_show(tuskar, args, outfile=sys.stdout):
|
||||||
"""Show an individual Overcloud Role by its ID."""
|
"""Show an individual Overcloud Role by its ID or name."""
|
||||||
overcloud_role = utils.find_resource(tuskar.overcloud_roles, args.id)
|
overcloud_role = utils.find_resource(tuskar.overcloud_roles, args.role)
|
||||||
print_role_detail(overcloud_role, outfile=outfile)
|
print_role_detail(overcloud_role, outfile=outfile)
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +47,8 @@ def do_overcloud_role_create(tuskar, args, outfile=sys.stdout):
|
|||||||
print_role_detail(overcloud_role, outfile=outfile)
|
print_role_detail(overcloud_role, outfile=outfile)
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('id', metavar="<ID>", help="ID of overcloud to show.")
|
@utils.arg('role', metavar="<ROLE>",
|
||||||
|
help="ID or name of the Overcloud Role to update.")
|
||||||
@utils.arg('-n', '--name', metavar="<NAME>",
|
@utils.arg('-n', '--name', metavar="<NAME>",
|
||||||
help='Name of the Overcloud Role to update.')
|
help='Name of the Overcloud Role to update.')
|
||||||
@utils.arg('-d', '--description', metavar="<DESCRIPTION>",
|
@utils.arg('-d', '--description', metavar="<DESCRIPTION>",
|
||||||
@ -56,8 +58,8 @@ def do_overcloud_role_create(tuskar, args, outfile=sys.stdout):
|
|||||||
@utils.arg('-f', '--flavor-id', metavar="<FLAVOR ID>",
|
@utils.arg('-f', '--flavor-id', metavar="<FLAVOR ID>",
|
||||||
help='UUID of the flavor of node this role should be deployed on.')
|
help='UUID of the flavor of node this role should be deployed on.')
|
||||||
def do_overcloud_role_update(tuskar, args, outfile=sys.stdout):
|
def do_overcloud_role_update(tuskar, args, outfile=sys.stdout):
|
||||||
"""Update an existing Overcloud Role by its ID."""
|
"""Update an existing Overcloud Role by its ID or name."""
|
||||||
overcloud_role = utils.find_resource(tuskar.overcloud_roles, args.id)
|
overcloud_role = utils.find_resource(tuskar.overcloud_roles, args.role)
|
||||||
overcloud_role_dict = create_overcloud_role_dict(args)
|
overcloud_role_dict = create_overcloud_role_dict(args)
|
||||||
updated_overcloud_role = tuskar.overcloud_roles.update(
|
updated_overcloud_role = tuskar.overcloud_roles.update(
|
||||||
overcloud_role.id,
|
overcloud_role.id,
|
||||||
@ -66,11 +68,12 @@ def do_overcloud_role_update(tuskar, args, outfile=sys.stdout):
|
|||||||
print_role_detail(updated_overcloud_role, outfile=outfile)
|
print_role_detail(updated_overcloud_role, outfile=outfile)
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('id', metavar="<ID>", help="ID of Overcloud Role to show.")
|
@utils.arg('role', metavar="<ROLE>",
|
||||||
|
help="ID or name of the Overcloud Role to delete.")
|
||||||
def do_overcloud_role_delete(tuskar, args, outfile=sys.stdout):
|
def do_overcloud_role_delete(tuskar, args, outfile=sys.stdout):
|
||||||
"""Delete an Overcloud Role by its ID."""
|
"""Delete an Overcloud Role by its ID or name."""
|
||||||
overcloud_role = utils.find_resource(tuskar.overcloud_roles, args.id)
|
overcloud_role = utils.find_resource(tuskar.overcloud_roles, args.role)
|
||||||
tuskar.overcloud_roles.delete(args.id)
|
tuskar.overcloud_roles.delete(overcloud_role.id)
|
||||||
print(u'Deleted Overcloud Role "%s".' % overcloud_role.name, file=outfile)
|
print(u'Deleted Overcloud Role "%s".' % overcloud_role.name, file=outfile)
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,10 +18,11 @@ import tuskarclient.common.formatting as fmt
|
|||||||
from tuskarclient.common import utils
|
from tuskarclient.common import utils
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('id', metavar="<ID>", help="ID of Overcloud to show.")
|
@utils.arg('overcloud', metavar="<OVERCLOUD>",
|
||||||
|
help="ID or name of the Overcloud to show.")
|
||||||
def do_overcloud_show(tuskar, args, outfile=sys.stdout):
|
def do_overcloud_show(tuskar, args, outfile=sys.stdout):
|
||||||
"""Show an individual Overcloud by its ID."""
|
"""Show an individual Overcloud by its ID or name."""
|
||||||
overcloud = utils.find_resource(tuskar.overclouds, args.id)
|
overcloud = utils.find_resource(tuskar.overclouds, args.overcloud)
|
||||||
print_overcloud_detail(overcloud, outfile=outfile)
|
print_overcloud_detail(overcloud, outfile=outfile)
|
||||||
|
|
||||||
|
|
||||||
@ -58,7 +59,8 @@ def do_overcloud_create(tuskar, args, outfile=sys.stdout):
|
|||||||
print_overcloud_detail(overcloud, outfile=outfile)
|
print_overcloud_detail(overcloud, outfile=outfile)
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('id', metavar="<ID>", help="ID of Overcloud to show.")
|
@utils.arg('overcloud', metavar="<OVERCLOUD>",
|
||||||
|
help="ID or name of the Overcloud to update.")
|
||||||
@utils.arg('-n', '--name', metavar="<NAME>",
|
@utils.arg('-n', '--name', metavar="<NAME>",
|
||||||
help='Name of the Overcloud Role to update.')
|
help='Name of the Overcloud Role to update.')
|
||||||
@utils.arg('-d', '--description', metavar="<DESCRIPTION>",
|
@utils.arg('-d', '--description', metavar="<DESCRIPTION>",
|
||||||
@ -73,8 +75,8 @@ def do_overcloud_create(tuskar, args, outfile=sys.stdout):
|
|||||||
help='This can be specified multiple times.',
|
help='This can be specified multiple times.',
|
||||||
action='append')
|
action='append')
|
||||||
def do_overcloud_update(tuskar, args, outfile=sys.stdout):
|
def do_overcloud_update(tuskar, args, outfile=sys.stdout):
|
||||||
"""Update an existing Overcloud by its ID."""
|
"""Update an existing Overcloud by its ID or name."""
|
||||||
overcloud = utils.find_resource(tuskar.overclouds, args.id)
|
overcloud = utils.find_resource(tuskar.overclouds, args.overcloud)
|
||||||
overcloud_roles = tuskar.overcloud_roles.list()
|
overcloud_roles = tuskar.overcloud_roles.list()
|
||||||
overcloud_dict = create_overcloud_dict(args, overcloud_roles)
|
overcloud_dict = create_overcloud_dict(args, overcloud_roles)
|
||||||
updated_overcloud = tuskar.overclouds.update(overcloud.id,
|
updated_overcloud = tuskar.overclouds.update(overcloud.id,
|
||||||
@ -82,11 +84,12 @@ def do_overcloud_update(tuskar, args, outfile=sys.stdout):
|
|||||||
print_overcloud_detail(updated_overcloud, outfile=outfile)
|
print_overcloud_detail(updated_overcloud, outfile=outfile)
|
||||||
|
|
||||||
|
|
||||||
@utils.arg('id', metavar="<ID>", help="ID of Overcloud to show.")
|
@utils.arg('overcloud', metavar="<OVERCLOUD>",
|
||||||
|
help="ID or name of the Overcloud to delete.")
|
||||||
def do_overcloud_delete(tuskar, args, outfile=sys.stdout):
|
def do_overcloud_delete(tuskar, args, outfile=sys.stdout):
|
||||||
"""Delete an Overcloud by its ID."""
|
"""Delete an Overcloud by its ID or name."""
|
||||||
overcloud = utils.find_resource(tuskar.overclouds, args.id)
|
overcloud = utils.find_resource(tuskar.overclouds, args.overcloud)
|
||||||
tuskar.overclouds.delete(args.id)
|
tuskar.overclouds.delete(overcloud.id)
|
||||||
print(u'Deleted Overcloud "%s".' % overcloud.name, file=outfile)
|
print(u'Deleted Overcloud "%s".' % overcloud.name, file=outfile)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user