Merge "Redfish: Adds HPEConnector to proliantutils"
This commit is contained in:
commit
5e2343e4bb
|
@ -0,0 +1,47 @@
|
|||
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
__author__ = 'HPE'
|
||||
|
||||
import retrying
|
||||
from sushy import connector
|
||||
from sushy import exceptions
|
||||
|
||||
|
||||
class HPEConnector(connector.Connector):
|
||||
"""Class that extends base Sushy Connector class
|
||||
|
||||
This class extends the Sushy's Connector class to override certain methods
|
||||
required to customize the functionality of the http operations.
|
||||
"""
|
||||
|
||||
MAX_RETRY_ATTEMPTS = 3 # Maximum number of attempts to be retried
|
||||
MAX_TIME_BEFORE_RETRY = 2 * 1000 # wait time in milliseconds before retry
|
||||
|
||||
@retrying.retry(
|
||||
retry_on_exception=(
|
||||
lambda e: isinstance(e, exceptions.ConnectionError)),
|
||||
stop_max_attempt_number=MAX_RETRY_ATTEMPTS,
|
||||
wait_fixed=MAX_TIME_BEFORE_RETRY)
|
||||
def _op(self, method, path='', data=None, headers=None):
|
||||
"""Overrides the base method to support retrying the operation.
|
||||
|
||||
:param method: The HTTP method to be used, e.g: GET, POST,
|
||||
PUT, PATCH, etc...
|
||||
:param path: The sub-URI path to the resource.
|
||||
:param data: Optional JSON data.
|
||||
:param headers: Optional dictionary of headers.
|
||||
:returns: The response from the connector.Connector's _op method.
|
||||
"""
|
||||
return super(HPEConnector, self)._op(method, path, data, headers)
|
|
@ -16,6 +16,7 @@ __author__ = 'HPE'
|
|||
|
||||
import sushy
|
||||
|
||||
from proliantutils.redfish import connector
|
||||
from proliantutils.redfish.resources.account_service import account_service
|
||||
from proliantutils.redfish.resources.manager import manager
|
||||
from proliantutils.redfish.resources.system import system
|
||||
|
@ -27,9 +28,35 @@ class HPESushy(sushy.Sushy):
|
|||
"""Class that extends base Sushy class
|
||||
|
||||
This class extends the Sushy class to override certain methods
|
||||
required to customize the functionality of different resources
|
||||
required to customize the functionality of different resources.
|
||||
It bypasses the initialization of the Sushy class and initializes
|
||||
the ResourceBase class with customized HPE specific connector subtype.
|
||||
"""
|
||||
|
||||
def __init__(self, base_url, username=None, password=None,
|
||||
root_prefix='/redfish/v1/', verify=True):
|
||||
"""Initializes HPE specific sushy object.
|
||||
|
||||
:param base_url: The base URL to the Redfish controller. It
|
||||
should include scheme and authority portion of the URL. For
|
||||
example: https://mgmt.vendor.com
|
||||
:param username: User account with admin/server-profile access
|
||||
privilege
|
||||
:param password: User account password
|
||||
:param root_prefix: The default URL prefix. This part includes
|
||||
the root service and version. Defaults to /redfish/v1
|
||||
:param verify: Either a boolean value, a path to a CA_BUNDLE
|
||||
file or directory with certificates of trusted CAs. If set to
|
||||
True the driver will verify the host certificates; if False
|
||||
the driver will ignore verifying the SSL certificate; if it's
|
||||
a path the driver will use the specified certificate or one of
|
||||
the certificates in the directory. Defaults to True.
|
||||
"""
|
||||
self._root_prefix = root_prefix
|
||||
super(sushy.Sushy, self).__init__(
|
||||
connector.HPEConnector(base_url, username, password, verify),
|
||||
path=self._root_prefix)
|
||||
|
||||
def get_system_collection_path(self):
|
||||
return utils.get_subresource_path_by(self, 'Systems')
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# Copyright 2017 Hewlett Packard Enterprise Development LP
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
from sushy import connector
|
||||
from sushy import exceptions
|
||||
import testtools
|
||||
|
||||
from proliantutils.redfish import connector as hpe_connector
|
||||
|
||||
|
||||
class HPEConnectorTestCase(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(HPEConnectorTestCase, self).setUp()
|
||||
|
||||
@mock.patch.object(connector.Connector, '_op', autospec=True)
|
||||
def test__op_no_exception(self, conn_mock):
|
||||
conn_mock.side_effect = ["Hello", exceptions.ConnectionError,
|
||||
"Hello", "World"]
|
||||
|
||||
hpe_conn = hpe_connector.HPEConnector(
|
||||
'http://foo.bar:1234', username='user',
|
||||
password='pass', verify=True)
|
||||
headers = {'X-Fake': 'header'}
|
||||
hpe_conn._op('GET', path='fake/path', data=None, headers=headers)
|
||||
conn_mock.assert_called_once_with(hpe_conn, 'GET', path='fake/path',
|
||||
data=None, headers=headers)
|
||||
self.assertEqual(1, conn_mock.call_count)
|
||||
|
||||
@mock.patch.object(connector.Connector, '_op', autospec=True)
|
||||
def test__op_with_exception(self, conn_mock):
|
||||
conn_mock.side_effect = [exceptions.ConnectionError,
|
||||
exceptions.ConnectionError, "Hello", "World"]
|
||||
|
||||
hpe_conn = hpe_connector.HPEConnector(
|
||||
'http://foo.bar:1234', username='user',
|
||||
password='pass', verify=True)
|
||||
headers = {'X-Fake': 'header'}
|
||||
lval = hpe_conn._op('GET', path='fake/path', data=None,
|
||||
headers=headers)
|
||||
self.assertEqual(3, conn_mock.call_count)
|
||||
self.assertEqual(lval, "Hello")
|
||||
|
||||
@mock.patch.object(connector.Connector, '_op', autospec=True)
|
||||
def test__op_all_exception(self, conn_mock):
|
||||
conn_mock.side_effect = [
|
||||
exceptions.ConnectionError] * (
|
||||
hpe_connector.HPEConnector.MAX_RETRY_ATTEMPTS) + (
|
||||
["Hello", "World"])
|
||||
|
||||
hpe_conn = hpe_connector.HPEConnector(
|
||||
'http://foo.bar:1234', username='user',
|
||||
password='pass', verify=True)
|
||||
headers = {'X-Fake': 'header'}
|
||||
self.assertRaises(
|
||||
exceptions.ConnectionError, hpe_conn._op,
|
||||
'GET', path='fake/path', data=None, headers=headers)
|
||||
self.assertEqual(hpe_connector.HPEConnector.MAX_RETRY_ATTEMPTS,
|
||||
conn_mock.call_count)
|
|
@ -16,10 +16,10 @@
|
|||
import json
|
||||
|
||||
import mock
|
||||
from sushy import connector
|
||||
import testtools
|
||||
|
||||
from proliantutils import exception
|
||||
from proliantutils.redfish import connector
|
||||
from proliantutils.redfish import main
|
||||
from proliantutils.redfish.resources.account_service import account_service
|
||||
from proliantutils.redfish.resources.manager import manager
|
||||
|
@ -29,7 +29,7 @@ from proliantutils.redfish.resources import update_service
|
|||
|
||||
class HPESushyTestCase(testtools.TestCase):
|
||||
|
||||
@mock.patch.object(connector, 'Connector', autospec=True)
|
||||
@mock.patch.object(connector, 'HPEConnector', autospec=True)
|
||||
def setUp(self, connector_mock):
|
||||
super(HPESushyTestCase, self).setUp()
|
||||
with open('proliantutils/tests/redfish/'
|
||||
|
|
Loading…
Reference in New Issue