Exemple #1
0
def dispatch_event(event, context):
    error = event.get('detail', {}).get('errorCode')
    if error and C7N_SKIP_EVTERR:
        log.debug("Skipping failed operation: %s" % error)
        return

    # one time initialization for cold starts.
    global policy_config, policy_data
    if policy_config is None:
        with open('config.json') as f:
            policy_data = json.load(f)
        policy_config = init_config(policy_data)
        load_resources(StructureParser().get_resource_types(policy_data))

    if C7N_DEBUG_EVENT:
        event['debug'] = True
        log.info("Processing event\n %s", format_event(event))

    if not policy_data or not policy_data.get('policies'):
        return False

    policies = PolicyCollection.from_data(policy_data, policy_config)
    for p in policies:
        try:
            # validation provides for an initialization point for
            # some filters/actions.
            p.validate()
            p.push(event, context)
        except Exception:
            log.exception("error during policy execution")
            if C7N_CATCH_ERR:
                continue
            raise
    return True
Exemple #2
0
 def validate(self, policy_data, resource_types=None):
     # before calling validate, gen_schema needs to be invoked
     # with the qualified resource types in policy_data.
     if resource_types is None:
         resource_types = StructureParser().get_resource_types(policy_data)
     self.gen_schema(tuple(sorted(resource_types)))
     errors = self._validate(policy_data)
     return errors or []
Exemple #3
0
def run(event, context, subscription_id=None):
    # policies file should always be valid in functions so do loading naively
    with open(context['config_file']) as f:
        policy_config = json.load(f)

    if not policy_config or not policy_config.get('policies'):
        log.error('Invalid policy config')
        return False

    options_overrides = \
        policy_config['policies'][0].get('mode', {}).get('execution-options', {})

    # setup our auth file location on disk
    options_overrides['authorization_file'] = context['auth_file']

    # if output_dir specified use that, otherwise make a temp directory
    if 'output_dir' not in options_overrides:
        options_overrides['output_dir'] = get_tmp_output_dir()

    # merge all our options in
    options = Config.empty(**options_overrides)

    if subscription_id is not None:
        options['account_id'] = subscription_id

    load_resources(StructureParser().get_resource_types(policy_config))

    options = Azure().initialize(options)

    policies = PolicyCollection.from_data(policy_config, options)
    if policies:
        for p in policies:
            try:
                p.push(event, context)
            except (CloudError, AzureHttpError) as error:
                log.error("Unable to process policy: %s :: %s" %
                          (p.name, error))

    reset_session_cache()
    return True
Exemple #4
0
 def __init__(self, config):
     self.policy_config = config
     self.validator = SchemaValidator()
     self.structure = StructureParser()
     self.seen_types = set()
Exemple #5
0
class PolicyLoader(object):

    default_schema_validate = bool(schema)
    default_schema_class = SchemaValidator
    collection_class = PolicyCollection

    def __init__(self, config):
        self.policy_config = config
        self.validator = SchemaValidator()
        self.structure = StructureParser()
        self.seen_types = set()

    def load_file(self, file_path, format=None):
        # should we do os.path.expanduser here?
        if not os.path.exists(file_path):
            raise IOError("Invalid path for config %r" % file_path)
        policy_data = load_file(file_path, format=format)
        return self.load_data(policy_data, file_path)

    def _handle_missing_resources(self, policy_data, missing):
        # for an invalid resource type catch and try to associate
        # it to the policy by name.
        for p in policy_data.get('policies', ()):
            pr = p['resource']
            if '.' not in pr:
                pr = "aws.%s" % pr
            if pr in missing:
                raise PolicyValidationError(
                    "Policy:%s references an unknown resource:%s" %
                    (p['name'], p['resource']))

    def load_data(self,
                  policy_data,
                  file_uri,
                  validate=None,
                  session_factory=None,
                  config=None):
        self.structure.validate(policy_data)

        # Use passed in policy exec configuration or default on loader
        config = config or self.policy_config

        # track policy resource types and only load if needed.
        rtypes = set(self.structure.get_resource_types(policy_data))

        missing = load_resources(list(rtypes))
        if missing:
            self._handle_missing_resources(policy_data, missing)

        if validate is not False or (validate is None
                                     and self.default_schema_validate):
            errors = self.validator.validate(policy_data, tuple(rtypes))
            if errors:
                raise PolicyValidationError(
                    "Failed to validate policy %s\n %s\n" %
                    (errors[1], errors[0]))

        collection = self.collection_class.from_data(policy_data, config,
                                                     session_factory)

        # non schema validation of policies isnt optional its
        # become a lazy initialization point for resources.
        #
        # it would be good to review where we do validation
        # as we also have to do after provider policy
        # initialization due to the region expansion.
        #
        # ie we should defer this to callers
        # [p.validate() for p in collection]
        return collection