Merge "Add indicator management harness to ManagementInterface"

This commit is contained in:
Zuul 2019-09-21 18:24:52 +00:00 committed by Gerrit Code Review
commit 499bee229c
6 changed files with 276 additions and 0 deletions

View File

@ -0,0 +1,33 @@
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Mapping of common hardware components of a computer system.
"""
CHASSIS = 'chassis'
"""Chassis enclosing one or more hardware components"""
SYSTEM = 'system'
"""Computing system"""
DISK = 'disk'
"""Storage drive"""
POWER = 'power'
"""Power supply unit"""
NIC = 'nic'
"""Network interface"""

View File

@ -0,0 +1,30 @@
# Copyright 2019 Red Hat, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""
Mapping of the indicator LED states.
"""
OFF = 'off'
"""LED is off"""
ON = 'on'
"""LED is on"""
BLINKING = 'blinking'
"""LED is blinking"""
UNKNOWN = 'unknown'
"""LED state is not known"""

View File

@ -1000,6 +1000,89 @@ class ManagementInterface(BaseInterface):
raise exception.UnsupportedDriverExtension(
driver=task.node.driver, extension='inject_nmi')
def get_supported_indicators(self, task, component=None):
"""Get a map of the supported indicators (e.g. LEDs).
:param task: A task from TaskManager.
:param component: If not `None`, return indicator information
for just this component, otherwise return indicators for
all existing components.
:returns: A dictionary of hardware components
(:mod:`ironic.common.components`) as keys with values
being dictionaries having indicator IDs as keys and indicator
properties as values.
::
{
'chassis': {
'enclosure-0': {
"readonly": true,
"states": [
"off",
"on"
]
}
},
'system':
'blade-A': {
"readonly": true,
"states": [
"pff",
"on"
]
}
},
'drive':
'ssd0': {
"readonly": true,
"states": [
"off",
"on"
]
}
}
}
"""
raise exception.UnsupportedDriverExtension(
driver=task.node.driver, extension='get_supported_indicators')
def set_indicator_state(self, task, component, indicator, state):
"""Set indicator on the hardware component to the desired state.
:param task: A task from TaskManager.
:param component: The hardware component, one of
:mod:`ironic.common.components`.
:param indicator: Indicator ID (as reported by
`get_supported_indicators`).
:state: Desired state of the indicator, one of
:mod:`ironic.common.indicator_states`.
:raises: InvalidParameterValue if an invalid component, indicator
or state is specified.
:raises: MissingParameterValue if a required parameter is missing
"""
raise exception.UnsupportedDriverExtension(
driver=task.node.driver, extension='set_indicator_state')
def get_indicator_state(self, task, component, indicator):
"""Get current state of the indicator of the hardware component.
:param task: A task from TaskManager.
:param component: The hardware component, one of
:mod:`ironic.common.components`.
:param indicator: Indicator ID (as reported by
`get_supported_indicators`).
:raises: InvalidParameterValue if an invalid component or indicator
is specified.
:raises: MissingParameterValue if a required parameter is missing
:returns: Current state of the indicator, one of
:mod:`ironic.common.indicator_states`.
"""
raise exception.UnsupportedDriverExtension(
driver=task.node.driver, extension='get_indicator_state')
class InspectInterface(BaseInterface):
"""Interface for inspection-related actions."""

View File

@ -27,8 +27,10 @@ on separate vendor_passthru methods.
from oslo_log import log
from ironic.common import boot_devices
from ironic.common import components
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import indicator_states
from ironic.common import states
from ironic.drivers import base
from ironic import objects
@ -219,6 +221,44 @@ class FakeManagement(base.ManagementInterface):
def get_sensors_data(self, task):
return {}
def get_supported_indicators(self, task, component=None):
indicators = {
components.CHASSIS: {
'led-0': {
"readonly": True,
"states": [
indicator_states.OFF,
indicator_states.ON
]
}
},
components.SYSTEM: {
'led': {
"readonly": False,
"states": [
indicator_states.BLINKING,
indicator_states.OFF,
indicator_states.ON
]
}
}
}
return {c: indicators[c] for c in indicators
if not component or component == c}
def get_indicator_state(self, task, component, indicator):
indicators = self.get_supported_indicators(task)
if component not in indicators:
raise exception.InvalidParameterValue(_(
"Invalid component %s specified.") % component)
if indicator not in indicators[component]:
raise exception.InvalidParameterValue(_(
"Invalid indicator %s specified.") % indicator)
return indicator_states.ON
class FakeInspect(base.InspectInterface):

View File

@ -17,7 +17,9 @@ import json
import mock
from ironic.common import components
from ironic.common import exception
from ironic.common import indicator_states
from ironic.common import raid
from ironic.common import states
from ironic.drivers import base as driver_base
@ -783,6 +785,53 @@ class TestManagementInterface(base.TestCase):
self.assertRaises(exception.UnsupportedDriverExtension,
management.get_boot_mode, task_mock)
def test_get_supported_indicators_default_impl(self):
management = fake.FakeManagement()
task_mock = mock.MagicMock(spec_set=['node'])
expected = {
components.CHASSIS: {
'led-0': {
"readonly": True,
"states": [
indicator_states.OFF,
indicator_states.ON
]
}
},
components.SYSTEM: {
'led': {
"readonly": False,
"states": [
indicator_states.BLINKING,
indicator_states.OFF,
indicator_states.ON
]
}
}
}
self.assertEqual(
expected, management.get_supported_indicators(task_mock))
def test_set_indicator_state_default_impl(self):
management = fake.FakeManagement()
task_mock = mock.MagicMock(spec_set=['node'])
self.assertRaises(exception.UnsupportedDriverExtension,
management.set_indicator_state, task_mock,
components.CHASSIS, 'led-0', indicator_states.ON)
def test_get_indicator_state_default_impl(self):
management = fake.FakeManagement()
task_mock = mock.MagicMock(spec_set=['node'])
expected = indicator_states.ON
self.assertEqual(
expected, management.get_indicator_state(
task_mock, components.CHASSIS, 'led-0'))
class TestBareDriver(base.TestCase):

View File

@ -20,7 +20,9 @@
from ironic.common import boot_devices
from ironic.common import boot_modes
from ironic.common import components
from ironic.common import exception
from ironic.common import indicator_states
from ironic.common import states
from ironic.conductor import task_manager
from ironic.drivers import base as driver_base
@ -119,6 +121,45 @@ class FakeHardwareTestCase(db_base.DbTestCase):
self.task, boot_modes.LEGACY_BIOS
)
def test_management_interface_get_supported_indicators(self):
expected = {
components.CHASSIS: {
'led-0': {
"readonly": True,
"states": [
indicator_states.OFF,
indicator_states.ON
]
}
},
components.SYSTEM: {
'led': {
"readonly": False,
"states": [
indicator_states.BLINKING,
indicator_states.OFF,
indicator_states.ON
]
}
}
}
self.assertEqual(
expected,
self.driver.management.get_supported_indicators(self.task))
def test_management_interface_get_indicator_state(self):
expected = indicator_states.ON
self.assertEqual(
expected, self.driver.management.get_indicator_state(
self.task, components.CHASSIS, 'led-0'))
def test_management_interface_set_indicator_state_good(self):
self.assertRaises(
exception.UnsupportedDriverExtension,
self.driver.management.set_indicator_state,
self.task, components.CHASSIS, 'led-0', indicator_states.ON)
def test_inspect_interface(self):
self.assertEqual({}, self.driver.inspect.get_properties())
self.driver.inspect.validate(self.task)