diff --git a/ironic/drivers/drac.py b/ironic/drivers/drac.py index ea0abb0654..12262d489e 100644 --- a/ironic/drivers/drac.py +++ b/ironic/drivers/drac.py @@ -20,6 +20,7 @@ from oslo_utils import importutils from ironic.common import exception from ironic.common.i18n import _ from ironic.drivers import base +from ironic.drivers import generic from ironic.drivers.modules.drac import inspect as drac_inspect from ironic.drivers.modules.drac import management from ironic.drivers.modules.drac import power @@ -27,9 +28,46 @@ from ironic.drivers.modules.drac import raid from ironic.drivers.modules.drac import vendor_passthru from ironic.drivers.modules import inspector from ironic.drivers.modules import iscsi_deploy +from ironic.drivers.modules import noop from ironic.drivers.modules import pxe +class IDRACHardware(generic.GenericHardware): + """integrated Dell Remote Access Controller hardware type""" + + # Required hardware interfaces + + @property + def supported_management_interfaces(self): + """List of supported management interfaces.""" + return [management.DracManagement] + + @property + def supported_power_interfaces(self): + """List of supported power interfaces.""" + return [power.DracPower] + + # Optional hardware interfaces + + @property + def supported_inspect_interfaces(self): + """List of supported inspect interfaces.""" + # Inspector support should have a higher priority than NoInspect + # if it is enabled by an operator (implying that the service is + # installed). + return [drac_inspect.DracInspect, inspector.Inspector, noop.NoInspect] + + @property + def supported_raid_interfaces(self): + """List of supported raid interfaces.""" + return [raid.DracRAID, noop.NoRAID] + + @property + def supported_vendor_interfaces(self): + """List of supported vendor interfaces.""" + return [vendor_passthru.DracVendorPassthru] + + class PXEDracDriver(base.BaseDriver): """DRAC driver using PXE for deploy.""" diff --git a/ironic/tests/unit/drivers/test_drac.py b/ironic/tests/unit/drivers/test_drac.py index 4d37947be4..d5e610a745 100644 --- a/ironic/tests/unit/drivers/test_drac.py +++ b/ironic/tests/unit/drivers/test_drac.py @@ -19,14 +19,18 @@ import mock from oslo_utils import importutils from ironic.common import exception +from ironic.conductor import task_manager from ironic.drivers import drac as drac_drivers +from ironic.drivers.modules import agent from ironic.drivers.modules import drac from ironic.drivers.modules import inspector from ironic.drivers.modules import iscsi_deploy from ironic.drivers.modules.network import flat as flat_net +from ironic.drivers.modules import noop from ironic.drivers.modules import pxe from ironic.drivers.modules.storage import noop as noop_storage from ironic.tests.unit.db import base as db_base +from ironic.tests.unit.objects import utils as obj_utils class BaseIDRACTestCase(db_base.DbTestCase): @@ -82,6 +86,51 @@ class BaseIDRACTestCase(db_base.DbTestCase): kwargs.get('vendor', drac.vendor_passthru.DracVendorPassthru)) +class IDRACHardwareTestCase(BaseIDRACTestCase): + + def setUp(self): + super(IDRACHardwareTestCase, self).setUp() + self.config(enabled_hardware_types=['idrac'], + enabled_management_interfaces=['idrac'], + enabled_power_interfaces=['idrac'], + enabled_inspect_interfaces=[ + 'idrac', 'inspector', 'no-inspect'], + enabled_network_interfaces=['flat', 'neutron', 'noop'], + enabled_raid_interfaces=['idrac', 'no-raid'], + enabled_vendor_interfaces=['idrac']) + + def test_default_interfaces(self): + node = obj_utils.create_test_node(self.context, driver='idrac') + with task_manager.acquire(self.context, node.id) as task: + self._validate_interfaces(task.driver, console=noop.NoConsole) + + def test_override_with_inspector(self): + node = obj_utils.create_test_node(self.context, driver='idrac', + inspect_interface='inspector') + with task_manager.acquire(self.context, node.id) as task: + self._validate_interfaces(task.driver, + console=noop.NoConsole, + inspect=inspector.Inspector) + + def test_override_with_agent(self): + node = obj_utils.create_test_node(self.context, driver='idrac', + deploy_interface='direct', + inspect_interface='inspector') + with task_manager.acquire(self.context, node.id) as task: + self._validate_interfaces(task.driver, + console=noop.NoConsole, + deploy=agent.AgentDeploy, + inspect=inspector.Inspector) + + def test_override_with_raid(self): + node = obj_utils.create_test_node(self.context, driver='idrac', + raid_interface='no-raid') + with task_manager.acquire(self.context, node.id) as task: + self._validate_interfaces(task.driver, + console=noop.NoConsole, + raid=noop.NoRAID) + + @mock.patch.object(importutils, 'try_import', spec_set=True, autospec=True) class DracClassicDriversTestCase(BaseIDRACTestCase): diff --git a/releasenotes/notes/idrac-hardware-type-54383960af3459d0.yaml b/releasenotes/notes/idrac-hardware-type-54383960af3459d0.yaml new file mode 100644 index 0000000000..9bda40ddaf --- /dev/null +++ b/releasenotes/notes/idrac-hardware-type-54383960af3459d0.yaml @@ -0,0 +1,17 @@ +--- +features: + - | + Adds a new hardware type, ``idrac``, for Dell EMC integrated Dell Remote + Access Controllers (iDRAC). ``idrac`` hardware type supports PXE-based + provisioning using an iDRAC. It supports the following driver interfaces: + + * boot: ``pxe`` + * console: ``no-console`` + * deploy: ``iscsi`` and ``direct`` + * inspect: ``idrac``, ``inspector``, and ``no-inspect`` + * management: ``idrac`` + * network: ``flat``, ``neutron``, and ``noop`` + * power: ``idrac`` + * raid: ``idrac`` and ``no-raid`` + * storage: ``noop`` and ``cinder`` + * vendor: ``idrac`` diff --git a/setup.cfg b/setup.cfg index c5ff2e928b..268571b855 100644 --- a/setup.cfg +++ b/setup.cfg @@ -103,6 +103,7 @@ ironic.hardware.interfaces.deploy = ironic.hardware.interfaces.inspect = fake = ironic.drivers.modules.fake:FakeInspect + idrac = ironic.drivers.modules.drac.inspect:DracInspect ilo = ironic.drivers.modules.ilo.inspect:IloInspect inspector = ironic.drivers.modules.inspector:Inspector irmc = ironic.drivers.modules.irmc.inspect:IRMCInspect @@ -112,6 +113,7 @@ ironic.hardware.interfaces.inspect = ironic.hardware.interfaces.management = cimc = ironic.drivers.modules.cimc.management:CIMCManagement fake = ironic.drivers.modules.fake:FakeManagement + idrac = ironic.drivers.modules.drac.management:DracManagement ilo = ironic.drivers.modules.ilo.management:IloManagement ipmitool = ironic.drivers.modules.ipmitool:IPMIManagement irmc = ironic.drivers.modules.irmc.management:IRMCManagement @@ -127,6 +129,7 @@ ironic.hardware.interfaces.network = ironic.hardware.interfaces.power = cimc = ironic.drivers.modules.cimc.power:Power fake = ironic.drivers.modules.fake:FakePower + idrac = ironic.drivers.modules.drac.power:DracPower ilo = ironic.drivers.modules.ilo.power:IloPower ipmitool = ironic.drivers.modules.ipmitool:IPMIPower irmc = ironic.drivers.modules.irmc.power:IRMCPower @@ -138,6 +141,7 @@ ironic.hardware.interfaces.power = ironic.hardware.interfaces.raid = agent = ironic.drivers.modules.agent:AgentRAID fake = ironic.drivers.modules.fake:FakeRAID + idrac = ironic.drivers.modules.drac.raid:DracRAID no-raid = ironic.drivers.modules.noop:NoRAID ironic.hardware.interfaces.rescue = @@ -150,6 +154,7 @@ ironic.hardware.interfaces.storage = ironic.hardware.interfaces.vendor = fake = ironic.drivers.modules.fake:FakeVendorB + idrac = ironic.drivers.modules.drac.vendor_passthru:DracVendorPassthru ipmitool = ironic.drivers.modules.ipmitool:VendorPassthru no-vendor = ironic.drivers.modules.noop:NoVendor @@ -157,6 +162,7 @@ ironic.hardware.types = cisco-ucs-managed = ironic.drivers.cisco_ucs:CiscoUCSManaged cisco-ucs-standalone = ironic.drivers.cisco_ucs:CiscoUCSStandalone fake-hardware = ironic.drivers.fake_hardware:FakeHardware + idrac = ironic.drivers.drac:IDRACHardware ilo = ironic.drivers.ilo:IloHardware ipmi = ironic.drivers.ipmi:IPMIHardware irmc = ironic.drivers.irmc:IRMCHardware