Browse Source

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
changes/26/603126/3
Dmitry Tantsur 4 years ago
parent
commit
0a26a6677d
  1. 6
      doc/source/user/usage.rst
  2. 22
      ironic_inspector/node_cache.py
  3. 14
      ironic_inspector/plugins/rules.py
  4. 38
      ironic_inspector/test/unit/test_plugins_rules.py
  5. 5
      releasenotes/notes/trait-actions-eec05cbb6a944619.yaml
  6. 2
      setup.cfg

6
doc/source/user/usage.rst

@ -123,6 +123,12 @@ Default available actions include:
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.
* ``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
from introspection, using `python string formatting notation
<https://docs.python.org/2/library/string.html#formatspec>`_::

22
ironic_inspector/node_cache.py

@ -470,6 +470,28 @@ class NodeInfo(object):
ironic=ironic,
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):
"""Delete port.

14
ironic_inspector/plugins/rules.py

@ -151,3 +151,17 @@ class ExtendAttributeAction(base.RuleActionPlugin):
return values
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'])

38
ironic_inspector/test/unit/test_plugins_rules.py

@ -14,6 +14,7 @@
"""Tests for introspection rules plugins."""
from ironicclient import exceptions
import mock
from ironic_inspector.common import ironic as ir_utils
@ -222,3 +223,40 @@ class TestExtendAttributeAction(test_base.NodeTest):
self.node.extra['value'] = [42]
self.act.apply(self.node_info, params)
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

@ -0,0 +1,5 @@
---
features:
- |
Adds new introspection rules actions to add or remove traits on nodes:
``add-trait`` and ``remove-trait``.

2
setup.cfg

@ -60,6 +60,8 @@ ironic_inspector.rules.actions =
set-attribute = ironic_inspector.plugins.rules:SetAttributeAction
set-capability = ironic_inspector.plugins.rules:SetCapabilityAction
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 =
dnsmasq = ironic_inspector.pxe_filter.dnsmasq:DnsmasqFilter
iptables = ironic_inspector.pxe_filter.iptables:IptablesFilter

Loading…
Cancel
Save