示例#1
0
def get_new_containers_log_targets(
        containers: list, containers_path: str, cluster_id: str, kube_url=None, strict_labels=None) -> list:
    """
    Return list of container log targets. A ``target`` includes:
        {
            "id": <container_id>,
            "kwargs": <template_kwargs>,
            "pod_labels": <container's pod labels>
        }

    :param containers: List of container configs dicts.
    :type containers: list

    :param containers_path: Path to mounted containers directory.
    :type containers_path: str

    :param cluster_id: kubernetes cluster ID. If not set, then it will not be added to job/config files.
    :type cluster_id: str

    :param kube_url: URL to Kube API proxy.
    :type kube_url: str

    :param strict_labels: List of labels pods need to posses in order to be followed.
    :type strict_labels: List

    :return: List of existing container log targets.
    :rtype: list
    """
    containers_log_targets = []
    strict_labels = strict_labels or []

    for container in containers:
        try:
            config = container['config']

            if kube.is_pause_container(config['Config']):
                # We have no interest in Pause containers.
                continue

            pod_name = get_container_label_value(config, 'pod.name')
            container_name = get_container_label_value(config, 'container.name')
            pod_namespace = get_container_label_value(config, 'pod.namespace')

            try:
                pod = kube.get_pod(pod_name, namespace=pod_namespace, kube_url=kube_url)
            except kube.PodNotFound:
                logger.warning('Cannot find pod "%s" ... skipping container: %s', pod_name, container_name)
                continue

            metadata = pod.obj['metadata']
            pod_labels, pod_annotations = metadata.get('labels', {}), metadata.get('annotations', {})

            kwargs = {}

            kwargs['container_id'] = container['id']
            kwargs['container_path'] = os.path.join(containers_path, container['id'])
            kwargs['log_file_name'] = os.path.basename(container['log_file'])
            kwargs['log_file_path'] = container['log_file']

            kwargs['image'], kwargs['image_version'] = get_container_image_parts(config['Config'])

            kwargs['application'] = pod_labels.get(APP_LABEL, '')
            kwargs['component'] = pod_labels.get(COMPONENT_LABEL)
            kwargs['environment'] = pod_labels.get(ENVIRONMENT_LABEL, CLUSTER_ENVIRONMENT)
            kwargs['version'] = pod_labels.get(VERSION_LABEL, '')
            kwargs['release'] = pod_labels.get('release', '')
            kwargs['cluster_id'] = cluster_id
            kwargs['pod_name'] = pod_name
            kwargs['namespace'] = pod_namespace
            kwargs['container_name'] = container_name
            kwargs['node_name'] = CLUSTER_NODE_NAME
            kwargs['pod_annotations'] = pod_annotations

            if set(strict_labels) - set(pod_labels.keys()):
                logger.warning('Labels "%s" are required for container(%s: %s) in pod(%s) ... Skipping!',
                               ','.join(strict_labels), container_name, container['id'], pod_name)
                continue

            containers_log_targets.append({'id': container['id'], 'kwargs': kwargs, 'pod_labels': pod_labels})
        except Exception:
            logger.exception('Failed to create log target for container(%s)', container['id'])

    return containers_log_targets
def test_pause_container(monkeypatch, config, res):
    assert res == is_pause_container(config)
示例#3
0
def get_new_containers_log_targets(containers: list,
                                   containers_path: str,
                                   cluster_id: str,
                                   kube_url=None,
                                   strict_labels=False) -> list:
    """
    Return list of container log targets. A ``target`` includes:
        {
            "id": <container_id>,
            "kwargs": <template_kwargs>,
            "pod_labels": <container's pod labels>
        }

    :param containers: List of container configs dicts.
    :type containers: list

    :param containers_path: Path to mounted containers directory.
    :type containers_path: str

    :param cluster_id: kubernetes cluster ID. If not set, then it will not be added to job/config files.
    :type cluster_id: str

    :param kube_url: URL to Kube API proxy.
    :type kube_url: str

    :param strict_labels: Only follow logs from pods with labels "application" and "version" labels set. Default False.
    :type strict_labels: bool

    :return: List of existing container log targets.
    :rtype: list
    """
    pod_map = {}

    pod_map[kube.DEFAULT_NAMESPACE] = kube.get_pods(kube_url=kube_url)

    containers_log_targets = []

    for container in containers:
        try:
            config = container['config']

            if kube.is_pause_container(config['Config']):
                # We have no interest in Pause containers.
                logger.debug('Skipping pause container({})'.format(
                    container['id']))
                continue

            pod_name = get_label_value(config, 'pod.name')
            container_name = get_label_value(config, 'container.name')
            pod_namespace = get_label_value(config, 'pod.namespace')

            pods = pod_map.get(pod_namespace)
            if not pods:
                # We need to get pods in different namespace
                logger.debug(
                    'Retrieving pods in namespace: {}'.format(pod_namespace))
                pods = kube.get_pods(kube_url=kube_url,
                                     namespace=pod_namespace)
                pod_map[pod_namespace] = pods

            pod_labels, pod_annotations = kube.get_pod_labels_annotations(
                pods, pod_name)

            kwargs = {}

            kwargs['container_id'] = container['id']
            kwargs['container_path'] = os.path.join(containers_path,
                                                    container['id'])
            kwargs['log_file_name'] = os.path.basename(container['log_file'])
            kwargs['log_file_path'] = container['log_file']

            kwargs['image'], kwargs[
                'image_version'] = get_container_image_parts(config['Config'])

            kwargs['application_id'] = pod_labels.get(APP_LABEL)
            kwargs['application_version'] = pod_labels.get(VERSION_LABEL, '')
            kwargs['release'] = pod_labels.get('release', '')
            kwargs['cluster_id'] = cluster_id
            kwargs['pod_name'] = pod_name
            kwargs['namespace'] = pod_namespace
            kwargs['container_name'] = container_name
            kwargs['node_name'] = CLUSTER_NODE_NAME
            kwargs['pod_annotations'] = pod_annotations

            if not all(
                [kwargs['application_id'], kwargs['application_version']]):
                if strict_labels:
                    logger.warning((
                        'Labels "{}" and "{}" are required for container({}: {}) in pod({}) '
                        '... Skipping!').format(APP_LABEL, VERSION_LABEL,
                                                container_name,
                                                container['id'], pod_name))
                    continue
                else:
                    if not kwargs['application_id']:
                        kwargs['application_id'] = kwargs['pod_name']

            containers_log_targets.append({
                'id': container['id'],
                'kwargs': kwargs,
                'pod_labels': pod_labels
            })
        except Exception:
            logger.exception(
                'Failed to create log target for container({})'.format(
                    container['id']))

    return containers_log_targets