Skip to content

Commit

Permalink
Simplify rules, allow to invert rule matcher.
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfontein committed Aug 12, 2024
1 parent 6951f8c commit 4a7e481
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 22 deletions.
15 changes: 12 additions & 3 deletions plugins/doc_fragments/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ class ModuleDocFragment(object):
- The field whose values to restrict.
required: true
type: str
match_disabled:
description:
- Whether disabled or not provided values should match.
type: bool
default: false
values:
description:
- The values of the field to limit to.
Expand All @@ -115,15 +120,19 @@ class ModuleDocFragment(object):
and librouteros converts the value returned by the API to the integer V(0),
then this will not match. If you are not sure, better include both variants:
both the string and the integer.
- Use V(none) for disabled values.
- Either O(restrict[].values) or O(restrict[].regex), but not both, must be specified.
type: list
elements: raw
regex:
description:
- A regular expression matching values of the field to limit to.
- Note that all values will be converted to strings before matching.
- It is not possible to match disabled values with regular expressions.
- Either O(restrict[].values) or O(restrict[].regex), but not both, must be specified.
Set O(restrict[].match_disabled=true) if you also want to match disabled values.
type: str
invert:
description:
- Invert the condition. This affects O(restrict[].match_disabled), O(restrict[].values),
and O(restrict[].regex).
type: bool
default: false
'''
51 changes: 32 additions & 19 deletions plugins/module_utils/_api_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,14 @@ def validate_and_prepare_restrict(module, path_info):
if f is None:
module.fail_json(msg='restrict: the field "{0}" does not exist for this path'.format(field))

new_rule = dict(field=field)
new_rule = dict(
field=field,
match_disabled=rule['match_disabled'],
invert=rule['invert'],
)
if rule['values'] is not None:
new_rule['values'] = rule['values']
elif rule['regex'] is not None:
if rule['regex'] is not None:
regex = rule['regex']
try:
new_rule['regex'] = re.compile(regex)
Expand All @@ -41,6 +45,25 @@ def validate_and_prepare_restrict(module, path_info):
return restrict_data


def _value_to_str(value):
if value is None:
return None
value_str = to_text(value)
if isinstance(value, bool):
value_str = value_str.lower()
return value_str


def _test_rule_except_invert(value, rule):
if value is None and rule['match_disabled']:
return True
if 'values' in rule and value in rule['values']:
return True
if 'regex' in rule and value is not None and rule['regex'].match(value_to_str(value)):
return True
return False


def restrict_entry_accepted(entry, path_info, restrict_data):
if restrict_data is None:
return True
Expand All @@ -54,18 +77,12 @@ def restrict_entry_accepted(entry, path_info, restrict_data):
if field not in entry and field_info.absent_value:
value = field_info.absent_value

# Actual test
if 'values' in rule and value not in rule['values']:
# Check
matches_rule = _test_rule_except_invert(value, rule)
if rule['invert']:
matches_rule = not matches_rule
if not matches_rule:
return False
if 'regex' in rule:
if value is None:
# regex cannot match None
return False
value_str = to_text(value)
if isinstance(value, bool):
value_str = value_str.lower()
if rule['regex'].match(value_str):
return False
return True


Expand All @@ -76,14 +93,10 @@ def restrict_argument_spec():
elements='dict',
options=dict(
field=dict(type='str', required=True),
match_disabled=dict(type='bool', default=False),
values=dict(type='list', elements='raw'),
regex=dict(type='str'),
invert=dict(type='bool', default=False),
),
mutually_exclusive=[
('values', 'regex'),
],
required_one_of=[
('values', 'regex'),
],
),
)

0 comments on commit 4a7e481

Please sign in to comment.