Adding check/recover actions to cluster nodes
This patch adds node check and recover into the cluster service. Implements: blueprint support-health-management-customization Change-Id: I4a756f6e5ca63dbd82e0803d66184a53f6a9dcf0
This commit is contained in:
@@ -405,6 +405,28 @@ class Proxy(proxy.BaseProxy):
|
|||||||
"""
|
"""
|
||||||
self._delete(_node.Node, node, ignore_missing=ignore_missing)
|
self._delete(_node.Node, node, ignore_missing=ignore_missing)
|
||||||
|
|
||||||
|
def check_node(self, node, **params):
|
||||||
|
"""check a node.
|
||||||
|
|
||||||
|
:param node: The value can be either the ID of a node or a
|
||||||
|
:class:`~openstack.cluster.v1.node.Node` instance.
|
||||||
|
|
||||||
|
:returns: A dictionary containing the action ID.
|
||||||
|
"""
|
||||||
|
obj = self._get_resource(_node.Node, node)
|
||||||
|
return obj.check(self.session, **params)
|
||||||
|
|
||||||
|
def recover_node(self, node, **params):
|
||||||
|
"""recover a node.
|
||||||
|
|
||||||
|
:param node: The value can be either the ID of a node or a
|
||||||
|
:class:`~openstack.cluster.v1.node.Node` instance.
|
||||||
|
|
||||||
|
:returns: A dictionary containing the action ID.
|
||||||
|
"""
|
||||||
|
obj = self._get_resource(_node.Node, node)
|
||||||
|
return obj.recover(self.session, **params)
|
||||||
|
|
||||||
def find_node(self, name_or_id, ignore_missing=True):
|
def find_node(self, name_or_id, ignore_missing=True):
|
||||||
"""Find a single node.
|
"""Find a single node.
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ from openstack.cluster import cluster_service
|
|||||||
from openstack.cluster.v1 import cluster as _cluster
|
from openstack.cluster.v1 import cluster as _cluster
|
||||||
from openstack.cluster.v1 import profile as _profile
|
from openstack.cluster.v1 import profile as _profile
|
||||||
from openstack import resource
|
from openstack import resource
|
||||||
|
from openstack import utils
|
||||||
|
|
||||||
|
|
||||||
class Node(resource.Resource):
|
class Node(resource.Resource):
|
||||||
@@ -68,3 +69,35 @@ class Node(resource.Resource):
|
|||||||
#: A map containing the details of the physical object this node
|
#: A map containing the details of the physical object this node
|
||||||
#: represents
|
#: represents
|
||||||
details = resource.prop('details', type=dict)
|
details = resource.prop('details', type=dict)
|
||||||
|
|
||||||
|
def _action(self, session, body):
|
||||||
|
"""Procedure the invoke an action API.
|
||||||
|
|
||||||
|
:param session: A session object used for sending request.
|
||||||
|
:param body: The body of action to be sent.
|
||||||
|
"""
|
||||||
|
url = utils.urljoin(self.base_path, self.id, 'actions')
|
||||||
|
resp = session.post(url, endpoint_filter=self.service, json=body)
|
||||||
|
return resp.json
|
||||||
|
|
||||||
|
def check(self, session, **params):
|
||||||
|
"""An action procedure for the node to check its health status.
|
||||||
|
|
||||||
|
:param session: A session object used for sending request.
|
||||||
|
:returns: A dictionary containing the action ID.
|
||||||
|
"""
|
||||||
|
body = {
|
||||||
|
'check': params
|
||||||
|
}
|
||||||
|
return self._action(session, body)
|
||||||
|
|
||||||
|
def recover(self, session, **params):
|
||||||
|
"""An action procedure for the node to recover.
|
||||||
|
|
||||||
|
:param session: A session object used for sending request.
|
||||||
|
:returns: A dictionary containing the action ID.
|
||||||
|
"""
|
||||||
|
body = {
|
||||||
|
'recover': params
|
||||||
|
}
|
||||||
|
return self._action(session, body)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import mock
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from openstack.cluster.v1 import node
|
from openstack.cluster.v1 import node
|
||||||
@@ -78,3 +79,31 @@ class TestNode(testtools.TestCase):
|
|||||||
self.assertEqual(FAKE['index'], sot.index)
|
self.assertEqual(FAKE['index'], sot.index)
|
||||||
self.assertEqual(FAKE['role'], sot.role)
|
self.assertEqual(FAKE['role'], sot.role)
|
||||||
self.assertEqual(FAKE['metadata'], sot.metadata)
|
self.assertEqual(FAKE['metadata'], sot.metadata)
|
||||||
|
|
||||||
|
def test_check(self):
|
||||||
|
sot = node.Node(FAKE)
|
||||||
|
sot['id'] = 'IDENTIFIER'
|
||||||
|
|
||||||
|
resp = mock.Mock()
|
||||||
|
resp.json = {'action': '1234-5678-abcd'}
|
||||||
|
sess = mock.Mock()
|
||||||
|
sess.post = mock.Mock(return_value=resp)
|
||||||
|
self.assertEqual(resp.json, sot.check(sess))
|
||||||
|
url = 'nodes/%s/actions' % sot.id
|
||||||
|
body = {'check': {}}
|
||||||
|
sess.post.assert_called_once_with(url, endpoint_filter=sot.service,
|
||||||
|
json=body)
|
||||||
|
|
||||||
|
def test_recover(self):
|
||||||
|
sot = node.Node(FAKE)
|
||||||
|
sot['id'] = 'IDENTIFIER'
|
||||||
|
|
||||||
|
resp = mock.Mock()
|
||||||
|
resp.json = {'action': '2345-6789-bbbb'}
|
||||||
|
sess = mock.Mock()
|
||||||
|
sess.post = mock.Mock(return_value=resp)
|
||||||
|
self.assertEqual(resp.json, sot.recover(sess))
|
||||||
|
url = 'nodes/%s/actions' % sot.id
|
||||||
|
body = {'recover': {}}
|
||||||
|
sess.post.assert_called_once_with(url, endpoint_filter=sot.service,
|
||||||
|
json=body)
|
||||||
|
|||||||
@@ -285,6 +285,24 @@ class TestClusterProxy(test_proxy_base.TestProxyBase):
|
|||||||
def test_node_update(self):
|
def test_node_update(self):
|
||||||
self.verify_update(self.proxy.update_node, node.Node)
|
self.verify_update(self.proxy.update_node, node.Node)
|
||||||
|
|
||||||
|
@mock.patch.object(proxy_base.BaseProxy, '_get_resource')
|
||||||
|
def test_node_check(self, mock_get):
|
||||||
|
mock_node = node.Node.from_id('FAKE_NODE')
|
||||||
|
mock_get.return_value = mock_node
|
||||||
|
self._verify("openstack.cluster.v1.node.Node.check",
|
||||||
|
self.proxy.check_node,
|
||||||
|
method_args=["FAKE_NODE"])
|
||||||
|
mock_get.assert_called_once_with(node.Node, "FAKE_NODE")
|
||||||
|
|
||||||
|
@mock.patch.object(proxy_base.BaseProxy, '_get_resource')
|
||||||
|
def test_node_recover(self, mock_get):
|
||||||
|
mock_node = node.Node.from_id('FAKE_NODE')
|
||||||
|
mock_get.return_value = mock_node
|
||||||
|
self._verify("openstack.cluster.v1.node.Node.recover",
|
||||||
|
self.proxy.recover_node,
|
||||||
|
method_args=["FAKE_NODE"])
|
||||||
|
mock_get.assert_called_once_with(node.Node, "FAKE_NODE")
|
||||||
|
|
||||||
def test_policy_create(self):
|
def test_policy_create(self):
|
||||||
self.verify_create(self.proxy.create_policy, policy.Policy)
|
self.verify_create(self.proxy.create_policy, policy.Policy)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user