From 56e447bc9dfab04243e609d1fe7d8dc79ceef5c9 Mon Sep 17 00:00:00 2001 From: dixiaoli Date: Sat, 20 Feb 2016 13:41:46 +0800 Subject: [PATCH] Add OpenstackClient plugin for cluster node create This change implements the "openstack cluster node create" command Based on the existing senlin command: senlin node-create Blueprint: senlin-support-python-openstackclient Change-Id: I65be6991ede45701b0ef6968fce73f67761022e9 --- senlinclient/osc/v1/node.py | 54 +++++++++++++++ senlinclient/tests/unit/osc/v1/test_node.py | 73 +++++++++++++++++++++ setup.cfg | 1 + 3 files changed, 128 insertions(+) diff --git a/senlinclient/osc/v1/node.py b/senlinclient/osc/v1/node.py index 8c1f73b7..18bce8d4 100644 --- a/senlinclient/osc/v1/node.py +++ b/senlinclient/osc/v1/node.py @@ -162,3 +162,57 @@ def _show_node(senlin_client, node_id, show_details=False): columns = list(six.iterkeys(node)) return columns, utils.get_dict_properties(node.to_dict(), columns, formatters=formatters) + + +class CreateNode(show.ShowOne): + """Create the node.""" + + log = logging.getLogger(__name__ + ".CreateNode") + + def get_parser(self, prog_name): + parser = super(CreateNode, self).get_parser(prog_name) + parser.add_argument( + '--profile', + metavar='', + required=True, + help=_('Profile Id or Name used for this node') + ) + parser.add_argument( + '--cluster', + metavar='', + help=_('Cluster Id or Name for this node') + ) + 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. ' + 'This can be specified multiple times, or once with ' + 'key-value pairs separated by a semicolon'), + action='append' + ) + parser.add_argument( + 'name', + metavar='', + help=_('Name of the node to create') + ) + return parser + + def take_action(self, parsed_args): + self.log.debug("take_action(%s)", parsed_args) + + senlin_client = self.app.client_manager.clustering + attrs = { + 'name': parsed_args.name, + 'cluster_id': parsed_args.cluster, + 'profile_id': parsed_args.profile, + 'role': parsed_args.role, + 'metadata': senlin_utils.format_parameters(parsed_args.metadata), + } + + node = senlin_client.create_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 84a0056c..d85fcaa0 100644 --- a/senlinclient/tests/unit/osc/v1/test_node.py +++ b/senlinclient/tests/unit/osc/v1/test_node.py @@ -193,3 +193,76 @@ class TestNodeShow(TestNode): error = self.assertRaises(exc.CommandError, self.cmd.take_action, parsed_args) self.assertEqual('Node not found: my_node', str(error)) + + +class TestNodeCreate(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 = { + "cluster_id": None, + "metadata": {}, + "name": "my_node", + "profile_id": "mystack", + "role": None + } + + def setUp(self): + super(TestNodeCreate, self).setUp() + self.cmd = osc_node.CreateNode(self.app, None) + self.mock_client.create_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_create_defaults(self): + arglist = ['my_node', '--profile', 'mystack'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.create_node.assert_called_with(**self.defaults) + + def test_node_create_with_metadata(self): + arglist = ['my_node', '--profile', 'mystack', + '--metadata', 'key1=value1;key2=value2'] + kwargs = copy.deepcopy(self.defaults) + kwargs['metadata'] = {'key1': 'value1', 'key2': 'value2'} + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.create_node.assert_called_with(**kwargs) + + def test_node_create_with_cluster(self): + arglist = ['my_node', '--profile', 'mystack', + '--cluster', 'mycluster'] + kwargs = copy.deepcopy(self.defaults) + kwargs['cluster_id'] = 'mycluster' + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.create_node.assert_called_with(**kwargs) + + def test_node_create_with_role(self): + arglist = ['my_node', '--profile', 'mystack', + '--role', 'master'] + kwargs = copy.deepcopy(self.defaults) + kwargs['role'] = 'master' + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.create_node.assert_called_with(**kwargs) diff --git a/setup.cfg b/setup.cfg index f4d7ae4d..0917179c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,6 +30,7 @@ openstack.cli.extension = clustering = senlinclient.osc.plugin 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_profile_create = senlinclient.osc.v1.profile:CreateProfile