def policy_report(config, args): """ Generate a report detailing your desired groups/rules as parsed by this command. """ regions = util.regions(config) region_width = report.column_width(["REGION"] + regions) if not args.rules_only: if args.headers: print "REGION".ljust(region_width) + "GROUP" for region in regions: for group in policy.groups(config): print region.ljust(region_width) + group if not args.groups_only: headers = ["REGION", "SOURCE", "TARGET", "PROTOCOL", "PORT/TYPE"] ### Every rule in the policy, duplicated to each region we're ### managing, sorted by region. ### ### dict([('region', region)] + rule.items()) adds the 'region' key to ### the rule (which is stored as a dict) without updating it in-place. rules = [dict([("region", region)] + rule.items()) for rule in policy.parse(config) for region in regions] ### The inner list comprehension gives us a list of the data values ### from the rule dicts corresponding to the header. So, when header ### is 'SOURCE', the inner comprehension gives us a list of values of ### rule['source'] for every rule. To this list we pre-pend the header ### itself so the label width is accounted for in the calculation of ### the column width. ### ### The outer list comprehension repeats the above for each header. widths = report.column_widths([[header] + [rule[header.lower()] for rule in rules] for header in headers]) if args.headers: print "".join([header.ljust(widths[index]) for index, header in enumerate(headers)]) for rule in sorted(rules, key=itemgetter("region")): print "".join([report.format(rule[hdr.lower()]).ljust(widths[index]) for index, hdr in enumerate(headers)])
def diff(config, args): """ Generate a report showing the differences between your desired groups/rules and your current groups/rules. """ regions = util.regions(config) if not args.rules_only: policy_groups = dict([(region, set(policy.groups(config))) for region in regions]) aws_groups = dict([(region, set(aws.groups(region))) for region in regions]) all_groups = reduce( lambda a, b: a.union(b), [policy_groups[region].union(aws_groups[region]) for region in regions] ) headers = ["ACTION", "GROUP", "REGION"] actions = ["CREATE", "DELETE"] widths = [ report.column_width(["ACTION"] + actions), report.column_width(["GROUP"] + list(all_groups)), report.column_width(["REGION"] + regions), ] if args.headers: print "".join([header.ljust(widths[index]) for index, header in enumerate(headers)]) actions = [ ("CREATE", group, reg) for reg in regions for group in policy_groups[reg].difference(aws_groups[reg]) ] actions += [ ("DELETE", group, reg) for reg in regions for group in aws_groups[reg].difference(policy_groups[reg]) ] for action, group, region in actions: print "%s%s%s" % (action.ljust(widths[0]), group.ljust(widths[1]), region.ljust(widths[2])) if not args.groups_only: headers = ["ACTION", "REGION", "SOURCE", "TARGET", "PROTOCOL", "PORT/TYPE"] actions = ["ADD", "REMOVE"] policy_rules = [ dict([("region", region)] + rule.items()) for rule in policy.parse(config) for region in regions ] aws_rules = aws.policy(config) widths = report.column_widths( [[header] + [rule[header.lower()] for rule in policy_rules + aws_rules] for header in headers[1:]] ) widths = [report.column_width(["ACTION"] + actions)] + widths if args.headers: print "".join([header.ljust(widths[index]) for index, header in enumerate(headers)]) actions = [dict([("action", "ADD")] + rule.items()) for rule in policy_rules if rule not in aws_rules] actions += [dict([("action", "REMOVE")] + rule.items()) for rule in aws_rules if rule not in policy_rules] for act in sorted(actions, key=itemgetter("region")): print "".join([report.format(act[hdr.lower()]).ljust(widths[index]) for index, hdr in enumerate(headers)])
def sync(config, args): """ Synchronize groups/rules with your configured policy. Adds new groups/rules and REMOVES groups/rules not defined in the configuration file. """ regions = util.regions(config) account_id = aws.account_id(config) if not args.groups_only: policy_rules = [ dict([("region", region)] + rule.items()) for rule in policy.parse(config) for region in regions ] aws_rules = aws.policy(config) add_rules = [rule for rule in policy_rules if rule not in aws_rules] for rule in add_rules: try: result = aws.authorize(rule, account_id) if result: action = "ADDED" else: action = "FAILED ADDING" except (BotoClientError, BotoServerError), exc: action = "FAILED ADDING" if args.debug: print "DEBUG: %s" % exc template = "%s FROM: %s TO: %s PROTOCOL: %s PORT/TYPE: %s" print template % (action, rule["source"], rule["target"], rule["protocol"], rule["port/type"]) del_rules = [rule for rule in aws_rules if rule not in policy_rules] for rule in del_rules: try: result = aws.revoke(rule, account_id) if result: action = "REMOVED" else: action = "FAILED REMOVING" except (BotoClientError, BotoServerError), exc: action = "FAILED REMOVING" if args.debug: print "DEBUG: %s" % exc template = "%s FROM: %s TO: %s PROTOCOL: %s PORT/TYPE: %s" print template % (action, rule["source"], rule["target"], rule["protocol"], rule["port/type"])
policy_groups = dict([(region, set(policy.groups(config))) for region in regions]) aws_groups = dict([(region, set(aws.groups(region))) for region in regions]) for region in regions: conn = connect_to_region(region) for group in policy_groups[region].difference(aws_groups[region]): try: conn.create_security_group(group, description=".") action = "CREATED" except (BotoClientError, BotoServerError), exc: action = "FAILED CREATING" if args.debug: print "DEBUG: %s" % exc print "%s %s in %s" % (action, group, region) if not args.groups_only: policy_rules = [ dict([("region", region)] + rule.items()) for rule in policy.parse(config) for region in regions ] aws_rules = aws.policy(config) update_rules = [rule for rule in policy_rules if rule not in aws_rules] for rule in update_rules: try: result = aws.authorize(rule, account_id) if result: action = "ADDED" else: action = "FAILED ADDING" except (BotoClientError, BotoServerError), exc: action = "FAILED ADDING" if args.debug: print "DEBUG: %s" % exc template = "%s FROM: %s TO: %s PROTOCOL: %s PORT/TYPE: %s"