Merge "Introduce hpOneView and ilorest to OneView"

This commit is contained in:
Jenkins 2017-09-06 15:13:17 +00:00 committed by Gerrit Code Review
commit e9318c7574
7 changed files with 152 additions and 1 deletions

View File

@ -9,6 +9,8 @@ pysnmp
python-ironic-inspector-client>=1.5.0
python-oneviewclient<3.0.0,>=2.5.2
python-scciclient>=0.5.0
python-ilorest-library>=1.9.2
hpOneView<4.0.0,>=3.2.1
UcsSdk==0.8.2.2
python-dracclient>=1.3.0

View File

@ -13,9 +13,9 @@
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from oslo_log import log as logging
from oslo_utils import importutils
from six.moves.urllib import parse
from ironic.common import exception
from ironic.common.i18n import _
@ -25,11 +25,18 @@ from ironic.drivers import utils
LOG = logging.getLogger(__name__)
# NOTE(mrtenio): hpOneView will be the default library for OneView. It
# is being introduced together with the python-oneviewclient to be used
# generally by other patches. python-oneviewclient will be removed
# subsequently.
client = importutils.try_import('oneview_client.client')
oneview_utils = importutils.try_import('oneview_client.utils')
oneview_states = importutils.try_import('oneview_client.states')
oneview_exceptions = importutils.try_import('oneview_client.exceptions')
hponeview_client = importutils.try_import('hpOneView.oneview_client')
redfish = importutils.try_import('redfish')
REQUIRED_ON_DRIVER_INFO = {
'server_hardware_uri': _("Server Hardware URI. Required in driver_info."),
}
@ -49,6 +56,8 @@ OPTIONAL_ON_PROPERTIES = {
"Enclosure Group URI. Optional in properties/capabilities."),
}
ILOREST_BASE_PORT = "443"
COMMON_PROPERTIES = {}
COMMON_PROPERTIES.update(REQUIRED_ON_DRIVER_INFO)
COMMON_PROPERTIES.update(REQUIRED_ON_PROPERTIES)
@ -83,6 +92,74 @@ def get_oneview_client():
return oneview_client
def prepare_manager_url(manager_url):
# NOTE(mrtenio) python-oneviewclient uses https or http in the manager_url
# while python-hpOneView does not. This will not be necessary when
# python-hpOneView client is the only OneView library.
if manager_url:
url_parse = parse.urlparse(manager_url)
manager_url = url_parse.netloc
return manager_url
def get_hponeview_client():
"""Generate an instance of the hpOneView client.
Generates an instance of the hpOneView client using the hpOneView library.
:returns: an instance of the OneViewClient
:raises: InvalidParameterValue if mandatory information is missing on the
node or on invalid input.
"""
manager_url = prepare_manager_url(CONF.oneview.manager_url)
config = {
"ip": manager_url,
"credentials": {
"userName": CONF.oneview.username,
"password": CONF.oneview.password
}
}
return hponeview_client.OneViewClient(config)
def get_ilorest_client(oneview_client, server_hardware):
"""Generate an instance of the iLORest library client.
:param oneview_client: an instance of a python-hpOneView
:param: server_hardware: a server hardware uuid or uri
:returns: an instance of the iLORest client
:raises: InvalidParameterValue if mandatory information is missing on the
node or on invalid input.
"""
remote_console = oneview_client.server_hardware.get_remote_console_url(
server_hardware
)
host_ip, ilo_token = _get_ilo_access(remote_console)
base_url = "https://%s:%s" % (host_ip, ILOREST_BASE_PORT)
return redfish.rest_client(base_url=base_url, sessionkey=ilo_token)
def _get_ilo_access(remote_console):
"""Get the needed information to access ilo.
Get the host_ip and a token of an iLO remote console instance which can be
used to perform operations on that controller.
The Remote Console url has the following format:
hplocons://addr=1.2.3.4&sessionkey=a79659e3b3b7c8209c901ac3509a6719
:param: remote_console: OneView Remote Console object with a
remoteConsoleUrl
:returns: A tuple with the Host IP and Token to access ilo, for
example: ('1.2.3.4', 'a79659e3b3b7c8209c901ac3509a6719')
"""
url = remote_console.get('remoteConsoleUrl')
url_parse = parse.urlparse(url)
host_ip = parse.parse_qs(url_parse.netloc).get('addr')[0]
token = parse.parse_qs(url_parse.netloc).get('sessionkey')[0]
return host_ip, token
def verify_node_info(node):
"""Verifies if fields and namespaces of a node are valid.

View File

@ -25,6 +25,7 @@ from ironic.tests.unit.db import base as db_base
from ironic.tests.unit.db import utils as db_utils
from ironic.tests.unit.objects import utils as obj_utils
hponeview_client = importutils.try_import('oneview_client.client')
oneview_states = importutils.try_import('oneview_client.states')
@ -58,6 +59,34 @@ class OneViewCommonTestCase(db_base.DbTestCase):
"server_hardware_type_uri"):
common.verify_node_info(self.node)
def test_prepare_manager_url(self):
self.assertEqual(
common.prepare_manager_url("https://1.2.3.4/"), "1.2.3.4")
self.assertEqual(
common.prepare_manager_url("http://oneview"), "oneview")
self.assertEqual(
common.prepare_manager_url("http://oneview:8080"), "oneview:8080")
self.assertEqual(
common.prepare_manager_url("http://oneview/something"), "oneview")
self.assertEqual(
common.prepare_manager_url("oneview/something"), "")
self.assertEqual(
common.prepare_manager_url("oneview"), "")
@mock.patch.object(hponeview_client, 'OneViewClient', spec_set=True,
autospec=True)
def test_get_hponeview_client(self, mock_hponeview_client):
common.get_hponeview_client()
mock_hponeview_client.assert_called_once_with(self.config)
def test_get_ilo_access(self):
url = ("hplocons://addr=1.2.3.4&sessionkey" +
"=a79659e3b3b7c8209c901ac3509a6719")
remote_console = {'remoteConsoleUrl': url}
host_ip, token = common._get_ilo_access(remote_console)
self.assertEqual(host_ip, "1.2.3.4")
self.assertEqual(token, "a79659e3b3b7c8209c901ac3509a6719")
def test_verify_node_info_missing_node_driver_info(self):
self.node.driver_info = {}

View File

@ -31,6 +31,7 @@ class AgentPXEOneViewInspectTestCase(db_base.DbTestCase):
def setUp(self):
super(AgentPXEOneViewInspectTestCase, self).setUp()
self.config(manager_url='https://1.2.3.4', group='oneview')
self.config(enabled=True, group='inspector')
mgr_utils.mock_the_extension_manager(driver="agent_pxe_oneview")
self.node = obj_utils.create_test_node(
@ -69,6 +70,7 @@ class ISCSIPXEOneViewInspectTestCase(db_base.DbTestCase):
def setUp(self):
super(ISCSIPXEOneViewInspectTestCase, self).setUp()
self.config(manager_url='https://1.2.3.4', group='oneview')
self.config(enabled=True, group='inspector')
mgr_utils.mock_the_extension_manager(driver="iscsi_pxe_oneview")
self.node = obj_utils.create_test_node(

View File

@ -143,6 +143,24 @@ ONEVIEWCLIENT_STATES_SPEC = (
'ONEVIEW_ERROR',
)
HPONEVIEW_SPEC = (
'oneview_client',
'resources',
'exceptions',
)
HPONEVIEW_CLS_SPEC = (
)
HPONEVIEW_STATES_SPEC = (
'ONEVIEW_POWER_OFF',
'ONEVIEW_POWERING_OFF',
'ONEVIEW_POWER_ON',
'ONEVIEW_POWERING_ON',
'ONEVIEW_RESETTING',
'ONEVIEW_ERROR',
)
SUSHY_CONSTANTS_SPEC = (
'BOOT_SOURCE_TARGET_PXE',
'BOOT_SOURCE_TARGET_HDD',

View File

@ -26,6 +26,7 @@ Current list of mocked libraries:
- pysnmp
- scciclient
- oneview_client
- hpOneView
- pywsman
- python-dracclient
"""
@ -99,6 +100,22 @@ if 'ironic.drivers.oneview' in sys.modules:
six.moves.reload_module(sys.modules['ironic.drivers.modules.oneview'])
hpOneView = importutils.try_import('hpOneView')
if not hpOneView:
hpOneView = mock.MagicMock(spec_set=mock_specs.HPONEVIEW_SPEC)
sys.modules['hpOneView'] = hpOneView
sys.modules['hpOneView.oneview_client'] = hpOneView.oneview_client
sys.modules['hpOneView.resources'] = hpOneView.resources
sys.modules['hpOneView.exceptions'] = hpOneView.exceptions
hpOneView.exceptions.HPOneViewException = type('HPOneViewException',
(Exception,), {})
sys.modules['hpOneView.oneview_client'].OneViewClient = mock.MagicMock(
spec_set=mock_specs.HPONEVIEW_CLS_SPEC
)
if 'ironic.drivers.oneview' in sys.modules:
six.moves.reload_module(sys.modules['ironic.drivers.modules.oneview'])
# attempt to load the external 'python-dracclient' library, which is required
# by the optional drivers.modules.drac module
dracclient = importutils.try_import('dracclient')

View File

@ -0,0 +1,6 @@
---
upgrade:
- |
Adds the ``hpOneView`` and ``ilorest`` library requirement
to the OneView Driver, in order to prepare for the eventual
removal of dependency on ``python-oneviewclient`` library.