Add introspection rules actions to add/remove traits on nodes
Otherwise it's not possible to modify them, since they're not updated via the regular node updating mechanism. Change-Id: I338015ff9dafe07f4e70a23ddcf6cd488eda9907 Story: #2003788 Task: #26496
This commit is contained in:
parent
34b150340c
commit
0a26a6677d
@ -123,6 +123,12 @@ Default available actions include:
|
|||||||
value as a list and appends value to it. If optional ``unique`` parameter is
|
value as a list and appends value to it. If optional ``unique`` parameter is
|
||||||
set to ``True``, nothing will be added if given value is already in a list.
|
set to ``True``, nothing will be added if given value is already in a list.
|
||||||
|
|
||||||
|
* ``add-trait`` adds a trait to an Ironic node. Requires a ``name`` field
|
||||||
|
with the name of the trait to add.
|
||||||
|
|
||||||
|
* ``remove-trait`` removes a trait from an Ironic node. Requires a ``name``
|
||||||
|
field with the name of the trait to remove.
|
||||||
|
|
||||||
Starting from Mitaka release, ``value`` field in actions supports fetching data
|
Starting from Mitaka release, ``value`` field in actions supports fetching data
|
||||||
from introspection, using `python string formatting notation
|
from introspection, using `python string formatting notation
|
||||||
<https://docs.python.org/2/library/string.html#formatspec>`_::
|
<https://docs.python.org/2/library/string.html#formatspec>`_::
|
||||||
|
@ -470,6 +470,28 @@ class NodeInfo(object):
|
|||||||
ironic=ironic,
|
ironic=ironic,
|
||||||
capabilities=ir_utils.dict_to_capabilities(existing))
|
capabilities=ir_utils.dict_to_capabilities(existing))
|
||||||
|
|
||||||
|
def add_trait(self, trait, ironic=None):
|
||||||
|
"""Add a trait to the node.
|
||||||
|
|
||||||
|
:param trait: trait to add
|
||||||
|
:param ironic: Ironic client to use instead of self.ironic
|
||||||
|
"""
|
||||||
|
ironic = ironic or self.ironic
|
||||||
|
ironic.node.add_trait(self.uuid, trait)
|
||||||
|
|
||||||
|
def remove_trait(self, trait, ironic=None):
|
||||||
|
"""Remove a trait from the node.
|
||||||
|
|
||||||
|
:param trait: trait to add
|
||||||
|
:param ironic: Ironic client to use instead of self.ironic
|
||||||
|
"""
|
||||||
|
ironic = ironic or self.ironic
|
||||||
|
try:
|
||||||
|
ironic.node.remove_trait(self.uuid, trait)
|
||||||
|
except exceptions.NotFound:
|
||||||
|
LOG.debug('Trait %s is not set, cannot remove', trait,
|
||||||
|
node_info=self)
|
||||||
|
|
||||||
def delete_port(self, port, ironic=None):
|
def delete_port(self, port, ironic=None):
|
||||||
"""Delete port.
|
"""Delete port.
|
||||||
|
|
||||||
|
@ -151,3 +151,17 @@ class ExtendAttributeAction(base.RuleActionPlugin):
|
|||||||
return values
|
return values
|
||||||
|
|
||||||
node_info.replace_field(params['path'], _replace, default=[])
|
node_info.replace_field(params['path'], _replace, default=[])
|
||||||
|
|
||||||
|
|
||||||
|
class AddTraitAction(base.RuleActionPlugin):
|
||||||
|
REQUIRED_PARAMS = {'name'}
|
||||||
|
|
||||||
|
def apply(self, node_info, params, **kwargs):
|
||||||
|
node_info.add_trait(params['name'])
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveTraitAction(base.RuleActionPlugin):
|
||||||
|
REQUIRED_PARAMS = {'name'}
|
||||||
|
|
||||||
|
def apply(self, node_info, params, **kwargs):
|
||||||
|
node_info.remove_trait(params['name'])
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
"""Tests for introspection rules plugins."""
|
"""Tests for introspection rules plugins."""
|
||||||
|
|
||||||
|
from ironicclient import exceptions
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from ironic_inspector.common import ironic as ir_utils
|
from ironic_inspector.common import ironic as ir_utils
|
||||||
@ -222,3 +223,40 @@ class TestExtendAttributeAction(test_base.NodeTest):
|
|||||||
self.node.extra['value'] = [42]
|
self.node.extra['value'] = [42]
|
||||||
self.act.apply(self.node_info, params)
|
self.act.apply(self.node_info, params)
|
||||||
self.assertFalse(mock_patch.called)
|
self.assertFalse(mock_patch.called)
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('ironic_inspector.common.ironic.get_client', autospec=True)
|
||||||
|
class TestAddTraitAction(test_base.NodeTest):
|
||||||
|
act = rules_plugins.AddTraitAction()
|
||||||
|
params = {'name': 'CUSTOM_FOO'}
|
||||||
|
|
||||||
|
def test_validate(self, mock_cli):
|
||||||
|
self.act.validate(self.params)
|
||||||
|
self.assertRaises(ValueError, self.act.validate, {'value': 42})
|
||||||
|
|
||||||
|
def test_add(self, mock_cli):
|
||||||
|
self.act.apply(self.node_info, self.params)
|
||||||
|
mock_cli.return_value.node.add_trait.assert_called_once_with(
|
||||||
|
self.uuid, 'CUSTOM_FOO')
|
||||||
|
|
||||||
|
|
||||||
|
@mock.patch('ironic_inspector.common.ironic.get_client', autospec=True)
|
||||||
|
class TestRemoveTraitAction(test_base.NodeTest):
|
||||||
|
act = rules_plugins.RemoveTraitAction()
|
||||||
|
params = {'name': 'CUSTOM_FOO'}
|
||||||
|
|
||||||
|
def test_validate(self, mock_cli):
|
||||||
|
self.act.validate(self.params)
|
||||||
|
self.assertRaises(ValueError, self.act.validate, {'value': 42})
|
||||||
|
|
||||||
|
def test_remove(self, mock_cli):
|
||||||
|
self.act.apply(self.node_info, self.params)
|
||||||
|
mock_cli.return_value.node.remove_trait.assert_called_once_with(
|
||||||
|
self.uuid, 'CUSTOM_FOO')
|
||||||
|
|
||||||
|
def test_remove_not_found(self, mock_cli):
|
||||||
|
mock_cli.return_value.node.remove_trait.side_effect = (
|
||||||
|
exceptions.NotFound('trait not found'))
|
||||||
|
self.act.apply(self.node_info, self.params)
|
||||||
|
mock_cli.return_value.node.remove_trait.assert_called_once_with(
|
||||||
|
self.uuid, 'CUSTOM_FOO')
|
||||||
|
5
releasenotes/notes/trait-actions-eec05cbb6a944619.yaml
Normal file
5
releasenotes/notes/trait-actions-eec05cbb6a944619.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- |
|
||||||
|
Adds new introspection rules actions to add or remove traits on nodes:
|
||||||
|
``add-trait`` and ``remove-trait``.
|
@ -60,6 +60,8 @@ ironic_inspector.rules.actions =
|
|||||||
set-attribute = ironic_inspector.plugins.rules:SetAttributeAction
|
set-attribute = ironic_inspector.plugins.rules:SetAttributeAction
|
||||||
set-capability = ironic_inspector.plugins.rules:SetCapabilityAction
|
set-capability = ironic_inspector.plugins.rules:SetCapabilityAction
|
||||||
extend-attribute = ironic_inspector.plugins.rules:ExtendAttributeAction
|
extend-attribute = ironic_inspector.plugins.rules:ExtendAttributeAction
|
||||||
|
add-trait = ironic_inspector.plugins.rules:AddTraitAction
|
||||||
|
remove-trait = ironic_inspector.plugins.rules:RemoveTraitAction
|
||||||
ironic_inspector.pxe_filter =
|
ironic_inspector.pxe_filter =
|
||||||
dnsmasq = ironic_inspector.pxe_filter.dnsmasq:DnsmasqFilter
|
dnsmasq = ironic_inspector.pxe_filter.dnsmasq:DnsmasqFilter
|
||||||
iptables = ironic_inspector.pxe_filter.iptables:IptablesFilter
|
iptables = ironic_inspector.pxe_filter.iptables:IptablesFilter
|
||||||
|
Loading…
Reference in New Issue
Block a user