def check_cilium_version_cb():
    """Checks whether cilium version is >= minimum supported version.

    Args:
        None

    Returns:
        True if successful, False otherwise.
    """
    ret_code = True
    for name, ready_status, status, node_name, namespace in \
            utils.get_pods_status_iterator_by_labels("k8s-app=cilium", []):
        cmd = ("kubectl describe pod {}"
               " -n {} | grep \"Image:.*docker.io/cilium/cilium\" | "
               "awk '{{print $2}}' "
               "| awk -F ':' '{{print $2}}'").format(name, namespace)
        output = ""
        try:
            encoded_output = subprocess.check_output(cmd, shell=True)
        except subprocess.CalledProcessError as grepexc:
            log.error("command to fetch cilium version has failed."
                      "error code: {} {}".format(grepexc.returncode,
                                                 grepexc.output))
            ret_code = False
            break
        output = encoded_output.decode().strip(' \t\n\r')
        m = re.match(r"v(\d+).(\d+).(\d+)", output)
        if not m:
            log.warning("cilium version {} not in the expected format "
                        "vX.Y.Z".format(output))
            ret_code = True
            break

        major = int(m.group(1))
        minor = int(m.group(2))
        patch = int(m.group(3))

        print_error = True
        if major > MINIMUM_SUPPORTED_CILIUM_VERSION_MAJOR:
            print_error = False
        elif major == MINIMUM_SUPPORTED_CILIUM_VERSION_MAJOR:
            if minor > MINIMUM_SUPPORTED_CILIUM_VERSION_MINOR:
                print_error = False
            elif minor == MINIMUM_SUPPORTED_CILIUM_VERSION_MINOR:
                if patch >= MINIMUM_SUPPORTED_CILIUM_VERSION_PATCH:
                    print_error = False

        if print_error:
            log.error('cilium version is {}. Minimum supported '
                      'version is: v{}.{}.{}'.format(
                          output, MINIMUM_SUPPORTED_CILIUM_VERSION_MAJOR,
                          MINIMUM_SUPPORTED_CILIUM_VERSION_MINOR,
                          MINIMUM_SUPPORTED_CILIUM_VERSION_PATCH))
            ret_code = False
        else:
            log.info('cilium version is {}'.format(output))

        break  # We do not need to inspect every cilium pod. Break here.

    return ret_code
示例#2
0
def check_rbac_cb():
    """Checks whether RBAC is enabled on all the kube-apiservers.

    Args:
        None

    Returns:
        True if successful, False otherwise.
    """
    ret_code = True
    for name, ready_status, status, node_name, namespace in \
            utils.get_pods_status_iterator_by_labels(
                "component=kube-apiserver", [], False):
        cmd = "kubectl describe pod {} -n {}".format(name, namespace)
        try:
            encoded_output = subprocess.check_output(cmd, shell=True)
        except subprocess.CalledProcessError as exc:
            log.error(
                "command to check kube-apiserver pod configuration has failed."
                "error code: {} {}".format(exc.returncode, exc.output))
            ret_code = False
        else:
            output = encoded_output.decode()
            if "--authorization-mode=RBAC" in output or \
                    "--authorization-mode=ABAC" in output:
                log.info("RBAC is enabled on the cluster")
            else:
                log.info("RBAC has been disabled on this cluster")
    return ret_code
def check_access_log_config_cb():
    """Checks cilium access log parameter.

    Args:
        None

    Returns:
        True if successful, False otherwise.
    """
    ret_code = True
    for name, ready_status, status, node_name in \
            utils.get_pods_status_iterator_by_labels("k8s-app=cilium", []):
        # TODO: Add volume checks.
        config = utils.get_pod_config(name)
        if not config:
            log.warn('could not check access log configuration on cilium'
                     ' pod {} on node {}'.format(name, node_name))
            ret_code = False
            continue
        if re.search('^.*--access-log.*/var/run/cilium/access.log.*', config,
                     re.DOTALL) is None:
            log.warn('cilium pod {} on node {} '
                     'has not been configured with '
                     '--access-log parameter or the '
                     'access log filename is incorrect.'
                     ' Fix this if you would like'
                     ' to see Layer 7 proxy logs.'.format(name, node_name))
            ret_code = False
        else:
            log.info('cilium pod {} on node {} '
                     'has been configured with '
                     '--access-log parameter and the '
                     'access log filename is correct'.format(name, node_name))
    return ret_code
 def collect_gops(self, label_selector, type_of_stat):
     pool = ThreadPool(multiprocessing.cpu_count() - 1)
     pool.map(
         functools.partial(self.collect_gops_per_pod,
                           type_of_stat=type_of_stat),
         utils.get_pods_status_iterator_by_labels(label_selector))
     pool.close()
     pool.join()
 def collect_cilium_bugtool_output(self, label_selector, node_ip_filter):
     pool = ThreadPool(multiprocessing.cpu_count())
     pool.map(
         self.collect_cilium_bugtool_output_per_pod,
         utils.get_pods_status_iterator_by_labels(
             label_selector, node_ip_filter))
     pool.close()
     pool.join()
示例#6
0
    def collect_logs(self, label_selector, node_ip_filter):
        pool = ThreadPool(min(32, multiprocessing.cpu_count() + 4))

        pool.map(
            self.collect_logs_per_pod,
            utils.get_pods_status_iterator_by_labels(label_selector,
                                                     node_ip_filter))
        pool.close()
        pool.join()
示例#7
0
 def collect_gops(self, pool, label_selector, node_filter, type_of_stat):
     must_exist = not("hubble" in label_selector)  # hubble is optional
     pool.map_async(
         functools.partial(self.collect_gops_per_pod,
                           type_of_stat=type_of_stat),
         utils.get_pods_status_iterator_by_labels(
             label_selector,
             node_filter,
             must_exist=must_exist,
         ))
示例#8
0
    def collect_cilium_bugtool_output(self, pool, label_selector, node_filter):
        log.info("collecting cilium-bugtool output ...")

        must_exist = not("hubble" in label_selector)  # hubble is optional
        pool.map_async(
            self.collect_cilium_bugtool_output_per_pod,
            utils.get_pods_status_iterator_by_labels(
                label_selector,
                node_filter,
                must_exist=must_exist,
            ))
示例#9
0
    def collect_logs(self, pool, subject, label_selector, node_filter):
        log.info("collecting {} logs ...".format(subject))

        must_exist = not("hubble" in label_selector)  # hubble is optional
        pool.map_async(
            self.collect_logs_per_pod,
            utils.get_pods_status_iterator_by_labels(
                label_selector,
                node_filter,
                must_exist=must_exist,
            ))
 def collect_cilium_bugtool_output(self, label_selector, node_ip_filter):
     pool = ThreadPool(min(32, multiprocessing.cpu_count() + 4))
     must_exist = not("hubble" in label_selector)  # hubble is optional
     pool.map(
         self.collect_cilium_bugtool_output_per_pod,
         utils.get_pods_status_iterator_by_labels(
             label_selector,
             node_ip_filter,
             must_exist=must_exist,
         ))
     pool.close()
     pool.join()
 def collect_gops(self, label_selector, node_ip_filter, type_of_stat):
     pool = ThreadPool(min(32, multiprocessing.cpu_count() + 4))
     must_exist = not("hubble" in label_selector)  # hubble is optional
     pool.map(
         functools.partial(self.collect_gops_per_pod,
                           type_of_stat=type_of_stat),
         utils.get_pods_status_iterator_by_labels(
             label_selector,
             node_ip_filter,
             must_exist=must_exist,
         ))
     pool.close()
     pool.join()
示例#12
0
def check_trace_notifications_enabled_cb():
    """Checks whether TraceNotification is enabled

    Args:
        None

    Returns:
        True if successful, False otherwise.
    """
    ret_code = True
    for name, ready_status, status, node_name in \
            utils.get_pods_status_iterator_by_labels("k8s-app=cilium"):
        cmd = "kubectl exec -it " + name + \
              " -n kube-system cilium config " \
              "| grep TraceNotification | awk '{print $2}'"
        output = ""
        try:
            encoded_output = subprocess.check_output(cmd, shell=True)
        except subprocess.CalledProcessError as grepexc:
            log.error("command to fetch cilium config has failed."
                      "error code: {} {}".format(grepexc.returncode,
                                                 grepexc.output))
            ret_code = False
            continue
        output = encoded_output.decode()
        if "Enabled" not in output.strip(' \t\n\r'):
            # Can't use exact match/string comparison as the output has
            # ASCII-encoded characters.
            log.error('cilium pod {} on '
                      'node {} has TraceNotifications {}'.format(
                          name,
                          node_name,
                          repr(output.strip(' \t\n\r'))))
            ret_code = False
        else:
            log.info('cilium pod {} on '
                     'node {} has TraceNotifications {}'.format(
                         name,
                         node_name,
                         output.strip(' \t\n\r')))
    return ret_code