From df499ea8aca4bbdd5589bba4a3b0265f148ca8b9 Mon Sep 17 00:00:00 2001 From: kkthxbye <400797+kkthxbye-code@users.noreply.github.com> Date: Mon, 13 Feb 2023 23:44:35 +0100 Subject: [PATCH] Fixes #11459 - Allow using null in conditions (#11722) * Fixes #11459 - Allow using null in conditions - Update docs to reflect this - Change docs example from primary_ip to primary_ip4 as computed properties are not serialized when queuing webhooks * Update netbox/extras/conditions.py --------- Co-authored-by: Simon Toft Co-authored-by: Jeremy Stretch --- docs/reference/conditions.md | 6 +++--- netbox/extras/conditions.py | 3 ++- netbox/extras/tests/test_conditions.py | 10 ++++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/reference/conditions.md b/docs/reference/conditions.md index fb8b66139..514006b01 100644 --- a/docs/reference/conditions.md +++ b/docs/reference/conditions.md @@ -97,7 +97,7 @@ Multiple conditions can be combined into nested sets using AND or OR logic. This ### Examples -`status` is "active" and `primary_ip` is defined _or_ the "exempt" tag is applied. +`status` is "active" and `primary_ip4` is defined _or_ the "exempt" tag is applied. ```json { @@ -109,8 +109,8 @@ Multiple conditions can be combined into nested sets using AND or OR logic. This "value": "active" }, { - "attr": "primary_ip", - "value": "", + "attr": "primary_ip4", + "value": null, "negate": true } ] diff --git a/netbox/extras/conditions.py b/netbox/extras/conditions.py index 965488c3a..c6744e524 100644 --- a/netbox/extras/conditions.py +++ b/netbox/extras/conditions.py @@ -44,7 +44,8 @@ class Condition: bool: (EQ, CONTAINS), int: (EQ, GT, GTE, LT, LTE, CONTAINS), float: (EQ, GT, GTE, LT, LTE, CONTAINS), - list: (EQ, IN, CONTAINS) + list: (EQ, IN, CONTAINS), + type(None): (EQ,) } def __init__(self, attr, value, op=EQ, negate=False): diff --git a/netbox/extras/tests/test_conditions.py b/netbox/extras/tests/test_conditions.py index 8e02eb75d..e7275482a 100644 --- a/netbox/extras/tests/test_conditions.py +++ b/netbox/extras/tests/test_conditions.py @@ -126,6 +126,16 @@ class ConditionSetTest(TestCase): with self.assertRaises(ValueError): ConditionSet({'foo': []}) + def test_null_value(self): + cs = ConditionSet({ + 'and': [ + {'attr': 'a', 'value': None, 'op': 'eq', 'negate': True}, + ] + }) + self.assertFalse(cs.eval({'a': None})) + self.assertTrue(cs.eval({'a': "string"})) + self.assertTrue(cs.eval({'a': {"key": "value"}})) + def test_and_single_depth(self): cs = ConditionSet({ 'and': [