from prometheus_client import start_http_server, Gauge
import requests
import urllib3
import psutil
import time
import os

# Disable SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# WHM details
WHM_HOST = "https://server.kts.ryj.mybluehostin.me:2087"
WHM_TOKEN = "2GT7UQBZGSL95O2C6KB3H1GEOF0Z3UMP"
WHM_USER = "root"

HEADERS = {
    "Authorization": f"whm {WHM_USER}:{WHM_TOKEN}"
}

# Prometheus Gauges
disk_gauge = Gauge("cpanel_disk_usage_mb", "Disk usage in MB", ["user"])
bw_gauge = Gauge("cpanel_bandwidth_usage_mb", "Bandwidth usage in MB", ["user"])
pkg_gauge = Gauge("cpanel_package", "Package name", ["user", "package"])
suspend_gauge = Gauge("cpanel_suspended", "Suspension status (1=yes, 0=no)", ["user"])
cpu_gauge = Gauge("server_cpu_percent", "Server CPU usage percentage")
mem_gauge = Gauge("server_memory_percent", "Server memory usage percentage")
user_cpu_gauge = Gauge("cpanel_user_cpu_percent", "CPU usage percentage by cPanel user", ["user"])
user_mem_gauge = Gauge("cpanel_user_mem_percent", "Memory usage percentage by cPanel user", ["user"])

def whm_api(endpoint, params=None):
    if params is None:
        params = {}
    params["api.version"] = 1
    url = f"{WHM_HOST}/json-api/{endpoint}"
    resp = requests.get(url, headers=HEADERS, params=params, verify=False, timeout=10)
    resp.raise_for_status()
    try:
        return resp.json()
    except Exception:
        print("Raw API response:", resp.text)
        return {}

def update_metrics():
    # Server-wide CPU/mem
    cpu_gauge.set(psutil.cpu_percent(interval=1))
    mem_gauge.set(psutil.virtual_memory().percent)

    # WHM account data
    data = whm_api("listaccts")
    accounts = data.get("data", {}).get("acct", [])
    if not accounts:
        print("No accounts found in WHM API response")
        return

    for acct in accounts:
        user = acct.get("user", "unknown")
        disk_used_mb = parse_size_mb(acct.get("diskused", "0M"))
        bw_used_mb = parse_size_mb(acct.get("bwusage", "0M"))
        package = acct.get("plan", "N/A")
        suspended = acct.get("suspended", 0)

        disk_gauge.labels(user=user).set(disk_used_mb)
        bw_gauge.labels(user=user).set(bw_used_mb)
        pkg_gauge.labels(user=user, package=package).set(1)
        suspend_gauge.labels(user=user).set(1 if suspended else 0)

    # Per-user CPU/mem usage from processes
    for proc in psutil.process_iter(['username', 'cpu_percent', 'memory_percent']):
        username = proc.info['username']
        if username and username.startswith("cpanel-"):
            cuser = username.replace("cpanel-", "")
            user_cpu_gauge.labels(user=cuser).inc(proc.info['cpu_percent'])
            user_mem_gauge.labels(user=cuser).inc(proc.info['memory_percent'])

def parse_size_mb(value):
    """Convert WHM disk/bw string to MB"""
    try:
        value = str(value).upper().strip()
        if value.endswith("M"):
            return float(value[:-1])
        elif value.endswith("G"):
            return float(value[:-1]) * 1024
        elif value.endswith("K"):
            return float(value[:-1]) / 1024
        else:
            return float(value)
    except:
        return 0.0

if __name__ == "__main__":
    start_http_server(9100)
    print("Exporter running on port 9100...")
    while True:
        update_metrics()
        time.sleep(30)
from prometheus_client import start_http_server, Gauge
import requests
import urllib3
import psutil
import time
import os

# Disable SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# WHM details
WHM_HOST = "https://server.kts.ryj.mybluehostin.me:2087"
WHM_TOKEN = "2GT7UQBZGSL95O2C6KB3H1GEOF0Z3UMP"
WHM_USER = "root"

HEADERS = {
    "Authorization": f"whm {WHM_USER}:{WHM_TOKEN}"
}

# Prometheus Gauges
disk_gauge = Gauge("cpanel_disk_usage_mb", "Disk usage in MB", ["user"])
bw_gauge = Gauge("cpanel_bandwidth_usage_mb", "Bandwidth usage in MB", ["user"])
pkg_gauge = Gauge("cpanel_package", "Package name", ["user", "package"])
suspend_gauge = Gauge("cpanel_suspended", "Suspension status (1=yes, 0=no)", ["user"])
cpu_gauge = Gauge("server_cpu_percent", "Server CPU usage percentage")
mem_gauge = Gauge("server_memory_percent", "Server memory usage percentage")
user_cpu_gauge = Gauge("cpanel_user_cpu_percent", "CPU usage percentage by cPanel user", ["user"])
user_mem_gauge = Gauge("cpanel_user_mem_percent", "Memory usage percentage by cPanel user", ["user"])

def whm_api(endpoint, params=None):
    if params is None:
        params = {}
    params["api.version"] = 1
    url = f"{WHM_HOST}/json-api/{endpoint}"
    resp = requests.get(url, headers=HEADERS, params=params, verify=False, timeout=10)
    resp.raise_for_status()
    try:
        return resp.json()
    except Exception:
        print("Raw API response:", resp.text)
        return {}

def update_metrics():
    # Server-wide CPU/mem
    cpu_gauge.set(psutil.cpu_percent(interval=1))
    mem_gauge.set(psutil.virtual_memory().percent)

    # WHM account data
    data = whm_api("listaccts")
    accounts = data.get("data", {}).get("acct", [])
    if not accounts:
        print("No accounts found in WHM API response")
        return

    for acct in accounts:
        user = acct.get("user", "unknown")
        disk_used_mb = parse_size_mb(acct.get("diskused", "0M"))
        bw_used_mb = parse_size_mb(acct.get("bwusage", "0M"))
        package = acct.get("plan", "N/A")
        suspended = acct.get("suspended", 0)

        disk_gauge.labels(user=user).set(disk_used_mb)
        bw_gauge.labels(user=user).set(bw_used_mb)
        pkg_gauge.labels(user=user, package=package).set(1)
        suspend_gauge.labels(user=user).set(1 if suspended else 0)

    # Per-user CPU/mem usage from processes
    for proc in psutil.process_iter(['username', 'cpu_percent', 'memory_percent']):
        username = proc.info['username']
        if username and username.startswith("cpanel-"):
            cuser = username.replace("cpanel-", "")
            user_cpu_gauge.labels(user=cuser).inc(proc.info['cpu_percent'])
            user_mem_gauge.labels(user=cuser).inc(proc.info['memory_percent'])

def parse_size_mb(value):
    """Convert WHM disk/bw string to MB"""
    try:
        value = str(value).upper().strip()
        if value.endswith("M"):
            return float(value[:-1])
        elif value.endswith("G"):
            return float(value[:-1]) * 1024
        elif value.endswith("K"):
            return float(value[:-1]) / 1024
        else:
            return float(value)
    except:
        return 0.0

if __name__ == "__main__":
    start_http_server(9100)
    print("Exporter running on port 9100...")
    while True:
        update_metrics()
        time.sleep(30)
