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
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 []
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
def __init__(self, config): self.policy_config = config self.validator = SchemaValidator() self.structure = StructureParser() self.seen_types = set()
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