diff options
author | Julia Kreger <juliaashleykreger@gmail.com> | 2018-08-31 11:34:57 -0700 |
---|---|---|
committer | Julia Kreger <juliaashleykreger@gmail.com> | 2018-10-15 16:32:15 -0700 |
commit | abb086577158df99ca36275adf96b75457dca742 (patch) | |
tree | 407cec5a6d2aece22961466a4ae118727947e40d /ironic | |
parent | bce7822a738b799fb3f0b3e0a932b6b245870974 (diff) | |
download | ironic-abb086577158df99ca36275adf96b75457dca742.tar.gz |
Remove oneview drivers
In accordance with the deprecation of oneview,
It is time to remove the oneview drivers.
This patch oneview interfaces and documentation.
Change-Id: Ided79fa788411f839614813ff033c42a13b88c75
Story: #2001924
Task: #24943
Diffstat (limited to 'ironic')
23 files changed, 2 insertions, 4109 deletions
diff --git a/ironic/common/exception.py b/ironic/common/exception.py index 62a685da4..90ae3b1ef 100644 --- a/ironic/common/exception.py +++ b/ironic/common/exception.py @@ -693,15 +693,6 @@ class CIMCException(DriverOperationError): _msg_fmt = _("Cisco IMC exception occurred for node %(node)s: %(error)s") -class OneViewError(DriverOperationError): - _msg_fmt = _("OneView exception occurred. Error: %(error)s") - - -class OneViewInvalidNodeParameter(OneViewError): - _msg_fmt = _("Error while obtaining OneView info from node %(node_uuid)s. " - "Error: %(error)s") - - class NodeTagNotFound(IronicException): _msg_fmt = _("Node %(node_id)s doesn't have a tag '%(tag)s'") diff --git a/ironic/conf/__init__.py b/ironic/conf/__init__.py index 3b63a40af..d3fd5e90b 100644 --- a/ironic/conf/__init__.py +++ b/ironic/conf/__init__.py @@ -38,7 +38,6 @@ from ironic.conf import iscsi from ironic.conf import metrics from ironic.conf import metrics_statsd from ironic.conf import neutron -from ironic.conf import oneview from ironic.conf import pxe from ironic.conf import redfish from ironic.conf import service_catalog @@ -71,7 +70,6 @@ iscsi.register_opts(CONF) metrics.register_opts(CONF) metrics_statsd.register_opts(CONF) neutron.register_opts(CONF) -oneview.register_opts(CONF) pxe.register_opts(CONF) redfish.register_opts(CONF) service_catalog.register_opts(CONF) diff --git a/ironic/conf/oneview.py b/ironic/conf/oneview.py deleted file mode 100644 index 77f071015..000000000 --- a/ironic/conf/oneview.py +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright 2016 Intel Corporation -# Copyright 2015 Hewlett Packard Development Company, LP -# Copyright 2015 Universidade Federal de Campina Grande -# -# 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. - -from oslo_config import cfg - -from ironic.common.i18n import _ - -opts = [ - cfg.StrOpt('manager_url', - help=_('URL where OneView is available.')), - cfg.StrOpt('username', - help=_('OneView username to be used.')), - cfg.StrOpt('password', - secret=True, - help=_('OneView password to be used.')), - cfg.BoolOpt('allow_insecure_connections', - default=False, - help=_('Option to allow insecure connection with OneView.')), - cfg.StrOpt('tls_cacert_file', - help=_('Path to CA certificate.')), - cfg.BoolOpt('enable_periodic_tasks', - default=True, - help=_('Whether to enable the periodic tasks for OneView ' - 'driver be aware when OneView hardware resources are ' - 'taken and released by Ironic or OneView users ' - 'and proactively manage nodes in clean fail state ' - 'according to Dynamic Allocation model of hardware ' - 'resources allocation in OneView.')), - cfg.IntOpt('periodic_check_interval', - default=300, - help=_('Period (in seconds) for periodic tasks to be ' - 'executed when enable_periodic_tasks=True.')), -] - - -def register_opts(conf): - conf.register_opts(opts, group='oneview') diff --git a/ironic/conf/opts.py b/ironic/conf/opts.py index 483a7f014..aa0e5786f 100644 --- a/ironic/conf/opts.py +++ b/ironic/conf/opts.py @@ -56,7 +56,6 @@ _opts = [ ('metrics', ironic.conf.metrics.opts), ('metrics_statsd', ironic.conf.metrics_statsd.opts), ('neutron', ironic.conf.neutron.list_opts()), - ('oneview', ironic.conf.oneview.opts), ('pxe', ironic.conf.pxe.opts), ('service_catalog', ironic.conf.service_catalog.list_opts()), ('snmp', ironic.conf.snmp.opts), diff --git a/ironic/drivers/modules/oneview/__init__.py b/ironic/drivers/modules/oneview/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/ironic/drivers/modules/oneview/__init__.py +++ /dev/null diff --git a/ironic/drivers/modules/oneview/common.py b/ironic/drivers/modules/oneview/common.py deleted file mode 100644 index 893fd4bda..000000000 --- a/ironic/drivers/modules/oneview/common.py +++ /dev/null @@ -1,553 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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 re - -from oslo_log import log as logging -from oslo_serialization import jsonutils -from oslo_utils import importutils -from six.moves.urllib import parse - -from ironic.common import exception -from ironic.common.i18n import _ -from ironic.conf import CONF -from ironic.drivers import utils - -LOG = logging.getLogger(__name__) - -hponeview_client = importutils.try_import('hpOneView.oneview_client') -redfish = importutils.try_import('redfish') -client_exception = importutils.try_import('hpOneView.exceptions') - -REQUIRED_ON_DRIVER_INFO = { - 'server_hardware_uri': _("Server Hardware URI. Required in driver_info."), -} - -REQUIRED_ON_PROPERTIES = { - 'server_hardware_type_uri': _( - "Server Hardware Type URI. Required in properties/capabilities." - ), - 'server_profile_template_uri': _( - "Server Profile Template URI to clone from. " - "Required in properties/capabilities." - ), -} - -OPTIONAL_ON_PROPERTIES = { - 'enclosure_group_uri': _( - "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) -COMMON_PROPERTIES.update(OPTIONAL_ON_PROPERTIES) - -# NOTE(xavierr): We don't want to translate NODE_IN_USE_BY_ONEVIEW and -# SERVER_HARDWARE_ALLOCATION_ERROR to avoid inconsistency in the nodes -# caused by updates on translation in upgrades of ironic. -NODE_IN_USE_BY_ONEVIEW = 'node in use by OneView' -SERVER_HARDWARE_ALLOCATION_ERROR = 'server hardware allocation error' - - -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_match = "^(http[s]?://)?([^/]+)(/.*)?$" - manager_url = re.search(url_match, manager_url).group(2) - 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. - :raises: OneViewError if try a secure connection without CA certificate. - """ - manager_url = prepare_manager_url(CONF.oneview.manager_url) - - insecure = CONF.oneview.allow_insecure_connections - ssl_certificate = CONF.oneview.tls_cacert_file - - if not (insecure or ssl_certificate): - msg = _("TLS CA certificate to connect with OneView is missing.") - raise exception.OneViewError(error=msg) - - # NOTE(nicodemos) Ignore the CA certificate if it's an insecure connection - if insecure and ssl_certificate: - LOG.warning("Performing an insecure connection with OneView, the CA " - "certificate file: %s will be ignored.", ssl_certificate) - ssl_certificate = None - - config = { - "ip": manager_url, - "credentials": { - "userName": CONF.oneview.username, - "password": CONF.oneview.password - }, - "ssl_certificate": ssl_certificate - } - return hponeview_client.OneViewClient(config) - - -def get_ilorest_client(server_hardware): - """Generate an instance of the iLORest library client. - - :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. - """ - oneview_client = get_hponeview_client() - 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. - - Verifies if the 'driver_info' field and the 'properties/capabilities' - namespace exist and are not empty. - - :param: node: node object to be verified - :raises: InvalidParameterValue if required node capabilities and/or - driver_info are malformed or missing - :raises: MissingParameterValue if required node capabilities and/or - driver_info are missing - """ - capabilities_dict = utils.capabilities_to_dict( - node.properties.get('capabilities', '') - ) - driver_info = node.driver_info - - _verify_node_info('properties/capabilities', capabilities_dict, - REQUIRED_ON_PROPERTIES) - - _verify_node_info('driver_info', driver_info, - REQUIRED_ON_DRIVER_INFO) - - -def get_oneview_info(node): - """Gets OneView information from the node. - - :param: node: node object to get information from - :returns: a dictionary containing: - :param server_hardware_uri: the uri of the server hardware in OneView - :param server_hardware_type_uri: the uri of the server hardware type in - OneView - :param enclosure_group_uri: the uri of the enclosure group in OneView - :server_profile_template_uri: the uri of the server profile template in - OneView - :raises: OneViewInvalidNodeParameter if node capabilities are malformed - """ - - try: - capabilities_dict = utils.capabilities_to_dict( - node.properties.get('capabilities', '') - ) - except exception.InvalidParameterValue as e: - raise exception.OneViewInvalidNodeParameter(node_uuid=node.uuid, - error=e) - - driver_info = node.driver_info - - oneview_info = { - 'server_hardware_uri': - driver_info.get('server_hardware_uri'), - 'server_hardware_type_uri': - capabilities_dict.get('server_hardware_type_uri'), - 'enclosure_group_uri': - capabilities_dict.get('enclosure_group_uri'), - 'server_profile_template_uri': - capabilities_dict.get('server_profile_template_uri'), - 'applied_server_profile_uri': - driver_info.get('applied_server_profile_uri'), - } - - return oneview_info - - -def validate_oneview_resources_compatibility(task): - """Validate if the node configuration is consistent with OneView. - - This method calls hpOneView functions to validate if the node - configuration is consistent with the OneView resources it represents, - including serverHardwareUri, serverHardwareTypeUri, serverGroupUri - serverProfileTemplateUri, enclosureGroupUri and node ports. If any - validation fails, the driver will raise an appropriate OneViewError. - - :param task: a TaskManager instance containing the node to act on. - :raises: OneViewError if any validation fails. - """ - ports = task.ports - oneview_client = get_hponeview_client() - oneview_info = get_oneview_info(task.node) - - _validate_node_server_profile_template(oneview_client, oneview_info) - _validate_node_server_hardware_type(oneview_client, oneview_info) - _validate_node_enclosure_group(oneview_client, oneview_info) - _validate_server_profile_template_mac_type(oneview_client, oneview_info) - _validate_node_port_mac_server_hardware( - oneview_client, oneview_info, ports) - - -def _verify_node_info(node_namespace, node_info_dict, info_required): - """Verify if info_required is present in node_namespace of the node info. - - """ - missing_keys = set(info_required) - set(node_info_dict) - - if missing_keys: - raise exception.MissingParameterValue( - _("Missing the keys for the following OneView data in node's " - "%(namespace)s: %(missing_keys)s.") % - {'namespace': node_namespace, - 'missing_keys': ', '.join(missing_keys) - } - ) - - # False and 0 can still be considered as valid values - missing_values_keys = [k for k in info_required - if node_info_dict[k] in ('', None)] - if missing_values_keys: - missing_keys = ["%s:%s" % (node_namespace, k) - for k in missing_values_keys] - raise exception.MissingParameterValue( - _("Missing parameter value for: '%s'") % "', '".join(missing_keys) - ) - - -def node_has_server_profile(func): - """Checks if the node's Server Hardware has a Server Profile associated. - - Decorator to execute before the function execution if the Server Profile - is applied to the Server Hardware. - - :param func: a given decorated function. - """ - def inner(self, *args, **kwargs): - task = args[0] - ensure_server_profile(task) - return func(self, *args, **kwargs) - return inner - - -def ensure_server_profile(task): - """Checks if the node's Server Hardware has a Server Profile associated. - - Function to check if the Server Profile is applied to the Server Hardware. - - :param task: a TaskManager instance containing the node to act on. - :raises: OneViewError if failed to get server profile from OneView - """ - oneview_client = get_hponeview_client() - try: - profile_uri = task.node.driver_info.get('applied_server_profile_uri') - oneview_client.server_profiles.get(profile_uri) - except client_exception.HPOneViewException as exc: - LOG.error( - "Failed to get server profile: %(profile)s from OneView appliance " - "for node %(node)s. Error: %(message)s", { - "profile": profile_uri, - "node": task.node.uuid, - "message": exc - } - ) - raise exception.OneViewError(error=exc) - - -def _get_server_hardware_mac_from_ilo(server_hardware): - """Get the MAC of Server Hardware's iLO controller. - - :param: server_hardware: a server hardware uuid or uri - :returns: MAC of Server Hardware's iLO controller. - :raises: InvalidParameterValue if required iLO credentials are missing. - :raises: OneViewError if can't get mac from a server hardware via iLO or - if fails to get JSON object with the default path. - """ - try: - ilo_client = get_ilorest_client(server_hardware) - ilo_path = "/rest/v1/systems/1" - hardware = jsonutils.loads(ilo_client.get(ilo_path).text) - hardware_mac = hardware['HostCorrelation']['HostMACAddress'][0] - except redfish.JsonDecodingError as exc: - LOG.error("Failed in JSON object getting path: %s", ilo_path) - raise exception.OneViewError(error=exc) - except (ValueError, TypeError, IndexError) as exc: - LOG.exception( - "Failed to get mac from server hardware %(server_hardware)s " - "via iLO. Error: %(message)s", { - "server_hardware": server_hardware.get("uri"), - "message": exc - } - ) - raise exception.OneViewError(error=exc) - - return hardware_mac - - -def _get_server_hardware_mac(server_hardware): - """Get the MAC address of the first PXE bootable port of an Ethernet port. - - :param server_hardware: OneView Server Hardware object. - :returns: MAC of the first Ethernet and function 'a' port of the - Server Hardware object. - :raises: OneViewError if there is no Ethernet port on the Server Hardware - or if there is no portMap on the Server Hardware requested. - """ - sh_physical_port = None - - if server_hardware.get('portMap'): - for device in server_hardware.get( - 'portMap', {}).get('deviceSlots', ()): - for physical_port in device.get('physicalPorts', ()): - if physical_port.get('type') == 'Ethernet': - sh_physical_port = physical_port - break - if sh_physical_port: - for virtual_port in sh_physical_port.get('virtualPorts', ()): - # NOTE(nicodemos): Ironic oneview drivers needs to use a - # port that type is Ethernet and function identifier 'a' for - # this FlexNIC to be able to make a deploy using PXE. - if virtual_port.get('portFunction') == 'a': - return virtual_port.get('mac', ()).lower() - raise exception.OneViewError( - _("There is no Ethernet port on the Server Hardware: %s") % - server_hardware.get('uri')) - else: - raise exception.OneViewError( - _("The Server Hardware: %s doesn't have a list of adapters/slots, " - "their ports and attributes. This information is available only " - "for blade servers. Is this a rack server?") % - server_hardware.get('uri')) - - -def _validate_node_server_profile_template(oneview_client, oneview_info): - """Validate if the Server Profile Template is consistent. - - :param oneview_client: an instance of the HPE OneView client. - :param oneview_info: the OneView related info in an Ironic node. - :raises: OneViewError if the node's Server Profile Template is not - consistent. - """ - server_profile_template = oneview_client.server_profile_templates.get( - oneview_info['server_profile_template_uri']) - server_hardware = oneview_client.server_hardware.get( - oneview_info['server_hardware_uri']) - - _validate_server_profile_template_server_hardware_type( - server_profile_template, server_hardware) - _validate_spt_enclosure_group(server_profile_template, server_hardware) - _validate_server_profile_template_manage_boot(server_profile_template) - - -def _validate_server_profile_template_server_hardware_type( - server_profile_template, server_hardware): - """Validate if the Server Hardware Types are the same. - - Validate if the Server Profile Template and the Server Hardware have the - same Server Hardware Type. - - :param server_profile_template: OneView Server Profile Template object. - :param server_hardware: OneView Server Hardware object. - :raises: OneViewError if the Server Profile Template and the Server - Hardware does not have the same Server Hardware Type. - """ - spt_server_hardware_type_uri = ( - server_profile_template.get('serverHardwareTypeUri') - ) - sh_server_hardware_type_uri = server_hardware.get('serverHardwareTypeUri') - - if spt_server_hardware_type_uri != sh_server_hardware_type_uri: - message = _( - "Server profile template %(spt_uri)s serverHardwareTypeUri is " - "inconsistent with server hardware %(server_hardware_uri)s " - "serverHardwareTypeUri.") % { - 'spt_uri': server_profile_template.get('uri'), - 'server_hardware_uri': server_hardware.get('uri')} - raise exception.OneViewError(message) - - -def _validate_spt_enclosure_group(server_profile_template, server_hardware): - """Validate Server Profile Template's Enclosure Group and Hardware's. - - :param server_profile_template: OneView Server Profile Template object. - :param server_hardware: OneView Server Hardware object. - :raises: OneViewError if the Server Profile Template's Enclosure Group does - not match the Server Hardware's. - """ - spt_enclosure_group_uri = server_profile_template.get('enclosureGroupUri') - sh_enclosure_group_uri = server_hardware.get('serverGroupUri') - - if spt_enclosure_group_uri != sh_enclosure_group_uri: - message = _("Server profile template %(spt_uri)s enclosureGroupUri is " - "inconsistent with server hardware %(sh_uri)s " - "serverGroupUri.") % { - 'spt_uri': server_profile_template.get('uri'), - 'sh_uri': server_hardware.get('uri')} - raise exception.OneViewError(message) - - -def _validate_server_profile_template_manage_boot(server_profile_template): - """Validate if the Server Profile Template allows to manage the boot order. - - :param server_profile_template: OneView Server Profile Template object. - :raises: OneViewError if the Server Profile Template does not allows to - manage the boot order. - """ - manage_boot = server_profile_template.get('boot', {}).get('manageBoot') - - if not manage_boot: - message = _("Server Profile Template: %s, does not allow to manage " - "boot order.") % server_profile_template.get('uri') - raise exception.OneViewError(message) - - -def _validate_node_server_hardware_type(oneview_client, oneview_info): - """Validate if the node's Server Hardware Type matches Server Hardware's. - - :param: oneview_client: the HPE OneView Client. - :param: oneview_info: the OneView related info in an Ironic node. - :raises: OneViewError if the node's Server Hardware Type group doesn't - match the Server Hardware's. - """ - node_server_hardware_type_uri = oneview_info['server_hardware_type_uri'] - server_hardware = oneview_client.server_hardware.get( - oneview_info['server_hardware_uri']) - server_hardware_sht_uri = server_hardware.get('serverHardwareTypeUri') - - if server_hardware_sht_uri != node_server_hardware_type_uri: - message = _("Node server_hardware_type_uri is inconsistent " - "with OneView's server hardware %(server_hardware_uri)s " - "serverHardwareTypeUri.") % { - 'server_hardware_uri': server_hardware.get('uri')} - raise exception.OneViewError(message) - - -def _validate_node_enclosure_group(oneview_client, oneview_info): - """Validate if the node's Enclosure Group matches the Server Hardware's. - - :param oneview_client: an instance of the HPE OneView client. - :param oneview_info: the OneView related info in an Ironic node. - :raises: OneViewError if the node's enclosure group doesn't match the - Server Hardware's. - """ - server_hardware = oneview_client.server_hardware.get( - oneview_info['server_hardware_uri']) - sh_enclosure_group_uri = server_hardware.get('serverGroupUri') - node_enclosure_group_uri = oneview_info['enclosure_group_uri'] - - if node_enclosure_group_uri and ( - sh_enclosure_group_uri != node_enclosure_group_uri): - message = _( - "Node enclosure_group_uri '%(node_enclosure_group_uri)s' " - "is inconsistent with OneView's server hardware " - "serverGroupUri '%(sh_enclosure_group_uri)s' of " - "ServerHardware %(server_hardware)s") % { - 'node_enclosure_group_uri': node_enclosure_group_uri, - 'sh_enclosure_group_uri': sh_enclosure_group_uri, - 'server_hardware': server_hardware.get('uri')} - raise exception.OneViewError(message) - - -def _validate_node_port_mac_server_hardware(oneview_client, - oneview_info, ports): - """Validate if a port matches the node's Server Hardware's MAC. - - :param oneview_client: an instance of the HPE OneView client. - :param oneview_info: the OneView related info in an Ironic node. - :param ports: a list of Ironic node's ports. - :raises: OneViewError if there is no port with MAC address matching one - in OneView. - - """ - server_hardware = oneview_client.server_hardware.get( - oneview_info['server_hardware_uri']) - - if not ports: - return - - # NOTE(nicodemos) If hponeview client's unable to get the MAC of the Server - # Hardware and raises an exception, the driver will try to get it from - # the iLOrest client. - try: - mac = _get_server_hardware_mac(server_hardware) - except exception.OneViewError: - mac = _get_server_hardware_mac_from_ilo(server_hardware) - - incompatible_macs = [] - for port in ports: - if port.address.lower() == mac.lower(): - return - incompatible_macs.append(port.address) - - message = _("The ports of the node are not compatible with its " - "server hardware %(server_hardware_uri)s. There are no Ironic " - "port MAC's: %(port_macs)s, that matches with the " - "server hardware's MAC: %(server_hardware_mac)s") % { - 'server_hardware_uri': server_hardware.get('uri'), - 'port_macs': ', '.join(incompatible_macs), - 'server_hardware_mac': mac} - raise exception.OneViewError(message) - - -def _validate_server_profile_template_mac_type(oneview_client, oneview_info): - """Validate if the node's Server Profile Template's MAC type is physical. - - :param oneview_client: an instance of the HPE OneView client. - :param oneview_info: the OneView related info in an Ironic node. - :raises: OneViewError if the node's Server Profile Template's MAC type is - not physical. - """ - server_profile_template = oneview_client.server_profile_templates.get( - oneview_info['server_profile_template_uri'] - ) - if server_profile_template.get('macType') != 'Physical': - message = _("The server profile template %s is not set to use " - "physical MAC.") % server_profile_template.get('uri') - raise exception.OneViewError(message) diff --git a/ironic/drivers/modules/oneview/deploy.py b/ironic/drivers/modules/oneview/deploy.py deleted file mode 100644 index c7faa5188..000000000 --- a/ironic/drivers/modules/oneview/deploy.py +++ /dev/null @@ -1,308 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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 abc - -from futurist import periodics -from ironic_lib import metrics_utils -from oslo_log import log as logging -import six - -from ironic.common import exception -from ironic.common import states -from ironic.conductor import utils -from ironic.conf import CONF -from ironic.drivers.modules import agent -from ironic.drivers.modules import iscsi_deploy -from ironic.drivers.modules.oneview import common -from ironic.drivers.modules.oneview import deploy_utils -from ironic import objects - -LOG = logging.getLogger(__name__) -METRICS = metrics_utils.get_metrics_logger(__name__) - - -@six.add_metaclass(abc.ABCMeta) -class OneViewPeriodicTasks(object): - - @periodics.periodic(spacing=CONF.oneview.periodic_check_interval, - enabled=CONF.oneview.enable_periodic_tasks - and CONF.oneview.periodic_check_interval > 0) - def _periodic_check_nodes_taken_by_oneview(self, manager, context): - """Checks if nodes in Ironic were taken by OneView users. - - This driver periodic task will check for nodes that were taken by - OneView users while the node is in available state, set the node to - maintenance mode with an appropriate maintenance reason message and - move the node to manageable state. - - :param manager: a ConductorManager instance - :param context: request context - :returns: None. - """ - - filters = { - 'provision_state': states.AVAILABLE, - 'maintenance': False, - 'driver': 'oneview' - } - node_iter = manager.iter_nodes(filters=filters) - - for node_uuid, driver, conductor_group in node_iter: - - node = objects.Node.get(context, node_uuid) - - try: - oneview_using = deploy_utils.is_node_in_use_by_oneview(node) - except exception.OneViewError as e: - # NOTE(xavierr): Skip this node and process the - # remaining nodes. This node will be checked in - # the next periodic call. - - LOG.error("Error while determining if node " - "%(node_uuid)s is in use by OneView. " - "Error: %(error)s", - {'node_uuid': node.uuid, 'error': e}) - - continue - - if oneview_using: - purpose_msg = ('Updating node %(node_uuid)s in use ' - 'by OneView from %(provision_state)s state ' - 'to %(target_state)s state and maintenance ' - 'mode %(maintenance)s.') - purpose_data = {'node_uuid': node_uuid, - 'provision_state': states.AVAILABLE, - 'target_state': states.MANAGEABLE, - 'maintenance': True} - - LOG.info(purpose_msg, purpose_data) - - node.maintenance = True - node.maintenance_reason = common.NODE_IN_USE_BY_ONEVIEW - manager.update_node(context, node) - manager.do_provisioning_action(context, node.uuid, 'manage') - - @periodics.periodic(spacing=CONF.oneview.periodic_check_interval, - enabled=CONF.oneview.enable_periodic_tasks - and CONF.oneview.periodic_check_interval > 0) - def _periodic_check_nodes_freed_by_oneview(self, manager, context): - """Checks if nodes taken by OneView users were freed. - - This driver periodic task will be responsible to poll the nodes that - are in maintenance mode and on manageable state to check if the Server - Profile was removed, indicating that the node was freed by the OneView - user. If so, it'll provide the node, that will pass through the - cleaning process and become available to be provisioned. - - :param manager: a ConductorManager instance - :param context: request context - :returns: None. - """ - - filters = { - 'provision_state': states.MANAGEABLE, - 'maintenance': True, - 'driver': 'oneview' - } - node_iter = manager.iter_nodes(fields=['maintenance_reason'], - filters=filters) - for (node_uuid, driver, conductor_group, - maintenance_reason) in node_iter: - - if maintenance_reason == common.NODE_IN_USE_BY_ONEVIEW: - - node = objects.Node.get(context, node_uuid) - - try: - oneview_using = deploy_utils.is_node_in_use_by_oneview( - node - ) - except exception.OneViewError as e: - # NOTE(xavierr): Skip this node and process the - # remaining nodes. This node will be checked in - # the next periodic call. - - LOG.error("Error while determining if node " - "%(node_uuid)s is in use by OneView. " - "Error: %(error)s", - {'node_uuid': node.uuid, 'error': e}) - - continue - - if not oneview_using: - purpose_msg = ('Bringing node %(node_uuid)s back from ' - 'use by OneView from %(provision_state)s ' - 'state to %(target_state)s state and ' - 'maintenance mode %(maintenance)s.') - purpose_data = {'node_uuid': node_uuid, - 'provision_state': states.MANAGEABLE, - 'target_state': states.AVAILABLE, - 'maintenance': False} - - LOG.info(purpose_msg, purpose_data) - - node.maintenance = False - node.maintenance_reason = None - manager.update_node(context, node) - manager.do_provisioning_action( - context, node.uuid, 'provide' - ) - - @periodics.periodic(spacing=CONF.oneview.periodic_check_interval, - enabled=CONF.oneview.enable_periodic_tasks) - def _periodic_check_nodes_taken_on_cleanfail(self, manager, context): - """Checks failed deploys due to Oneview users taking Server Hardware. - - This last driver periodic task will take care of nodes that would be - caught on a race condition between OneView and a deploy by Ironic. In - such cases, the validation will fail, throwing the node on deploy fail - and, afterwards on clean fail. - - This task will set the node to maintenance mode with a proper reason - message and move it to manageable state, from where the second task - can rescue the node as soon as the Server Profile is removed. - - :param manager: a ConductorManager instance - :param context: request context - :returns: None. - """ - - filters = { - 'provision_state': states.CLEANFAIL, - 'driver': 'oneview' - } - node_iter = manager.iter_nodes(fields=['driver_internal_info'], - filters=filters) - - for (node_uuid, driver, conductor_group, - driver_internal_info) in node_iter: - - node_oneview_error = driver_internal_info.get('oneview_error') - if node_oneview_error == common.SERVER_HARDWARE_ALLOCATION_ERROR: - - node = objects.Node.get(context, node_uuid) - - purpose_msg = ('Bringing node %(node_uuid)s back from use ' - 'by OneView from %(provision_state)s state ' - 'to %(target_state)s state and ' - 'maintenance mode %(maintenance)s.') - purpose_dict = {'node_uuid': node_uuid, - 'provision_state': states.CLEANFAIL, - 'target_state': states.MANAGEABLE, - 'maintenance': False} - - LOG.info(purpose_msg, purpose_dict) - - node.maintenance = True - node.maintenance_reason = common.NODE_IN_USE_BY_ONEVIEW - driver_internal_info = node.driver_internal_info - driver_internal_info.pop('oneview_error', None) - node.driver_internal_info = driver_internal_info - manager.update_node(context, node) - manager.do_provisioning_action(context, node.uuid, 'manage') - - -class OneViewIscsiDeploy(iscsi_deploy.ISCSIDeploy, OneViewPeriodicTasks): - """Class for OneView ISCSI deployment driver.""" - - # NOTE(TheJulia): Marking as unsupported as 3rd party CI was taken down - # shortly before the beginning of the Rocky cycle, and no replies have - # indicated that 3rd party CI will be re-established nor visible - # actions observed regarding re-establishing 3rd party CI. - # TODO(TheJulia): This should be expected to be removed in Stein. - supported = False - - def get_properties(self): - return deploy_utils.get_properties() - - @METRICS.timer('OneViewIscsiDeploy.validate') - def validate(self, task): - common.verify_node_info(task.node) - try: - common.validate_oneview_resources_compatibility(task) - except exception.OneViewError as oneview_exc: - raise exception.InvalidParameterValue(oneview_exc) - super(OneViewIscsiDeploy, self).validate(task) - - @METRICS.timer('OneViewIscsiDeploy.prepare') - def prepare(self, task): - deploy_utils.prepare(task) - super(OneViewIscsiDeploy, self).prepare(task) - - @METRICS.timer('OneViewIscsiDeploy.tear_down') - def tear_down(self, task): - # teardown if automated clean is disabled on the node - # or if general automated clean is not enabled generally - # and not on the node as well - if utils.skip_automated_cleaning(task.node): - deploy_utils.tear_down(task) - return super(OneViewIscsiDeploy, self).tear_down(task) - - @METRICS.timer('OneViewIscsiDeploy.prepare_cleaning') - def prepare_cleaning(self, task): - deploy_utils.prepare_cleaning(task) - return super(OneViewIscsiDeploy, self).prepare_cleaning(task) - - @METRICS.timer('OneViewIscsiDeploy.tear_down_cleaning') - def tear_down_cleaning(self, task): - deploy_utils.tear_down_cleaning(task) - super(OneViewIscsiDeploy, self).tear_down_cleaning(task) - - -class OneViewAgentDeploy(agent.AgentDeploy, OneViewPeriodicTasks): - """Class for OneView Agent deployment driver.""" - - # NOTE(TheJulia): Marking as unsupported as 3rd party CI was taken down - # shortly before the beginning of the Rocky cycle, and no replies have - # indicated that 3rd party CI will be re-established nor visible - # actions observed regarding re-establishing 3rd party CI. - # TODO(TheJulia): This should be expected to be removed in Stein. - supported = False - - def get_properties(self): - return deploy_utils.get_properties() - - @METRICS.timer('OneViewAgentDeploy.validate') - def validate(self, task): - common.verify_node_info(task.node) - try: - common.validate_oneview_resources_compatibility(task) - except exception.OneViewError as oneview_exc: - raise exception.InvalidParameterValue(oneview_exc) - super(OneViewAgentDeploy, self).validate(task) - - @METRICS.timer('OneViewAgentDeploy.prepare') - def prepare(self, task): - deploy_utils.prepare(task) - super(OneViewAgentDeploy, self).prepare(task) - - @METRICS.timer('OneViewAgentDeploy.tear_down') - def tear_down(self, task): - # if node specifically has cleanup disabled, or general cleanup - # is disabled and node has not it enabled - if utils.skip_automated_cleaning(task.node): - deploy_utils.tear_down(task) - return super(OneViewAgentDeploy, self).tear_down(task) - - @METRICS.timer('OneViewAgentDeploy.prepare_cleaning') - def prepare_cleaning(self, task): - deploy_utils.prepare_cleaning(task) - return super(OneViewAgentDeploy, self).prepare_cleaning(task) - - @METRICS.timer('OneViewAgentDeploy.tear_down_cleaning') - def tear_down_cleaning(self, task): - deploy_utils.tear_down_cleaning(task) - super(OneViewAgentDeploy, self).tear_down_cleaning(task) diff --git a/ironic/drivers/modules/oneview/deploy_utils.py b/ironic/drivers/modules/oneview/deploy_utils.py deleted file mode 100644 index eed1a46b1..000000000 --- a/ironic/drivers/modules/oneview/deploy_utils.py +++ /dev/null @@ -1,384 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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 operator - -from oslo_log import log as logging -from oslo_utils import importutils - -from ironic.common import exception -from ironic.common.i18n import _ -from ironic.common import states -from ironic.drivers.modules.oneview import common - -LOG = logging.getLogger(__name__) - -client_exception = importutils.try_import('hpOneView.exceptions') - - -def get_properties(): - return common.COMMON_PROPERTIES - - -def prepare(task): - """Applies Server Profile and update the node when preparing. - - This method is responsible for applying a Server Profile to the Server - Hardware and add the uri of the applied Server Profile in the node's - 'applied_server_profile_uri' field on properties/capabilities. - - :param task: A TaskManager object - :raises InstanceDeployFailure: If the node doesn't have the needed OneView - informations, if Server Hardware is in use by an OneView user, or - if the Server Profile can't be applied. - - """ - if task.node.provision_state == states.DEPLOYING: - try: - instance_display_name = task.node.instance_info.get('display_name') - instance_uuid = task.node.instance_uuid - server_profile_name = ( - "%(instance_name)s [%(instance_uuid)s]" % - {"instance_name": instance_display_name, - "instance_uuid": instance_uuid} - ) - allocate_server_hardware_to_ironic(task.node, server_profile_name) - except exception.OneViewError as e: - raise exception.InstanceDeployFailure(node=task.node.uuid, - reason=e) - - -def tear_down(task): - """Remove Server profile and update the node when tear down. - - This method is responsible for power a Server Hardware off, remove a Server - Profile from the Server Hardware and remove the uri of the applied Server - Profile from the node's 'applied_server_profile_uri' in - properties/capabilities. - - :param task: A TaskManager object - :raises InstanceDeployFailure: If node has no uri of applied Server - Profile, or if some error occur while deleting Server Profile. - - """ - try: - deallocate_server_hardware_from_ironic(task) - except exception.OneViewError as e: - raise exception.InstanceDeployFailure(node=task.node.uuid, reason=e) - - -def prepare_cleaning(task): - """Applies Server Profile and update the node when preparing cleaning. - - This method is responsible for applying a Server Profile to the Server - Hardware and add the uri of the applied Server Profile in the node's - 'applied_server_profile_uri' field on properties/capabilities. - - :param task: A TaskManager object - :raises NodeCleaningFailure: If the node doesn't have the needed OneView - informations, if Server Hardware is in use by an OneView user, or - if the Server Profile can't be applied. - - """ - try: - server_profile_name = "Ironic Cleaning [%s]" % task.node.uuid - allocate_server_hardware_to_ironic(task.node, server_profile_name) - except exception.OneViewError as e: - oneview_error = common.SERVER_HARDWARE_ALLOCATION_ERROR - driver_internal_info = task.node.driver_internal_info - driver_internal_info['oneview_error'] = oneview_error - task.node.driver_internal_info = driver_internal_info - task.node.save() - raise exception.NodeCleaningFailure(node=task.node.uuid, - reason=e) - - -def tear_down_cleaning(task): - """Remove Server profile and update the node when tear down cleaning. - - This method is responsible for power a Server Hardware off, remove a Server - Profile from the Server Hardware and remove the uri of the applied Server - Profile from the node's 'applied_server_profile_uri' in - properties/capabilities. - - :param task: A TaskManager object - :raises NodeCleaningFailure: If node has no uri of applied Server Profile, - or if some error occur while deleting Server Profile. - - """ - try: - deallocate_server_hardware_from_ironic(task) - except exception.OneViewError as e: - raise exception.NodeCleaningFailure(node=task.node.uuid, reason=e) - - -def _create_profile_from_template( - oneview_client, server_profile_name, - server_hardware_uri, server_profile_template): - """Create a server profile from a server profile template. - - :param oneview_client: an HPE OneView Client instance - :param server_profile_name: the name of the new server profile - :param server_hardware_uri: the server_hardware assigned to server profile - :param server_profile_template: the server profile template id or uri - :returns: The new server profile generated with the name and server - hardware passed on parameters - :raises OneViewError: if the communication with OneView fails - - """ - server_profile = oneview_client.server_profile_templates.get_new_profile( - server_profile_template - ) - server_profile['name'] = server_profile_name - server_profile['serverHardwareUri'] = server_hardware_uri - server_profile['serverProfileTemplateUri'] = "" - try: - return oneview_client.server_profiles.create(server_profile) - except client_exception.HPOneViewException as e: - msg = (_("Error while creating a Server Profile for Server Hardware: " - "%(sh_uri)s. Error: %(error)s") % - {'sh_uri': server_hardware_uri, 'error': e}) - raise exception.OneViewError(error=msg) - - -def _is_node_in_use(server_hardware, applied_sp_uri, by_oneview=False): - """Check if node is in use by ironic or by OneView. - - :param server_hardware: Server Hardware object. - :param applied_sp_uri: Server Profile URI applied in the node. - :param by_oneview: Boolean value. True when want to verify if node is in - use by OneView. False to verify if node is in use by - ironic. - :returns: Boolean value. True if by_oneview param is also True and node is - in use by OneView, False otherwise. True if by_oneview param is - False and node is in use by ironic, False otherwise. - """ - operation = operator.ne if by_oneview else operator.eq - server_profile_uri = server_hardware.get('serverProfileUri') - return (server_profile_uri - and operation(applied_sp_uri, server_profile_uri)) - - -def is_node_in_use_by_oneview(node): - """Check if node is in use by OneView user. - - :param node: an ironic node object. - :returns: Boolean value. True if node is in use by OneView, - False otherwise. - :raises OneViewError: if not possible to get OneView's informations - for the given node, if not possible to retrieve Server Hardware - from OneView. - """ - oneview_client = common.get_hponeview_client() - positive = _("Node '%s' is in use by OneView.") % node.uuid - negative = _("Node '%s' is not in use by OneView.") % node.uuid - - def predicate(server_hardware, applied_sp_uri): - # Check if Profile exists in Oneview and it is different of the one - # applied by ironic - return _is_node_in_use(server_hardware, applied_sp_uri, - by_oneview=True) - - return _check_applied_server_profile(oneview_client, node, - predicate, positive, negative) - - -def is_node_in_use_by_ironic(node): - """Check if node is in use by ironic in OneView. - - :param node: an ironic node object. - :returns: Boolean value. True if node is in use by ironic, - False otherwise. - :raises OneViewError: if not possible to get OneView's information - for the given node, if not possible to retrieve Server Hardware - from OneView. - """ - oneview_client = common.get_hponeview_client() - positive = _("Node '%s' is in use by Ironic.") % node.uuid - negative = _("Node '%s' is not in use by Ironic.") % node.uuid - - def predicate(server_hardware, applied_sp_uri): - # Check if Profile exists in Oneview and it is equals of the one - # applied by ironic - return _is_node_in_use(server_hardware, applied_sp_uri, - by_oneview=False) - - return _check_applied_server_profile(oneview_client, node, - predicate, positive, negative) - - -def _check_applied_server_profile(oneview_client, node, - predicate, positive, negative): - """Check if node is in use by ironic in OneView. - - :param oneview_client: an instance of the OneView client - :param node: an ironic node object - :returns: Boolean value. True if node is in use by ironic, - False otherwise. - :raises OneViewError: if not possible to get OneView's information - for the given node, if not possible to retrieve Server Hardware - from OneView. - - """ - oneview_info = common.get_oneview_info(node) - try: - server_hardware = oneview_client.server_hardware.get( - oneview_info.get('server_hardware_uri') - ) - except client_exception.HPOneViewResourceNotFound as e: - msg = (_("Error while obtaining Server Hardware from node " - "%(node_uuid)s. Error: %(error)s") % - {'node_uuid': node.uuid, 'error': e}) - raise exception.OneViewError(error=msg) - - applied_sp_uri = node.driver_info.get('applied_server_profile_uri') - result = predicate(server_hardware, applied_sp_uri) - - if result: - LOG.debug(positive) - else: - LOG.debug(negative) - - return result - - -def _add_applied_server_profile_uri_field(node, applied_profile): - """Adds the applied Server Profile uri to a node. - - :param node: an ironic node object - :param applied_profile: the server_profile that will be applied to node - """ - driver_info = node.driver_info - driver_info['applied_server_profile_uri'] = applied_profile.get('uri') - node.driver_info = driver_info - node.save() - - -def _del_applied_server_profile_uri_field(node): - """Delete the applied Server Profile uri from a node if it exists. - - :param node: an ironic node object - - """ - driver_info = node.driver_info - driver_info.pop('applied_server_profile_uri', None) - node.driver_info = driver_info - node.save() - - -def allocate_server_hardware_to_ironic(node, server_profile_name): - """Allocate Server Hardware to ironic. - - :param node: an ironic node object. - :param server_profile_name: a formatted string with the Server Profile - name. - :raises OneViewError: if an error occurs while allocating the Server - Hardware to ironic or the node is already in use by OneView. - """ - oneview_client = common.get_hponeview_client() - node_in_use_by_oneview = is_node_in_use_by_oneview(node) - - if not node_in_use_by_oneview: - - oneview_info = common.get_oneview_info(node) - - applied_sp_uri = node.driver_info.get('applied_server_profile_uri') - sh_uri = oneview_info.get("server_hardware_uri") - spt_uri = oneview_info.get("server_profile_template_uri") - server_hardware = oneview_client.server_hardware.get(sh_uri) - - if not server_hardware: - msg = _("An error occurred during allocating server hardware to " - "ironic. Server hardware: %s not found.") % sh_uri - raise exception.OneViewError(error=msg) - - # Don't have Server Profile on OneView but has - # `applied_server_profile_uri` on driver_info - if not server_hardware.get('serverProfileUri') and applied_sp_uri: - - _del_applied_server_profile_uri_field(node) - LOG.info( - "Inconsistent 'applied_server_profile_uri' parameter " - "value in driver_info. There is no Server Profile " - "applied to node %(node_uuid)s. Value deleted.", - {"node_uuid": node.uuid} - ) - - # applied_server_profile_uri exists and is equal to Server profile - # applied on Hardware. Do not apply again. - if (applied_sp_uri and server_hardware.get( - 'serverProfileUri') == applied_sp_uri): - LOG.info( - "The Server Profile %(applied_sp_uri)s was already applied " - "by ironic on node %(node_uuid)s. Reusing.", - {"node_uuid": node.uuid, "applied_sp_uri": applied_sp_uri} - ) - return - - try: - applied_profile = _create_profile_from_template( - oneview_client, server_profile_name, sh_uri, spt_uri - ) - _add_applied_server_profile_uri_field(node, applied_profile) - - LOG.info( - "Server Profile %(server_profile_uuid)s was successfully" - " applied to node %(node_uuid)s.", - {"node_uuid": node.uuid, - "server_profile_uuid": applied_profile.get('uri')} - ) - - except client_exception.HPOneViewInvalidResource as e: - LOG.error("An error occurred during allocating server " - "hardware to ironic during prepare: %s", e) - raise exception.OneViewError(error=e) - else: - msg = _("Node %s is already in use by OneView.") % node.uuid - raise exception.OneViewError(error=msg) - - -def deallocate_server_hardware_from_ironic(task): - """Deallocate Server Hardware from ironic. - - :param task: a TaskManager object - :raises OneViewError: if an error occurs while deallocating the Server - Hardware to ironic - - """ - node = task.node - oneview_client = common.get_hponeview_client() - - if is_node_in_use_by_ironic(node): - oneview_info = common.get_oneview_info(node) - server_profile_uri = oneview_info.get('applied_server_profile_uri') - - try: - task.driver.power.set_power_state(task, states.POWER_OFF) - oneview_client.server_profiles.delete(server_profile_uri) - _del_applied_server_profile_uri_field(node) - LOG.info("Server Profile %(server_profile_uri)s was deleted " - "from node %(node_uuid)s in OneView.", - {'server_profile_uri': server_profile_uri, - 'node_uuid': node.uuid}) - except client_exception.HPOneViewException as e: - msg = (_("Error while deleting applied Server Profile from node " - "%(node_uuid)s. Error: %(error)s") % - {'node_uuid': node.uuid, 'error': e}) - raise exception.OneViewError(error=msg) - - else: - LOG.warning("Cannot deallocate node %(node_uuid)s " - "in OneView because it is not in use by " - "ironic.", {'node_uuid': node.uuid}) diff --git a/ironic/drivers/modules/oneview/inspect.py b/ironic/drivers/modules/oneview/inspect.py deleted file mode 100644 index 2ba40efbb..000000000 --- a/ironic/drivers/modules/oneview/inspect.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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. - -from futurist import periodics -from ironic_lib import metrics_utils - -from ironic.common import exception -from ironic.common import states -from ironic.conductor import task_manager -from ironic.conf import CONF -from ironic.drivers.modules import inspector -from ironic.drivers.modules.oneview import common -from ironic.drivers.modules.oneview import deploy_utils - -METRICS = metrics_utils.get_metrics_logger(__name__) - - -class OneViewInspect(inspector.Inspector): - """Interface for in band inspection.""" - - # NOTE(TheJulia): Marking as unsupported as 3rd party CI was taken down - # shortly before the beginning of the Rocky cycle, and no replies have - # indicated that 3rd party CI will be re-established nor visible - # actions observed regarding re-establishing 3rd party CI. - # TODO(TheJulia): This should be expected to be removed in Stein. - supported = False - - def get_properties(self): - return deploy_utils.get_properties() - - @METRICS.timer('OneViewInspect.validate') - def validate(self, task): - """Checks required info on 'driver_info' and validates node for OneView - - Validates whether the 'driver_info' property of the supplied - task's node contains the required info such as server_hardware_uri, - server_hardware_type, server_profile_template_uri and - enclosure_group_uri. Also, checks if the server profile of the node is - applied, if NICs are valid for the server profile of the node. - - :param task: a task from TaskManager. - :raises: InvalidParameterValue if parameters set are inconsistent with - resources in OneView - """ - - common.verify_node_info(task.node) - - try: - common.validate_oneview_resources_compatibility(task) - except exception.OneViewError as oneview_exc: - raise exception.InvalidParameterValue(oneview_exc) - - @METRICS.timer('OneViewInspect.inspect_hardware') - def inspect_hardware(self, task): - profile_name = 'Ironic Inspecting [%s]' % task.node.uuid - deploy_utils.allocate_server_hardware_to_ironic( - task.node, profile_name - ) - return super(OneViewInspect, self).inspect_hardware(task) - - @periodics.periodic(spacing=CONF.inspector.status_check_period) - def _periodic_check_result(self, manager, context): - filters = {'provision_state': states.INSPECTWAIT, - 'driver': 'oneview'} - node_iter = manager.iter_nodes(filters=filters) - - for node_uuid, driver, conductor_group in node_iter: - try: - lock_purpose = 'checking hardware inspection status' - with task_manager.acquire(context, node_uuid, - shared=True, - purpose=lock_purpose) as task: - self._check_status(task) - except (exception.NodeLocked, exception.NodeNotFound): - continue - - def _check_status(self, task): - state_before = task.node.provision_state - result = inspector._check_status(task) - state_after = task.node.provision_state - - # inspection finished - if state_before == states.INSPECTWAIT and state_after in [ - states.MANAGEABLE, states.INSPECTFAIL - ]: - deploy_utils.deallocate_server_hardware_from_ironic(task.node) - - return result diff --git a/ironic/drivers/modules/oneview/management.py b/ironic/drivers/modules/oneview/management.py deleted file mode 100644 index 7caeddc35..000000000 --- a/ironic/drivers/modules/oneview/management.py +++ /dev/null @@ -1,325 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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. - -from ironic_lib import metrics_utils -from oslo_log import log as logging -from oslo_utils import importutils - -from ironic.common import boot_devices -from ironic.common import exception -from ironic.common.i18n import _ -from ironic.conductor import task_manager -from ironic.drivers import base -from ironic.drivers.modules.oneview import common -from ironic.drivers.modules.oneview import deploy_utils - -client_exception = importutils.try_import('hpOneView.exceptions') - -LOG = logging.getLogger(__name__) -METRICS = metrics_utils.get_metrics_logger(__name__) - -BOOT_DEVICE_MAP_ONEVIEW = { - boot_devices.CDROM: 'CD', - boot_devices.DISK: 'HardDisk', - boot_devices.PXE: 'PXE' -} - -BOOT_DEVICE_MAP_ONEVIEW_REV = { - v: k for k, v in BOOT_DEVICE_MAP_ONEVIEW.items()} - -BOOT_DEVICE_MAP_ILO = { - boot_devices.CDROM: 'Cd', - boot_devices.DISK: 'Hdd', - boot_devices.PXE: 'Pxe' -} - -BOOT_DEVICE_MAP_ILO_REV = { - v: k for k, v in BOOT_DEVICE_MAP_ILO.items()} - -ILO_SYSTEM_PATH = "/rest/v1/Systems/1" - -ILO_REQUEST_HEADERS = {"Content-Type": "application/json"} - - -def set_onetime_boot(task): - """Set onetime boot to server hardware. - - Change the onetime boot option of an OneView server hardware. - - :param task: a task from TaskManager. - """ - driver_internal_info = task.node.driver_internal_info - next_boot_device = driver_internal_info.get('next_boot_device') - - if not next_boot_device: - return - - boot_device = next_boot_device.get('boot_device') - persistent = next_boot_device.get('persistent') - - if persistent: - return - - server_hardware = task.node.driver_info.get('server_hardware_uri') - ilo_client = common.get_ilorest_client(server_hardware) - boot_device = BOOT_DEVICE_MAP_ILO.get(boot_device) - body = { - "Boot": { - "BootSourceOverrideTarget": boot_device, - "BootSourceOverrideEnabled": "Once" - } - } - try: - ilo_client.patch(path=ILO_SYSTEM_PATH, body=body, - headers=ILO_REQUEST_HEADERS) - except Exception as e: - msg = (_("Error while trying to set onetime boot on Server Hardware: " - "%(sh_uri)s. Error: %(error)s") % - {'sh_uri': server_hardware, 'error': e}) - raise exception.OneViewError(error=msg) - - -def _is_onetime_boot(task): - """Check onetime boot from server hardware. - - Check if the onetime boot option of an OneView server hardware - is set to 'Once' in iLO. - - :param task: a task from TaskManager. - :returns: Boolean value. True if onetime boot is 'Once' - False otherwise. - """ - server_hardware = task.node.driver_info.get('server_hardware_uri') - ilo_client = common.get_ilorest_client(server_hardware) - response = ilo_client.get(path=ILO_SYSTEM_PATH, - headers=ILO_REQUEST_HEADERS) - onetime_boot = None - boot = response.dict.get('Boot', {}) - if boot: - onetime_boot = boot.get('BootSourceOverrideEnabled') - return onetime_boot == 'Once' - - -def set_boot_device(task): - """Sets the boot device for a node. - - Sets the boot device to use on next reboot of the node. - - :param task: a task from TaskManager. - :raises: InvalidParameterValue if an invalid boot device is - specified. - :raises: OneViewError if the communication with OneView fails - """ - oneview_client = common.get_hponeview_client() - common.ensure_server_profile(task) - driver_internal_info = task.node.driver_internal_info - next_boot_device = driver_internal_info.get('next_boot_device') - - if next_boot_device: - boot_device = next_boot_device.get('boot_device') - persistent = next_boot_device.get('persistent') - - if boot_device not in sorted(BOOT_DEVICE_MAP_ONEVIEW): - raise exception.InvalidParameterValue( - _("Invalid boot device %s specified.") % boot_device) - - LOG.debug("Setting boot device to %(boot_device)s and " - "persistent to %(persistent)s for node %(node)s", - {"boot_device": boot_device, "persistent": persistent, - "node": task.node.uuid}) - - profile = task.node.driver_info.get('applied_server_profile_uri') - boot_device = BOOT_DEVICE_MAP_ONEVIEW.get(boot_device) - - try: - server_profile = oneview_client.server_profiles.get(profile) - boot = server_profile.get('boot', {}) - order = boot.get('order', []) - if boot_device in order: - order.remove(boot_device) - order.insert(0, boot_device) - boot['order'] = order - server_profile['boot'] = boot - oneview_client.server_profiles.update(server_profile, profile) - set_onetime_boot(task) - driver_internal_info.pop('next_boot_device', None) - task.node.driver_internal_info = driver_internal_info - task.node.save() - except client_exception.HPOneViewException as oneview_exc: - msg = (_( - "Error setting boot device on OneView. Error: %s") - % oneview_exc - ) - raise exception.OneViewError(error=msg) - - else: - LOG.debug("Not going to set boot device because there is no " - "'next_boot_device' on driver_internal_info " - "for the %(node)s", - {"node": task.node.uuid}) - - -class OneViewManagement(base.ManagementInterface): - - # NOTE(TheJulia): Marking as unsupported as 3rd party CI was taken down - # shortly before the beginning of the Rocky cycle, and no replies have - # indicated that 3rd party CI will be re-established nor visible - # actions observed regarding re-establishing 3rd party CI. - # TODO(TheJulia): This should be expected to be removed in Stein. - supported = False - - def get_properties(self): - return deploy_utils.get_properties() - - @METRICS.timer('OneViewManagement.validate') - def validate(self, task): - """Checks required info on 'driver_info' and validates node for OneView - - Validates whether the 'driver_info' property of the supplied - task's node contains the required info such as server_hardware_uri, - server_hardware_type, server_profile_template_uri and - enclosure_group_uri. Also, checks if the server profile of the node is - applied, if NICs are valid for the server profile of the node, and if - the server hardware attributes (ram, memory, vcpus count) are - consistent with OneView. - - :param task: a task from TaskManager. - :raises: InvalidParameterValue if parameters set are inconsistent with - resources in OneView - """ - - common.verify_node_info(task.node) - - try: - common.validate_oneview_resources_compatibility(task) - - if not deploy_utils.is_node_in_use_by_ironic(task.node): - raise exception.InvalidParameterValue( - _("Node %s is not in use by ironic.") % task.node.uuid) - except exception.OneViewError as oneview_exc: - raise exception.InvalidParameterValue(oneview_exc) - - @METRICS.timer('OneViewManagement.get_supported_boot_devices') - def get_supported_boot_devices(self, task): - """Gets a list of the supported boot devices. - - :param task: a task from TaskManager. - :returns: A list with the supported boot devices defined - in :mod:`ironic.common.boot_devices`. - """ - - return sorted(BOOT_DEVICE_MAP_ONEVIEW) - - @METRICS.timer('OneViewManagement.set_boot_device') - @task_manager.require_exclusive_lock - @common.node_has_server_profile - def set_boot_device(self, task, device, persistent=False): - """Set the next boot device to the node. - - Sets the boot device to the node next_boot_device on - driver_internal_info namespace. The operation will be - performed before the next node power on. - - :param task: a task from TaskManager. - :param device: the boot device, one of the supported devices - listed in :mod:`ironic.common.boot_devices`. - :param persistent: Boolean value. True if the boot device will - persist to all future boots, False if not. - Default: False. - :raises: InvalidParameterValue if an invalid boot device is - specified. - """ - if device not in self.get_supported_boot_devices(task): - raise exception.InvalidParameterValue( - _("Invalid boot device %s specified.") % device) - - driver_internal_info = task.node.driver_internal_info - next_boot_device = {'boot_device': device, - 'persistent': persistent} - driver_internal_info['next_boot_device'] = next_boot_device - task.node.driver_internal_info = driver_internal_info - task.node.save() - LOG.debug("The 'next_boot_device' flag was updated on " - "driver_internal_info with device=%(boot_device)s " - "and persistent=%(persistent)s for the node " - "%(node)s", - {"boot_device": device, "persistent": persistent, - "node": task.node.uuid}) - - @METRICS.timer('OneViewManagement.get_boot_device') - @common.node_has_server_profile - def get_boot_device(self, task): - """Get the current boot device from the node. - - Gets the boot device from the node 'next_boot_device on - driver_internal_info namespace if exists. Gets through - a request to OneView otherwise. - - :param task: a task from TaskManager. - :returns: a dictionary containing: - :boot_device: the boot device, one of - :mod:`ironic.common.boot_devices` [PXE, DISK, CDROM] - :persistent: Whether the boot device will persist to all - future boots or not, None if it is unknown. - :raises: InvalidParameterValue if the boot device is unknown - :raises: OneViewError if the communication with OneView fails - """ - oneview_client = common.get_hponeview_client() - driver_internal_info = task.node.driver_internal_info - next_boot_device = driver_internal_info.get('next_boot_device') - - if next_boot_device: - return next_boot_device - - driver_info = task.node.driver_info - server_profile = driver_info.get('applied_server_profile_uri') - - try: - profile = oneview_client.server_profiles.get(server_profile) - primary_device = None - boot = profile.get('boot', {}) - boot_order = boot.get('order', []) - if boot_order: - primary_device = boot_order[0] - except client_exception.HPOneViewException as exc: - msg = _("Error on node: %(node)s while getting Server Profile: " - "%(profile)s of the from OneView. Error: %(error)s.") % { - 'profile': server_profile, - 'node': task.node.uuid, - 'error': exc - } - raise exception.OneViewError(msg) - - if primary_device not in BOOT_DEVICE_MAP_ONEVIEW_REV: - raise exception.InvalidParameterValue( - _("Unsupported boot device %(device)s for node: %(node)s") - % {"device": primary_device, "node": task.node.uuid} - ) - - boot_device = { - 'boot_device': BOOT_DEVICE_MAP_ONEVIEW_REV.get(primary_device), - 'persistent': not _is_onetime_boot(task) - } - - return boot_device - - @METRICS.timer('OneViewManagement.get_sensors_data') - def get_sensors_data(self, task): - """Get sensors data. - - Not implemented by this driver. - :param task: a TaskManager instance. - """ - raise NotImplementedError() diff --git a/ironic/drivers/modules/oneview/power.py b/ironic/drivers/modules/oneview/power.py deleted file mode 100644 index 21013f104..000000000 --- a/ironic/drivers/modules/oneview/power.py +++ /dev/null @@ -1,224 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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. - -from ironic_lib import metrics_utils -from oslo_log import log as logging -from oslo_utils import importutils - -from ironic.common import exception -from ironic.common.i18n import _ -from ironic.common import states -from ironic.conductor import task_manager -from ironic.drivers import base -from ironic.drivers.modules.oneview import common -from ironic.drivers.modules.oneview import deploy_utils -from ironic.drivers.modules.oneview import management - -client_exception = importutils.try_import('hpOneView.exceptions') - -LOG = logging.getLogger(__name__) - -METRICS = metrics_utils.get_metrics_logger(__name__) - -POWER_ON = {'powerState': 'On'} -POWER_OFF = {'powerState': 'Off', 'powerControl': 'PressAndHold'} -REBOOT = {'powerState': 'On', 'powerControl': 'ColdBoot'} -SOFT_REBOOT = {'powerState': 'On', 'powerControl': 'Reset'} -SOFT_POWER_OFF = {'powerState': 'Off', 'powerControl': 'MomentaryPress'} - -GET_POWER_STATE_MAP = { - 'On': states.POWER_ON, - 'Off': states.POWER_OFF, - 'Resetting': states.REBOOT, - 'PoweringOff': states.POWER_ON, - 'PoweringOn': states.POWER_OFF -} - -SET_POWER_STATE_MAP = { - states.POWER_ON: POWER_ON, - states.POWER_OFF: POWER_OFF, - states.REBOOT: REBOOT, - states.SOFT_REBOOT: SOFT_REBOOT, - states.SOFT_POWER_OFF: SOFT_POWER_OFF -} - - -class OneViewPower(base.PowerInterface): - - # NOTE(TheJulia): Marking as unsupported as 3rd party CI was taken down - # shortly before the beginning of the Rocky cycle, and no replies have - # indicated that 3rd party CI will be re-established nor visible - # actions observed regarding re-establishing 3rd party CI. - # TODO(TheJulia): This should be expected to be removed in Stein. - supported = False - - def get_properties(self): - return deploy_utils.get_properties() - - @METRICS.timer('OneViewPower.validate') - def validate(self, task): - """Checks required info on 'driver_info' and validates node for OneView - - Validates whether the 'oneview_info' property of the supplied - task's node contains the required info such as server_hardware_uri, - server_hardware_type, server_profile_template_uri and - enclosure_group_uri. Also, checks if the server profile of the node is - applied, if NICs are valid for the server profile of the node, and if - the server hardware attributes (ram, memory, vcpus count) are - consistent with OneView. It validates if the node is being used by - Oneview. - - :param task: a task from TaskManager. - :raises: MissingParameterValue if a required parameter is missing. - :raises: InvalidParameterValue if parameters set are inconsistent with - resources in OneView - :raises: InvalidParameterValue if the node in use by OneView. - :raises: OneViewError if not possible to get OneView's information - for the given node, if not possible to retrieve Server - Hardware from OneView. - """ - common.verify_node_info(task.node) - - try: - common.validate_oneview_resources_compatibility(task) - if deploy_utils.is_node_in_use_by_oneview(task.node): - raise exception.InvalidParameterValue( - _("Node %s is in use by OneView.") % task.node.uuid) - except exception.OneViewError as oneview_exc: - raise exception.InvalidParameterValue(oneview_exc) - - @METRICS.timer('OneViewPower.get_power_state') - def get_power_state(self, task): - """Gets the current power state. - - :param task: a TaskManager instance. - :returns: one of :mod:`ironic.common.states` POWER_OFF, - POWER_ON or ERROR. - :raises: OneViewError if fails to retrieve power state of OneView - resource - """ - oneview_client = common.get_hponeview_client() - server_hardware = task.node.driver_info.get('server_hardware_uri') - try: - server_hardware = oneview_client.server_hardware.get( - server_hardware) - except client_exception.HPOneViewException as exc: - LOG.error( - "Error getting power state for node %(node)s. Error:" - "%(error)s", - {'node': task.node.uuid, 'error': exc} - ) - raise exception.OneViewError(error=exc) - else: - power_state = server_hardware.get('powerState') - return GET_POWER_STATE_MAP.get(power_state) - - @METRICS.timer('OneViewPower.set_power_state') - @task_manager.require_exclusive_lock - def set_power_state(self, task, power_state, timeout=None): - """Turn the current power state on or off. - - :param task: a TaskManager instance. - :param power_state: The desired power state POWER_ON, POWER_OFF or - REBOOT from :mod:`ironic.common.states`. - :param timeout: timeout (in seconds) positive integer (> 0) for any - power state. ``None`` indicates the default timeout. - :raises: InvalidParameterValue if an invalid power state was specified. - :raises: PowerStateFailure if the power couldn't be set to power_state. - :raises: OneViewError if OneView fails setting the power state. - """ - oneview_client = common.get_hponeview_client() - - if deploy_utils.is_node_in_use_by_oneview(task.node): - raise exception.PowerStateFailure(_( - "Cannot set power state '%(power_state)s' to node %(node)s. " - "The node is in use by OneView.") % - {'power_state': power_state, - 'node': task.node.uuid}) - - if power_state not in SET_POWER_STATE_MAP: - raise exception.InvalidParameterValue( - _("set_power_state called with invalid power state %(state)s " - "on node: %(node)s") % { - 'state': power_state, - 'node': task.node.uuid - }) - - LOG.debug('Setting power state of node %(node_uuid)s to ' - '%(power_state)s', - {'node_uuid': task.node.uuid, 'power_state': power_state}) - - server_hardware = task.node.driver_info.get('server_hardware_uri') - timeout = -1 if timeout is None else timeout - - try: - if power_state == states.POWER_ON: - management.set_boot_device(task) - oneview_client.server_hardware.update_power_state( - SET_POWER_STATE_MAP.get(power_state), - server_hardware, timeout=timeout) - elif (power_state == states.REBOOT - or power_state == states.SOFT_REBOOT): - power_off_mode = (states.POWER_OFF - if power_state == states.REBOOT - else states.SOFT_POWER_OFF) - - oneview_client.server_hardware.update_power_state( - SET_POWER_STATE_MAP.get(power_off_mode), - server_hardware, timeout=timeout) - management.set_boot_device(task) - oneview_client.server_hardware.update_power_state( - SET_POWER_STATE_MAP.get(states.POWER_ON), - server_hardware, timeout=timeout) - else: - oneview_client.server_hardware.update_power_state( - SET_POWER_STATE_MAP.get(power_state), - server_hardware, timeout=timeout) - except client_exception.HPOneViewException as exc: - raise exception.OneViewError( - _("Failed to setting power state on node: %(node)s. " - "Error: %(error)s.") % { - 'node': task.node.uuid, - 'error': exc - }) - - @METRICS.timer('OneViewPower.reboot') - @task_manager.require_exclusive_lock - def reboot(self, task, timeout=None): - """Reboot the node. - - :param task: a TaskManager instance. - :param timeout: timeout (in seconds) positive integer (> 0) for any - power state. ``None`` indicates to use default timeout. - :raises: PowerStateFailure if the final state of the node is not - POWER_ON. - """ - current_power_state = self.get_power_state(task) - if current_power_state == states.POWER_ON: - self.set_power_state(task, states.REBOOT, timeout=timeout) - else: - self.set_power_state(task, states.POWER_ON, timeout=timeout) - - @METRICS.timer('OneViewPower.get_supported_power_states') - def get_supported_power_states(self, task): - """Get a list of the supported power states. - - :param task: A TaskManager instance containing the node to act on. - Currently not used. - :returns: A list with the supported power states defined - in :mod:`ironic.common.states`. - """ - return [states.POWER_ON, states.POWER_OFF, states.REBOOT, - states.SOFT_REBOOT, states.SOFT_POWER_OFF] diff --git a/ironic/drivers/oneview.py b/ironic/drivers/oneview.py deleted file mode 100644 index 287f6cdc7..000000000 --- a/ironic/drivers/oneview.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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. - -""" -OneView hardware type. -""" - -from ironic.drivers import generic -from ironic.drivers.modules import noop -from ironic.drivers.modules.oneview import deploy -from ironic.drivers.modules.oneview import inspect -from ironic.drivers.modules.oneview import management -from ironic.drivers.modules.oneview import power - - -class OneViewHardware(generic.GenericHardware): - """OneView hardware type. - - OneView hardware type is targeted for OneView - """ - # NOTE(TheJulia): Marking as unsupported as 3rd party CI was taken down - # shortly before the beginning of the Rocky cycle, and no replies have - # indicated that 3rd party CI will be re-established nor visible - # actions observed regarding re-establishing 3rd party CI. - # TODO(TheJulia): This should be expected to be removed in Stein. - supported = False - - @property - def supported_deploy_interfaces(self): - """List of supported deploy interfaces.""" - return [deploy.OneViewIscsiDeploy, deploy.OneViewAgentDeploy] - - @property - def supported_inspect_interfaces(self): - """List of supported inspect interfaces.""" - return [inspect.OneViewInspect, noop.NoInspect] - - @property - def supported_management_interfaces(self): - """List of supported management interfaces.""" - return [management.OneViewManagement] - - @property - def supported_power_interfaces(self): - """List of supported power interfaces.""" - return [power.OneViewPower] diff --git a/ironic/tests/unit/db/utils.py b/ironic/tests/unit/db/utils.py index 294d24107..75bf016d9 100644 --- a/ironic/tests/unit/db/utils.py +++ b/ironic/tests/unit/db/utils.py @@ -423,24 +423,6 @@ def get_test_cimc_info(): } -def get_test_oneview_properties(): - return { - "cpu_arch": "x86_64", - "cpus": "8", - "local_gb": "10", - "memory_mb": "4096", - "capabilities": ("server_hardware_type_uri:fake_sht_uri," - "enclosure_group_uri:fake_eg_uri," - "server_profile_template_uri:fake_spt_uri"), - } - - -def get_test_oneview_driver_info(): - return { - 'server_hardware_uri': 'fake_sh_uri', - } - - def get_test_redfish_info(): return { "redfish_address": "https://example.com", diff --git a/ironic/tests/unit/drivers/modules/oneview/__init__.py b/ironic/tests/unit/drivers/modules/oneview/__init__.py deleted file mode 100644 index e69de29bb..000000000 --- a/ironic/tests/unit/drivers/modules/oneview/__init__.py +++ /dev/null diff --git a/ironic/tests/unit/drivers/modules/oneview/test_common.py b/ironic/tests/unit/drivers/modules/oneview/test_common.py deleted file mode 100644 index 6f2452bc5..000000000 --- a/ironic/tests/unit/drivers/modules/oneview/test_common.py +++ /dev/null @@ -1,406 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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 oslo_utils import importutils - -from ironic.common import exception -from ironic.conductor import task_manager -from ironic.drivers.modules.oneview import common -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('hpOneView.oneview_client') - - -class BaseOneViewTest(db_base.DbTestCase): - - deploy_interface = None - - def setUp(self): - super(BaseOneViewTest, self).setUp() - self.config(enabled_hardware_types=['oneview', 'fake-hardware'], - enabled_deploy_interfaces=['oneview-direct', - 'oneview-iscsi', 'fake'], - enabled_management_interfaces=['oneview', 'fake'], - enabled_inspect_interfaces=['oneview', 'fake', - 'no-inspect'], - enabled_power_interfaces=['oneview', 'fake']) - self.node = obj_utils.create_test_node( - self.context, driver='oneview', - deploy_interface=self.deploy_interface, - properties=db_utils.get_test_oneview_properties(), - driver_info=db_utils.get_test_oneview_driver_info(), - ) - - -class OneViewCommonTestCase(BaseOneViewTest): - - def setUp(self): - super(OneViewCommonTestCase, self).setUp() - self.config(manager_url='https://1.2.3.4', group='oneview') - self.config(username='user', group='oneview') - self.config(password='password', group='oneview') - self.config(tls_cacert_file='ca_file', group='oneview') - self.config(allow_insecure_connections=False, group='oneview') - - 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"), "oneview") - self.assertEqual( - common.prepare_manager_url("oneview"), "oneview") - - @mock.patch.object(hponeview_client, 'OneViewClient', 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_hponeview_client_insecure_false(self): - self.config(tls_cacert_file=None, group='oneview') - self.assertRaises(exception.OneViewError, common.get_hponeview_client) - - @mock.patch.object(hponeview_client, 'OneViewClient', autospec=True) - def test_get_hponeview_client_insecure_cafile(self, mock_oneview): - self.config(allow_insecure_connections=True, group='oneview') - credentials = { - "ip": 'https://1.2.3.4', - "credentials": { - "userName": 'user', - "password": 'password' - }, - "ssl_certificate": None - } - mock_oneview.assert_called_once_with(credentials) - - 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(self): - common.verify_node_info(self.node) - - def test_verify_node_info_missing_node_properties(self): - self.node.properties = { - "cpu_arch": "x86_64", - "cpus": "8", - "local_gb": "10", - "memory_mb": "4096", - "capabilities": ("enclosure_group_uri:fake_eg_uri," - "server_profile_template_uri:fake_spt_uri") - } - with self.assertRaisesRegex(exception.MissingParameterValue, - "server_hardware_type_uri"): - common.verify_node_info(self.node) - - def test_verify_node_info_missing_node_driver_info(self): - self.node.driver_info = {} - - with self.assertRaisesRegex(exception.MissingParameterValue, - "server_hardware_uri"): - common.verify_node_info(self.node) - - def test_verify_node_info_missing_spt(self): - properties = db_utils.get_test_oneview_properties() - properties["capabilities"] = ("server_hardware_type_uri:fake_sht_uri," - "enclosure_group_uri:fake_eg_uri") - - self.node.properties = properties - with self.assertRaisesRegex(exception.MissingParameterValue, - "server_profile_template_uri"): - common.verify_node_info(self.node) - - def test_verify_node_info_missing_sh(self): - driver_info = db_utils.get_test_oneview_driver_info() - - del driver_info["server_hardware_uri"] - properties = db_utils.get_test_oneview_properties() - properties["capabilities"] = ( - "server_hardware_type_uri:fake_sht_uri," - "enclosure_group_uri:fake_eg_uri," - "server_profile_template_uri:fake_spt_uri" - ) - - self.node.properties = properties - self.node.driver_info = driver_info - with self.assertRaisesRegex(exception.MissingParameterValue, - "server_hardware_uri"): - common.verify_node_info(self.node) - - def test_verify_node_info_missing_sht(self): - driver_info = db_utils.get_test_oneview_driver_info() - properties = db_utils.get_test_oneview_properties() - properties["capabilities"] = ( - "enclosure_group_uri:fake_eg_uri," - "server_profile_template_uri:fake_spt_uri" - ) - - self.node.properties = properties - self.node.driver_info = driver_info - with self.assertRaisesRegex(exception.MissingParameterValue, - "server_hardware_type_uri"): - common.verify_node_info(self.node) - - def test_get_oneview_info(self): - complete_node = self.node - expected_node_info = { - 'server_hardware_uri': 'fake_sh_uri', - 'server_hardware_type_uri': 'fake_sht_uri', - 'enclosure_group_uri': 'fake_eg_uri', - 'server_profile_template_uri': 'fake_spt_uri', - 'applied_server_profile_uri': None, - } - - self.assertEqual( - expected_node_info, - common.get_oneview_info(complete_node) - ) - - def test_get_oneview_info_missing_spt(self): - driver_info = db_utils.get_test_oneview_driver_info() - properties = db_utils.get_test_oneview_properties() - properties["capabilities"] = ("server_hardware_type_uri:fake_sht_uri," - "enclosure_group_uri:fake_eg_uri") - - self.node.driver_info = driver_info - self.node.properties = properties - - incomplete_node = self.node - expected_node_info = { - 'server_hardware_uri': 'fake_sh_uri', - 'server_hardware_type_uri': 'fake_sht_uri', - 'enclosure_group_uri': 'fake_eg_uri', - 'server_profile_template_uri': None, - 'applied_server_profile_uri': None, - } - - self.assertEqual( - expected_node_info, - common.get_oneview_info(incomplete_node) - ) - - def test_get_oneview_info_missing_sh(self): - driver_info = db_utils.get_test_oneview_driver_info() - - del driver_info["server_hardware_uri"] - properties = db_utils.get_test_oneview_properties() - properties["capabilities"] = ( - "server_hardware_type_uri:fake_sht_uri," - "enclosure_group_uri:fake_eg_uri," - "server_profile_template_uri:fake_spt_uri" - ) - - self.node.driver_info = driver_info - self.node.properties = properties - - incomplete_node = self.node - expected_node_info = { - 'server_hardware_uri': None, - 'server_hardware_type_uri': 'fake_sht_uri', - 'enclosure_group_uri': 'fake_eg_uri', - 'server_profile_template_uri': 'fake_spt_uri', - 'applied_server_profile_uri': None, - } - - self.assertEqual( - expected_node_info, - common.get_oneview_info(incomplete_node) - ) - - def test_get_oneview_info_malformed_capabilities(self): - driver_info = db_utils.get_test_oneview_driver_info() - - del driver_info["server_hardware_uri"] - properties = db_utils.get_test_oneview_properties() - properties["capabilities"] = "anything,000" - - self.node.driver_info = driver_info - self.node.properties = properties - - self.assertRaises(exception.OneViewInvalidNodeParameter, - common.get_oneview_info, - self.node) - - def test__verify_node_info(self): - common._verify_node_info("properties", - {"a": True, - "b": False, - "c": 0, - "d": "something", - "e": "somethingelse"}, - ["a", "b", "c", "e"]) - - def test__verify_node_info_fails(self): - self.assertRaises( - exception.MissingParameterValue, - common._verify_node_info, - "properties", - {"a": 1, "b": 2, "c": 3}, - ["x"] - ) - - def test__verify_node_info_missing_values_empty_string(self): - with self.assertRaisesRegex(exception.MissingParameterValue, - "'properties:a', 'properties:b'"): - common._verify_node_info("properties", - {"a": '', "b": None, "c": "something"}, - ["a", "b", "c"]) - - @mock.patch.object(common, 'get_hponeview_client', autospec=True) - @mock.patch.object(common, '_validate_node_server_profile_template') - @mock.patch.object(common, '_validate_node_server_hardware_type') - @mock.patch.object(common, '_validate_node_enclosure_group') - @mock.patch.object(common, '_validate_node_port_mac_server_hardware') - @mock.patch.object(common, '_validate_server_profile_template_mac_type') - def test_validate_oneview_resources_compatibility( - self, mock_spt_mac_type, mock_port_mac_sh, mock_enclosure, - mock_sh_type, mock_sp_template, mock_hponeview): - """Validate compatibility of resources. - - 1) Check _validate_node_server_profile_template method is called - 2) Check _validate_node_server_hardware_type method is called - 3) Check _validate_node_enclosure_group method is called - 4) Check _validate_node_port_mac_server_hardware method is called - 5) Check _validate_server_profile_template_mac_type method is called - """ - oneview_client = mock_hponeview() - fake_port = db_utils.create_test_port() - fake_port.address = 'AA:BB:CC:DD:EE' - fake_device = {'physicalPorts': [ - {'type': 'Ethernet', - 'virtualPorts': [ - {'portFunction': 'a', - 'mac': 'AA:BB:CC:DD:EE'} - ]} - ]} - fake_spt = { - 'serverHardwareTypeUri': 'fake_sht_uri', - 'enclosureGroupUri': 'fake_eg_uri', - 'macType': 'Physical', - 'boot': {'manageBoot': True} - } - fake_sh = { - 'serverHardwareTypeUri': 'fake_sht_uri', - 'serverGroupUri': 'fake_eg_uri', - 'processorCoreCount': 4, - 'processorCount': 2, - 'memoryMb': 4096, - 'portMap': {'deviceSlots': [fake_device]} - } - oneview_client.server_profile_templates.get.return_value = fake_spt - oneview_client.server_hardware.get.return_value = fake_sh - - with task_manager.acquire(self.context, self.node.uuid) as task: - task.ports = [fake_port] - common.validate_oneview_resources_compatibility(task) - self.assertTrue(mock_sp_template.called) - self.assertTrue(mock_sh_type.called) - self.assertTrue(mock_enclosure.called) - self.assertTrue(mock_port_mac_sh.called) - self.assertTrue(mock_spt_mac_type.called) - - @mock.patch.object(common, 'get_hponeview_client', autospec=True) - def test__validate_server_profile_template_mac_type_virtual( - self, mock_hponeview): - oneview_client = mock_hponeview() - fake_spt = {'macType': 'Virtual'} - oneview_client.server_hardware.get.return_value = fake_spt - oneview_info = {'server_profile_template_uri': 'fake_uri'} - - self.assertRaises(exception.OneViewError, - common._validate_server_profile_template_mac_type, - oneview_client, oneview_info) - - @mock.patch.object(common, 'get_hponeview_client', autospec=True) - def test__validate_node_port_mac_server_hardware_invalid( - self, mock_hponeview): - oneview_client = mock_hponeview() - fake_device = { - 'physicalPorts': [ - {'type': 'notEthernet', - 'mac': '00:11:22:33:44', - 'virtualPorts': [{ - 'portFunction': 'a', - 'mac': 'AA:BB:CC:DD:EE'}]}, - {'type': 'Ethernet', - 'mac': '11:22:33:44:55', - 'virtualPorts': [{ - 'portFunction': 'a', - 'mac': 'BB:CC:DD:EE:FF'}]}]} - fake_sh = {'portMap': {'deviceSlots': [fake_device]}} - fake_port = db_utils.create_test_port(address='AA:BB:CC:DD:EE') - oneview_client.server_hardware.get.return_value = fake_sh - oneview_info = db_utils.get_test_oneview_driver_info() - - self.assertRaises(exception.OneViewError, - common._validate_node_port_mac_server_hardware, - oneview_client, oneview_info, [fake_port]) - - @mock.patch.object(common, 'get_hponeview_client', autospec=True) - def test__validate_node_enclosure_group_invalid(self, mock_hponeview): - oneview_client = mock_hponeview() - fake_sh = {'serverGroupUri': 'invalid_fake_eg_uri'} - oneview_client.server_hardware.get.return_value = fake_sh - oneview_info = {'server_hardware_uri': 'fake_sh_uri', - 'enclosure_group_uri': 'fake_eg_uri'} - - self.assertRaises(exception.OneViewError, - common._validate_node_enclosure_group, - oneview_client, oneview_info) - - @mock.patch.object(common, 'get_hponeview_client', autospec=True) - def test__validate_node_server_hardware_type(self, mock_hponeview): - oneview_client = mock_hponeview() - fake_sh = {'serverHardwareTypeUri': 'invalid_fake_sh_uri'} - oneview_client.server_hardware.get.return_value = fake_sh - oneview_info = {'server_hardware_uri': 'fake_sh_uri', - 'server_hardware_type_uri': 'fake_sht_uri'} - - self.assertRaises(exception.OneViewError, - common._validate_node_server_hardware_type, - oneview_client, oneview_info) - - def test__validate_server_profile_template_manage_boot_false(self): - fake_spt = {'boot': {'manageBoot': False}} - self.assertRaises(exception.OneViewError, - common._validate_server_profile_template_manage_boot, - fake_spt) - - def test__validate_spt_enclosure_group_invalid(self): - fake_spt = {'enclosureGroupUri': 'fake_eg_uri'} - fake_sh = {'serverGroupUri': 'invalid_fake_eg_uri'} - self.assertRaises(exception.OneViewError, - common._validate_spt_enclosure_group, - fake_spt, fake_sh) - - def test__validate_server_profile_template_server_hardware_type(self): - fake_spt = {'serverHardwareTypeUri': 'fake_sht_uri'} - fake_sh = {'serverHardwareTypeUri': 'invalid_fake_sht_uri'} - self.assertRaises( - exception.OneViewError, - common._validate_server_profile_template_server_hardware_type, - fake_spt, fake_sh) diff --git a/ironic/tests/unit/drivers/modules/oneview/test_deploy.py b/ironic/tests/unit/drivers/modules/oneview/test_deploy.py deleted file mode 100644 index 4baeeffa3..000000000 --- a/ironic/tests/unit/drivers/modules/oneview/test_deploy.py +++ /dev/null @@ -1,456 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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 ironic.common import exception -from ironic.common import states -from ironic.conductor import task_manager -from ironic.conf import CONF -from ironic.drivers.modules import agent -from ironic.drivers.modules import iscsi_deploy -from ironic.drivers.modules.oneview import common -from ironic.drivers.modules.oneview import deploy -from ironic.drivers.modules.oneview import deploy_utils -from ironic.tests.unit.drivers.modules.oneview import test_common -from ironic.tests.unit.objects import utils as obj_utils - -METHODS = ['iter_nodes', 'update_node', 'do_provisioning_action'] - -oneview_error = common.SERVER_HARDWARE_ALLOCATION_ERROR -maintenance_reason = common.NODE_IN_USE_BY_ONEVIEW - -driver_internal_info = {'oneview_error': oneview_error} -nodes_taken_by_oneview = [(1, 'oneview', '')] -nodes_freed_by_oneview = [(1, 'oneview', '', maintenance_reason)] -nodes_taken_on_cleanfail = [(1, 'oneview', '', driver_internal_info)] -nodes_taken_on_cleanfail_no_info = [(1, 'oneview', '', {})] - -GET_POWER_STATE_RETRIES = 5 - - -def _setup_node_in_available_state(node): - node.provision_state = states.AVAILABLE - node.maintenance = False - node.maintenance_reason = None - node.save() - - -def _setup_node_in_manageable_state(node): - node.provision_state = states.MANAGEABLE - node.maintenance = True - node.maintenance_reason = common.NODE_IN_USE_BY_ONEVIEW - node.save() - - -def _setup_node_in_cleanfailed_state_with_oneview_error(node): - node.provision_state = states.CLEANFAIL - node.maintenance = False - node.maintenance_reason = None - driver_internal_info = node.driver_internal_info - oneview_error = common.SERVER_HARDWARE_ALLOCATION_ERROR - driver_internal_info['oneview_error'] = oneview_error - node.driver_internal_info = driver_internal_info - node.save() - - -def _setup_node_in_cleanfailed_state_without_oneview_error(node): - node.provision_state = states.CLEANFAIL - node.maintenance = False - node.maintenance_reason = None - node.save() - - -class OneViewDriverDeploy(deploy.OneViewPeriodicTasks): - oneview_driver = 'oneview' - - -@mock.patch('ironic.objects.Node', spec_set=True, autospec=True) -@mock.patch.object(deploy_utils, 'is_node_in_use_by_oneview') -class OneViewPeriodicTasks(test_common.BaseOneViewTest): - - def setUp(self): - super(OneViewPeriodicTasks, self).setUp() - self.config(manager_url='https://1.2.3.4', group='oneview') - self.config(username='user', group='oneview') - self.config(password='password', group='oneview') - - self.deploy = OneViewDriverDeploy() - self.os_primary = mock.MagicMock(spec=METHODS) - - def test_node_manageable_maintenance_when_in_use_by_oneview( - self, mock_is_node_in_use_by_oneview, mock_node_get - ): - mock_node_get.get.return_value = self.node - _setup_node_in_available_state(self.node) - self.os_primary.iter_nodes.return_value = nodes_taken_by_oneview - mock_is_node_in_use_by_oneview.return_value = True - self.deploy._periodic_check_nodes_taken_by_oneview( - self.os_primary, self.context - ) - mock_is_node_in_use_by_oneview.assert_called_once_with(self.node) - self.assertTrue(self.os_primary.update_node.called) - self.assertTrue(self.os_primary.do_provisioning_action.called) - self.assertTrue(self.node.maintenance) - self.assertEqual(common.NODE_IN_USE_BY_ONEVIEW, - self.node.maintenance_reason) - - def test_node_stay_available_when_not_in_use_by_oneview( - self, mock_is_node_in_use_by_oneview, mock_node_get - ): - mock_node_get.get.return_value = self.node - _setup_node_in_available_state(self.node) - mock_node_get.return_value = self.node - mock_is_node_in_use_by_oneview.return_value = False - self.os_primary.iter_nodes.return_value = nodes_taken_by_oneview - self.deploy._periodic_check_nodes_taken_by_oneview( - self.os_primary, self.context - ) - mock_is_node_in_use_by_oneview.assert_called_once_with(self.node) - self.assertFalse(self.os_primary.update_node.called) - self.assertFalse(self.os_primary.do_provisioning_action.called) - self.assertFalse(self.node.maintenance) - self.assertIsNone(self.node.maintenance_reason) - - def test_node_stay_available_when_raise_exception( - self, mock_is_node_in_use_by_oneview, mock_node_get - ): - mock_node_get.get.return_value = self.node - _setup_node_in_available_state(self.node) - side_effect = exception.OneViewError('boom') - mock_is_node_in_use_by_oneview.side_effect = side_effect - self.os_primary.iter_nodes.return_value = nodes_taken_by_oneview - self.deploy._periodic_check_nodes_taken_by_oneview( - self.os_primary, self.context - ) - mock_is_node_in_use_by_oneview.assert_called_once_with(self.node) - self.assertFalse(self.os_primary.update_node.called) - self.assertFalse(self.os_primary.do_provisioning_action.called) - self.assertFalse(self.node.maintenance) - self.assertNotEqual(common.NODE_IN_USE_BY_ONEVIEW, - self.node.maintenance_reason) - - def test_node_available_when_not_in_use_by_oneview( - self, mock_is_node_in_use_by_oneview, mock_node_get - ): - mock_node_get.get.return_value = self.node - _setup_node_in_manageable_state(self.node) - self.os_primary.iter_nodes.return_value = nodes_freed_by_oneview - mock_is_node_in_use_by_oneview.return_value = False - self.deploy._periodic_check_nodes_freed_by_oneview( - self.os_primary, self.context - ) - mock_is_node_in_use_by_oneview.assert_called_once_with(self.node) - self.assertTrue(self.os_primary.update_node.called) - self.assertTrue(self.os_primary.do_provisioning_action.called) - self.assertFalse(self.node.maintenance) - self.assertIsNone(self.node.maintenance_reason) - - def test_node_stay_manageable_when_in_use_by_oneview( - self, mock_is_node_in_use_by_oneview, mock_node_get - ): - mock_node_get.get.return_value = self.node - _setup_node_in_manageable_state(self.node) - mock_is_node_in_use_by_oneview.return_value = True - self.os_primary.iter_nodes.return_value = nodes_freed_by_oneview - self.deploy._periodic_check_nodes_freed_by_oneview( - self.os_primary, self.context - ) - mock_is_node_in_use_by_oneview.assert_called_once_with(self.node) - self.assertFalse(self.os_primary.update_node.called) - self.assertFalse(self.os_primary.do_provisioning_action.called) - self.assertTrue(self.node.maintenance) - self.assertEqual(common.NODE_IN_USE_BY_ONEVIEW, - self.node.maintenance_reason) - - def test_node_stay_manageable_maintenance_when_raise_exception( - self, mock_is_node_in_use_by_oneview, mock_node_get - ): - mock_node_get.get.return_value = self.node - _setup_node_in_manageable_state(self.node) - side_effect = exception.OneViewError('boom') - mock_is_node_in_use_by_oneview.side_effect = side_effect - self.os_primary.iter_nodes.return_value = nodes_freed_by_oneview - self.deploy._periodic_check_nodes_freed_by_oneview( - self.os_primary, self.context - ) - mock_is_node_in_use_by_oneview.assert_called_once_with(self.node) - self.assertFalse(self.os_primary.update_node.called) - self.assertFalse(self.os_primary.do_provisioning_action.called) - self.assertTrue(self.node.maintenance) - self.assertEqual(common.NODE_IN_USE_BY_ONEVIEW, - self.node.maintenance_reason) - - def test_node_manageable_maintenance_when_oneview_error( - self, mock_is_node_in_use_by_oneview, mock_node_get - ): - mock_node_get.get.return_value = self.node - _setup_node_in_cleanfailed_state_with_oneview_error(self.node) - self.os_primary.iter_nodes.return_value = nodes_taken_on_cleanfail - self.deploy._periodic_check_nodes_taken_on_cleanfail( - self.os_primary, self.context - ) - self.assertTrue(self.os_primary.update_node.called) - self.assertTrue(self.os_primary.do_provisioning_action.called) - self.assertTrue(self.node.maintenance) - self.assertEqual(common.NODE_IN_USE_BY_ONEVIEW, - self.node.maintenance_reason) - self.assertNotIn('oneview_error', self.node.driver_internal_info) - - def test_node_stay_clean_failed_when_no_oneview_error( - self, mock_is_node_in_use_by_oneview, mock_node_get - ): - mock_node_get.get.return_value = self.node - _setup_node_in_cleanfailed_state_without_oneview_error(self.node) - self.os_primary.iter_nodes.return_value = ( - nodes_taken_on_cleanfail_no_info) - self.deploy._periodic_check_nodes_taken_on_cleanfail( - self.os_primary, self.context - ) - self.assertFalse(self.os_primary.update_node.called) - self.assertFalse(self.os_primary.do_provisioning_action.called) - self.assertFalse(self.node.maintenance) - self.assertNotEqual(common.NODE_IN_USE_BY_ONEVIEW, - self.node.maintenance_reason) - self.assertNotIn('oneview_error', self.node.driver_internal_info) - - -class OneViewIscsiDeployTestCase(test_common.BaseOneViewTest): - - deploy_interface = 'oneview-iscsi' - - def setUp(self): - super(OneViewIscsiDeployTestCase, self).setUp() - self.config(manager_url='https://1.2.3.4', group='oneview') - self.config(username='user', group='oneview') - self.config(password='password', group='oneview') - - self.port = obj_utils.create_test_port(self.context, - node_id=self.node.id) - self.info = common.get_oneview_info(self.node) - - def test_get_properties(self): - expected = common.COMMON_PROPERTIES - self.assertEqual(expected, - deploy.OneViewIscsiDeploy().get_properties()) - - @mock.patch.object(common, 'validate_oneview_resources_compatibility', - spect_set=True, autospec=True) - @mock.patch.object(iscsi_deploy.ISCSIDeploy, 'validate', - spec_set=True, autospec=True) - def test_validate( - self, iscsi_deploy_validate_mock, mock_validate): - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.deploy.validate(task) - self.assertTrue(mock_validate.called) - iscsi_deploy_validate_mock.assert_called_once_with(mock.ANY, task) - - @mock.patch.object(iscsi_deploy.ISCSIDeploy, 'prepare', autospec=True) - @mock.patch.object(deploy_utils, 'allocate_server_hardware_to_ironic') - def test_prepare(self, allocate_server_hardware_mock, - iscsi_deploy_prepare_mock): - self.node.provision_state = states.DEPLOYING - self.node.save() - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.deploy.prepare(task) - iscsi_deploy_prepare_mock.assert_called_once_with(mock.ANY, task) - self.assertTrue(allocate_server_hardware_mock.called) - - @mock.patch.object(iscsi_deploy.ISCSIDeploy, 'prepare', - spec_set=True, autospec=True) - def test_prepare_active_node(self, iscsi_deploy_prepare_mock): - """Ensure nodes in running states are not inadvertently changed""" - test_states = list(states.STABLE_STATES) - test_states.extend([states.CLEANING, - states.CLEANWAIT, - states.INSPECTING]) - for state in test_states: - self.node.provision_state = state - self.node.save() - iscsi_deploy_prepare_mock.reset_mock() - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.deploy.prepare(task) - iscsi_deploy_prepare_mock.assert_called_once_with( - mock.ANY, task) - - @mock.patch.object(iscsi_deploy.ISCSIDeploy, 'deploy', - spec_set=True, autospec=True) - def test_deploy(self, iscsi_deploy_mock): - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.deploy.deploy(task) - iscsi_deploy_mock.assert_called_once_with(mock.ANY, task) - - @mock.patch.object(iscsi_deploy.ISCSIDeploy, 'tear_down', spec_set=True, - autospec=True) - def test_tear_down(self, iscsi_tear_down_mock): - iscsi_tear_down_mock.return_value = states.DELETED - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - returned_state = task.driver.deploy.tear_down(task) - iscsi_tear_down_mock.assert_called_once_with(mock.ANY, task) - self.assertEqual(states.DELETED, returned_state) - - @mock.patch.object(iscsi_deploy.ISCSIDeploy, 'tear_down', spec_set=True, - autospec=True) - @mock.patch.object(deploy_utils, 'deallocate_server_hardware_from_ironic') - def test_tear_down_with_automated_clean_disabled( - self, deallocate_server_hardware_mock, iscsi_tear_down_mock): - CONF.conductor.automated_clean = False - iscsi_tear_down_mock.return_value = states.DELETED - - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - returned_state = task.driver.deploy.tear_down(task) - iscsi_tear_down_mock.assert_called_once_with(mock.ANY, task) - self.assertEqual(states.DELETED, returned_state) - self.assertTrue(deallocate_server_hardware_mock.called) - - @mock.patch.object(iscsi_deploy.ISCSIDeploy, 'prepare_cleaning', - spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'allocate_server_hardware_to_ironic') - def test_prepare_cleaning( - self, allocate_server_hardware_mock, iscsi_prep_clean_mock): - iscsi_prep_clean_mock.return_value = states.CLEANWAIT - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - ret = task.driver.deploy.prepare_cleaning(task) - self.assertEqual(states.CLEANWAIT, ret) - iscsi_prep_clean_mock.assert_called_once_with(mock.ANY, task) - self.assertTrue(allocate_server_hardware_mock.called) - - @mock.patch.object(iscsi_deploy.ISCSIDeploy, 'tear_down_cleaning', - spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'deallocate_server_hardware_from_ironic') - def test_tear_down_cleaning( - self, deallocate_server_hardware_mock, iscsi_tear_down_clean_mock): - iscsi_tear_down_clean_mock.return_value = states.CLEANWAIT - - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.deploy.tear_down_cleaning(task) - iscsi_tear_down_clean_mock.assert_called_once_with(mock.ANY, task) - self.assertTrue(deallocate_server_hardware_mock.called) - - -class OneViewAgentDeployTestCase(test_common.BaseOneViewTest): - - deploy_interface = 'oneview-direct' - - def setUp(self): - super(OneViewAgentDeployTestCase, self).setUp() - self.config(manager_url='https://1.2.3.4', group='oneview') - self.config(username='user', group='oneview') - self.config(password='password', group='oneview') - - self.port = obj_utils.create_test_port(self.context, - node_id=self.node.id) - self.info = common.get_oneview_info(self.node) - - def test_get_properties(self): - expected = common.COMMON_PROPERTIES - self.assertEqual(expected, - deploy.OneViewAgentDeploy().get_properties()) - - @mock.patch.object(common, 'validate_oneview_resources_compatibility', - spect_set=True, autospec=True) - @mock.patch.object(agent.AgentDeploy, 'validate', - spec_set=True, autospec=True) - def test_validate( - self, agent_deploy_validate_mock, mock_validate): - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.deploy.validate(task) - self.assertTrue(mock_validate.called) - - @mock.patch.object(agent.AgentDeploy, 'prepare', - spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'allocate_server_hardware_to_ironic') - def test_prepare( - self, allocate_server_hardware_mock, agent_deploy_prepare_mock): - self.node.provision_state = states.DEPLOYING - self.node.save() - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.deploy.prepare(task) - agent_deploy_prepare_mock.assert_called_once_with(mock.ANY, task) - self.assertTrue(allocate_server_hardware_mock.called) - - @mock.patch.object(agent.AgentDeploy, 'prepare', - spec_set=True, autospec=True) - def test_prepare_active_node(self, agent_deploy_prepare_mock): - """Ensure nodes in running states are not inadvertently changed""" - test_states = list(states.STABLE_STATES) - test_states.extend([states.CLEANING, - states.CLEANWAIT, - states.INSPECTING]) - for state in test_states: - self.node.provision_state = state - self.node.save() - agent_deploy_prepare_mock.reset_mock() - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.deploy.prepare(task) - agent_deploy_prepare_mock.assert_called_once_with( - mock.ANY, task) - - @mock.patch.object(agent.AgentDeploy, 'deploy', - spec_set=True, autospec=True) - def test_deploy(self, agent_deploy_mock): - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.deploy.deploy(task) - agent_deploy_mock.assert_called_once_with(mock.ANY, task) - - @mock.patch.object(agent.AgentDeploy, 'tear_down', spec_set=True, - autospec=True) - @mock.patch.object(deploy_utils, 'deallocate_server_hardware_from_ironic') - def test_tear_down_with_automated_clean_disabled( - self, deallocate_server_hardware_mock, agent_tear_down_mock): - CONF.conductor.automated_clean = False - agent_tear_down_mock.return_value = states.DELETED - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - returned_state = task.driver.deploy.tear_down(task) - agent_tear_down_mock.assert_called_once_with(mock.ANY, task) - self.assertEqual(states.DELETED, returned_state) - self.assertTrue(deallocate_server_hardware_mock.called) - - @mock.patch.object(agent.AgentDeploy, 'prepare_cleaning', - spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'allocate_server_hardware_to_ironic') - def test_prepare_cleaning( - self, allocate_server_hardware_mock, agent_prep_clean_mock): - agent_prep_clean_mock.return_value = states.CLEANWAIT - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - ret = task.driver.deploy.prepare_cleaning(task) - self.assertEqual(states.CLEANWAIT, ret) - agent_prep_clean_mock.assert_called_once_with(mock.ANY, task) - self.assertTrue(allocate_server_hardware_mock.called) - - @mock.patch.object(agent.AgentDeploy, 'tear_down_cleaning', - spec_set=True, autospec=True) - @mock.patch.object(deploy_utils, 'deallocate_server_hardware_from_ironic') - def test_tear_down_cleaning( - self, deallocate_server_hardware_mock, agent_tear_down_clean_mock): - agent_tear_down_clean_mock.return_value = states.CLEANWAIT - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.deploy.tear_down_cleaning(task) - agent_tear_down_clean_mock.assert_called_once_with(mock.ANY, task) - self.assertTrue(deallocate_server_hardware_mock.called) diff --git a/ironic/tests/unit/drivers/modules/oneview/test_deploy_utils.py b/ironic/tests/unit/drivers/modules/oneview/test_deploy_utils.py deleted file mode 100644 index e97a6eac8..000000000 --- a/ironic/tests/unit/drivers/modules/oneview/test_deploy_utils.py +++ /dev/null @@ -1,327 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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 oslo_utils import importutils - -from ironic.common import exception -from ironic.common import states -from ironic.conductor import task_manager -from ironic.drivers.modules.oneview import common -from ironic.drivers.modules.oneview import deploy_utils -from ironic import objects -from ironic.tests.unit.drivers.modules.oneview import test_common - -oneview_models = importutils.try_import('oneview_client.models') - - -@mock.patch.object(common, 'get_hponeview_client') -class OneViewDeployUtilsTestCase(test_common.BaseOneViewTest): - - def setUp(self): - super(OneViewDeployUtilsTestCase, self).setUp() - self.config(manager_url='https://1.2.3.4', group='oneview') - self.config(username='user', group='oneview') - self.config(password='password', group='oneview') - self.info = common.get_oneview_info(self.node) - deploy_utils.is_node_in_use_by_oneview = mock.Mock(return_value=False) - deploy_utils.is_node_in_use_by_ironic = mock.Mock(return_value=True) - - # Tests for prepare - def test_prepare_node_is_in_use_by_oneview(self, mock_oneview_client): - """`prepare` behavior when the node has a Profile on OneView.""" - deploy_utils.is_node_in_use_by_oneview.return_value = True - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.provision_state = states.DEPLOYING - self.assertRaises( - exception.InstanceDeployFailure, - deploy_utils.prepare, - task - ) - - @mock.patch.object(objects.Node, 'save') - def test_prepare_node_is_successfuly_allocated_to_ironic( - self, mock_save, mock_oneview_client): - """`prepare` behavior when the node is free from OneView standpoint.""" - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.provision_state = states.DEPLOYING - deploy_utils.prepare(task) - self.assertTrue(mock_save.called) - - # Tests for tear_down - def test_tear_down(self, mock_oneview_client): - """`tear_down` behavior when node already has Profile applied.""" - oneview_client = mock_oneview_client() - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - '/rest/server-profiles/1234556789' - ) - self.assertTrue( - 'applied_server_profile_uri' in task.node.driver_info - ) - deploy_utils.tear_down(task) - self.assertFalse( - 'applied_server_profile_uri' in task.node.driver_info - ) - self.assertTrue(oneview_client.server_profiles.delete.called) - - # Tests for prepare_cleaning - @mock.patch.object(objects.Node, 'save') - def test_prepare_cleaning_when_node_does_not_have_sp_applied( - self, mock_save, mock_oneview_client): - """`prepare_cleaning` behavior when node is free.""" - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertFalse( - 'applied_server_profile_uri' in task.node.driver_info - ) - deploy_utils.prepare_cleaning(task) - self.assertTrue( - 'applied_server_profile_uri' in task.node.driver_info - ) - - @mock.patch.object(objects.Node, 'save') - def test_prepare_cleaning_when_node_has_sp_applied( - self, mock_node_save, mock_oneview_client): - """`prepare_cleaning` behavior when node has Profile applied.""" - oneview_client = mock_oneview_client() - oneview_client.server_hardware.get.return_value = { - 'serverProfileUri': 'same/sp_applied' - } - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - 'same/sp_applied' - ) - deploy_utils.prepare_cleaning(task) - self.assertFalse(mock_node_save.called) - - def test_prepare_cleaning_node_is_in_use_by_oneview( - self, mock_oneview_client): - """`prepare_cleaning` behavior when node has Profile on OneView.""" - deploy_utils.is_node_in_use_by_oneview.return_value = True - - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.NodeCleaningFailure, - deploy_utils.prepare_cleaning, - task - ) - - # Tests for tear_down_cleaning - def test_tear_down_cleaning(self, mock_oneview_client): - """Check if Server Profile was deleted and its uri removed.""" - oneview_client = mock_oneview_client() - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - '/rest/server-profiles/1234556789' - ) - self.assertTrue( - 'applied_server_profile_uri' in task.node.driver_info - ) - deploy_utils.tear_down_cleaning(task) - self.assertFalse( - 'applied_server_profile_uri' in task.node.driver_info - ) - self.assertTrue(oneview_client.server_profiles.delete.called) - - # Tests for is_node_in_use_by_oneview - def test_is_node_in_use_by_oneview(self, mock_oneview_client): - """Node has a Server Profile applied by a third party user.""" - server_hardware = { - 'serverProfileUri': '/rest/server-profile/123456789' - } - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - '/rest/server-profile/987654321' - ) - self.assertTrue( - deploy_utils._is_node_in_use( - server_hardware, - task.node.driver_info['applied_server_profile_uri'], - by_oneview=True - ) - ) - - def test_is_node_in_use_by_oneview_no_server_profile( - self, mock_oneview_client): - """Node has no Server Profile.""" - server_hardware = {'serverProfileUri': None} - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - '/rest/server-profile/123456789' - ) - self.assertFalse( - deploy_utils._is_node_in_use( - server_hardware, - task.node.driver_info['applied_server_profile_uri'], - by_oneview=True - ) - ) - - def test_is_node_in_use_by_oneview_same_server_profile_applied( - self, mock_oneview_client): - """Check if node's Server Profile uri is the same applied by ironic.""" - server_hardware = { - 'serverProfileUri': '/rest/server-profile/123456789' - } - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - '/rest/server-profile/123456789' - ) - self.assertFalse( - deploy_utils._is_node_in_use( - server_hardware, - task.node.driver_info['applied_server_profile_uri'], - by_oneview=True - ) - ) - - # Tests for is_node_in_use_by_ironic - def test_is_node_in_use_by_ironic(self, mock_oneview_client): - """Node has a Server Profile applied by ironic.""" - server_hardware = {'serverProfileUri': 'same/applied_sp_uri/'} - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - 'same/applied_sp_uri/' - ) - self.assertTrue( - deploy_utils._is_node_in_use( - server_hardware, - task.node.driver_info['applied_server_profile_uri'], - by_oneview=False - ) - ) - - def test_is_node_in_use_by_ironic_no_server_profile( - self, mock_oneview_client): - """Node has no Server Profile.""" - server_hardware = {'serverProfileUri': None} - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - '/applied_sp_uri/' - ) - self.assertFalse( - deploy_utils._is_node_in_use( - server_hardware, - task.node.driver_info['applied_server_profile_uri'], - by_oneview=False - ) - ) - - def test__create_profile_from_template(self, mock_oneview_client): - """Check if the server_profile was created from template.""" - server_hardware_uri = "server_hardware/12456789" - sp_template_uri = "server_profile_template_uri/13245798" - oneview_client = mock_oneview_client() - oneview_client.server_profile_templates.\ - get_new_profile.return_value = {} - server_profile = {"name": "server_profile_name", - "serverHardwareUri": server_hardware_uri, - "serverProfileTemplateUri": ""} - deploy_utils._create_profile_from_template( - oneview_client, - "server_profile_name", - server_hardware_uri, - sp_template_uri - ) - oneview_client.server_profiles.create.assert_called_with( - server_profile) - - # Tests for _add_applied_server_profile_uri_field - @mock.patch.object(objects.Node, 'save') - def test__add_applied_server_profile_uri_field( - self, save, mock_oneview_client): - """Check if applied_server_profile_uri was added to driver_info.""" - server_profile = {'uri': 'any/applied_sp_uri/'} - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info.pop('applied_server_profile_uri', None) - self.assertNotIn( - 'applied_server_profile_uri', task.node.driver_info - ) - deploy_utils._add_applied_server_profile_uri_field( - task.node, - server_profile - ) - self.assertIn('applied_server_profile_uri', task.node.driver_info) - - # Tests for _del_applied_server_profile_uri_field - @mock.patch.object(objects.Node, 'save') - def test__del_applied_server_profile_uri_field( - self, save, mock_oneview_client): - """Check if applied_server_profile_uri was removed from driver_info.""" - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - 'any/applied_sp_uri/' - ) - self.assertIn('applied_server_profile_uri', task.node.driver_info) - deploy_utils._del_applied_server_profile_uri_field(task.node) - self.assertNotIn( - 'applied_server_profile_uri', task.node.driver_info - ) - - # Tests for allocate_server_hardware_to_ironic - @mock.patch.object(objects.Node, 'save') - def test_allocate_server_hardware_to_ironic( - self, mock_node_save, mock_oneview_client): - """Check if a Profile was created and its uri is in driver_info.""" - oneview_client = mock_oneview_client() - server_hardware = {'serverProfileUri': None} - oneview_client.server_hardware.get.return_value = server_hardware - - with task_manager.acquire(self.context, self.node.uuid) as task: - deploy_utils.allocate_server_hardware_to_ironic( - task.node, 'serverProfileName' - ) - self.assertTrue(mock_node_save.called) - self.assertIn('applied_server_profile_uri', task.node.driver_info) - - @mock.patch.object(objects.Node, 'save') - def test_allocate_server_hardware_to_ironic_node_has_server_profile( - self, mock_node_save, mock_oneview_client): - """Test profile allocation when applied_server_profile_uri exists. - - This test consider that no Server Profile is applied on the Server - Hardware but the applied_server_profile_uri remained on the node. Thus, - the conductor should remove the value and apply a new server profile to - use the node. - """ - oneview_client = mock_oneview_client() - server_hardware = {'serverProfileUri': None} - oneview_client.server_hardware.get.return_value = server_hardware - - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - 'any/applied_sp_uri/' - ) - deploy_utils.allocate_server_hardware_to_ironic( - task.node, 'serverProfileName' - ) - self.assertTrue(mock_node_save.called) - - # Tests for deallocate_server_hardware_from_ironic - @mock.patch.object(objects.Node, 'save') - def test_deallocate_server_hardware_from_ironic( - self, mock_node_save, mock_oneview_client): - oneview_client = mock_oneview_client() - server_hardware = {'serverProfileUri': 'any/applied_sp_uri/'} - oneview_client.server_hardware.get.return_value = server_hardware - with task_manager.acquire(self.context, self.node.uuid) as task: - task.node.driver_info['applied_server_profile_uri'] = ( - 'any/applied_sp_uri/' - ) - deploy_utils.deallocate_server_hardware_from_ironic(task) - self.assertTrue(mock_node_save.called) - self.assertTrue( - 'applied_server_profile_uri' not in task.node.driver_info - ) diff --git a/ironic/tests/unit/drivers/modules/oneview/test_inspect.py b/ironic/tests/unit/drivers/modules/oneview/test_inspect.py deleted file mode 100644 index 4a00cfd96..000000000 --- a/ironic/tests/unit/drivers/modules/oneview/test_inspect.py +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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 ironic.conductor import task_manager -from ironic.drivers.modules.oneview import common as ov_common -from ironic.drivers.modules.oneview import deploy_utils -from ironic.tests.unit.drivers.modules.oneview import test_common - - -class OneViewInspectTestCase(test_common.BaseOneViewTest): - - def setUp(self): - super(OneViewInspectTestCase, self).setUp() - self.config(enabled=True, group='inspector') - self.config(manager_url='https://1.2.3.4', group='oneview') - - def test_get_properties(self): - expected = deploy_utils.get_properties() - with task_manager.acquire(self.context, self.node.uuid, - shared=True) as task: - self.assertEqual(expected, task.driver.inspect.get_properties()) - - @mock.patch.object(ov_common, 'validate_oneview_resources_compatibility', - autospect=True) - def test_validate(self, mock_validate): - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.inspect.validate(task) - self.assertTrue(mock_validate.called) - - @mock.patch.object(deploy_utils, 'allocate_server_hardware_to_ironic', - autospect=True) - def test_inspect_hardware(self, mock_allocate_server_hardware_to_ironic): - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.inspect.inspect_hardware(task) - self.assertTrue(mock_allocate_server_hardware_to_ironic.called) diff --git a/ironic/tests/unit/drivers/modules/oneview/test_management.py b/ironic/tests/unit/drivers/modules/oneview/test_management.py deleted file mode 100644 index b897dbd56..000000000 --- a/ironic/tests/unit/drivers/modules/oneview/test_management.py +++ /dev/null @@ -1,365 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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 oslo_utils import importutils -from oslo_utils import uuidutils - -from ironic.common import boot_devices -from ironic.common import exception -from ironic.conductor import task_manager -from ironic.drivers.modules.oneview import common -from ironic.drivers.modules.oneview import deploy_utils -from ironic.drivers.modules.oneview import management -from ironic.tests.unit.drivers.modules.oneview import test_common -from ironic.tests.unit.objects import utils as obj_utils - -client_exception = importutils.try_import('hpOneView.exceptions') - - -@mock.patch.object(common, 'get_hponeview_client') -class OneViewManagementDriverFunctionsTestCase(test_common.BaseOneViewTest): - - def setUp(self): - super(OneViewManagementDriverFunctionsTestCase, self).setUp() - self.config(manager_url='https://1.2.3.4', group='oneview') - self.config(username='user', group='oneview') - self.config(password='password', group='oneview') - self.info = common.get_oneview_info(self.node) - - @mock.patch.object(common, 'get_ilorest_client') - def test_set_boot_device( - self, mock_get_ilo_client, mock_get_ov_client): - ilo_client = mock_get_ilo_client() - - with task_manager.acquire(self.context, self.node.uuid) as task: - driver_internal_info = task.node.driver_internal_info - next_boot_device = {'boot_device': boot_devices.PXE, - 'persistent': True} - driver_internal_info['next_boot_device'] = next_boot_device - task.node.driver_internal_info = driver_internal_info - management.set_boot_device(task) - self.assertFalse(ilo_client.called) - patch = ilo_client.patch - self.assertFalse(patch.called) - driver_internal_info = task.node.driver_internal_info - self.assertNotIn('next_boot_device', driver_internal_info) - - @mock.patch.object(common, 'get_ilorest_client') - def test_set_boot_device_not_persistent( - self, mock_get_ilo_client, mock_get_ov_client): - ilo_client = mock_get_ilo_client() - client = mock_get_ov_client() - server_profile = {'boot': {'order': - list(management.BOOT_DEVICE_MAP_ONEVIEW_REV)}} - client.server_profiles.get.return_value = server_profile - boot_device_map_ilo = management.BOOT_DEVICE_MAP_ILO - boot_device = boot_device_map_ilo.get(boot_devices.PXE) - body = { - "Boot": { - "BootSourceOverrideTarget": boot_device, - "BootSourceOverrideEnabled": "Once" - } - } - with task_manager.acquire(self.context, self.node.uuid) as task: - driver_info = task.node.driver_info - profile_uri = driver_info.get('applied_server_profile_uri') - driver_internal_info = task.node.driver_internal_info - next_boot_device = {'boot_device': boot_devices.PXE, - 'persistent': False} - driver_internal_info['next_boot_device'] = next_boot_device - task.node.driver_internal_info = driver_internal_info - management.set_boot_device(task) - update = client.server_profiles.update - update.assert_called_once_with(server_profile, profile_uri) - patch = ilo_client.patch - patch.assert_called_once_with( - path=management.ILO_SYSTEM_PATH, - body=body, - headers=management.ILO_REQUEST_HEADERS - ) - driver_internal_info = task.node.driver_internal_info - self.assertNotIn('next_boot_device', driver_internal_info) - - def test_set_boot_device_invalid_device(self, mock_get_ov_client): - client = mock_get_ov_client() - - with task_manager.acquire(self.context, self.node.uuid) as task: - driver_internal_info = task.node.driver_internal_info - next_boot_device = {'boot_device': 'pixie-boots', - 'persistent': True} - driver_internal_info['next_boot_device'] = next_boot_device - task.node.driver_internal_info = driver_internal_info - self.assertRaises(exception.InvalidParameterValue, - management.set_boot_device, - task) - self.assertFalse(client.set_boot_device.called) - self.assertIn('next_boot_device', driver_internal_info) - - def test_set_boot_device_fail_to_get_server_profile( - self, mock_get_ov_client): - client = mock_get_ov_client() - exc = client_exception.HPOneViewException() - client.server_profiles.get.side_effect = exc - - with task_manager.acquire(self.context, self.node.uuid) as task: - driver_internal_info = task.node.driver_internal_info - next_boot_device = {'device': 'disk', - 'persistent': True} - driver_internal_info['next_boot_device'] = next_boot_device - task.node.driver_internal_info = driver_internal_info - self.assertRaises( - exception.OneViewError, - management.set_boot_device, - task - ) - self.assertIn('next_boot_device', driver_internal_info) - - @mock.patch.object(common, 'get_ilorest_client') - def test_set_onetime_boot_persistent( - self, mock_iloclient, mock_get_ov_client): - ilo_client = mock_iloclient() - driver_internal_info = self.node.driver_internal_info - next_boot_device = {'device': 'disk', 'persistent': False} - driver_internal_info['next_boot_device'] = next_boot_device - with task_manager.acquire(self.context, self.node.uuid) as task: - management.set_onetime_boot(task) - self.assertFalse(ilo_client.called) - self.assertFalse(ilo_client.patch.called) - - @mock.patch.object(common, 'get_ilorest_client') - def test_set_onetime_boot_not_persistent( - self, mock_iloclient, mock_get_ov_client): - ilo_client = mock_iloclient() - boot_device = management.BOOT_DEVICE_MAP_ILO.get(boot_devices.DISK) - body = { - "Boot": { - "BootSourceOverrideTarget": boot_device, - "BootSourceOverrideEnabled": "Once" - } - } - with task_manager.acquire(self.context, self.node.uuid) as task: - driver_internal_info = task.node.driver_internal_info - next_boot_device = {'boot_device': 'disk', 'persistent': False} - driver_internal_info['next_boot_device'] = next_boot_device - task.node.driver_internal_info = driver_internal_info - management.set_onetime_boot(task) - self.assertTrue(mock_iloclient.called) - ilo_client.patch.assert_called_once_with( - path=management.ILO_SYSTEM_PATH, - body=body, - headers=management.ILO_REQUEST_HEADERS - ) - - @mock.patch.object(common, 'get_ilorest_client') - def test__is_onetime_boot_true( - self, mock_iloclient, mock_get_ov_client): - - class RestResponse(object): - @property - def dict(self): - return {'Boot': {'BootSourceOverrideEnabled': "Once"}} - - ilo_client = mock_iloclient() - ilo_client.get.return_value = RestResponse() - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertTrue(management._is_onetime_boot(task)) - self.assertTrue(mock_iloclient.called) - ilo_client.get.assert_called_with( - path=management.ILO_SYSTEM_PATH, - headers=management.ILO_REQUEST_HEADERS - ) - - @mock.patch.object(common, 'get_ilorest_client') - def test__is_onetime_boot_false( - self, mock_iloclient, mock_get_ov_client): - - class RestResponse(object): - @property - def dict(self): - return {'Boot': {'BootSourceOverrideEnabled': "Disabled"}} - - ilo_client = mock_iloclient() - ilo_client.get.return_value = RestResponse() - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertFalse(management._is_onetime_boot(task)) - self.assertTrue(mock_iloclient.called) - ilo_client.get.assert_called_with( - path=management.ILO_SYSTEM_PATH, - headers=management.ILO_REQUEST_HEADERS - ) - - -class OneViewManagementDriverTestCase(test_common.BaseOneViewTest): - - def setUp(self): - super(OneViewManagementDriverTestCase, self).setUp() - self.config(manager_url='https://1.2.3.4', group='oneview') - self.config(username='user', group='oneview') - self.config(password='password', group='oneview') - self.config(tls_cacert_file='ca_file', group='oneview') - self.config(allow_insecure_connections=False, group='oneview') - self.info = common.get_oneview_info(self.node) - - @mock.patch.object(deploy_utils, 'is_node_in_use_by_ironic', - spect_set=True, autospec=True) - @mock.patch.object(common, 'validate_oneview_resources_compatibility', - spect_set=True, autospec=True) - def test_validate(self, mock_validate, mock_ironic_node): - mock_ironic_node.return_value = True - with task_manager.acquire(self.context, self.node.uuid, - shared=False) as task: - task.driver.management.validate(task) - self.assertTrue(mock_validate.called) - - @mock.patch.object(deploy_utils, 'is_node_in_use_by_ironic', - spect_set=True, autospec=True) - def test_validate_for_node_not_in_use_by_ironic(self, mock_ironic_node): - mock_ironic_node.return_value = False - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises(exception.InvalidParameterValue, - task.driver.management.validate, task) - - def test_validate_fail(self): - node = obj_utils.create_test_node( - self.context, uuid=uuidutils.generate_uuid(), - id=999, driver='oneview' - ) - with task_manager.acquire(self.context, node.uuid) as task: - self.assertRaises(exception.MissingParameterValue, - task.driver.management.validate, task) - - @mock.patch.object(common, 'validate_oneview_resources_compatibility') - def test_validate_fail_exception(self, mock_validate): - mock_validate.side_effect = exception.OneViewError('message') - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises(exception.InvalidParameterValue, - task.driver.management.validate, - task) - - def test_get_properties(self): - expected = common.COMMON_PROPERTIES - self.assertItemsEqual(expected, - management.OneViewManagement().get_properties()) - - def test_set_boot_device_persistent_true(self): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.management.set_boot_device( - task, boot_devices.PXE, True) - driver_internal_info = task.node.driver_internal_info - next_boot_device = driver_internal_info.get('next_boot_device') - self.assertIn('next_boot_device', driver_internal_info) - self.assertEqual( - next_boot_device.get('boot_device'), boot_devices.PXE) - self.assertTrue(next_boot_device.get('persistent')) - - def test_set_boot_device_persistent_false(self): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.management.set_boot_device( - task, boot_devices.PXE, False) - driver_internal_info = task.node.driver_internal_info - next_boot_device = driver_internal_info.get('next_boot_device') - self.assertIn('next_boot_device', driver_internal_info) - self.assertEqual( - next_boot_device.get('boot_device'), boot_devices.PXE) - self.assertFalse(next_boot_device.get('persistent')) - - def test_set_boot_device_invalid_device(self): - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises(exception.InvalidParameterValue, - task.driver.management.set_boot_device, - task, 'unknown-device', False) - driver_internal_info = task.node.driver_internal_info - self.assertNotIn('next_boot_device', driver_internal_info) - - def test_get_supported_boot_devices(self): - with task_manager.acquire(self.context, self.node.uuid) as task: - expected = [ - boot_devices.PXE, boot_devices.DISK, boot_devices.CDROM - ] - self.assertItemsEqual( - expected, - task.driver.management.get_supported_boot_devices(task), - ) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(common, 'get_ilorest_client') - def test_get_boot_device(self, mock_iloclient, mock_get_ov_client): - ilo_client = mock_iloclient() - oneview_client = mock_get_ov_client() - device_mapping = management.BOOT_DEVICE_MAP_ONEVIEW.items() - with task_manager.acquire(self.context, self.node.uuid) as task: - # For each known device on OneView, Ironic should return its - # counterpart value - for ironic_device, oneview_device in device_mapping: - profile = {'boot': {'order': [oneview_device]}} - oneview_client.server_profiles.get.return_value = profile - expected = {'boot_device': ironic_device, 'persistent': True} - response = management.OneViewManagement().get_boot_device(task) - self.assertEqual(expected, response) - self.assertTrue(oneview_client.server_profiles.get.called) - self.assertTrue(ilo_client.get.called) - - @mock.patch.object(common, 'get_ilorest_client') - def test_get_boot_device_from_next_boot_device(self, mock_iloclient): - ilo_client = mock_iloclient() - with task_manager.acquire(self.context, self.node.uuid) as task: - driver_internal_info = task.node.driver_internal_info - next_boot_device = {'boot_device': boot_devices.DISK, - 'persistent': True} - driver_internal_info['next_boot_device'] = next_boot_device - task.node.driver_internal_info = driver_internal_info - expected_response = { - 'boot_device': boot_devices.DISK, - 'persistent': True - } - response = management.OneViewManagement().get_boot_device(task) - self.assertEqual(expected_response, response) - self.assertFalse(ilo_client.get.called) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(common, 'get_ilorest_client') - def test_get_boot_device_fail(self, mock_iloclient, mock_get_ov_client): - client = mock_get_ov_client() - ilo_client = mock_iloclient() - exc = client_exception.HPOneViewException() - client.server_profiles.get.side_effect = exc - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.OneViewError, - management.OneViewManagement().get_boot_device, - task - ) - self.assertTrue(client.server_profiles.get.called) - self.assertFalse(ilo_client.get.called) - - @mock.patch.object(common, 'get_ilorest_client') - def test_get_boot_device_unknown_device(self, mock_iloclient): - ilo_client = mock_iloclient() - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.InvalidParameterValue, - task.driver.management.get_boot_device, - task - ) - self.assertFalse(ilo_client.get.called) - - def test_get_sensors_data_not_implemented(self): - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - NotImplementedError, - task.driver.management.get_sensors_data, - task - ) diff --git a/ironic/tests/unit/drivers/modules/oneview/test_power.py b/ironic/tests/unit/drivers/modules/oneview/test_power.py deleted file mode 100644 index e55eca9f4..000000000 --- a/ironic/tests/unit/drivers/modules/oneview/test_power.py +++ /dev/null @@ -1,308 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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 oslo_utils import importutils -from oslo_utils import uuidutils - -from ironic.common import exception -from ironic.common import states -from ironic.conductor import task_manager -from ironic.drivers.modules.oneview import common -from ironic.drivers.modules.oneview import deploy_utils -from ironic.drivers.modules.oneview import management -from ironic.drivers.modules.oneview import power -from ironic.tests.unit.drivers.modules.oneview import test_common -from ironic.tests.unit.objects import utils as obj_utils - -client_exception = importutils.try_import('hpOneView.exceptions') - - -class OneViewPowerDriverTestCase(test_common.BaseOneViewTest): - - def setUp(self): - super(OneViewPowerDriverTestCase, self).setUp() - self.config(manager_url='https://1.2.3.4', group='oneview') - self.config(username='user', group='oneview') - self.config(password='password', group='oneview') - self.config(tls_cacert_file='ca_file', group='oneview') - self.config(allow_insecure_connections=False, group='oneview') - - self.info = common.get_oneview_info(self.node) - deploy_utils.is_node_in_use_by_oneview = mock.Mock(return_value=False) - - @mock.patch.object(common, 'validate_oneview_resources_compatibility') - def test_validate(self, mock_validate): - with task_manager.acquire(self.context, self.node.uuid) as task: - task.driver.power.validate(task) - self.assertTrue(mock_validate.called) - - def test_validate_missing_parameter(self): - node = obj_utils.create_test_node( - self.context, uuid=uuidutils.generate_uuid(), - id=999, driver='oneview') - with task_manager.acquire(self.context, node.uuid) as task: - self.assertRaises( - exception.MissingParameterValue, - task.driver.power.validate, - task) - - @mock.patch.object(common, 'validate_oneview_resources_compatibility') - def test_validate_exception(self, mock_validate): - mock_validate.side_effect = exception.OneViewError('message') - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.InvalidParameterValue, - task.driver.power.validate, - task) - - def test_validate_node_in_use_by_oneview(self): - deploy_utils.is_node_in_use_by_oneview.return_value = True - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.InvalidParameterValue, - task.driver.power.validate, - task) - - def test_get_properties(self): - expected = common.COMMON_PROPERTIES - self.assertEqual(expected, power.OneViewPower().get_properties()) - - @mock.patch.object(common, 'get_hponeview_client') - def test_get_power_state(self, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = {'powerState': 'On'} - client.server_hardware.get.return_value = server_hardware - with task_manager.acquire(self.context, self.node.uuid) as task: - power_state = power.OneViewPower().get_power_state(task) - self.assertEqual(states.POWER_ON, power_state) - - @mock.patch.object(common, 'get_hponeview_client') - def test_get_power_state_fail(self, mock_get_ov_client): - client = mock_get_ov_client() - exc = client_exception.HPOneViewException() - client.server_hardware.get.side_effect = exc - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.OneViewError, - power.OneViewPower().get_power_state, - task) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_on(self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = self.node.driver_info.get('server_hardware_uri') - with task_manager.acquire(self.context, self.node.uuid) as task: - power.OneViewPower().set_power_state(task, states.POWER_ON) - self.assertTrue(mock_set_boot_device.called) - update = client.server_hardware.update_power_state - update.assert_called_once_with(power.POWER_ON, server_hardware, - timeout=-1) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_on_with_timeout( - self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = self.node.driver_info.get('server_hardware_uri') - with task_manager.acquire(self.context, self.node.uuid) as task: - power.OneViewPower().set_power_state(task, states.POWER_ON, - timeout=2) - self.assertTrue(mock_set_boot_device.called) - update = client.server_hardware.update_power_state - update.assert_called_once_with(power.POWER_ON, server_hardware, - timeout=2) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_off(self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = self.node.driver_info.get('server_hardware_uri') - with task_manager.acquire(self.context, self.node.uuid) as task: - power.OneViewPower().set_power_state(task, states.POWER_OFF) - self.assertFalse(mock_set_boot_device.called) - update = client.server_hardware.update_power_state - update.assert_called_once_with(power.POWER_OFF, server_hardware, - timeout=-1) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_off_with_timeout( - self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = self.node.driver_info.get('server_hardware_uri') - with task_manager.acquire(self.context, self.node.uuid) as task: - power.OneViewPower().set_power_state(task, states.POWER_OFF, - timeout=2) - self.assertFalse(mock_set_boot_device.called) - update = client.server_hardware.update_power_state - update.assert_called_once_with(power.POWER_OFF, server_hardware, - timeout=2) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_reboot(self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = self.node.driver_info.get('server_hardware_uri') - with task_manager.acquire(self.context, self.node.uuid) as task: - power.OneViewPower().set_power_state(task, states.REBOOT) - calls = [mock.call(power.POWER_OFF, server_hardware, timeout=-1), - mock.call(power.POWER_ON, server_hardware, timeout=-1)] - update = client.server_hardware.update_power_state - update.assert_has_calls(calls) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_soft_reboot( - self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - interface = power.OneViewPower() - interface.client = client - server_hardware = self.node.driver_info.get('server_hardware_uri') - with task_manager.acquire(self.context, self.node.uuid) as task: - interface.set_power_state(task, states.SOFT_REBOOT) - calls = [mock.call(power.SOFT_POWER_OFF, server_hardware, - timeout=-1), - mock.call(power.POWER_ON, server_hardware, timeout=-1)] - update = client.server_hardware.update_power_state - update.assert_has_calls(calls) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_on_fail(self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - exc = client_exception.HPOneViewException() - client.server_hardware.update_power_state.side_effect = exc - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.OneViewError, - power.OneViewPower().set_power_state, - task, - states.POWER_ON) - mock_set_boot_device.assert_called_once_with(task) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_off_fail( - self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - exc = client_exception.HPOneViewException() - client.server_hardware.update_power_state.side_effect = exc - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.OneViewError, - power.OneViewPower().set_power_state, - task, - states.POWER_OFF) - self.assertFalse(mock_set_boot_device.called) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_reboot_fail_with_hardware_on( - self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = {'powerState': 'On'} - client.server_hardware.get.return_value = server_hardware - exc = client_exception.HPOneViewException() - client.server_hardware.update_power_state.side_effect = exc - interface = power.OneViewPower() - interface.client = client - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.OneViewError, - interface.reboot, - task) - self.assertFalse(mock_set_boot_device.called) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_reboot_fail_with_hardware_off( - self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = {'powerState': 'Off'} - client.server_hardware.get.return_value = server_hardware - exc = client_exception.HPOneViewException() - client.server_hardware.update_power_state.side_effect = exc - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.OneViewError, - power.OneViewPower().reboot, - task) - mock_set_boot_device.assert_called_once_with(task) - - @mock.patch.object(management, 'set_boot_device') - def test_set_power_invalid_state(self, mock_set_boot_device): - with task_manager.acquire(self.context, self.node.uuid) as task: - self.assertRaises( - exception.InvalidParameterValue, - power.OneViewPower().set_power_state, - task, - 'fake_state') - self.assertFalse(mock_set_boot_device.called) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_reboot_with_hardware_on( - self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = {'powerState': 'On'} - client.server_hardware.get.return_value = server_hardware - server_hardware = self.node.driver_info.get('server_hardware_uri') - with task_manager.acquire(self.context, self.node.uuid) as task: - power.OneViewPower().reboot(task) - calls = [mock.call(power.POWER_OFF, server_hardware, timeout=-1), - mock.call(power.POWER_ON, server_hardware, timeout=-1)] - update = client.server_hardware.update_power_state - update.assert_has_calls(calls) - mock_set_boot_device.assert_called_once_with(task) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_reboot_with_hardware_off( - self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = {'powerState': 'Off'} - client.server_hardware.get.return_value = server_hardware - server_hardware = self.node.driver_info.get('server_hardware_uri') - with task_manager.acquire(self.context, self.node.uuid) as task: - power.OneViewPower().reboot(task, timeout=-1) - update = client.server_hardware.update_power_state - update.assert_called_once_with(power.POWER_ON, server_hardware, - timeout=-1) - mock_set_boot_device.assert_called_once_with(task) - - @mock.patch.object(common, 'get_hponeview_client') - @mock.patch.object(management, 'set_boot_device') - def test_set_power_reboot_with_hardware_off_with_timeout( - self, mock_set_boot_device, mock_get_ov_client): - client = mock_get_ov_client() - server_hardware = {'powerState': 'Off'} - client.server_hardware.get.return_value = server_hardware - server_hardware = self.node.driver_info.get('server_hardware_uri') - with task_manager.acquire(self.context, self.node.uuid) as task: - power.OneViewPower().reboot(task, timeout=2) - update = client.server_hardware.update_power_state - update.assert_called_once_with(power.POWER_ON, server_hardware, - timeout=2) - mock_set_boot_device.assert_called_once_with(task) - - def test_get_supported_power_states(self): - with task_manager.acquire(self.context, self.node.uuid, - shared=True) as task: - supported_power_states = ( - task.driver.power.get_supported_power_states(task)) - self.assertEqual(set(power.SET_POWER_STATE_MAP), - set(supported_power_states)) diff --git a/ironic/tests/unit/drivers/test_oneview.py b/ironic/tests/unit/drivers/test_oneview.py deleted file mode 100644 index 484630a0c..000000000 --- a/ironic/tests/unit/drivers/test_oneview.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright (2015-2017) Hewlett Packard Enterprise Development LP -# Copyright (2015-2017) Universidade Federal de Campina Grande -# -# 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. - -"""Test class for HPE OneView Drivers.""" - -from ironic.conductor import task_manager -from ironic.drivers.modules import agent -from ironic.drivers.modules import noop -from ironic.drivers.modules import pxe -from ironic.drivers.modules.storage import noop as noop_storage -from ironic.drivers import oneview -from ironic.tests.unit.db import base as db_base -from ironic.tests.unit.objects import utils as obj_utils - - -class OneViewHardwareTestCase(db_base.DbTestCase): - - def setUp(self): - super(OneViewHardwareTestCase, self).setUp() - self.config(enabled_hardware_types=['oneview'], - enabled_deploy_interfaces=[ - 'oneview-direct', 'oneview-iscsi'], - enabled_inspect_interfaces=['oneview'], - enabled_management_interfaces=['oneview'], - enabled_power_interfaces=['oneview'], - enabled_raid_interfaces=['no-raid', 'agent'], - enabled_console_interfaces=['no-console'], - enabled_vendor_interfaces=['no-vendor']) - - def test_default_interfaces(self): - node = obj_utils.create_test_node(self.context, - driver='oneview') - with task_manager.acquire(self.context, node.id) as task: - self.assertIsInstance(task.driver.boot, - pxe.PXEBoot) - self.assertIsInstance(task.driver.deploy, - oneview.deploy.OneViewIscsiDeploy) - self.assertIsInstance(task.driver.inspect, - oneview.inspect.OneViewInspect) - self.assertIsInstance(task.driver.management, - oneview.management.OneViewManagement) - self.assertIsInstance(task.driver.power, - oneview.power.OneViewPower), - self.assertIsInstance(task.driver.storage, - noop_storage.NoopStorage), - self.assertIsInstance(task.driver.console, - noop.NoConsole), - self.assertIsInstance(task.driver.raid, - noop.NoRAID) - self.assertIsInstance(task.driver.vendor, - noop.NoVendor) - - def test_default_with_inspector_interface_enabled(self): - self.config(enabled_inspect_interfaces=['inspector', 'oneview']) - node = obj_utils.create_test_node( - self.context, driver='oneview', - deploy_interface='oneview-direct', - inspect_interface='oneview', - raid_interface='agent') - with task_manager.acquire(self.context, node.id) as task: - self.assertIsInstance(task.driver.boot, - pxe.PXEBoot) - self.assertIsInstance(task.driver.deploy, - oneview.deploy.OneViewAgentDeploy) - self.assertIsInstance(task.driver.inspect, - oneview.inspect.OneViewInspect) - self.assertIsInstance(task.driver.management, - oneview.management.OneViewManagement) - self.assertIsInstance(task.driver.power, - oneview.power.OneViewPower) - self.assertIsInstance(task.driver.raid, - agent.AgentRAID) - self.assertIsInstance(task.driver.vendor, - noop.NoVendor) - - def test_override_with_direct(self): - node = obj_utils.create_test_node( - self.context, driver='oneview', - deploy_interface='oneview-direct', - boot_interface='pxe', - raid_interface='agent') - with task_manager.acquire(self.context, node.id) as task: - self.assertIsInstance(task.driver.boot, - pxe.PXEBoot) - self.assertIsInstance(task.driver.deploy, - oneview.deploy.OneViewAgentDeploy) - self.assertIsInstance(task.driver.inspect, - oneview.inspect.OneViewInspect) - self.assertIsInstance(task.driver.management, - oneview.management.OneViewManagement) - self.assertIsInstance(task.driver.power, - oneview.power.OneViewPower) - self.assertIsInstance(task.driver.raid, - agent.AgentRAID) - - def test_override_with_iscsi(self): - node = obj_utils.create_test_node( - self.context, driver='oneview', - deploy_interface='oneview-iscsi', - boot_interface='pxe', - raid_interface='agent') - with task_manager.acquire(self.context, node.id) as task: - self.assertIsInstance(task.driver.boot, - pxe.PXEBoot) - self.assertIsInstance(task.driver.deploy, - oneview.deploy.OneViewIscsiDeploy) - self.assertIsInstance(task.driver.inspect, - oneview.inspect.OneViewInspect) - self.assertIsInstance(task.driver.management, - oneview.management.OneViewManagement) - self.assertIsInstance(task.driver.power, - oneview.power.OneViewPower) - self.assertIsInstance(task.driver.raid, - agent.AgentRAID) diff --git a/ironic/tests/unit/drivers/third_party_driver_mock_specs.py b/ironic/tests/unit/drivers/third_party_driver_mock_specs.py index ca2be0b30..a5b1c6b5a 100644 --- a/ironic/tests/unit/drivers/third_party_driver_mock_specs.py +++ b/ironic/tests/unit/drivers/third_party_driver_mock_specs.py @@ -123,24 +123,6 @@ SCCICLIENT_VIOM_CONF_SPEC = ( 'terminate', ) -HPE_ONEVIEW_SPEC = ( - 'oneview_client', - 'resources', - 'exceptions', -) - -HPE_ONEVIEW_CLS_SPEC = ( -) - -HPE_ONEVIEW_STATES_SPEC = ( - 'ONEVIEW_POWER_OFF', - 'ONEVIEW_POWERING_OFF', - 'ONEVIEW_POWER_ON', - 'ONEVIEW_POWERING_ON', - 'ONEVIEW_RESETTING', - 'ONEVIEW_ERROR', -) - REDFISH_SPEC = ( 'redfish', ) diff --git a/ironic/tests/unit/drivers/third_party_driver_mocks.py b/ironic/tests/unit/drivers/third_party_driver_mocks.py index 52fe30059..fe955ba39 100644 --- a/ironic/tests/unit/drivers/third_party_driver_mocks.py +++ b/ironic/tests/unit/drivers/third_party_driver_mocks.py @@ -25,7 +25,6 @@ Current list of mocked libraries: - proliantutils - pysnmp - scciclient -- hpOneView - pywsman - python-dracclient """ @@ -69,30 +68,13 @@ if not proliantutils: if 'ironic.drivers.ilo' in sys.modules: six.moves.reload_module(sys.modules['ironic.drivers.ilo']) - -hpOneView = importutils.try_import('hpOneView') -if not hpOneView: - hpOneView = mock.MagicMock(spec_set=mock_specs.HPE_ONEVIEW_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.HPE_ONEVIEW_CLS_SPEC -) -if 'ironic.drivers.oneview' in sys.modules: - six.moves.reload_module(sys.modules['ironic.drivers.modules.oneview']) - - redfish = importutils.try_import('redfish') if not redfish: redfish = mock.MagicMock(spec_set=mock_specs.REDFISH_SPEC) sys.modules['redfish'] = redfish -if 'ironic.drivers.oneview' in sys.modules: - six.moves.reload_module(sys.modules['ironic.drivers.modules.oneview']) +if 'ironic.drivers.redfish' in sys.modules: + six.moves.reload_module(sys.modules['ironic.drivers.modules.redfish']) # attempt to load the external 'python-dracclient' library, which is required # by the optional drivers.modules.drac module |