def do_discovery()

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)
  }))