Browse Source

Add new condition: is-empty

Now, if operators want to check some attribute isn't specified,
they should use 'eq' condition with None, '', etc values:

    {'op': 'eq', 'field': 'inventory.bmc_addres', 'value': ''}

It would be useful to have condition plugin witch verify this case,
'is-empty' checks that field is empty string, list, dict or None value:

    {'op': 'is-empty', 'field': 'inventory.bmc_addres'}

Change-Id: I6596a067e769530092c3db34405e0f0917d2f052
changes/23/278923/8
Anton Arefiev 6 years ago
parent
commit
061d839a26
  1. 5
      doc/source/usage.rst
  2. 7
      ironic_inspector/plugins/rules.py
  3. 4
      ironic_inspector/test/functional.py
  4. 20
      ironic_inspector/test/test_plugins_rules.py
  5. 4
      releasenotes/notes/empty-condition-abc707b771be6be3.yaml
  6. 1
      setup.cfg

5
doc/source/usage.rst

@ -69,7 +69,10 @@ A condition is represented by an object with fields:
* ``matches`` - requires a full match against a given regular expression;
* ``contains`` - requires a value to contain a given regular expression.
* ``contains`` - requires a value to contain a given regular expression;
* ``is-empty`` - checks that field is an empty string, list, dict or
None value.
``field`` a `JSON path <http://goessner.net/articles/JsonPath/>`_ to the field
in the introspection data to use in comparison.

7
ironic_inspector/plugins/rules.py

@ -67,6 +67,13 @@ class NeCondition(SimpleCondition):
op = operator.ne
class EmptyCondition(base.RuleConditionPlugin):
REQUIRED_PARAMS = set()
def check(self, node_info, field, params, **kwargs):
return field in ('', None, [], {})
class NetCondition(base.RuleConditionPlugin):
def validate(self, params, **kwargs):
super(NetCondition, self).validate(params, **kwargs)

4
ironic_inspector/test/functional.py

@ -94,7 +94,8 @@ class Base(base.NodeTest):
'bmc_address': self.bmc_address
},
'root_disk': {'name': '/dev/sda', 'model': 'Big Data Disk',
'size': 1000 * units.Gi},
'size': 1000 * units.Gi,
'wwn': None},
}
self.data_old_ramdisk = {
'cpus': 4,
@ -308,6 +309,7 @@ class Test(Base):
{'field': 'local_gb', 'op': 'lt', 'value': 1000},
{'field': 'local_gb', 'op': 'matches', 'value': '[0-9]+'},
{'field': 'cpu_arch', 'op': 'contains', 'value': '[0-9]+'},
{'field': 'root_disk.wwn', 'op': 'is-empty'}
],
'actions': [
{'action': 'set-attribute', 'path': '/extra/foo',

20
ironic_inspector/test/test_plugins_rules.py

@ -115,6 +115,26 @@ class TestNetCondition(test_base.BaseTest):
{'value': '192.0.2.1/24'}))
class TestEmptyCondition(test_base.BaseTest):
cond = rules_plugins.EmptyCondition()
def test_check_none(self):
self.assertTrue(self.cond.check(None, None, {}))
self.assertFalse(self.cond.check(None, 0, {}))
def test_check_empty_string(self):
self.assertTrue(self.cond.check(None, '', {}))
self.assertFalse(self.cond.check(None, '16', {}))
def test_check_empty_list(self):
self.assertTrue(self.cond.check(None, [], {}))
self.assertFalse(self.cond.check(None, ['16'], {}))
def test_check_empty_dict(self):
self.assertTrue(self.cond.check(None, {}, {}))
self.assertFalse(self.cond.check(None, {'test': '16'}, {}))
class TestFailAction(test_base.BaseTest):
act = rules_plugins.FailAction()

4
releasenotes/notes/empty-condition-abc707b771be6be3.yaml

@ -0,0 +1,4 @@
---
features:
- Added new condition plugin "is-empty", which allows to match
empty string, list, dictionary or None.

1
setup.cfg

@ -45,6 +45,7 @@ ironic_inspector.rules.conditions =
in-net = ironic_inspector.plugins.rules:NetCondition
matches = ironic_inspector.plugins.rules:MatchesCondition
contains = ironic_inspector.plugins.rules:ContainsCondition
is-empty = ironic_inspector.plugins.rules:EmptyCondition
ironic_inspector.rules.actions =
example = ironic_inspector.plugins.example:ExampleRuleAction
fail = ironic_inspector.plugins.rules:FailAction

Loading…
Cancel
Save