Skip to content

Commit ccc3f57

Browse files
feat(port-scan-report): add JSON format for open ports summary
This adds a new function to format all scan results into a standardized JSON format and includes a summary log entry with all detected open ports. The log message format is improved with a consistent prefix for better filtering. feat(vpc-auto-stop-start): make ignore group configurable via environment variable Replaces hardcoded ignore group with a configurable list from the IGNORE_GROUP environment variable, allowing more flexible deployment without code changes.
1 parent da87394 commit ccc3f57

File tree

3 files changed

+467
-9
lines changed

3 files changed

+467
-9
lines changed

jobs/account-port-scan/port-scan-report.py

Lines changed: 79 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
2828

2929
"""
30-
Pull IBM Cloud API key and Logging endpoint from environment. If not set, raise an error.
30+
Pull IBM Cloud API key from environment. If not set, raise an error.
3131
"""
3232
ibmcloud_api_key = os.environ.get('IBMCLOUD_API_KEY')
3333
if not ibmcloud_api_key:
@@ -37,6 +37,7 @@
3737
if not cloud_logging_endpoint:
3838
raise ValueError("IBM_CLOUD_LOGGING_ENDPOINT environment variable not found")
3939

40+
4041
"""
4142
Create an IAM authenticator object for use with the VPC API.
4243
"""
@@ -179,6 +180,50 @@ def get_iam_token():
179180
return None
180181

181182

183+
def format_ports_json(vpc_results, vg_results, bm_results):
184+
"""
185+
Format all results into a single JSON array in the specified format
186+
187+
Args:
188+
vpc_results (dict): Dictionary with IP addresses as keys and lists of open ports as values for VPC
189+
vg_results (dict): Dictionary with IP addresses as keys and lists of open ports as values for Virtual Guests
190+
bm_results (dict): Dictionary with IP addresses as keys and lists of open ports as values for Bare Metal servers
191+
192+
Returns:
193+
list: List of formatted entries in the specified format
194+
"""
195+
all_ports_json = []
196+
197+
# Process VPC floating IPs
198+
for ip, ports in vpc_results.items():
199+
for port in ports:
200+
all_ports_json.append({
201+
"server-ip": ip,
202+
"open-port": str(port),
203+
"environment": "VPC"
204+
})
205+
206+
# Process Classic Virtual Guests
207+
for ip, ports in vg_results.items():
208+
for port in ports:
209+
all_ports_json.append({
210+
"server-ip": ip,
211+
"open-port": str(port),
212+
"environment": "Classic"
213+
})
214+
215+
# Process Classic Bare Metal servers
216+
for ip, ports in bm_results.items():
217+
for port in ports:
218+
all_ports_json.append({
219+
"server-ip": ip,
220+
"open-port": str(port),
221+
"environment": "Classic"
222+
})
223+
224+
return all_ports_json
225+
226+
182227
def format_scan_results(target_type, results):
183228
"""
184229
Format scan results to be sent to IBM Cloud Logging
@@ -191,7 +236,10 @@ def format_scan_results(target_type, results):
191236
list: List of formatted log entries
192237
"""
193238
log_entries = []
239+
240+
# Get computer name from environment variable or fall back to local system name
194241
computer_name = os.environ.get('CE_PROJECT_ID', socket.gethostname())
242+
195243
for ip, ports in results.items():
196244
if ports: # Only include IPs with open ports
197245
log_entry = {
@@ -202,20 +250,21 @@ def format_scan_results(target_type, results):
202250
"ip_address": ip,
203251
"open_ports": ports,
204252
"target_type": target_type,
205-
"message": f"Open ports detected on {target_type} {ip}: {ports}"
253+
"message": f"Open-Port-Detected: Open ports detected on {target_type} {ip}: {ports}"
206254
}
207255
}
208256
log_entries.append(log_entry)
209257

210258
return log_entries
211259

212260

213-
def send_to_ibm_cloud_logging(log_entries):
261+
def send_to_ibm_cloud_logging(log_entries, all_ports_json):
214262
"""
215263
Send log entries to IBM Cloud Logging
216264
217265
Args:
218266
log_entries (list): List of formatted log entries
267+
all_ports_json (list): List of all open ports in the specified JSON format
219268
220269
Returns:
221270
bool: True if logs were sent successfully, False otherwise
@@ -236,6 +285,21 @@ def send_to_ibm_cloud_logging(log_entries):
236285
"Authorization": f"Bearer {token}"
237286
}
238287

288+
# Add a summary log entry with the full JSON of all open ports
289+
computer_name = os.environ.get('CE_PROJECT_ID', socket.gethostname())
290+
summary_entry = {
291+
"applicationName": "account-port-scan",
292+
"subsystemName": "summary-scan",
293+
"computerName": computer_name,
294+
"text": {
295+
"message": "Open-Port-Detected: Summary of all open ports across all environments",
296+
"open_ports_summary": all_ports_json
297+
}
298+
}
299+
300+
# Add the summary entry to the log entries
301+
log_entries.append(summary_entry)
302+
239303
try:
240304
response = requests.post(log_endpoint, headers=headers, json=log_entries)
241305
response.raise_for_status()
@@ -286,18 +350,25 @@ def main():
286350
print(f"Open ports on {target}: {open_ports}")
287351
print("Classic Bare Metals Scan complete.")
288352

289-
# Format and send results to IBM Cloud Logging
353+
# Create the consolidated JSON object for all open ports
354+
all_ports_json = format_ports_json(
355+
floating_ip_results,
356+
virtual_guest_results,
357+
bare_metal_results
358+
)
359+
360+
# Format the individual log entries
290361
floating_ip_logs = format_scan_results("floating_ip", floating_ip_results)
291362
virtual_guest_logs = format_scan_results("virtual_guest", virtual_guest_results)
292363
bare_metal_logs = format_scan_results("bare_metal", bare_metal_results)
293364

294-
# Combine all logs into a single list
365+
# Combine all individual logs into a single list
295366
all_logs = floating_ip_logs + virtual_guest_logs + bare_metal_logs
296367

297368
# Send logs to IBM Cloud Logging
298-
if all_logs:
299-
print(f"Sending {len(all_logs)} log entries to IBM Cloud Logging...")
300-
success = send_to_ibm_cloud_logging(all_logs)
369+
if all_logs or all_ports_json:
370+
print(f"Sending {len(all_logs)} log entries and a summary to IBM Cloud Logging...")
371+
success = send_to_ibm_cloud_logging(all_logs, all_ports_json)
301372
if success:
302373
print("Successfully sent logs to IBM Cloud Logging")
303374
else:

0 commit comments

Comments
 (0)