Closed dbarrosop closed 1 year ago
Would be interested to hear what is the problem we trying to solve here?
Seems interesting solution, but struggling to come out with use case for it, that grammar seems quiet human readable as, IMHO, this:
1: f = parse("(site == 'site2' OR role == 'www') AND my_var == 'comes_from_dev1.group_1'")
easier to read/comprehand compared to
2: f = (F(site="site2") | F(role="www")) & F(my_var="comes_from_dev1.group_1")
however, what about this form: 3:
f = parse(
[
{"site": "site2", "my_var": "comes_from_dev1.group_1"},
{"role": "www", "my_var": "comes_from_dev1.group_1"}
]
)
where, for instance, list of dictionaries express OR logic between items, but AND logic within each dictionary, that way host satisfying any of the dictionaries will pass the filter, equivalent to:
f = (
(F(site="site2", my_var="comes_from_dev1.group_1") |
(F(role="www", my_var="comes_from_dev1.group_1"))
)
Option | Pros | Cons |
---|---|---|
1 | Human readable | Hard to construct programmatically and need to learn grammar |
2 | Built into NR, already exists | Relatively hard to read and remember, hard to construct programmatically |
3 | Human readable and easy to construct/process programmatically | Need to remember implicit filtering logic, less flexible (?) |
Also, to implement option 3, code might be:
def _filter_FO(nr, filter_data):
"""
Function to filter hosts using Filter Object
"""
ret = nr
ret = ret.filter(F(**filter_data[0]))
for item in filter_data[1:]:
filtered_hosts = nr.filter(F(**item))
ret.inventory.hosts.update(filtered_hosts.inventory.hosts)
return ret
This is for use in command lines (i.e. a —filter
flag), apis, etc where you have no python.
Notice that this grammar parser doesn’t replace the F object, as a matter of fact, the grammar parser converts a string into it so without it it wouldn’t work :) The recommended way of filtering within python will still be using the F object but everybody seems to be inventing some way of describing F objects in text somehow for their command line tools so this is the response to that.
Ic, makes more sense now, thanks for explanation.
I love the idea of having a standard filter grammar parser. Here's my 2 cents:
"name==hostname”
“name==‘rtr1’”
“name==rtr1”
NOT
and !=
seem to overlap. Consider using key=value
instead of ==
and keeping NOT
NOT
/AND
/OR
or supporting both cases__endswith
supported?Some examples considering the above comments:
rtr1
name=rtr1
name__startswith=rtr
(group=routers or group=switches) and not platform=cisco_ios
Implemented a grammar parser that turns a string into an F object. For instance:
f = F(site="site1")
is equivalent tof = parse("site == 'site1'")
f = (F(site="site2") | F(role="www")) & F(my_var="comes_from_dev1.group_1")
is equivalent tof = parse("(site == 'site2' OR role == 'www') AND my_var == 'comes_from_dev1.group_1'")
and long etc.
Look at the tests for more examples.
TODO: