1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

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 <SITO@telenor.dk>
Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
kkthxbye
2023-02-13 23:44:35 +01:00
committed by GitHub
parent b5da383a17
commit df499ea8ac
3 changed files with 15 additions and 4 deletions

View File

@ -97,7 +97,7 @@ Multiple conditions can be combined into nested sets using AND or OR logic. This
### Examples ### 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 ```json
{ {
@ -109,8 +109,8 @@ Multiple conditions can be combined into nested sets using AND or OR logic. This
"value": "active" "value": "active"
}, },
{ {
"attr": "primary_ip", "attr": "primary_ip4",
"value": "", "value": null,
"negate": true "negate": true
} }
] ]

View File

@ -44,7 +44,8 @@ class Condition:
bool: (EQ, CONTAINS), bool: (EQ, CONTAINS),
int: (EQ, GT, GTE, LT, LTE, CONTAINS), int: (EQ, GT, GTE, LT, LTE, CONTAINS),
float: (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): def __init__(self, attr, value, op=EQ, negate=False):

View File

@ -126,6 +126,16 @@ class ConditionSetTest(TestCase):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
ConditionSet({'foo': []}) 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): def test_and_single_depth(self):
cs = ConditionSet({ cs = ConditionSet({
'and': [ 'and': [