Adds Node Vendor passthru

Implements: Adds node vendor passthru
Task: #40959
Story: #2008193
Change-Id: Ie63d8232fa86d93f0ae71d2e1bd808c80c8c93cf
This commit is contained in:
Kajal Sah 2021-04-08 22:13:56 +05:30
parent 2c5200748d
commit bf73fd91ad
4 changed files with 119 additions and 0 deletions

View File

@ -1014,6 +1014,25 @@ class Proxy(proxy.Proxy):
res = self._get_resource(_node.Node, node) res = self._get_resource(_node.Node, node)
return res.remove_trait(self, trait, ignore_missing=ignore_missing) return res.remove_trait(self, trait, ignore_missing=ignore_missing)
def call_node_vendor_passthru(self, node, verb, method, body=None):
"""Calls vendor_passthru for a node.
:param session: The session to use for making this request.
:param verb: The HTTP verb, one of GET, SET, POST, DELETE.
:param method: The method to call using vendor_passthru.
:param body: The JSON body in the HTTP call.
"""
res = self._get_resource(_node.Node, node)
return res.call_vendor_passthru(self, verb, method, body)
def list_node_vendor_passthru(self, node):
"""Lists vendor_passthru for a node.
:param session: The session to use for making this request.
"""
res = self._get_resource(_node.Node, node)
return res.list_vendor_passthru(self)
def set_node_traits(self, node, traits): def set_node_traits(self, node, traits):
"""Set traits for a node. """Set traits for a node.

View File

@ -920,6 +920,55 @@ class Node(_common.ListMixin, resource.Resource):
self.traits = traits self.traits = traits
def call_vendor_passthru(self, session, verb, method, body=None):
"""Call a vendor passthru method.
:param session: The session to use for making this request.
:param verb: The HTTP verb, one of GET, SET, POST, DELETE.
:param method: The method to call using vendor_passthru.
:param body: The JSON body in the HTTP call.
:returns: The HTTP response.
"""
session = self._get_session(session)
version = self._get_microversion_for(session, 'commit')
request = self._prepare_request(requires_id=True)
request.url = utils.urljoin(request.url, 'vendor_passthru?method={}'
.format(method))
call = getattr(session, verb.lower())
response = call(
request.url, json=body,
headers=request.headers, microversion=version,
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
msg = ("Failed to call vendor_passthru for node {node}, verb {verb}"
" and method {method}"
.format(node=self.id, verb=verb, method=method))
exceptions.raise_from_response(response, error_message=msg)
return response
def list_vendor_passthru(self, session):
"""List vendor passthru methods.
:param session: The session to use for making this request.
:returns: The HTTP response.
"""
session = self._get_session(session)
version = self._get_microversion_for(session, 'fetch')
request = self._prepare_request(requires_id=True)
request.url = utils.urljoin(request.url, 'vendor_passthru/methods')
response = session.get(
request.url, headers=request.headers, microversion=version,
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
msg = ("Failed to list vendor_passthru methods for node {node}"
.format(node=self.id))
exceptions.raise_from_response(response, error_message=msg)
return response.json()
def patch(self, session, patch=None, prepend_key=True, has_body=True, def patch(self, session, patch=None, prepend_key=True, has_body=True,
retry_on_conflict=None, base_path=None, reset_interfaces=None): retry_on_conflict=None, base_path=None, reset_interfaces=None):

View File

@ -840,3 +840,50 @@ class TestNodeWaitForPowerState(base.TestCase):
self.assertRaises(exceptions.ResourceTimeout, self.assertRaises(exceptions.ResourceTimeout,
self.node.wait_for_power_state, self.node.wait_for_power_state,
self.session, 'power off', timeout=0.001) self.session, 'power off', timeout=0.001)
@mock.patch.object(utils, 'pick_microversion', lambda session, v: v)
@mock.patch.object(node.Node, 'fetch', lambda self, session: self)
@mock.patch.object(exceptions, 'raise_from_response', mock.Mock())
class TestNodePassthru(object):
def setUp(self):
super(TestNodePassthru, self).setUp()
self.node = node.Node(**FAKE)
self.session = node.Mock(spec=adapter.Adapter,
default_microversion='1.37')
self.session.log = mock.Mock()
def test_get_passthru(self):
self.node.call_vendor_passthru(self.session, "GET", "test_method")
self.session.get.assert_called_once_with(
'nodes/%s/vendor_passthru?method=test_method' % self.node.id,
headers=mock.ANY, microversion='1.37',
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
def test_post_passthru(self):
self.node.call_vendor_passthru(self.session, "POST", "test_method")
self.session.post.assert_called_once_with(
'nodes/%s/vendor_passthru?method=test_method' % self.node.id,
headers=mock.ANY, microversion='1.37',
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
def test_put_passthru(self):
self.node.call_vendor_passthru(self.session, "PUT", "test_method")
self.session.put.assert_called_once_with(
'nodes/%s/vendor_passthru?method=test_method' % self.node.id,
headers=mock.ANY, microversion='1.37',
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
def test_delete_passthru(self):
self.node.call_vendor_passthru(self.session, "DELETE", "test_method")
self.session.delete.assert_called_once_with(
'nodes/%s/vendor_passthru?method=test_method' % self.node.id,
headers=mock.ANY, microversion='1.37',
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)
def test_list_passthru(self):
self.node.list_vendor_passthru(self.session)
self.session.get.assert_called_once_with(
'nodes/%s/vendor_passthru/methods' % self.node.id,
headers=mock.ANY, microversion='1.37',
retriable_status_codes=_common.RETRIABLE_STATUS_CODES)

View File

@ -0,0 +1,4 @@
---
features:
- |
Add node vendor_passthru interface for Ironic API.