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 | |
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
32 files changed, 15 insertions, 4516 deletions
diff --git a/devstack/lib/ironic b/devstack/lib/ironic index 74e038a66..d559f3a36 100644 --- a/devstack/lib/ironic +++ b/devstack/lib/ironic @@ -113,9 +113,6 @@ IRONIC_HW_ARCH=${IRONIC_HW_ARCH:-x86_64} # cisco-ucs-managed: # <BMC address> <MAC address> <BMC username> <BMC password> <UCS service profile> # -# oneview: -# <Server Hardware URI> <Server Hardware Type URI> <Enclosure Group URI> <Server Profile Template URI> <MAC of primary connection> <Applied Server Profile URI> -# # idrac: # <BMC address> <MAC address> <BMC username> <BMC password> # @@ -288,7 +285,7 @@ fi # are ``ipmi``, ``snmp`` and ``redfish``. # # Additional valid choices if IRONIC_IS_HARDWARE == true are: -# ``cisco-ucs-managed``, ``cisco-ucs-standalone``, ``oneview``, ``idrac``, +# ``cisco-ucs-managed``, ``cisco-ucs-standalone``, ``idrac``, # and ``irmc``. IRONIC_DEPLOY_DRIVER=${IRONIC_DEPLOY_DRIVER:-ipmi} @@ -627,11 +624,6 @@ function is_deployed_by_ucs { return 1 } -function is_deployed_by_oneview { - [[ "${IRONIC_DEPLOY_DRIVER}" == oneview ]] && return 0 - return 1 -} - function is_deployed_by_ilo { [[ "${IRONIC_DEPLOY_DRIVER}" == ilo ]] && return 0 return 1 @@ -1936,32 +1928,6 @@ function enroll_nodes { --driver-info ucs_password=$bmc_passwd \ --driver-info ucs_username=$bmc_username \ --driver-info ucs_service_profile=$ucs_service_profile" - elif is_deployed_by_oneview; then - local server_hardware_uri - server_hardware_uri=$(echo $hardware_info |awk '{print $1}') - local server_hardware_type_uri - server_hardware_type_uri=$(echo $hardware_info |awk '{print $2}') - local enclosure_group_uri - enclosure_group_uri=$(echo $hardware_info |awk '{print $3}') - local server_profile_template_uri - server_profile_template_uri=$(echo $hardware_info |awk '{print $4}') - mac_address=$(echo $hardware_info |awk '{print $5}') - local applied_server_profile_uri - applied_server_profile_uri=$(echo $hardware_info |awk '{print $6}') - - node_options+=" --driver-info server_hardware_uri=$server_hardware_uri" - if [[ -n "$applied_server_profile_uri" ]]; then - node_options+=" --driver-info applied_server_profile_uri=$applied_server_profile_uri" - fi - - if [[ "$node_capabilities" ]]; then - node_capabilities+="," - else - node_capabilities+=" --property capabilities=" - fi - node_capabilities+="server_hardware_type_uri:$server_hardware_type_uri," - node_capabilities+="enclosure_group_uri:$enclosure_group_uri," - node_capabilities+="server_profile_template_uri:$server_profile_template_uri" elif is_deployed_by_ilo; then node_options+=" --driver-info ilo_address=$bmc_address \ --driver-info ilo_password=$bmc_passwd \ diff --git a/doc/source/admin/drivers.rst b/doc/source/admin/drivers.rst index cf38fb4d7..6eca9d392 100644 --- a/doc/source/admin/drivers.rst +++ b/doc/source/admin/drivers.rst @@ -22,7 +22,6 @@ Hardware Types drivers/ilo drivers/ipmitool drivers/irmc - drivers/oneview drivers/redfish drivers/snmp drivers/ucs diff --git a/doc/source/admin/drivers/oneview.rst b/doc/source/admin/drivers/oneview.rst deleted file mode 100644 index 17b704178..000000000 --- a/doc/source/admin/drivers/oneview.rst +++ /dev/null @@ -1,343 +0,0 @@ -.. _oneview: - -============== -OneView driver -============== - -.. note:: - The `oneview` hardware type, along with related interfaces to support - OneView, have been deprecated, and should be expected to be - removed from ironic in the Stein cycle. Please see - `storyboard <https://storyboard.openstack.org/#!/story/2001924>`_ for - additional details. - -Overview -======== - -HP OneView [1]_ is a single integrated platform, packaged as an appliance that -implements a software-defined approach to managing physical infrastructure. -The appliance supports scenarios such as deploying bare metal servers, for -instance. In this context, the ``HP OneView driver`` for ironic enables the -users of OneView to use ironic as a bare metal provider to their managed -physical hardware. - -HPE OneView hardware is supported by the ``oneview`` hardware type. - -To provide a bare metal instance there are four components involved in the -process: - -* The ironic service -* The ironic-inspector service (if using hardware inspection) -* The ironic hardware type for OneView -* The hpOneView library -* The OneView appliance - -The role of ironic is to serve as a bare metal provider to OneView's managed -physical hardware and to provide communication with other necessary OpenStack -services such as Nova and Glance. When ironic receives a boot request, it -works together with the ironic OneView driver to access a machine in OneView, -the ``hpOneView`` being responsible for the communication with the OneView -appliance. - -From the Newton release on, OneView drivers enables a new feature called -**dynamic allocation** of nodes [6]_. In this model, the driver allocates -resources in OneView only at boot time, allowing idle resources in ironic -to be used by OneView users, enabling actual resource sharing among ironic -and OneView users. - -Since OneView can claim nodes in ``available`` state at any time, a set of -tasks runs periodically to detect nodes in use by OneView. A node in use by -OneView is placed in ``manageable`` state and has maintenance mode set. Once -the node is no longer in use, these tasks will make place them back in -``available`` state and clear maintenance mode. - -Prerequisites -============= - -* ``OneView appliance`` is the HP physical infrastructure manager to be - integrated with the OneView driver. - - Minimum version supported is 2.0. - -* ``hpOneView`` is a python package containing a client to manage the - communication between ironic and OneView. - - Install the ``hpOneView`` module to enable the communication. Minimum version - required is 4.4.0 but it is recommended to install the most up-to-date - version:: - - $ pip install "hpOneView>=4.4.0" - -* ``ironic-inspector`` if using hardware inspection. - -Tested platforms -================ - -* The OneView appliance used for testing was the OneView 2.0. - -* The Enclosure used for testing was the ``BladeSystem c7000 Enclosure G2``. - -* The driver should work on HP Proliant Gen8 and Gen9 Servers supported by - OneView 2.0 and above, or any hardware whose network can be managed by - OneView's ServerProfile. It has been tested with the following servers: - - - Proliant BL460c Gen8 - - Proliant BL460c Gen9 - - Proliant BL465c Gen8 - - Proliant DL360 Gen9 - - Notice that for the driver to work correctly with Gen8 and Gen9 DL servers - in general, the hardware also needs to run version 4.2.3 of iLO, with - Redfish enabled. - -Hardware Interfaces -=================== - -The ``oneview`` hardware type supports the following hardware interfaces: - -* boot - Supports only ``pxe``. It can be enabled by using the - ``[DEFAULT]enabled_boot_interfaces`` option in ``ironic.conf`` - as given below: - - .. code-block:: ini - - [DEFAULT] - enabled_hardware_types = oneview - enabled_boot_interfaces = pxe - -* console - Supports only ``no-console``. It can be enabled by using the - ``[DEFAULT]enabled_console_interfaces`` - option in ``ironic.conf`` as given below: - - .. code-block:: ini - - [DEFAULT] - enabled_hardware_types = oneview - enabled_console_interfaces = no-console - -* deploy - Supports ``oneview-direct`` and ``oneview-iscsi``. The default is - ``oneview-iscsi``. They can be enabled by using the - ``[DEFAULT]enabled_deploy_interfaces`` option in ``ironic.conf`` - as given below: - - .. code-block:: ini - - [DEFAULT] - enabled_hardware_types = oneview - enabled_deploy_interfaces = oneview-iscsi,oneview-direct - -* inspect - Supports ``oneview`` and ``no-inspect``. The default is ``oneview``. - They can be enabled by using the ``[DEFAULT]enabled_inspect_interfaces`` - option in ``ironic.conf`` as given below: - - .. code-block:: ini - - [DEFAULT] - enabled_hardware_types = oneview - enabled_inspect_interfaces = oneview,no-inspect - -* management - Supports only ``oneview``. It can be enabled by using the - ``[DEFAULT]enabled_management_interfaces`` option in ``ironic.conf`` as - given below: - - .. code-block:: ini - - [DEFAULT] - enabled_hardware_types = oneview - enabled_management_interfaces = oneview - -* power - Supports only ``oneview``. It can be enabled by using the - ``[DEFAULT]enabled_power_interfaces`` option in ``ironic.conf`` as given - below: - - .. code-block:: ini - - [DEFAULT] - enabled_hardware_types = oneview - enabled_power_interfaces = oneview - -The ``oneview`` hardware type also supports the standard *network* and -*storage* interfaces. - -Here is an example of putting multiple interfaces configuration at once: - -.. code-block:: ini - - [DEFAULT] - enabled_hardware_types = oneview - enabled_deploy_interfaces = oneview-direct,oneview-iscsi - enabled_inspect_interfaces = oneview - enabled_power_interfaces = oneview - enabled_management_interfaces = oneview - -Deploy process with oneview-iscsi deploy interface -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -1. Admin configures the Proliant baremetal node to use ``oneview-iscsi`` - deploy interface. -2. ironic gets a request to deploy a Glance image on the baremetal node. -3. Driver sets the boot device to PXE. -4. Driver powers on the baremetal node. -5. ironic downloads the deploy and user images from a TFTP server. -6. Driver reboots the baremetal node. -7. User image is now deployed. -8. Driver powers off the machine. -9. Driver sets boot device to Disk. -10. Driver powers on the machine. -11. Baremetal node is active and ready to be used. - -Deploy process with oneview-direct deploy interface -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -1. Admin configures the Proliant baremetal node to use ``oneview-direct`` - deploy interface. -2. ironic gets a request to deploy a Glance image on the baremetal node. -3. Driver sets the boot device to PXE. -4. Driver powers on the baremetal node. -5. Node downloads the agent deploy images. -6. Agent downloads the user images and writes it to disk. -7. Driver reboots the baremetal node. -8. User image is now deployed. -9. Driver powers off the machine. -10. Driver sets boot device to Disk. -11. Driver powers on the machine. -12. Baremetal node is active and ready to be used. - -Hardware inspection -=================== - -The OneView driver for ironic has the ability to do hardware inspection. -Hardware inspection is the process of discovering hardware properties like -memory size, CPU cores, processor architecture and disk size, of a given -hardware. The OneView driver does in-band inspection, that involves booting a -ramdisk on the hardware and fetching information directly from it. For that, -your cloud controller needs to have the ``ironic-inspector`` component -[9]_ running and properly enabled in ironic's configuration file. - -See [10]_ for more information on how to install and configure -``ironic-inspector``. - -Registering a OneView node in ironic -==================================== - -Nodes configured to use the OneView driver should have the ``driver`` -property set to ``oneview``. Considering our context, a node is the -representation of a ``Server Hardware`` in OneView, -and should be consistent with all its properties and related components, such -as ``Server Hardware Type``, ``Server Profile Template``, ``Enclosure Group``, -etc. In this case, to be enrolled, the node must have the following parameters: - -* In ``driver_info`` - - - ``server_hardware_uri``: URI of the ``Server Hardware`` on OneView. - -* In ``properties/capabilities`` - - - ``server_hardware_type_uri``: URI of the ``Server Hardware Type`` of the - ``Server Hardware``. - - ``server_profile_template_uri``: URI of the ``Server Profile Template`` used - to create the ``Server Profile`` of the ``Server Hardware``. - - ``enclosure_group_uri`` (optional): URI of the ``Enclosure Group`` of the - ``Server Hardware``. - -To enroll a node with the OneView driver using default values for the -supported hardware interfaces, do:: - - $ openstack baremetal node create --driver oneview - -To enroll a node with the OneView driver using specific hardware -interfaces, do:: - - $ openstack baremetal node create --driver oneview \ - --deploy-interface oneview-direct \ - --power-interface oneview - -To update the ``driver_info`` field of a newly enrolled OneView node, do:: - - $ openstack baremetal node set $NODE_UUID --driver-info server_hardware_uri=$SH_URI - -To update the ``properties/capabilities`` namespace of a newly enrolled -OneView node, do:: - - $ openstack baremetal node set $NODE_UUID \ - --property capabilities=server_hardware_type_uri:$SHT_URI,enclosure_group_uri:$EG_URI,server_profile_template_uri=$SPT_URI - -In order to deploy, ironic will create and apply, at boot time, a ``Server -Profile`` based on the ``Server Profile Template`` specified on the node to the -``Server Hardware`` it represents on OneView. The URI of such ``Server Profile`` -will be stored in ``driver_info.applied_server_profile_uri`` field while the -Server is allocated to ironic. - -The ``Server Profile Templates`` and, therefore, the ``Server Profiles`` derived -from them MUST comply with the following requirements: - -* The option `MAC Address` in the `Advanced` section of - ``Server Profile``/``Server Profile Template`` should be set to `Physical` - option; - -* Their first `Connection` interface should be: - - * Connected to ironic's provisioning network and; - * The `Boot` option should be set to primary. - -Node ports should be created considering the **MAC address of the first -Interface** of the given ``Server Hardware``. - -To tell ironic which NIC should be connected to the provisioning network, do:: - - $ openstack baremetal port create --node $NODE_UUID $MAC_ADDRESS - -For more information on the enrollment process of an ironic node, see -:ref:`enrollment`. - -For more information on the definitions of ``Server Hardware``, ``Server -Profile``, ``Server Profile Template`` and other OneView entities, refer to -[1]_ or browse Help in your OneView appliance menu. - -.. note:: - Ironic manages OneView machines either when they have - a Server Profile applied by the driver or when they don't have any Server - Profile. Trying to change the power state of the machine in OneView without - first assigning a Server Profile will lead to allowing Ironic to revert the - power state change. Ironic will NOT change the power state of machines - which the Server Profile was applied by another OneView user. - -3rd Party Tools -=============== - -In order to ease user manual tasks, which are often time-consuming, we provide -useful tools that work nicely with the OneView driver. - -ironic-oneview-cli -~~~~~~~~~~~~~~~~~~ - -The ``ironic-oneView`` CLI is a command line interface for management tasks -involving OneView nodes. Its features include a facility to create of ironic -nodes with all required parameters for OneView nodes, creation of Nova flavors -for OneView nodes. - -For more details on how Ironic-OneView CLI works and how to set it up, see -[8]_. - -ironic-oneviewd -~~~~~~~~~~~~~~~ - -The ``ironic-oneviewd`` daemon monitors the ironic inventory of resources and -provides facilities to operators managing OneView driver deployments. - -For more details on how Ironic-OneViewd works and how to set it up, see [7]_. - -References -========== -.. [1] HP OneView - https://www.hpe.com/us/en/integrated-systems/software.html -.. [6] Dynamic Allocation in OneView drivers - https://specs.openstack.org/openstack/ironic-specs/specs/not-implemented/oneview-drivers-dynamic-allocation.html -.. [7] ironic-oneviewd - https://pypi.org/project/ironic-oneviewd/ -.. [8] ironic-oneview-cli - https://pypi.org/project/ironic-oneview-cli/ -.. [9] ironic-inspector - https://docs.openstack.org/ironic-inspector/latest/ -.. [10] ironic-inspector install - https://docs.openstack.org/ironic-inspector/latest/install/index.html diff --git a/doc/source/admin/interfaces/deploy.rst b/doc/source/admin/interfaces/deploy.rst index 2e7e70998..acbd02357 100644 --- a/doc/source/admin/interfaces/deploy.rst +++ b/doc/source/admin/interfaces/deploy.rst @@ -11,10 +11,9 @@ to the target disk. iSCSI deploy ============ -With ``iscsi`` deploy interface (and also ``oneview-iscsi``, specific to the -``oneview`` hardware type) the deploy ramdisk publishes the node's hard drive -as an iSCSI_ share. The ironic-conductor then copies the image to this share. -See :ref:`iSCSI deploy diagram <iscsi-deploy-example>` for a detailed +With ``iscsi`` deploy interface, the deploy ramdisk publishes the node's hard +drive as an iSCSI_ share. The ironic-conductor then copies the image to this +share. See :ref:`iSCSI deploy diagram <iscsi-deploy-example>` for a detailed explanation of how this deploy interface works. This interface is used by default, if enabled (see @@ -31,8 +30,7 @@ when creating or updating a node:: Direct deploy ============= -With ``direct`` deploy interface (and also ``oneview-direct``, specific to the -``oneview`` hardware type), the deploy ramdisk fetches the image from an +With ``direct`` deploy interface, the deploy ramdisk fetches the image from an HTTP location. It can be an object storage (swift or RadosGW) temporary URL or a user-provided HTTP URL. The deploy ramdisk then copies the image to the target disk. See :ref:`direct deploy diagram <direct-deploy-example>` for @@ -94,7 +92,7 @@ While somewhat more complex to set up, this deploy interface provides greater flexibility in terms of advanced node preparation during provisioning. This interface is supported by most but not all hardware types declared -in ironic (for example, ``oneview`` hardware type does not support it). +in ironic. However this deploy interface is not enabled by default. To enable it, add ``ansible`` to the list of enabled deploy interfaces in ``enabled_deploy_interfaces`` option in the ``[DEFAULT]`` diff --git a/doc/source/admin/report.txt b/doc/source/admin/report.txt index 972ce029e..bbf0838b9 100644 --- a/doc/source/admin/report.txt +++ b/doc/source/admin/report.txt @@ -535,16 +535,6 @@ neutron: url = None url_timeout = 30 -oneview: - allow_insecure_connections = False - enable_periodic_tasks = True - manager_url = None - max_polling_attempts = 12 - password = *** - periodic_check_interval = 300 - tls_cacert_file = None - username = None - oslo_concurrency: disable_process_locking = False lock_path = None diff --git a/doc/source/admin/upgrade-to-hardware-types.rst b/doc/source/admin/upgrade-to-hardware-types.rst index 7daaada0a..fb1c90955 100644 --- a/doc/source/admin/upgrade-to-hardware-types.rst +++ b/doc/source/admin/upgrade-to-hardware-types.rst @@ -22,11 +22,9 @@ agent_ilo ilo ilo-virtual-media direct agent_ipmitool ipmi pxe direct inspector ipmitool ipmitool agent_ipmitool_socat ipmi pxe direct inspector ipmitool ipmitool agent_irmc irmc irmc-virtual-media direct irmc irmc irmc -agent_pxe_oneview oneview pxe oneview-direct oneview oneview oneview agent_ucs cisco-ucs-managed pxe direct inspector ucsm ucsm iscsi_ilo ilo ilo-virtual-media iscsi ilo ilo ilo iscsi_irmc irmc irmc-virtual-media iscsi irmc irmc irmc -iscsi_pxe_oneview oneview pxe oneview-iscsi oneview oneview oneview pxe_agent_cimc cisco-ucs-standalone pxe direct inspector cimc cimc pxe_drac idrac pxe iscsi idrac idrac idrac pxe_drac_inspector idrac pxe iscsi inspector idrac idrac diff --git a/driver-requirements.txt b/driver-requirements.txt index 0a0ade982..e8f1c615e 100644 --- a/driver-requirements.txt +++ b/driver-requirements.txt @@ -7,10 +7,7 @@ proliantutils>=2.6.0 pysnmp>=4.3.0,<5.0.0 python-ironic-inspector-client>=1.5.0 -python-oneviewclient<3.0.0,>=2.5.2 python-scciclient>=0.8.0 -python-ilorest-library>=2.1.0 -hpOneView>=4.4.0 UcsSdk==0.8.2.2 python-dracclient>=1.3.0 python-xclarityclient>=0.1.6 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 diff --git a/releasenotes/notes/remove-oneview-9315c7b926fd4aa2.yaml b/releasenotes/notes/remove-oneview-9315c7b926fd4aa2.yaml new file mode 100644 index 000000000..3711639ab --- /dev/null +++ b/releasenotes/notes/remove-oneview-9315c7b926fd4aa2.yaml @@ -0,0 +1,7 @@ +--- +other: + - | + The ``oneview`` hardware type and related interfaces have been + removed due to a lack of maintainer and 3rd-party CI. Please see + `story 2001924 <https://storyboard.openstack.org/#!/story/2001924>`_ + for additional information. @@ -78,8 +78,6 @@ ironic.hardware.interfaces.deploy = direct = ironic.drivers.modules.agent:AgentDeploy fake = ironic.drivers.modules.fake:FakeDeploy iscsi = ironic.drivers.modules.iscsi_deploy:ISCSIDeploy - oneview-direct = ironic.drivers.modules.oneview.deploy:OneViewAgentDeploy - oneview-iscsi = ironic.drivers.modules.oneview.deploy:OneViewIscsiDeploy ramdisk = ironic.drivers.modules.pxe:PXERamdiskDeploy ironic.hardware.interfaces.inspect = @@ -89,7 +87,6 @@ ironic.hardware.interfaces.inspect = inspector = ironic.drivers.modules.inspector:Inspector irmc = ironic.drivers.modules.irmc.inspect:IRMCInspect no-inspect = ironic.drivers.modules.noop:NoInspect - oneview = ironic.drivers.modules.oneview.inspect:OneViewInspect ironic.hardware.interfaces.management = cimc = ironic.drivers.modules.cimc.management:CIMCManagement @@ -99,7 +96,6 @@ ironic.hardware.interfaces.management = ipmitool = ironic.drivers.modules.ipmitool:IPMIManagement irmc = ironic.drivers.modules.irmc.management:IRMCManagement noop = ironic.drivers.modules.noop_mgmt:NoopManagement - oneview = ironic.drivers.modules.oneview.management:OneViewManagement redfish = ironic.drivers.modules.redfish.management:RedfishManagement ucsm = ironic.drivers.modules.ucs.management:UcsManagement xclarity = ironic.drivers.modules.xclarity.management:XClarityManagement @@ -116,7 +112,6 @@ ironic.hardware.interfaces.power = ilo = ironic.drivers.modules.ilo.power:IloPower ipmitool = ironic.drivers.modules.ipmitool:IPMIPower irmc = ironic.drivers.modules.irmc.power:IRMCPower - oneview = ironic.drivers.modules.oneview.power:OneViewPower redfish = ironic.drivers.modules.redfish.power:RedfishPower snmp = ironic.drivers.modules.snmp:SNMPPower ucsm = ironic.drivers.modules.ucs.power:Power @@ -156,7 +151,6 @@ ironic.hardware.types = ipmi = ironic.drivers.ipmi:IPMIHardware irmc = ironic.drivers.irmc:IRMCHardware manual-management = ironic.drivers.generic:ManualManagementHardware - oneview = ironic.drivers.oneview:OneViewHardware redfish = ironic.drivers.redfish:RedfishHardware snmp = ironic.drivers.snmp:SNMPHardware xclarity = ironic.drivers.xclarity:XClarityHardware |