1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
import json
import yaml
import logging
import requests
import argparse
URLS = {
"keystone": "https://api.github.com/repos/openstack/keystone/contents/api-ref/source/v3",
"nova": "https://api.github.com/repos/openstack/nova/contents/api-ref/source",
"neutron": "https://api.github.com/repos/openstack/neutron-lib/contents/api-ref/source/v2",
"glance": "https://api.github.com/repos/openstack/glance/contents/api-ref/source/v2",
"swift": "https://api.github.com/repos/openstack/swift/contents/api-ref/source",
"cinder": "https://api.github.com/repos/openstack/cinder/contents/api-ref/source/v3",
}
logger = None
USER = ""
PASS = ""
def init():
global logger, USER, PASS
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", "-v", action='store_true', help="verbose mode")
parser.add_argument("--debug", "-d", action='store_true', help="debug mode")
parser.add_argument("--format", "-f", help="Output format (txt, json)", default="json")
parser.add_argument("--output", "-o", help="Output filename")
parser.add_argument("--from-policies", "-p", help="Get API from policy.{json,yaml}", target="policies")
parser.add_argument("--credentials", "-c", help="Github credential filename (inside format user:pass)")
args = parser.parse_args()
FORMAT = '%(levelname)s %(message)s'
if args.verbose:
logging.basicConfig(
format=FORMAT,
level=logging.INFO)
elif args.debug:
logging.basicConfig(
format=FORMAT,
level=logging.DEBUG)
else:
logging.basicConfig(
format=FORMAT,
level=logging.WARNING)
if args.credentials:
cred = open(args.credentials).read()
USER = cred.split(":")[0]
PASS = cred.split(":")[1]
logger = logging.getLogger(__name__)
return args
def get_api_item(url):
if USER:
r = requests.get(url, auth=(USER, PASS))
else:
r = requests.get(url)
items = []
for line in r.text.splitlines():
if ".. rest_method::" in line:
items.append(line.replace(".. rest_method::", "").strip())
logger.debug("\n\t".join(items))
return items
def get_content(key, args):
logger.info("Analysing {}".format(key))
if USER:
r = requests.get(URLS[key], auth=(USER, PASS))
else:
r = requests.get(URLS[key])
data = r.json()
results = {}
for item in data:
try:
logger.debug("{} {}".format(item['name'], item['download_url']))
if item['type'] == "file" and ".inc" in item['name']:
results[item['name'].replace(".inc", "")] = get_api_item(item['download_url'])
except TypeError:
logger.error("Error with {}".format(item))
except requests.exceptions.MissingSchema:
logger.error("MissingSchema error {}".format(item))
return results
def to_str(results):
output = ""
for key in results:
output += "{}\n".format(key)
for item in results[key]:
output += "\t{}\n".format(item)
for value in results[key][item]:
output += "\t\t{}\n".format(value)
return output
def get_data_from_policies(policies):
for filename in policies.split(","):
try:
obj = json.loads(open(filename.strip()).read())
def save(results, args):
if args.output:
if args.format == 'json':
json.dump(results, open(args.output, "w"), indent=4)
elif args.format == 'txt':
open(args.output, "w").write(to_str(results))
else:
if args.format == 'json':
print(json.dumps(results, indent=4))
elif args.format in ('txt', 'text'):
print(to_str(results))
def main():
args = init()
results = {}
if not args.policies:
for key in URLS:
results[key] = get_content(key, args)
else:
get_data_from_policies(args.policies)
save(results, args)
if __name__ == "__main__":
main()
|