import argparse
from kubernetes import client, config
from kubernetes.utils import parse_quantity
import math

# k8s 1.14
# pip3 install kubernetes==11.0.0

def human_readable_bytes(num_bytes):
    if num_bytes <= 0:
        return "0"
    units = ["B", "KB", "MB", "GB", "TB", "PB"]

    i = int(math.floor(math.log(num_bytes, 1024)))
    power = math.pow(1024, i)
    size = round(float(num_bytes) / power, 2)

    return f"{size} {units[i]}"


def get_resourcequota(client, namespace):
    res = client.list_namespaced_resource_quota(namespace)
    value = res.items[0] if len(res.items) > 0 else None
    if value and value.status.used:
        cpu_request_used = parse_quantity(value.status.used.get("requests.cpu"))
        cpu_request_hard = parse_quantity(value.status.hard.get("requests.cpu"))
        mem_request_used = parse_quantity(value.status.used.get("requests.memory"))
        mem_request_hard = parse_quantity(value.status.hard.get("requests.memory"))

        cpu_limit_used = parse_quantity(value.status.used.get("limits.cpu"))
        cpu_limit_hard = parse_quantity(value.status.hard.get("limits.cpu"))
        mem_limit_used = parse_quantity(value.status.used.get("limits.memory"))
        mem_limit_hard = parse_quantity(value.status.hard.get("limits.memory"))
        print(
            f'\trequest cpu => {cpu_request_used}/{cpu_request_hard}, usage => {cpu_request_used/cpu_request_hard * 100:.2f}%\n',
            f'\tlimits cpu => {cpu_limit_used}/{cpu_limit_hard}, usage => {cpu_limit_used/cpu_limit_hard * 100:.2f}%\n',
        )
        print(
            f'\trequest memory => {mem_request_used}/{mem_request_hard}, usage => {mem_request_used/mem_request_hard * 100:.2f}%\n',
            f'\tlimits memory => {mem_limit_used}/{mem_limit_hard}, usage => {mem_limit_used/mem_limit_hard * 100:.2f}%\n',
        )
        print("\n")

def get_pod_resource(client, namespace):
    pods = client.list_namespaced_pod(namespace)

    ns_requests_cpu_total = 0
    ns_requests_memory_total = 0
    ns_limits_cpu_total = 0
    ns_limits_memory_total = 0
    num_pod = 0
    for pod in pods.items:
        if "ing" not in pod.status.phase:
            continue
        else:
            num_pod += 1
        requests_cpu_total = 0
        requests_memory_total = 0
        limits_cpu_total = 0
        limits_memory_total = 0
        for container in pod.spec.containers:
            requests_cpu = container.resources.requests.get("cpu")
            requests_memory = container.resources.requests.get("memory")
            limits_cpu = container.resources.limits.get("cpu")
            limits_memory = container.resources.limits.get("memory")
            if requests_cpu:
                requests_cpu_total += parse_quantity(requests_cpu)
            if requests_memory:
                requests_memory_total += parse_quantity(requests_memory)
            if limits_cpu:
                limits_cpu_total += parse_quantity(limits_cpu)
            if limits_memory:
                limits_memory_total += parse_quantity(limits_memory)

        print(
            f"pod_name => {pod.metadata.name} \n",
            f"\trequests_cpu => {requests_cpu_total}, requests_memory => {human_readable_bytes(requests_memory_total)}; limits_cpu => {limits_cpu_total}, limits_memory => {human_readable_bytes(limits_memory_total)}"
        )
        ns_requests_cpu_total += requests_cpu_total
        ns_requests_memory_total += requests_memory_total
        ns_limits_cpu_total += limits_cpu_total
        ns_limits_memory_total += limits_memory_total

    print(
        "\n---------------------------------------------------------------------------------------------------------------------------\n",
        f"\tnum_pod => {num_pod}, requests_cpu => {ns_requests_cpu_total}, requests_memory => {human_readable_bytes(ns_requests_memory_total)}; limits_cpu => {ns_limits_cpu_total}, limits_memory => {human_readable_bytes(ns_limits_memory_total)}"
    )

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-n", "--namespace", help="namespace to analyse", required=True)
    args = parser.parse_args()

    config.load_kube_config()

    client = client.CoreV1Api()

    print(
        "===========================================================================================================================\n",
        "namespace pods resources \n"
        "===========================================================================================================================\n",
    )
    get_pod_resource(client, args.namespace)

    # 这个放后面,放前面可能看不到
    print(
        "\n",
        "===========================================================================================================================\n",
        "namespace resource quota \n",
        "===========================================================================================================================\n",
    )
    get_resourcequota(client, args.namespace)