Support to cluster-op and node-op operations

This patch adds support to node-op and cluster-op operations.

Change-Id: I72de19ff5a18bf36eb8d9d2cec2d8d75f47f9f58
This commit is contained in:
tengqm 2017-06-29 23:46:08 -04:00
parent fb090544f3
commit 7cf040ee4a
4 changed files with 154 additions and 19 deletions

View File

@ -1441,6 +1441,40 @@ class ShellTest(testtools.TestCase):
mock_print.assert_called_once_with(attrs, fields,
formatters=formatters)
def test_do_cluster_op(self):
service = mock.Mock()
args = {
'id': 'cluster1',
'operation': 'dance',
'params': ['style=tango']
}
args = self._make_args(args)
attrs = {
'style': 'tango'
}
service.perform_operation_on_cluster = mock.Mock()
sh.do_cluster_op(service, args)
service.perform_operation_on_cluster.assert_called_once_with(
'cluster1', 'dance', **attrs)
def test_do_cluster_op_not_found(self):
service = mock.Mock()
ex = exc.HTTPNotFound
service.perform_operation_on_cluster.side_effect = ex
args = {
'id': 'cluster1',
'operation': 'swim',
'params': []
}
args = self._make_args(args)
ex = self.assertRaises(exc.CommandError,
sh.do_cluster_op, service, args)
msg = _('Cluster "cluster1" is not found')
self.assertEqual(msg, six.text_type(ex))
@mock.patch.object(utils, 'print_list')
def test_do_node_list(self, mock_print):
service = mock.Mock()
@ -1529,6 +1563,31 @@ class ShellTest(testtools.TestCase):
sh.do_node_show(service, args)
mock_show.assert_called_once_with(service, 'node1', False)
@mock.patch.object(sh, '_show_node')
def test_do_node_update(self, mock_show):
service = mock.Mock()
args = {
'id': 'node_id',
'name': 'node1',
'role': 'master',
'profile': 'profile1',
'metadata': ['user=demo'],
}
args = self._make_args(args)
attrs = {
'name': 'node1',
'role': 'master',
'profile_id': 'profile1',
'metadata': {'user': 'demo'},
}
node = mock.Mock()
node.id = 'node_id'
service.get_node.return_value = node
sh.do_node_update(service, args)
service.get_node.assert_called_once_with('node_id')
service.update_node.assert_called_once_with(node, **attrs)
mock_show.assert_called_once_with(service, 'node_id')
def test_do_node_delete(self):
service = mock.Mock()
args = self._make_args({'id': ['node1']})
@ -1589,30 +1648,39 @@ class ShellTest(testtools.TestCase):
msg = _('Failed to recover some of the specified nodes.')
self.assertEqual(msg, six.text_type(ex))
@mock.patch.object(sh, '_show_node')
def test_do_node_update(self, mock_show):
def test_do_node_op(self):
service = mock.Mock()
args = {
'id': 'node_id',
'name': 'node1',
'role': 'master',
'profile': 'profile1',
'metadata': ['user=demo'],
'id': 'node1',
'operation': 'dance',
'params': ['style=tango']
}
args = self._make_args(args)
attrs = {
'name': 'node1',
'role': 'master',
'profile_id': 'profile1',
'metadata': {'user': 'demo'},
'style': 'tango'
}
node = mock.Mock()
node.id = 'node_id'
service.get_node.return_value = node
sh.do_node_update(service, args)
service.get_node.assert_called_once_with('node_id')
service.update_node.assert_called_once_with(node, **attrs)
mock_show.assert_called_once_with(service, 'node_id')
service.perform_operation_on_node = mock.Mock()
sh.do_node_op(service, args)
service.perform_operation_on_node.assert_called_once_with(
'node1', 'dance', **attrs)
def test_do_node_op_not_found(self):
service = mock.Mock()
ex = exc.HTTPNotFound
service.perform_operation_on_node.side_effect = ex
args = {
'id': 'node1',
'operation': 'swim',
'params': []
}
args = self._make_args(args)
ex = self.assertRaises(exc.CommandError,
sh.do_node_op, service, args)
msg = _('Node "node1" is not found')
self.assertEqual(msg, six.text_type(ex))
@mock.patch.object(utils, 'print_list')
def test_do_event_list(self, mock_print):

View File

@ -320,6 +320,16 @@ class Client(object):
"""
return self.service.recover_cluster(cluster, **params)
def perform_operation_on_cluster(self, cluster, operation, **params):
"""Perform an operation on a cluster.
Doc link:
https://developer.openstack.org/api-ref/clustering/
#perform-an-operation-on-a-cluster
"""
return self.service.perform_operation_on_cluster(cluster, operation,
**params)
def nodes(self, **queries):
"""List nodes
@ -377,6 +387,16 @@ class Client(object):
"""
return self.service.recover_node(node, **params)
def perform_operation_on_node(self, node, operation, **params):
"""Perform an operation on a node.
Doc link:
https://developer.openstack.org/api-ref/clustering/
#perform-an-operation-on-a-node
"""
return self.service.perform_operation_on_node(node, operation,
**params)
def receivers(self, **queries):
"""List receivers

View File

@ -1177,6 +1177,28 @@ def do_cluster_recover(service, args):
'action %(action)s.' % {'cid': cid, 'action': resp['action']})
@utils.arg('-p', '--params', metavar='<"KEY1=VALUE1;KEY2=VALUE2...">',
help=_("Parameter name and values for the operation specified. "
"This can be specified multiple times, or once with "
"key-value pairs separated by a semicolon."),
action='append')
@utils.arg('-o', '--operation', metavar='<OPERATION>',
help=_("Name of an operation to be executed on the cluster."))
@utils.arg('id', metavar='<CLUSTER>',
help=_('ID or name of a cluster.'))
def do_cluster_op(service, args):
"""Run an operation on a cluster."""
show_deprecated('senlin cluster-op', 'openstack cluster op')
params = utils.format_parameters(args.params)
try:
service.perform_operation_on_cluster(args.id, args.operation,
**params)
except exc.HTTPNotFound:
raise exc.CommandError(_('Cluster "%s" is not found') % args.id)
print('Request accepted')
# NODES
@ -1394,6 +1416,31 @@ def do_node_recover(service, args):
print('Request accepted')
@utils.arg('-p', '--params', metavar='<"KEY1=VALUE1;KEY2=VALUE2...">',
help=_("Parameter name and values for the operation specified. "
"This can be specified multiple times, or once with "
"key-value pairs separated by a semicolon."),
action='append')
@utils.arg('-o', '--operation', metavar='<OPERATION>',
help=_("Name of an operation to be executed on the node"))
@utils.arg('id', metavar='<NODE>',
help=_('ID or name of a node.'))
def do_node_op(service, args):
"""Run an operation on a node."""
show_deprecated('senlin node-op', 'openstack cluster node op')
if args.params:
params = utils.format_parameters(args.params)
else:
params = {}
try:
service.perform_operation_on_node(args.id, args.operation,
**params)
except exc.HTTPNotFound:
raise exc.CommandError(_('Node "%s" is not found') % args.id)
print('Request accepted')
# RECEIVERS

View File

@ -42,7 +42,7 @@ commands=
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html
[flake8]
ignore = D100,D101,D102,D103,D104,D105,D200,D201,D202,D204,D205,D300,D301,D400,D401
ignore = D100,D101,D102,D103,D104,D105,D200,D201,D202,D204,D205,D300,D301,D400,D401,I100,I201
show-source = True
enable-extensions = H203,H106
exclude=.venv,.git,.tox,dist,*lib/python*,*egg,build