Skip to content

Commit 8fbfa7a

Browse files
initial stage of python script, will tweak this more tomorrow
1 parent 663da18 commit 8fbfa7a

2 files changed

Lines changed: 173 additions & 1 deletion

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ output.json
44
*.logs
55
.DS_Store
66
output.csv
7-
apps_and_servers.csv
7+
apps_and_servers.csv
8+
server_app_metadata.csv
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
import requests
2+
import base64
3+
import getpass
4+
import json
5+
6+
class Application:
7+
def __init__(self, app_id, name):
8+
self.app_id = app_id
9+
self.name = name
10+
11+
def getApplications(headers, params, org_id):
12+
url = f"{contrast_url}/api/ng/{org_id}/applications"
13+
response = requests.get(url, headers=headers, params=params)
14+
return response
15+
16+
def getServers(headers, servers_href):
17+
url = f"{contrast_url}/api{servers_href}"
18+
print(f" Fetching servers from: {url}")
19+
response = requests.get(url, headers=headers)
20+
return response
21+
22+
def read_creds_file(filename="../.creds"):
23+
"""Read credentials from a .creds file"""
24+
creds = {}
25+
try:
26+
with open(filename, "r") as f:
27+
for line in f:
28+
line = line.strip()
29+
if line and not line.startswith("#"):
30+
key, value = line.split("=", 1)
31+
creds[key] = value
32+
except FileNotFoundError:
33+
print(f"Warning: {filename} file not found. Please input values.")
34+
return creds
35+
36+
# Read credentials from .creds file
37+
creds = read_creds_file()
38+
39+
# Set the default for re-using within your organization.
40+
contrast_url = creds.get("CONTRAST_URL", "")
41+
org_id = creds.get("ORG_ID", "")
42+
username = creds.get("USERNAME", "")
43+
api_key = creds.get("API_KEY", "")
44+
service_key = creds.get("SERVICE_KEY", "")
45+
app_id = creds.get("APP_ID", "")
46+
47+
headers = {
48+
"Accept": "application/json"
49+
}
50+
params = {
51+
"expand": ["apps", "vulns", "metadata"]
52+
}
53+
54+
def main():
55+
global contrast_url, org_id, username, api_key, service_key
56+
57+
msg = f"Enter your Contrast URL (blank will use default '{contrast_url}'): "
58+
contrast_url_input = input(msg)
59+
if contrast_url_input.strip():
60+
contrast_url = contrast_url_input
61+
else:
62+
while not contrast_url_input.strip() and not contrast_url.strip():
63+
print("Contrast URL cannot be blank.")
64+
contrast_url_input = input(msg)
65+
contrast_url = contrast_url_input
66+
67+
msg = f"Enter your Organization ID (blank will use default '{org_id}'): "
68+
org_id_input = input(msg)
69+
if org_id_input.strip():
70+
org_id = org_id_input
71+
else:
72+
while not org_id_input.strip() and not org_id.strip():
73+
print("Organization ID cannot be blank.")
74+
org_id_input = input(msg)
75+
org_id = org_id_input
76+
77+
msg = f"Enter your username (blank will use default '{username}'): "
78+
username_input = input(msg)
79+
if username_input.strip():
80+
username = username_input
81+
else:
82+
while not username_input.strip() and not username.strip():
83+
print("Username cannot be blank.")
84+
username_input = input(msg)
85+
username = username_input
86+
87+
msg = f"Enter your API key (blank will use default '****************************'): "
88+
api_key_input = getpass.getpass(msg)
89+
if api_key_input.strip():
90+
api_key = api_key_input
91+
else:
92+
while not api_key_input.strip() and not api_key.strip():
93+
print("API key cannot be blank.")
94+
api_key_input = getpass.getpass(msg)
95+
api_key = api_key_input
96+
97+
msg = f"Enter your service key (blank will use default '************'): "
98+
service_key_input = getpass.getpass(msg)
99+
if service_key_input.strip():
100+
service_key = service_key_input
101+
else:
102+
while not service_key_input.strip() and not service_key.strip():
103+
print("Service key cannot be blank.")
104+
service_key_input = getpass.getpass(msg)
105+
service_key = service_key_input
106+
107+
auth_str = f"{username}:{service_key}"
108+
auth_b64 = base64.b64encode(auth_str.encode()).decode()
109+
headers["Authorization"] = f"Basic {auth_b64}"
110+
headers["API-Key"] = api_key
111+
112+
response = getApplications(headers, params, org_id)
113+
if response.status_code == 200:
114+
data = response.json()
115+
with open("output.json", "w") as f:
116+
json.dump(data, f, indent=2)
117+
print("Applications response saved to output.json")
118+
119+
if data.get("applications"):
120+
application_list = data["applications"]
121+
print(f"Total Applications: {len(application_list)}")
122+
123+
for app in application_list:
124+
app_name = app.get("name", "N/A")
125+
app_id = app.get("app_id", "N/A")
126+
metadata_entities = app.get("metadataEntities", [])
127+
128+
print(f"\nApplication: {app_name} (ID: {app_id})")
129+
130+
# Output metadata entities
131+
if metadata_entities:
132+
print(f" Metadata Entities:")
133+
for entity in metadata_entities:
134+
print(f" {json.dumps(entity, indent=6)}")
135+
else:
136+
print(f" Metadata Entities: None")
137+
138+
# Get the links array from the application
139+
links = app.get("links", [])
140+
141+
# Find the servers link
142+
servers_href = None
143+
for link in links:
144+
if link.get("rel") == "servers":
145+
servers_href = link.get("href")
146+
break
147+
148+
if servers_href:
149+
print(f"DEBUG: servers_href = {servers_href}")
150+
servers_response = getServers(headers, servers_href)
151+
152+
if servers_response.status_code == 200:
153+
servers_data = servers_response.json()
154+
servers = servers_data.get("servers", [])
155+
156+
for server in servers:
157+
server_name = server.get("name", "N/A")
158+
server_id = server.get("server_id", "N/A")
159+
print(f" - Server: {server_name} (ID: {server_id})")
160+
else:
161+
print(f" Error fetching servers: {servers_response.status_code}")
162+
else:
163+
print(" No servers link found for this application")
164+
else:
165+
print("No applications found in response.")
166+
return
167+
else:
168+
print(f"Error: {response.status_code} - {response.text}")
169+
170+
if __name__ == "__main__":
171+
main()

0 commit comments

Comments
 (0)