Ensures that OneView nodes are free for use by Ironic
Following the requirement. The validation is used within "OneViewPower.validate". As a result it enforces that a machine is owned by OneView, thus it cannot be powered on or off by the Ironic driver. Raising an exception when the node is owned by Oneview. Change-Id: Ibf500577b7a3b5976fd49fd217c1be3d3e9c0f46 Closes-Bug: 1627034 Co-Authored-By: Stenio Araujo <steniaraujo@lsd.ufcg.edu.br>
This commit is contained in:
parent
3871a015f6
commit
2505cb58f7
@ -52,18 +52,28 @@ class OneViewPower(base.PowerInterface):
|
|||||||
enclosure_group_uri. Also, checks if the server profile of the node is
|
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
|
applied, if NICs are valid for the server profile of the node, and if
|
||||||
the server hardware attributes (ram, memory, vcpus count) are
|
the server hardware attributes (ram, memory, vcpus count) are
|
||||||
consistent with OneView.
|
consistent with OneView. It validates if the node is being used by
|
||||||
|
Oneview.
|
||||||
|
|
||||||
:param task: a task from TaskManager.
|
:param task: a task from TaskManager.
|
||||||
:raises: MissingParameterValue if a required parameter is missing.
|
:raises: MissingParameterValue if a required parameter is missing.
|
||||||
:raises: InvalidParameterValue if parameters set are inconsistent with
|
:raises: InvalidParameterValue if parameters set are inconsistent with
|
||||||
resources in OneView
|
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)
|
common.verify_node_info(task.node)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
common.validate_oneview_resources_compatibility(
|
common.validate_oneview_resources_compatibility(
|
||||||
self.oneview_client, task)
|
self.oneview_client, task)
|
||||||
|
|
||||||
|
if deploy_utils.is_node_in_use_by_oneview(self.oneview_client,
|
||||||
|
task.node):
|
||||||
|
raise exception.InvalidParameterValue(
|
||||||
|
_("Node %s is in use by OneView.") % task.node.uuid)
|
||||||
except exception.OneViewError as oneview_exc:
|
except exception.OneViewError as oneview_exc:
|
||||||
raise exception.InvalidParameterValue(oneview_exc)
|
raise exception.InvalidParameterValue(oneview_exc)
|
||||||
|
|
||||||
@ -72,7 +82,6 @@ class OneViewPower(base.PowerInterface):
|
|||||||
"""Gets the current power state.
|
"""Gets the current power state.
|
||||||
|
|
||||||
:param task: a TaskManager instance.
|
:param task: a TaskManager instance.
|
||||||
:param node: The Node.
|
|
||||||
:returns: one of :mod:`ironic.common.states` POWER_OFF,
|
:returns: one of :mod:`ironic.common.states` POWER_OFF,
|
||||||
POWER_ON or ERROR.
|
POWER_ON or ERROR.
|
||||||
:raises: OneViewError if fails to retrieve power state of OneView
|
:raises: OneViewError if fails to retrieve power state of OneView
|
||||||
@ -99,7 +108,6 @@ class OneViewPower(base.PowerInterface):
|
|||||||
"""Turn the current power state on or off.
|
"""Turn the current power state on or off.
|
||||||
|
|
||||||
:param task: a TaskManager instance.
|
:param task: a TaskManager instance.
|
||||||
:param node: The Node.
|
|
||||||
:param power_state: The desired power state POWER_ON, POWER_OFF or
|
:param power_state: The desired power state POWER_ON, POWER_OFF or
|
||||||
REBOOT from :mod:`ironic.common.states`.
|
REBOOT from :mod:`ironic.common.states`.
|
||||||
:raises: InvalidParameterValue if an invalid power state was specified.
|
:raises: InvalidParameterValue if an invalid power state was specified.
|
||||||
@ -135,7 +143,6 @@ class OneViewPower(base.PowerInterface):
|
|||||||
"""Reboot the node
|
"""Reboot the node
|
||||||
|
|
||||||
:param task: a TaskManager instance.
|
:param task: a TaskManager instance.
|
||||||
:param node: The Node.
|
|
||||||
:raises: PowerStateFailure if the final state of the node is not
|
:raises: PowerStateFailure if the final state of the node is not
|
||||||
POWER_ON.
|
POWER_ON.
|
||||||
"""
|
"""
|
||||||
|
@ -255,7 +255,7 @@ class OneViewDeployUtilsTestCase(db_base.DbTestCase):
|
|||||||
task.node)
|
task.node)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Tests for is_node_in_use_by_oneview
|
# Tests for is_node_in_use_by_ironic
|
||||||
def test_is_node_in_use_by_ironic(self, mock_get_ov_client):
|
def test_is_node_in_use_by_ironic(self, mock_get_ov_client):
|
||||||
"""Node has a Server Profile applied by ironic.
|
"""Node has a Server Profile applied by ironic.
|
||||||
|
|
||||||
|
@ -24,12 +24,12 @@ from ironic.common import exception
|
|||||||
from ironic.common import states
|
from ironic.common import states
|
||||||
from ironic.conductor import task_manager
|
from ironic.conductor import task_manager
|
||||||
from ironic.drivers.modules.oneview import common
|
from ironic.drivers.modules.oneview import common
|
||||||
|
from ironic.drivers.modules.oneview import deploy_utils
|
||||||
from ironic.tests.unit.conductor import mgr_utils
|
from ironic.tests.unit.conductor import mgr_utils
|
||||||
from ironic.tests.unit.db import base as db_base
|
from ironic.tests.unit.db import base as db_base
|
||||||
from ironic.tests.unit.db import utils as db_utils
|
from ironic.tests.unit.db import utils as db_utils
|
||||||
from ironic.tests.unit.objects import utils as obj_utils
|
from ironic.tests.unit.objects import utils as obj_utils
|
||||||
|
|
||||||
|
|
||||||
oneview_exceptions = importutils.try_import('oneview_client.exceptions')
|
oneview_exceptions = importutils.try_import('oneview_client.exceptions')
|
||||||
|
|
||||||
POWER_ON = 'On'
|
POWER_ON = 'On'
|
||||||
@ -58,7 +58,11 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
|||||||
|
|
||||||
@mock.patch.object(common, 'validate_oneview_resources_compatibility',
|
@mock.patch.object(common, 'validate_oneview_resources_compatibility',
|
||||||
spect_set=True, autospec=True)
|
spect_set=True, autospec=True)
|
||||||
def test_power_interface_validate(self, mock_validate, mock_get_ov_client):
|
@mock.patch.object(deploy_utils, 'is_node_in_use_by_oneview',
|
||||||
|
spect_set=True, autospec=True)
|
||||||
|
def test_power_interface_validate(self, mock_is_node_in_use_by_oneview,
|
||||||
|
mock_validate, mock_get_ov_client):
|
||||||
|
mock_is_node_in_use_by_oneview.return_value = False
|
||||||
with task_manager.acquire(self.context, self.node.uuid) as task:
|
with task_manager.acquire(self.context, self.node.uuid) as task:
|
||||||
task.driver.power.validate(task)
|
task.driver.power.validate(task)
|
||||||
self.assertTrue(mock_validate.called)
|
self.assertTrue(mock_validate.called)
|
||||||
@ -82,6 +86,35 @@ class OneViewPowerDriverTestCase(db_base.DbTestCase):
|
|||||||
task.driver.power.validate,
|
task.driver.power.validate,
|
||||||
task)
|
task)
|
||||||
|
|
||||||
|
@mock.patch.object(common, 'validate_oneview_resources_compatibility',
|
||||||
|
spect_set=True, autospec=True)
|
||||||
|
@mock.patch.object(deploy_utils, 'is_node_in_use_by_oneview',
|
||||||
|
spect_set=True, autospec=True)
|
||||||
|
def test_power_validate_fail_node_used_by_oneview(
|
||||||
|
self, mock_is_node_in_use_by_oneview, mock_validate,
|
||||||
|
mock_get_ov_client):
|
||||||
|
mock_validate.return_value = True
|
||||||
|
mock_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)
|
||||||
|
|
||||||
|
@mock.patch.object(common, 'validate_oneview_resources_compatibility',
|
||||||
|
spect_set=True, autospec=True)
|
||||||
|
@mock.patch.object(deploy_utils, 'is_node_in_use_by_oneview',
|
||||||
|
spect_set=True, autospec=True)
|
||||||
|
def test_validate_fail_node_in_use_by_oneview(
|
||||||
|
self, mock_is_node_in_use_by_oneview, mock_validate,
|
||||||
|
mock_get_ov_client):
|
||||||
|
mock_validate.return_value = True
|
||||||
|
mock_is_node_in_use_by_oneview.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_power_interface_get_properties(self, mock_get_ov_client):
|
def test_power_interface_get_properties(self, mock_get_ov_client):
|
||||||
expected = common.COMMON_PROPERTIES
|
expected = common.COMMON_PROPERTIES
|
||||||
self.assertItemsEqual(expected, self.driver.power.get_properties())
|
self.assertItemsEqual(expected, self.driver.power.get_properties())
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
fixes:
|
||||||
|
- Fixes an issue with ironic being able to change
|
||||||
|
the power state of nodes currently in use by OneView.
|
Loading…
Reference in New Issue
Block a user