diff --git a/senlinclient/osc/v1/cluster.py b/senlinclient/osc/v1/cluster.py index 63ca440..409540d 100644 --- a/senlinclient/osc/v1/cluster.py +++ b/senlinclient/osc/v1/cluster.py @@ -137,3 +137,76 @@ def _show_cluster(senlin_client, cluster_id): columns = list(six.iterkeys(cluster)) return columns, utils.get_dict_properties(cluster.to_dict(), columns, formatters=formatters) + + +class CreateCluster(show.ShowOne): + """Create the cluster.""" + + log = logging.getLogger(__name__ + ".CreateCluster") + + def get_parser(self, prog_name): + parser = super(CreateCluster, self).get_parser(prog_name) + parser.add_argument( + '--profile', + metavar='', + required=True, + help=_('Profile Id used for this cluster') + ) + parser.add_argument( + '--min-size', + metavar='', + default=0, + help=_('Min size of the cluster. Default to 0') + ) + parser.add_argument( + '--max-size', + metavar='', + default=-1, + help=_('Max size of the cluster. Default to -1, means unlimited') + ) + parser.add_argument( + '--desired-capacity', + metavar='', + default=0, + help=_('Desired capacity of the cluster. Default to min_size if ' + 'min_size is specified else 0.') + ) + parser.add_argument( + '--timeout', + metavar='', + type=int, + help=_('Cluster creation timeout in seconds') + ) + parser.add_argument( + '--metadata', + metavar='', + help=_('Metadata values to be attached to the cluster. ' + '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 cluster 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 + if parsed_args.min_size and not parsed_args.desired_capacity: + parsed_args.desired_capacity = parsed_args.min_size + attrs = { + 'name': parsed_args.name, + 'profile_id': parsed_args.profile, + 'min_size': parsed_args.min_size, + 'max_size': parsed_args.max_size, + 'desired_capacity': parsed_args.desired_capacity, + 'metadata': senlin_utils.format_parameters(parsed_args.metadata), + 'timeout': parsed_args.timeout + } + + cluster = senlin_client.create_cluster(**attrs) + return _show_cluster(senlin_client, cluster.id) diff --git a/senlinclient/tests/unit/osc/v1/test_cluster.py b/senlinclient/tests/unit/osc/v1/test_cluster.py index 3aa4c62..9b349e6 100644 --- a/senlinclient/tests/unit/osc/v1/test_cluster.py +++ b/senlinclient/tests/unit/osc/v1/test_cluster.py @@ -188,3 +188,74 @@ class TestClusterShow(TestCluster): error = self.assertRaises(exc.CommandError, self.cmd.take_action, parsed_args) self.assertEqual('Cluster not found: my_cluster', str(error)) + + +class TestClusterCreate(TestCluster): + response = {"cluster": { + "action": "bbf4558b-9fa3-482a-93c2-a4aa5cc85317", + "created_at": 'null', + "data": {}, + "desired_capacity": 4, + "domain": 'null', + "id": "45edadcb-c73b-4920-87e1-518b2f29f54b", + "init_at": "2015-02-10T14:16:10", + "max_size": -1, + "metadata": {}, + "min_size": 0, + "name": "test_cluster", + "nodes": [], + "policies": [], + "profile_id": "edc63d0a-2ca4-48fa-9854-27926da76a4a", + "profile_name": "mystack", + "project": "6e18cc2bdbeb48a5b3cad2dc499f6804", + "status": "INIT", + "status_reason": "Initializing", + "timeout": 3600, + "updated_at": 'null', + "user": "5e5bf8027826429c96af157f68dc9072" + }} + + defaults = { + "desired_capacity": 0, + "max_size": -1, + "metadata": {}, + "min_size": 0, + "name": "test_cluster", + "profile_id": "mystack", + "timeout": None + } + + def setUp(self): + super(TestClusterCreate, self).setUp() + self.cmd = osc_cluster.CreateCluster(self.app, None) + self.mock_client.create_cluster = mock.Mock( + return_value=sdk_cluster.Cluster(None, self.response)) + self.mock_client.get_cluster = mock.Mock( + return_value=sdk_cluster.Cluster(None, self.response)) + + def test_cluster_create_defaults(self): + arglist = ['test_cluster', '--profile', 'mystack'] + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.create_cluster.assert_called_with(**self.defaults) + + def test_cluster_create_with_metadata(self): + arglist = ['test_cluster', '--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_cluster.assert_called_with(**kwargs) + + def test_cluster_create_with_size(self): + arglist = ['test_cluster', '--profile', 'mystack', + '--min-size', '1', '--max-size', '10', + '--desired-capacity', '2'] + kwargs = copy.deepcopy(self.defaults) + kwargs['min_size'] = '1' + kwargs['max_size'] = '10' + kwargs['desired_capacity'] = '2' + parsed_args = self.check_parser(self.cmd, arglist, []) + self.cmd.take_action(parsed_args) + self.mock_client.create_cluster.assert_called_with(**kwargs) diff --git a/setup.cfg b/setup.cfg index ea670ce..a148470 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,6 +30,7 @@ openstack.cli.extension = clustering = senlinclient.osc.plugin openstack.clustering.v1 = + cluster_create = senlinclient.osc.v1.cluster:CreateCluster cluster_list = senlinclient.osc.v1.cluster:ListCluster cluster_show = senlinclient.osc.v1.cluster:ShowCluster cluster_node_create = senlinclient.osc.v1.node:CreateNode