예제 #1
0
def wait_for_pod():
    """
    Wait for the given pod to be running

    Usage:
      wait_for_pod --namespace=<namespace> --pod=<pod> [--context=<context>] [--maxdelay=<maxdelay>]

    Options:
        -h --help               Show this screen
        --context=<context>     kube context [default: dev-seb]
        --namespace=<namespace> kubernetes namespace
        --pod=<pod>             Pod we want to wait for
        --maxdelay=<maxdelay>   Maximum time to wait in seconds [default: 300]
    """
    args = docopt.docopt(wait_for_pod.__doc__)
    LOG.debug(args)

    kube = kubelib.KubeConfig(context=args['--context'],
                              namespace=args['--namespace'])

    pod = kubelib.Pod(kube).wait_for_pod(pod_name=args['--pod'],
                                         max_delay=float(args['--maxdelay']))

    print(pod)
    return (0)
예제 #2
0
def see_limits():
    """
    View all current namespace limits.

    Usage:
      see_limits [--context=<context>] [--namespace=<namespace>]

    Options:
      --context=<context>   kube context [default: None]
      --namespace=<namespace> kube namespace [default: None]
    """
    args = docopt.docopt(see_limits.__doc__)
    context = args['--context']
    exit_code = 0
    errors = []

    if context == "None":
        LOG.debug('Defaulting to the current kubectl context')
        context = sh.kubectl.config('current-context').stdout.strip().decode('ascii')

    namespace_name = args['--namespace']

    tv = TableView()
    namespace = TableView('Namespace', center=True, link="namespace")
    pod_name = TableView('Pod Name', center=True, link="pod.name")
    container_name = TableView('Container Name', center=True, link="container.name")

    pod = TableView('Pod', center=True)
    pod_cpu = TableView('CPU', center=True)
    pod_cpu_min = TableView('min', center=True, link="pod.min.cpu")
    pod_cpu_max = TableView('max', center=True, link="pod.max.cpu")
    pod_cpu.add_columns([pod_cpu_min, pod_cpu_max])

    pod_mem = TableView('Memory', center=True)
    pod_mem_min = TableView('min', center=True, link="pod.min.memory")
    pod_mem_max = TableView('max', center=True, link="pod.max.memory")
    pod_mem.add_columns([pod_mem_min, pod_mem_max])

    pod.add_columns([pod_cpu, pod_mem])

    container = TableView('Container', center=True)
    container_restart = TableView('Restarts', center=True, link="container.restart")
    container_last = TableView('LastState', center=True, link="container.laststate")

    container_cpu = TableView('CPU', center=True)
    container_cpu_min = TableView('min', center=True, link="container.min.cpu")
    container_cpu_max = TableView('max', center=True, link="container.max.cpu")
    container_cpu.add_columns([container_cpu_min, container_cpu_max])

    container_mem = TableView('Memory', center=True)
    container_mem_min = TableView('min', center=True, link="container.min.memory")
    container_mem_max = TableView('max', center=True, link="container.max.memory")
    container_mem.add_columns([container_mem_min, container_mem_max])

    container_default = TableView('Default', center=True)
    container_default_cpu = TableView('cpu', center=True, link="container.default.cpu")
    container_default_mem = TableView('mem', center=True, link="container.default.memory")
    container_default.add_columns([
        container_default_cpu, container_default_mem
    ])

    container_defaultreq = TableView('Def Request', center=True)
    container_defaultreq_cpu = TableView('cpu', center=True, link="container.defaultRequest.cpu")
    container_defaultreq_mem = TableView('mem', center=True, link="container.defaultRequest.memory")
    container_defaultreq.add_columns([
        container_defaultreq_cpu, container_defaultreq_mem
    ])

    container_maxratio = TableView('Max Ratio', center=True)
    container_maxratio_cpu = TableView('cpu', center=True, link="container.maxLimitRequestRatio.cpu")
    container_maxratio.add_column(container_maxratio_cpu)

    container.add_columns([
        container_restart, container_last, container_cpu, container_mem,
        container_default, container_defaultreq, container_maxratio
    ])

    pvc = TableView('PVC', center=True)
    pvc_min = TableView('min', center=True, link="pvc.min.storage")
    pvc_max = TableView('max', center=True, link="pvc.max.storage")
    pvc.add_columns([pvc_min, pvc_max])

    tv.add_columns([namespace, pod_name, container_name, pod, container, pvc])

    if namespace_name in [None, "None"]:
        # all
        namespaces = []
        kube = kubelib.KubeConfig(context=context, namespace="")
        namespace_objects = kubelib.Namespace(kube).get_list()
        for ns in namespace_objects:
            namespaces.append(ns.metadata.name)
    else:
        namespaces = [namespace_name]

    for namespace_name in namespaces:
        kube = kubelib.KubeConfig(context=context, namespace=namespace_name)
        limits_list = _get_namespace_limits(kube, namespace_name)

        namespace_limit = {
            'namespace': namespace_name,
            'pod.name': '',
            'container.name': ''
        }
        for limits in limits_list:
            # can there be multiple namespace limits?
            for limit in limits.spec.limits:
                if limit.type == "Pod":
                    namespace_limit['pod.min.cpu'] = limit.min.cpu
                    namespace_limit['pod.min.memory'] = limit.min.memory
                    namespace_limit['pod.max.cpu'] = limit.max.cpu
                    namespace_limit['pod.max.memory'] = limit.max.memory

                elif limit.type == "Container":
                    try:
                        namespace_limit['container.min.cpu'] = limit.min.cpu
                    except AttributeError:
                        pass

                    try:
                        namespace_limit['container.min.memory'] = limit.min.memory
                    except AttributeError:
                        pass

                    try:
                        namespace_limit['container.max.cpu'] = limit.max.cpu
                    except AttributeError:
                        pass

                    try:
                        namespace_limit['container.max.memory'] = limit.max.memory
                    except AttributeError:
                        pass

                    # default
                    try:
                        namespace_limit['container.default.cpu'] = limit.default.cpu
                    except AttributeError:
                        pass

                    try:
                        namespace_limit['container.default.memory'] = limit.default.memory
                    except AttributeError:
                        pass

                    # defrequest
                    namespace_limit['container.defaultRequest.cpu'] = limit.defaultRequest.cpu

                    try:
                        namespace_limit['container.defaultRequest.memory'] = limit.defaultRequest.memory
                    except AttributeError:
                        pass

                    # maxratio
                    try:
                        namespace_limit['container.maxLimitRequestRatio.cpu'] = limit.maxLimitRequestRatio.cpu
                    except AttributeError:
                        pass

                elif limit.type == "PersistentVolumeClaim":
                    namespace_limit['pvc.min.storage'] = limit.min.storage
                    namespace_limit['pvc.max.storage'] = limit.max.storage

        data = [
            namespace_limit
        ]

        # gather pod limits
        pods = kubelib.Pod(kube).get_list()
        for pod in pods:
            pod_name = pod.metadata.name
            cstatus = {}
            for cstatus_dict in getattr(pod.status, "containerStatuses", []):
                cstatus[cstatus_dict['name']] = cstatus_dict

            for container in pod.spec.containers:
                row = {
                    'namespace': namespace_name,
                    'pod.name': pod_name,
                    'container.name': container.name,
                    'container.restart': cstatus.get(container.name, {}).get("restartCount", '?'),
                    'container.laststate': cstatus.get(container.name, {}).get("lastState", {}).get('terminated', {}).get('reason', ''),
                    'container.min.cpu': container.get(
                        "resources", {}
                    ).get(
                        'requests', {}
                    ).get(
                        'cpu',
                        namespace_limit.get('container.defaultRequest.cpu')
                    ),
                    'container.min.memory': container.get(
                        "resources", {}
                    ).get(
                        'requests', {}
                    ).get(
                        'memory',
                        namespace_limit.get('container.defaultRequest.memory')
                    ),
                    'container.max.cpu': container.get(
                        "resources", {}
                    ).get(
                        'limits', {}
                    ).get(
                        'cpu',
                        namespace_limit.get('container.default.cpu')
                    ),
                    'container.max.memory': container.get(
                        "resources", {}
                    ).get(
                        'limits', {}
                    ).get(
                        'memory', namespace_limit.get('container.default.memory')
                    ),
                }

                if namespace_limit.get('container.min.memory') is None:
                    # unlimited
                    pass
                elif less_than(
                    row['container.min.memory'],
                    namespace_limit.get('container.min.memory')
                ):
                    msg = ('%s Pod %s min memory %s is below namespace minimum %s' % (
                        namespace_name,
                        pod_name,
                        row['container.min.memory'],
                        namespace_limit.get('container.min.memory')
                    ))
                    print(msg)
                    errors.append(msg)
                    exit_code = 1

                if namespace_limit.get('container.max.memory') is None:
                    # unlimited
                    pass
                elif greater_than(
                    row['container.max.memory'],
                    namespace_limit.get('container.max.memory')
                ):
                    msg = ('%s Pod %s max memory %s is above namespace maximum %s' % (
                        namespace_name,
                        pod_name,
                        row['container.max.memory'],
                        namespace_limit.get('container.max.memory')
                    ))
                    print(msg)
                    errors.append(msg)
                    exit_code = 1

                if namespace_limit.get('container.min.cpu') is None:
                    # unlimited
                    pass
                elif less_than(
                    row['container.min.cpu'],
                    namespace_limit.get('container.min.cpu')
                ):
                    msg = ('%s Pod %s min cpu %s is below namespace minimum %s' % (
                        namespace_name,
                        pod_name,
                        row['container.min.cpu'],
                        namespace_limit.get('container.min.cpu')
                    ))
                    print(msg)
                    errors.append(msg)
                    exit_code = 1

                if namespace_limit.get('container.max.cpu') is None:
                    # unlimited
                    pass
                elif greater_than(
                    row['container.max.cpu'],
                    namespace_limit.get('container.max.cpu')
                ):
                    msg = ('%s Pod %s max cpu %s is above namespace maximum %s' % (
                        namespace_name,
                        pod_name,
                        row['container.max.cpu'],
                        namespace_limit.get('container.max.cpu')
                    ))
                    print(msg)
                    errors.append(msg)
                    exit_code = 1

                    # colorama.Fore.RED + "!! " + str + " !!" + colorama.Style.RESET_ALL)
                data.append(row)

        tv.set_data(data)
        print(tv)

    if errors:
        for err in errors:
            print(err)
    sys.exit(exit_code)