#!/usr/bin/env python """Download markdown files with AWS managed ConfigRule info and convert to JSON. Invocation: ./pull_down_aws_managed_rules.py - Execute from the moto/scripts directory. - To track download progress, use the "-v" command line switch. - MANAGED_RULES_OUTPUT_FILENAME is the variable containing the name of the file that will be overwritten when this script is run. NOTE: This script takes a while to download all the files. Summary: The first markdown file is read to obtain the names of markdown files for all the AWS managed config rules. Then each of those markdown files are read and info is extracted with the final results written to a JSON file. The JSON output will look as follows: { "ManagedRules": [ { "ACCESS_KEYS_ROTATED": { "AWS Region": "All supported AWS regions", "Parameters": [ { "Default": "90", "Name": "maxAccessKeyAgeType", "Optional": false, "Type": "intDefault" } ], "Trigger type": "Periodic" }, }, ... ] } """ import argparse import json import re import sys import requests MANAGED_RULES_OUTPUT_FILENAME = "../moto/config/resources/aws_managed_rules.json" AWS_MARKDOWN_URL_START = "https://raw.githubusercontent.com/awsdocs/aws-config-developer-guide/main/doc_source/" LIST_OF_MARKDOWNS_URL = "managed-rules-by-aws-config.md" def extract_param_info(line): """Return dict containing parameter info extracted from line.""" # Examples of parameter definitions: # maxAccessKeyAgeType: intDefault: 90 # IgnorePublicAcls \(Optional\)Type: StringDefault: True # MasterAccountId \(Optional\)Type: String # endpointConfigurationTypesType: String values = re.split(r":\s?", line) name = values[0] param_type = values[1] # If there is no Optional keyword, then sometimes there # isn't a space between the parameter name and "Type". name = re.sub("Type$", "", name) # Sometimes there isn't a space between the type and the # word "Default". if "Default" in param_type: param_type = re.sub("Default$", "", param_type) optional = False if "Optional" in line: optional = True # Remove "Optional" from the line. name = name.split()[0] param_info = { "Name": name, "Optional": optional, "Type": param_type, } # A default value isn't always provided. if len(values) > 2: param_info["Default"] = values[2] return param_info def extract_managed_rule_info(lines): """Return dict of qualifiers/rules extracted from a markdown file.""" rule_info = {} label_pattern = re.compile(r"(?:\*\*)(?P