Files
vm-cloudflare/scripts/monitoring_dashboard.py
Vault Sovereign f0b8d962de
Some checks failed
WAF Intelligence Guardrail / waf-intel (push) Waiting to run
Cloudflare Registry Validation / validate-registry (push) Has been cancelled
chore: pre-migration snapshot
Layer0, MCP servers, Terraform consolidation
2025-12-27 01:52:27 +00:00

261 lines
9.0 KiB
Python

#!/usr/bin/env python3
"""
Cloudflare Infrastructure Monitoring Dashboard
Provides real-time monitoring of Cloudflare resources and services
"""
import os
import json
import time
import requests
from datetime import datetime, timedelta
from typing import Dict, List, Any
class CloudflareMonitor:
def __init__(self):
self.base_url = "https://api.cloudflare.com/client/v4"
self.headers = {
"Authorization": f"Bearer {os.getenv('CLOUDFLARE_API_TOKEN')}",
"Content-Type": "application/json",
}
self.account_id = os.getenv("CLOUDFLARE_ACCOUNT_ID")
if not self.account_id or not os.getenv("CLOUDFLARE_API_TOKEN"):
raise ValueError("Missing Cloudflare credentials in environment")
def make_request(self, endpoint: str) -> Dict[str, Any]:
"""Make API request with error handling"""
url = f"{self.base_url}{endpoint}"
try:
response = requests.get(url, headers=self.headers, timeout=10)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
return {"success": False, "errors": [str(e)]}
def get_account_info(self) -> Dict[str, Any]:
"""Get account information"""
return self.make_request(f"/accounts/{self.account_id}")
def get_zones(self) -> List[Dict[str, Any]]:
"""Get all zones"""
result = self.make_request(f"/zones?account.id={self.account_id}&per_page=50")
return result.get("result", []) if result.get("success") else []
def get_zone_analytics(self, zone_id: str) -> Dict[str, Any]:
"""Get zone analytics for the last hour"""
since = (datetime.now() - timedelta(hours=1)).isoformat()
return self.make_request(f"/zones/{zone_id}/analytics/dashboard?since={since}")
def get_waf_rules(self, zone_id: str) -> List[Dict[str, Any]]:
"""Get WAF rules for a zone"""
result = self.make_request(f"/zones/{zone_id}/firewall/waf/packages")
if result.get("success"):
packages = result.get("result", [])
rules = []
for package in packages:
rules_result = self.make_request(
f"/zones/{zone_id}/firewall/waf/packages/{package['id']}/rules"
)
if rules_result.get("success"):
rules.extend(rules_result.get("result", []))
return rules
return []
def get_tunnels(self) -> List[Dict[str, Any]]:
"""Get Cloudflare Tunnels"""
result = self.make_request(f"/accounts/{self.account_id}/cfd_tunnel")
return result.get("result", []) if result.get("success") else []
def get_dns_records(self, zone_id: str) -> List[Dict[str, Any]]:
"""Get DNS records for a zone"""
result = self.make_request(f"/zones/{zone_id}/dns_records?per_page=100")
return result.get("result", []) if result.get("success") else []
def get_health_status(self) -> Dict[str, Any]:
"""Get overall health status"""
status = "healthy"
issues = []
# Check zones
zones = self.get_zones()
if not zones:
issues.append("No zones found")
status = "warning"
# Check account access
account_info = self.get_account_info()
if not account_info.get("success"):
issues.append("Account access failed")
status = "critical"
return {"status": status, "issues": issues}
def format_table(data: List[Dict[str, Any]], headers: List[str]) -> str:
"""Format data as a table"""
if not data:
return "No data available"
# Calculate column widths
col_widths = [len(header) for header in headers]
for row in data:
for i, header in enumerate(headers):
value = str(row.get(header, ""))
col_widths[i] = max(col_widths[i], len(value))
# Create header row
header_row = " | ".join(
header.ljust(col_widths[i]) for i, header in enumerate(headers)
)
separator = "-" * len(header_row)
# Create data rows
rows = [header_row, separator]
for row in data:
row_data = [
str(row.get(header, "")).ljust(col_widths[i])
for i, header in enumerate(headers)
]
rows.append(" | ".join(row_data))
return "\n".join(rows)
def main():
print("🌐 Cloudflare Infrastructure Monitoring Dashboard")
print("=" * 60)
print(f"Timestamp: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
print()
try:
monitor = CloudflareMonitor()
# Health check
print("🔍 Health Status")
print("-" * 30)
health = monitor.get_health_status()
status_emoji = {"healthy": "", "warning": "⚠️", "critical": ""}
print(
f"Status: {status_emoji.get(health['status'], '')} {health['status'].upper()}"
)
if health["issues"]:
for issue in health["issues"]:
print(f" - {issue}")
print()
# Account information
print("🏢 Account Information")
print("-" * 30)
account_info = monitor.get_account_info()
if account_info.get("success"):
account = account_info["result"]
print(f"Name: {account.get('name', 'N/A')}")
print(f"Type: {account.get('type', 'N/A')}")
print(f"Created: {account.get('created_on', 'N/A')}")
else:
print("Failed to retrieve account information")
print()
# Zones overview
print("🌐 Zones Overview")
print("-" * 30)
zones = monitor.get_zones()
zone_data = []
for zone in zones[:10]: # Limit to first 10 zones
zone_data.append(
{
"Name": zone.get("name", "N/A"),
"Status": zone.get("status", "N/A"),
"Plan": zone.get("plan", {}).get("name", "N/A"),
"Development": zone.get("development_mode", "N/A"),
}
)
print(format_table(zone_data, ["Name", "Status", "Plan", "Development"]))
print(f"Total zones: {len(zones)}")
print()
# DNS Records (for first zone)
dns_records = []
waf_rules = []
if zones:
first_zone = zones[0]
print("📋 DNS Records (First Zone)")
print("-" * 30)
dns_records = monitor.get_dns_records(first_zone["id"])
dns_data = []
for record in dns_records[:15]: # Limit to first 15 records
dns_data.append(
{
"Type": record.get("type", "N/A"),
"Name": record.get("name", "N/A"),
"Content": record.get("content", "N/A")[:40] + "..."
if len(record.get("content", "")) > 40
else record.get("content", "N/A"),
}
)
print(format_table(dns_data, ["Type", "Name", "Content"]))
print(f"Total DNS records: {len(dns_records)}")
print()
# Tunnels
print("🔗 Cloudflare Tunnels")
print("-" * 30)
tunnels = monitor.get_tunnels()
tunnel_data = []
for tunnel in tunnels:
tunnel_data.append(
{
"Name": tunnel.get("name", "N/A"),
"Status": tunnel.get("status", "N/A"),
"Connections": len(tunnel.get("connections", [])),
}
)
print(format_table(tunnel_data, ["Name", "Status", "Connections"]))
print(f"Total tunnels: {len(tunnels)}")
print()
# WAF Rules (for first zone)
if zones:
first_zone = zones[0]
print("🛡️ WAF Rules (First Zone)")
print("-" * 30)
waf_rules = monitor.get_waf_rules(first_zone["id"])
waf_data = []
for rule in waf_rules[:10]: # Limit to first 10 rules
waf_data.append(
{
"ID": rule.get("id", "N/A"),
"Description": rule.get("description", "N/A")[:50] + "..."
if len(rule.get("description", "")) > 50
else rule.get("description", "N/A"),
"Mode": rule.get("mode", "N/A"),
}
)
print(format_table(waf_data, ["ID", "Description", "Mode"]))
print(f"Total WAF rules: {len(waf_rules)}")
print()
# Summary
print("📊 Summary")
print("-" * 30)
print(f"Zones: {len(zones)}")
print(f"Tunnels: {len(tunnels)}")
if zones:
print(f"DNS Records (first zone): {len(dns_records)}")
print(f"WAF Rules (first zone): {len(waf_rules)}")
except Exception as e:
print(f"❌ Error: {e}")
print("Please ensure your Cloudflare credentials are properly configured.")
if __name__ == "__main__":
main()