Added multiple filter support

Hopefully doens't break anything running

YOLOOOOOOOOOO
This commit is contained in:
Daniel Dayley 2021-06-01 17:36:34 -06:00
parent 30808eee70
commit b4f4a8346c
3 changed files with 34 additions and 14 deletions

View File

@ -34,7 +34,7 @@ optional arguments:
-c CONFIG, --config CONFIG
Specify a config file (~/.config/ifxlookup.yml by default)
-f FILTER, --filter FILTER
Apply a JSONPath filter to the results
Apply a JSONPath filter to the results (multiple filters may be specified)
-j, --json Format output as json
-cg, --vip Return VIP information about the subject (f5)
-b, --bluecat Return network information about the subject (bluecat)
@ -76,6 +76,8 @@ IFXLookup may filter the results returned by any and all plugins by applying a [
ifxlookup -d -f '*.dns.mx' sling.com dish.com
```
You can specify multiple filters with -f, however, all filters run on the results dataset separately. Filters cannot be stacked due to the nature of JSONPath.
#### Examples
To find the DHCP assigned gateway for a the IP 10.124.24.130:
@ -174,9 +176,9 @@ Returns a map of plugins configured to use in the lookup.
#### lookup()
```python
ifxlookup.IFXLookup.lookup(self,subjects,filter=None)
ifxlookup.IFXLookup.lookup(self,subjects,filters=None)
```
Performs a search with the configured plugins and filter and returns a dictionary of search data.
Performs a search with the configured plugins and filters and returns a dictionary of search data.
#### search_plugins(directory)
```python

View File

@ -50,7 +50,7 @@ if __name__ == '__main__':
# Gather Argument options
parser = argparse.ArgumentParser(epilog=EXAMPLE_TEXT,formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-c', '--config', action='store', help='Specify a config file (~/.config/ifxlookup.yml by default)')
parser.add_argument('-f', '--filter', action='store', default=None, help='Apply a JSONPath filter to the results')
parser.add_argument('-f', '--filter', action='append', default=None, help='Apply a JSONPath filter to the results (multiple filters may be specified)')
parser.add_argument('-j', '--json', action='store_true', help='Format output as json')
# parser.add_argument('-l', '--link', action='store_true', help='Return physical link information about the subject')
for delegate in available_plugins.values() :
@ -124,7 +124,7 @@ if __name__ == '__main__':
search.set_debug_level(args.debug)
# Run search
report = search.lookup(args.subjects,filter=args.filter)
report = search.lookup(args.subjects,filters=args.filter)
if args.json :
print(json.dumps(report))
else :

View File

@ -62,7 +62,12 @@ class IFXLookup():
"""Generate map of ifxlookup runtime values that should be made available to plugins."""
return {'debug' : self._debug_level,'caching': self._caching}
def __filter_and_return(self,subjects,dataset,filter) :
def __apply_filter(self,dataset,jsonpath_filter) :
"""Applies the given jsonpath filter to the dataset and returns the filtered results."""
filtered_result = [x.value for x in jsonpath_filter.find(dataset)]
return filtered_result
def __prepare_final(self,subjects,dataset,filters) :
"""Returns the submitted dataset, applying the given filter."""
final_result = {}
if 'error' in dataset or 'warn' in dataset :
@ -76,11 +81,13 @@ class IFXLookup():
for plugin in [x for x in dataset if x != 'error' and x != 'warn'] :
subjectdataset.update({plugin:dataset[plugin][subject]})
final_result.update({subject:subjectdataset})
# Apply Filter
if filter :
jsonpath_filter = jsonpath_ng.parse(filter)
final_result = [x.value for x in jsonpath_filter.find(final_result)]
return final_result
# Apply Filters
if type(filters) != list :
raise TypeError('argument \'filters\' should be of type list')
filtered_result = []
for filter in filters :
filtered_result.extend(self.__apply_filter(final_result, filter))
return filtered_result
def use_plugins(self,plugins,reload=False) :
"""Defines plugins that should be used in a lookup, optionally forcing them to reload."""
@ -162,12 +169,22 @@ class IFXLookup():
self._caching = False
return self
def lookup(self,subjects,filter=None) :
"""Performs a search with the configured plugins and filter and returns a dictionary of search data."""
def lookup(self,subjects,filter=None,filters=None) :
"""Performs a search with the configured plugins and filters and returns a dictionary of search data."""
# Filter argument provided for backwards compatibility, please use `filters` instead.
hints = {}
final_report = {}
error_info = {}
warn_info = {}
# Clean and verify filters
if filter and not filters :
filters = [filter]
valid_filters = []
for filter in filters :
new_filter = jsonpath_ng.parse(filter)
valid_filters.append(new_filter)
# Assert that each plugin has a config
for delegatename,delegate in self._delegate_map.items() :
if not delegatename in self._config.keys() :
@ -212,7 +229,8 @@ class IFXLookup():
# If caching is enabled prevent shutdown. Otherwise shutdown.
if not self._caching :
self.__shutdown_plugins()
return self.__filter_and_return(subjects,final_report,filter)
final = self.__prepare_final(subjects,final_report,valid_filters)
return final
def finish(self) :
"""In the case that caching has been enabled, this enables the plugins to be manually shut down."""