docs: def validate(config):
      '''
      Validate the beacon configuration
      '''
      valid = True
      messages = []
  
      if not isinstance(config, list):
          valid = False
          messages.append('[-] Configuration for %s beacon must be a list', config)
      else:
          _config = {}
          list(map(_config.update, config))
  
      try:
          sites = _config.get('sites', {})
      except AttributeError:
          valid = False
          messages.append('[-] Sites for %s beacon must be a dict', __virtualname__)
  
      if not sites:
          valid = False
          messages.append('[-] Configuration does not contain sites')
  
      for site, settings in sites.items():
          if required_site_attributes.isdisjoint(set(settings.keys())):
              valid = False
              messages.append('[-] Sites for {} beacon requires {}'.format(__virtualname__,
                                                                           required_site_attributes))
          log.debug('[+] site: %s', site)
          log.debug('[+] settings: %s', settings)
  
          for optional_attrs in itertools.chain(settings.get(attr, []) for attr in optional_site_attributes):
              for item in optional_attrs:
                  cmp = item.get('comp')
                  if cmp and cmp not in comparisons:
                      valid = False
                      messages.append('[-] Invalid comparison operator %s', cmp)
  
      messages.append('[+] Valid beacon configuration')
      return valid, messages