in blueprints/cloud-operations/network-quota-monitoring/src/main.py [0:0]
def do_discovery(resources):
'''Calls discovery plugin functions and collect discovered resources.
The communication with discovery plugins uses double dispatch, where plugins
accept either no args and return 1-n HTTP request instances, or a single HTTP
response and return 1-n resource instances. A queue is set up for each plugin
results since each call can return multiple requests or resources.
Args:
resources: pre-initialized map where discovered resources will be stored.
'''
LOGGER.info(f'discovery start')
for plugin in plugins.get_discovery_plugins():
# set up the queue with the initial list of HTTP requests from this plugin
q = collections.deque(plugin.func(resources))
while q:
result = q.popleft()
if isinstance(result, plugins.HTTPRequest):
# fetch a single HTTP request
response = fetch(result)
if not response:
continue
if result.json:
try:
# decode the JSON HTTP response and pass it to the plugin
LOGGER.debug(f'passing JSON result to {plugin.name}')
results = plugin.func(resources, response, response.json())
except json.decoder.JSONDecodeError as e:
LOGGER.critical(
f'error decoding JSON for {result.url}: {e.args[0]}')
continue
else:
# pass the raw HTTP response to the plugin
LOGGER.debug(f'passing raw result to {plugin.name}')
results = plugin.func(resources, response)
q += collections.deque(results)
elif isinstance(result, plugins.Resource):
# store a resource the plugin derived from a previous HTTP response
LOGGER.debug(f'got resource {result} from {plugin.name}')
if result.key:
# this specific resource is indexed by an additional key
resources[result.type][result.id][result.key] = result.data
else:
resources[result.type][result.id] = result.data
LOGGER.info('discovery end {}'.format({
k: len(v) for k, v in resources.items() if not isinstance(v, str)
}))