def resources_gc_prefix(options, policy_collection): """Garbage collect old custodian policies based on prefix. We attempt to introspect to find the event sources for a policy but without the old configuration this is implicit. """ session_factory = SessionFactory(options.region, options.profile, options.assume_role) manager = mu.LambdaManager(session_factory) funcs = list(manager.list_functions('custodian-')) client = session_factory().client('lambda') remove = [] current_policies = [p.name for p in policy_collection] for f in funcs: pn = f['FunctionName'].split('-', 1)[1] if pn not in current_policies: remove.append(f) for n in remove: events = [] try: result = client.get_policy(FunctionName=n['FunctionName']) except ClientError as e: if e.response['Error']['Code'] == 'ResourceNotFoundException': log.warn( "Lambda Function or Access Policy Statement missing: {}". format(n['FunctionName'])) else: log.warn("Unexpected error: {} for function {}".format( e, n['FunctionName'])) # Continue on with next function instead of raising an exception continue if 'Policy' not in result: pass else: p = json.loads(result['Policy']) for s in p['Statement']: principal = s.get('Principal') if not isinstance(principal, dict): log.info("Skipping function %s" % n['FunctionName']) continue if principal == {'Service': 'events.amazonaws.com'}: events.append(mu.CloudWatchEventSource({}, session_factory)) elif principal == {'Service': 'config.amazonaws.com'}: events.append(mu.ConfigRule({}, session_factory)) f = mu.LambdaFunction( { 'name': n['FunctionName'], 'role': n['Role'], 'handler': n['Handler'], 'timeout': n['Timeout'], 'memory_size': n['MemorySize'], 'description': n['Description'], 'runtime': n['Runtime'], 'events': events }, None) log.info("Removing %s" % n['FunctionName']) if options.dryrun: log.info("Dryrun skipping removal") continue manager.remove(f) log.info("Removed %s" % n['FunctionName'])
def region_gc(options, region, policy_config, policies): session_factory = SessionFactory(region=region, assume_role=policy_config.assume_role, profile=policy_config.profile, external_id=policy_config.external_id) manager = mu.LambdaManager(session_factory) funcs = list(manager.list_functions(options.prefix)) client = session_factory().client('lambda') remove = [] current_policies = [p.name for p in policies] pattern = re.compile(options.policy_regex) for f in funcs: if not pattern.match(f['FunctionName']): continue match = False for pn in current_policies: if f['FunctionName'].endswith(pn): match = True if options.present: if match: remove.append(f) elif not match: remove.append(f) for n in remove: events = [] try: result = client.get_policy(FunctionName=n['FunctionName']) except ClientError as e: if e.response['Error']['Code'] == 'ResourceNotFoundException': log.warning( "Region:%s Lambda Function or Access Policy Statement missing: %s", region, n['FunctionName']) else: log.warning("Region:%s Unexpected error: %s for function %s", region, e, n['FunctionName']) # Continue on with next function instead of raising an exception continue if 'Policy' not in result: pass else: p = json.loads(result['Policy']) for s in p['Statement']: principal = s.get('Principal') if not isinstance(principal, dict): log.info("Skipping function %s" % n['FunctionName']) continue if principal == {'Service': 'events.amazonaws.com'}: events.append(mu.CloudWatchEventSource({}, session_factory)) elif principal == {'Service': 'config.amazonaws.com'}: events.append(mu.ConfigRule({}, session_factory)) f = mu.LambdaFunction( { 'name': n['FunctionName'], 'role': n['Role'], 'handler': n['Handler'], 'timeout': n['Timeout'], 'memory_size': n['MemorySize'], 'description': n['Description'], 'runtime': n['Runtime'], 'events': events }, None) log.info("Region:%s Removing %s", region, n['FunctionName']) if options.dryrun: log.info("Dryrun skipping removal") continue manager.remove(f) log.info("Region:%s Removed %s", region, n['FunctionName'])