def get_policy_state(obj, stack_name, resources, managed_policy=False): def _filter(pols): return [p for p in pols['AttachedPolicies'] if p['PolicyName'] == policy_name] iam = aws_stack.connect_to_service('iam') props = obj.props policy_name = props.get('PolicyName') or props.get('ManagedPolicyName') result = {} roles = props.get('Roles', []) users = props.get('Users', []) groups = props.get('Groups', []) if managed_policy: result['policy'] = iam.get_policy(PolicyArn=aws_stack.policy_arn(policy_name)) for role in roles: role = obj.resolve_refs_recursively(stack_name, role, resources) policies = (_filter(iam.list_attached_role_policies(RoleName=role)) if managed_policy else iam.get_role_policy(RoleName=role, PolicyName=policy_name)) result['role:%s' % role] = policies for user in users: user = obj.resolve_refs_recursively(stack_name, user, resources) policies = (_filter(iam.list_attached_user_policies(UserName=user)) if managed_policy else iam.get_user_policy(UserName=user, PolicyName=policy_name)) result['user:%s' % user] = policies for group in groups: group = obj.resolve_refs_recursively(stack_name, group, resources) policies = (_filter(iam.list_attached_group_policies(GroupName=group)) if managed_policy else iam.get_group_policy(GroupName=group, PolicyName=policy_name)) result['group:%s' % group] = policies result = {k: v for k, v in result.items() if v} return result or None
def fetch_state(self, stack_name, resources): iam = aws_stack.connect_to_service('iam') props = self.props policy_name = LAMBDA_POLICY_NAME_PATTERN % props.get('FunctionName') policy_arn = aws_stack.policy_arn(policy_name) policy = iam.get_policy(PolicyArn=policy_arn)['Policy'] version = policy.get('DefaultVersionId') policy = iam.get_policy_version(PolicyArn=policy_arn, VersionId=version)['PolicyVersion'] statements = policy['Document']['Statement'] statements = statements if isinstance(statements, list) else [statements] func_arn = aws_stack.lambda_function_arn(props['FunctionName']) principal = props.get('Principal') existing = [ s for s in statements if s['Action'] == props['Action'] and s['Resource'] == func_arn and (not principal or s['Principal'] in [principal, { 'Service': principal }, { 'Service': [principal] }]) ] return existing[0] if existing else None
def get_policy_state(cls, obj, stack_name, resources, managed_policy=False): def _filter(pols): return [ p for p in pols["AttachedPolicies"] if p["PolicyName"] == policy_name ] iam = aws_stack.connect_to_service("iam") props = obj.props result = {} # Note: util function reused for both IAM::Policy and IAM::ManagedPolicy policy_name = props.get("PolicyName") or props.get("ManagedPolicyName") roles = props.get("Roles", []) users = props.get("Users", []) groups = props.get("Groups", []) if managed_policy: result["policy"] = iam.get_policy( PolicyArn=aws_stack.policy_arn(policy_name)) for role in roles: role = obj.resolve_refs_recursively(stack_name, role, resources) policies = (_filter(iam.list_attached_role_policies( RoleName=role)) if managed_policy else iam.get_role_policy( RoleName=role, PolicyName=policy_name)) result["role:%s" % role] = policies for user in users: user = obj.resolve_refs_recursively(stack_name, user, resources) policies = (_filter(iam.list_attached_user_policies( UserName=user)) if managed_policy else iam.get_user_policy( UserName=user, PolicyName=policy_name)) result["user:%s" % user] = policies for group in groups: group = obj.resolve_refs_recursively(stack_name, group, resources) policies = (_filter( iam.list_attached_group_policies(GroupName=group)) if managed_policy else iam.get_group_policy( GroupName=group, PolicyName=policy_name)) result["group:%s" % group] = policies result = {k: v for k, v in result.items() if v} return result or None
def do_fetch_state(self, resource_name, resource_arn): iam = aws_stack.connect_to_service("iam") props = self.props policy_name = LAMBDA_POLICY_NAME_PATTERN % resource_name policy_arn = aws_stack.policy_arn(policy_name) policy = iam.get_policy(PolicyArn=policy_arn)["Policy"] version = policy.get("DefaultVersionId") policy = iam.get_policy_version(PolicyArn=policy_arn, VersionId=version)["PolicyVersion"] statements = policy["Document"]["Statement"] statements = statements if isinstance(statements, list) else [statements] principal = props.get("Principal") existing = [ s for s in statements if s["Action"] == props["Action"] and s["Resource"] == resource_arn and ( not principal or s["Principal"] in [principal, {"Service": principal}, {"Service": [principal]}] ) ] return existing[0] if existing else None
def _delete_params(params, *args, **kwargs): return {"PolicyArn": aws_stack.policy_arn(params["PolicyName"])}
def get_physical_resource_id(self, attribute=None, **kwargs): return aws_stack.policy_arn(self.props["ManagedPolicyName"])