OSC command for node op and cluster op

This patch adds OSC support to cluster op and cluster node op.

Change-Id: I93ff66e3a4f29041196b8d1814b5e2cee833cb08
This commit is contained in:
tengqm 2017-06-30 01:33:12 -04:00
parent 29efa09cb4
commit cfdf62a470
5 changed files with 150 additions and 0 deletions

View File

@ -810,6 +810,36 @@ class TestClusterRecover(TestCluster):
self.assertIn('Cluster not found: cluster1', str(error))
class TestClusterOp(TestCluster):
response = {"action": "a3c6d04c-3fca-4e4a-b0b3-c0522ef711f1"}
def setUp(self):
super(TestClusterOp, self).setUp()
self.cmd = osc_cluster.ClusterOp(self.app, None)
self.mock_client.perform_operation_on_cluster = mock.Mock(
return_value=self.response)
def test_cluster_op(self):
arglist = ['--operation', 'dance', '--params', 'style=tango',
'my_cluster']
parsed_args = self.check_parser(self.cmd, arglist, [])
self.cmd.take_action(parsed_args)
self.mock_client.perform_operation_on_cluster.assert_called_once_with(
'my_cluster',
'dance',
style='tango')
def test_cluster_op_not_found(self):
arglist = ['--operation', 'dance', 'cluster1']
ex = sdk_exc.ResourceNotFound
self.mock_client.perform_operation_on_cluster.side_effect = ex
parsed_args = self.check_parser(self.cmd, arglist, [])
error = self.assertRaises(exc.CommandError, self.cmd.take_action,
parsed_args)
self.assertIn('Cluster not found: cluster1', str(error))
class TestClusterCollect(TestCluster):
response = [
{

View File

@ -456,3 +456,33 @@ class TestNodeRecover(TestNode):
error = self.assertRaises(exc.CommandError, self.cmd.take_action,
parsed_args)
self.assertIn('Node not found: node1', str(error))
class TestNodeOp(TestNode):
response = {"action": "1db0f5c5-9183-4c47-9ef1-a5a97402a2c1"}
def setUp(self):
super(TestNodeOp, self).setUp()
self.cmd = osc_node.NodeOp(self.app, None)
self.mock_client.perform_operation_on_node = mock.Mock(
return_value=self.response)
def test_node_op(self):
arglist = ['--operation', 'dance', '--params', 'style=tango',
'my_node']
parsed_args = self.check_parser(self.cmd, arglist, [])
self.cmd.take_action(parsed_args)
self.mock_client.perform_operation_on_node.assert_called_once_with(
'my_node',
'dance',
style='tango')
def test_node_op_not_found(self):
arglist = ['--operation', 'dance', 'node1']
ex = sdk_exc.ResourceNotFound
self.mock_client.perform_operation_on_node.side_effect = ex
parsed_args = self.check_parser(self.cmd, arglist, [])
error = self.assertRaises(exc.CommandError, self.cmd.take_action,
parsed_args)
self.assertIn('Node not found: node1', str(error))

View File

@ -919,6 +919,50 @@ class ClusterCollect(command.Lister):
for a in attrs))
class ClusterOp(command.Lister):
"""Perform an operation on all nodes across a cluster."""
log = logging.getLogger(__name__ + ".ClusterOp")
def get_parser(self, prog_name):
parser = super(ClusterOp, self).get_parser(prog_name)
parser.add_argument(
'--operation',
metavar='<operation>',
required=True,
help=_('Operation to be performed on the cluster')
)
parser.add_argument(
'--params',
metavar='<key1=value1;key2=value2...>',
help=_("Parameters to for the specified operation. "
"This can be specified multiple times, or once with "
"parameters separated by a semicolon."),
action='append'
)
parser.add_argument(
'cluster',
metavar='<cluster>',
help=_('ID or name of cluster to operate on.')
)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
senlin_client = self.app.client_manager.clustering
cid = parsed_args.cluster
if parsed_args.params:
params = senlin_utils.format_parameters(parsed_args.params)
else:
params = {}
try:
resp = senlin_client.perform_operation_on_cluster(
cid, parsed_args.operation, **params)
print('Request accepted by action: %s' % resp['action'])
except sdk_exc.ResourceNotFound:
raise exc.CommandError(_('Cluster not found: %s') % cid)
class ClusterRun(command.Command):
"""Run scripts on cluster."""
log = logging.getLogger(__name__ + ".ClusterRun")

View File

@ -396,3 +396,47 @@ class RecoverNode(command.Command):
print('Node recover request on node %(nid)s is accepted by '
'action %(action)s.'
% {'nid': nid, 'action': resp['action']})
class NodeOp(command.Lister):
"""Perform an operation on a node."""
log = logging.getLogger(__name__ + ".NodeOp")
def get_parser(self, prog_name):
parser = super(NodeOp, self).get_parser(prog_name)
parser.add_argument(
'--operation',
metavar='<operation>',
required=True,
help=_('Operation to be performed on the node.')
)
parser.add_argument(
'--params',
metavar='<key1=value1;key2=value2...>',
help=_("Parameters to for the specified operation. "
"This can be specified multiple times, or once with "
"parameters separated by a semicolon."),
action="append"
)
parser.add_argument(
'node',
metavar='<node>',
help=_('ID or name the node operate on.')
)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)", parsed_args)
senlin_client = self.app.client_manager.clustering
nid = parsed_args.node
if parsed_args.params:
params = senlin_utils.format_parameters(parsed_args.params)
else:
params = {}
try:
resp = senlin_client.perform_operation_on_node(
nid, parsed_args.operation, **params)
print('Request accepted by action: %s' % resp['action'])
except sdk_exc.ResourceNotFound:
raise exc.CommandError(_('Node not found: %s') % nid)

View File

@ -50,6 +50,7 @@ openstack.clustering.v1 =
cluster_node_recover = senlinclient.v1.node:RecoverNode
cluster_node_show = senlinclient.v1.node:ShowNode
cluster_node_update = senlinclient.v1.node:UpdateNode
cluster_node_op = senlinclient.v1.node:NodeOp
cluster_policy_attach = senlinclient.v1.cluster:ClusterPolicyAttach
cluster_policy_binding_list = senlinclient.v1.cluster_policy:ClusterPolicyList
cluster_policy_binding_show = senlinclient.v1.cluster_policy:ClusterPolicyShow
@ -85,6 +86,7 @@ openstack.clustering.v1 =
cluster_collect = senlinclient.v1.cluster:ClusterCollect
cluster_run = senlinclient.v1.cluster:ClusterRun
cluster_service_list = senlinclient.v1.service:ListService
cluster_op = senlinclient.v1.cluster:ClusterOp
[global]
setup-hooks =