From 94abd4972da2af91e88a4496d51dc67b839ba1d0 Mon Sep 17 00:00:00 2001 From: Devananda van der Veen <devananda.vdv@gmail.com> Date: Mon, 23 Feb 2015 16:47:30 -0800 Subject: [PATCH] Add support for logical names Add client support for node logical names. - update help strings to indicate places where Names can be used instead of UUIDs - add new "-n" / "--name" parameter to "ironic node-create" - add Name field to output of both "node-list" and "node-show" Change-Id: Id16255e9611e95bd37a225ff475268f609726e37 Implements: blueprint logical-names --- ironicclient/tests/unit/v1/test_node.py | 20 +++++++++++ ironicclient/tests/unit/v1/test_node_shell.py | 9 +++++ ironicclient/v1/node.py | 2 +- ironicclient/v1/node_shell.py | 36 +++++++++++-------- ironicclient/v1/resource_fields.py | 8 ++--- 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/ironicclient/tests/unit/v1/test_node.py b/ironicclient/tests/unit/v1/test_node.py index b834df2fc..801998940 100644 --- a/ironicclient/tests/unit/v1/test_node.py +++ b/ironicclient/tests/unit/v1/test_node.py @@ -32,6 +32,7 @@ NODE1 = {'id': 123, 'driver': 'fake', 'driver_info': {'user': 'foo', 'password': 'bar'}, 'properties': {'num_cpu': 4}, + 'name': 'fake-node-1', 'extra': {}} NODE2 = {'id': 456, 'uuid': '66666666-7777-8888-9999-111111111111', @@ -165,6 +166,13 @@ fake_responses = { NODE2, ), }, + '/v1/nodes/%s' % NODE1['name']: + { + 'GET': ( + {}, + NODE1, + ), + }, '/v1/nodes/%s/ports' % NODE1['uuid']: { 'GET': ( @@ -342,6 +350,10 @@ class NodeManagerTest(testtools.TestCase): self.assertEqual(expect, self.api.calls) self.assertEqual(2, len(nodes)) + def test_node_list_shows_name(self): + nodes = self.mgr.list() + self.assertIsNotNone(getattr(nodes[0], 'name')) + def test_node_list_limit(self): self.api = utils.FakeAPI(fake_responses_pagination) self.mgr = node.NodeManager(self.api) @@ -464,6 +476,14 @@ class NodeManagerTest(testtools.TestCase): self.assertEqual(expect, self.api.calls) self.assertEqual(NODE2['uuid'], node.uuid) + def test_node_show_by_name(self): + node = self.mgr.get(NODE1['name']) + expect = [ + ('GET', '/v1/nodes/%s' % NODE1['name'], {}, None), + ] + self.assertEqual(expect, self.api.calls) + self.assertEqual(NODE1['uuid'], node.uuid) + def test_create(self): node = self.mgr.create(**CREATE_NODE) expect = [ diff --git a/ironicclient/tests/unit/v1/test_node_shell.py b/ironicclient/tests/unit/v1/test_node_shell.py index 1e6bf31fe..86807b63a 100644 --- a/ironicclient/tests/unit/v1/test_node_shell.py +++ b/ironicclient/tests/unit/v1/test_node_shell.py @@ -42,6 +42,7 @@ class NodeShellTest(utils.BaseTestCase): 'last_error', 'maintenance', 'maintenance_reason', + 'name', 'power_state', 'properties', 'provision_state', @@ -147,6 +148,14 @@ class NodeShellTest(utils.BaseTestCase): n_shell.do_node_create(client_mock, args) client_mock.node.create.assert_called_once_with(uuid=args.uuid) + def test_do_node_create_with_name(self): + client_mock = mock.MagicMock() + args = mock.MagicMock() + args.name = 'node_name' + + n_shell.do_node_create(client_mock, args) + client_mock.node.create.assert_called_once_with(name=args.name) + def test_do_node_show(self): client_mock = mock.MagicMock() args = mock.MagicMock() diff --git a/ironicclient/v1/node.py b/ironicclient/v1/node.py index 5624716f5..4ba8041c4 100644 --- a/ironicclient/v1/node.py +++ b/ironicclient/v1/node.py @@ -21,7 +21,7 @@ from ironicclient.common import utils from ironicclient import exc CREATION_ATTRIBUTES = ['chassis_uuid', 'driver', 'driver_info', 'extra', - 'uuid', 'properties'] + 'uuid', 'properties', 'name'] class Node(base.Resource): diff --git a/ironicclient/v1/node_shell.py b/ironicclient/v1/node_shell.py index 434775073..c4deff574 100644 --- a/ironicclient/v1/node_shell.py +++ b/ironicclient/v1/node_shell.py @@ -33,7 +33,8 @@ def _print_node_show(node): @cliutils.arg( 'node', metavar='<id>', - help="UUID of the node (or instance UUID if --instance is specified).") + help="Name or UUID of the node " + "(or instance UUID if --instance is specified).") @cliutils.arg( '--instance', dest='instance_uuid', @@ -151,10 +152,14 @@ def do_node_list(cc, args): '-u', '--uuid', metavar='<uuid>', help="Unique UUID for the node.") +@cliutils.arg( + '-n', '--name', + metavar='<name>', + help="Unique name for the node.") def do_node_create(cc, args): """Register a new node with the Ironic service.""" field_list = ['chassis_uuid', 'driver', 'driver_info', - 'properties', 'extra', 'uuid'] + 'properties', 'extra', 'uuid', 'name'] fields = dict((k, v) for (k, v) in vars(args).items() if k in field_list and not (v is None)) fields = utils.args_array_to_dict(fields, 'driver_info') @@ -166,7 +171,10 @@ def do_node_create(cc, args): cliutils.print_dict(data, wrap=72) -@cliutils.arg('node', metavar='<node>', nargs='+', help="UUID of the node.") +@cliutils.arg('node', + metavar='<node>', + nargs='+', + help="Name or UUID of the node.") def do_node_delete(cc, args): """Unregister a node from the Ironic service.""" for n in args.node: @@ -174,7 +182,7 @@ def do_node_delete(cc, args): print(_('Deleted node %s') % n) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg( 'op', metavar='<op>', @@ -197,7 +205,7 @@ def do_node_update(cc, args): @cliutils.arg('node', metavar='<node>', - help="UUID of the node.") + help="Name or UUID of the node.") @cliutils.arg('method', metavar='<method>', help="Vendor-passthru method to be called.") @@ -279,7 +287,7 @@ def do_node_port_list(cc, args): sortby_index=None) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg( 'maintenance_mode', metavar='<maintenance-mode>', @@ -300,7 +308,7 @@ def do_node_set_maintenance(cc, args): maint_reason=args.reason) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg( 'power_state', metavar='<power-state>', @@ -311,7 +319,7 @@ def do_node_set_power_state(cc, args): cc.node.set_power_state(args.node, args.power_state) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg( 'provision_state', metavar='<provision state>', @@ -335,7 +343,7 @@ def do_node_set_provision_state(cc, args): configdrive=args.config_drive) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") def do_node_validate(cc, args): """Validate a node's driver interfaces.""" ifaces = cc.node.validate(args.node) @@ -349,14 +357,14 @@ def do_node_validate(cc, args): cliutils.print_list(obj_list, fields, field_labels=field_labels) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") def do_node_get_console(cc, args): """Get the connection information for a node's console, if enabled.""" info = cc.node.get_console(args.node) cliutils.print_dict(info, wrap=72) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg( 'enabled', metavar='<enabled>', @@ -368,7 +376,7 @@ def do_node_set_console_mode(cc, args): cc.node.set_console_mode(args.node, args.enabled) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") @cliutils.arg( 'device', metavar='<boot-device>', @@ -385,14 +393,14 @@ def do_node_set_boot_device(cc, args): cc.node.set_boot_device(args.node, args.device, args.persistent) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") def do_node_get_boot_device(cc, args): """Get the current boot device for a node.""" boot_device = cc.node.get_boot_device(args.node) cliutils.print_dict(boot_device, wrap=72) -@cliutils.arg('node', metavar='<node>', help="UUID of the node.") +@cliutils.arg('node', metavar='<node>', help="Name or UUID of the node.") def do_node_get_supported_boot_devices(cc, args): """Get the supported boot devices for a node.""" boot_devices = cc.node.get_supported_boot_devices(args.node) diff --git a/ironicclient/v1/resource_fields.py b/ironicclient/v1/resource_fields.py index cff472abf..4c731014b 100644 --- a/ironicclient/v1/resource_fields.py +++ b/ironicclient/v1/resource_fields.py @@ -37,7 +37,7 @@ NODE_FIELDS = ['chassis_uuid', 'created_at', 'console_enabled', 'driver', 'properties', 'provision_state', 'reservation', 'target_power_state', 'target_provision_state', 'updated_at', 'inspection_finished_at', - 'inspection_started_at', 'uuid'] + 'inspection_started_at', 'uuid', 'name'] NODE_FIELD_LABELS = ['Chassis UUID', 'Created At', 'Console Enabled', 'Driver', 'Driver Info', 'Driver Internal Info', 'Extra', @@ -46,12 +46,12 @@ NODE_FIELD_LABELS = ['Chassis UUID', 'Created At', 'Console Enabled', 'Driver', 'Properties', 'Provision State', 'Reservation', 'Target Power State', 'Target Provision State', 'Updated At', 'Inspection Finished At', - 'Inspection Started At', 'UUID'] + 'Inspection Started At', 'UUID', 'Name'] -NODE_LIST_FIELDS = ['uuid', 'instance_uuid', 'power_state', +NODE_LIST_FIELDS = ['uuid', 'name', 'instance_uuid', 'power_state', 'provision_state', 'maintenance'] -NODE_LIST_FIELD_LABELS = ['UUID', 'Instance UUID', 'Power State', +NODE_LIST_FIELD_LABELS = ['UUID', 'Name', 'Instance UUID', 'Power State', 'Provisioning State', 'Maintenance']