From 874a57f98d19282c1bc9a56e82bc032796599fad Mon Sep 17 00:00:00 2001 From: dixiaoli Date: Sat, 20 Feb 2016 15:13:31 +0800 Subject: [PATCH] Add OpenstackClient plugin for cluster node update This change implements the "openstack cluster node update" command Based on the existing senlin command: senlin node-update Change-Id: I199a54bfb89cd3b0830a48ad73325ea875a959ac Blueprint: senlin-support-python-openstackclient --- senlinclient/osc/v1/node.py | 59 ++++++++++++++++++++ senlinclient/tests/unit/osc/v1/test_node.py | 61 +++++++++++++++++++++ setup.cfg | 1 + 3 files changed, 121 insertions(+) diff --git a/senlinclient/osc/v1/node.py b/senlinclient/osc/v1/node.py index 18bce8d4..ccf19162 100644 --- a/senlinclient/osc/v1/node.py +++ b/senlinclient/osc/v1/node.py @@ -216,3 +216,62 @@ class CreateNode(show.ShowOne): node = senlin_client.create_node(**attrs) return _show_node(senlin_client, node.id) + + +class UpdateNode(show.ShowOne): + """Update the node.""" + + log = logging.getLogger(__name__ + ".UpdateNode") + + def get_parser(self, prog_name): + parser = super(UpdateNode, self).get_parser(prog_name) + parser.add_argument( + '--name', + metavar='', + help=_('New name for the node') + ) + parser.add_argument( + '--profile', + metavar='', + help=_('ID of new profile to use') + ) + parser.add_argument( + '--role', + metavar='', + help=_('Role for this node in the specific cluster') + ) + parser.add_argument( + '--metadata', + metavar='', + help=_('Metadata values to be attached to the node. ' + 'Metadata can be specified multiple times, or once with ' + 'key-value pairs separated by a semicolon'), + action='append' + ) + parser.add_argument( + 'node', + metavar='', + help=_('Name or ID of node to update') + ) + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)", parsed_args) + + senlin_client = self.app.client_manager.clustering + + # Find the node first, we need its UUID + try: + node = senlin_client.get_node(parsed_args.node) + except sdk_exc.ResourceNotFound: + raise exc.CommandError(_('Node not found: %s') % parsed_args.node) + + attrs = { + 'name': parsed_args.name, + 'role': parsed_args.role, + 'profile_id': parsed_args.profile, + 'metadata': senlin_utils.format_parameters(parsed_args.metadata), + } + + senlin_client.update_node(parsed_args.node, **attrs) + return _show_node(senlin_client, node.id) diff --git a/senlinclient/tests/unit/osc/v1/test_node.py b/senlinclient/tests/unit/osc/v1/test_node.py index d85fcaa0..a63e9c8f 100644 --- a/senlinclient/tests/unit/osc/v1/test_node.py +++ b/senlinclient/tests/unit/osc/v1/test_node.py @@ -266,3 +266,64 @@ class TestNodeCreate(TestNode): parsed_args = self.check_parser(self.cmd, arglist, []) self.cmd.take_action(parsed_args) self.mock_client.create_node.assert_called_with(**kwargs) + + +class TestNodeUpdate(TestNode): + response = {"node": { + "action": "2366d440-c73e-4961-9254-6d1c3af7c167", + "cluster_id": None, + "created_at": None, + "data": {}, + "domain": None, + "id": "0df0931b-e251-4f2e-8719-4ebfda3627ba", + "index": -1, + "init_time": "2015-03-05T08:53:15", + "metadata": {}, + "name": "my_node", + "physical_id": "", + "profile_id": "edc63d0a-2ca4-48fa-9854-27926da76a4a", + "profile_name": "mystack", + "project": "6e18cc2bdbeb48a5b3cad2dc499f6804", + "role": "master", + "status": "INIT", + "status_reason": "Initializing", + "updated_at": None, + "user": "5e5bf8027826429c96af157f68dc9072" + }} + + defaults = { + "name": "new_node", + "metadata": { + "nk1": "nv1", + "nk2": "nv2", + }, + "profile_id": "new_profile", + "role": "new_role" + } + + def setUp(self): + super(TestNodeUpdate, self).setUp() + self.cmd = osc_node.UpdateNode(self.app, None) + self.mock_client.update_node = mock.Mock( + return_value=sdk_node.Node(None, self.response)) + self.mock_client.get_node = mock.Mock( + return_value=sdk_node.Node(None, self.response)) + + def test_node_update_defaults(self): + arglist = ['--name', 'new_node', '--metadata', 'nk1=nv1;nk2=nv2', + '--profile', 'new_profile', '--role', 'new_role', + 'c6b8b252'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.update_node.assert_called_with('c6b8b252', + **self.defaults) + + def test_node_update_not_found(self): + arglist = ['--name', 'new_node', '--metadata', 'nk1=nv1;nk2=nv2', + '--profile', 'new_profile', '--role', 'new_role', + 'c6b8b252'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.mock_client.get_node.side_effect = sdk_exc.ResourceNotFound() + error = self.assertRaises(exc.CommandError, self.cmd.take_action, + parsed_args) + self.assertIn('Node not found: c6b8b252', str(error)) diff --git a/setup.cfg b/setup.cfg index 0917179c..8f78b62d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -33,6 +33,7 @@ openstack.clustering.v1 = cluster_node_create = senlinclient.osc.v1.node:CreateNode cluster_node_list = senlinclient.osc.v1.node:ListNode cluster_node_show = senlinclient.osc.v1.node:ShowNode + cluster_node_update = senlinclient.osc.v1.node:UpdateNode cluster_profile_create = senlinclient.osc.v1.profile:CreateProfile cluster_profile_delete = senlinclient.osc.v1.profile:DeleteProfile cluster_profile_list = senlinclient.osc.v1.profile:ListProfile