def test_get_pod_pykube_not_found(monkeypatch, namespace): get = MagicMock() pod = MagicMock() res = [] pod.objects.return_value.filter.return_value = res monkeypatch.setattr('kube_log_watcher.kube.get_client', get) monkeypatch.setattr('pykube.Pod', pod) with pytest.raises(PodNotFound): get_pod('my-pod', namespace=namespace) get.assert_called_once() pod.objects.return_value.filter.assert_called_with( namespace=namespace, field_selector={'metadata.name': 'my-pod'})
def test_get_pod_pykube_not_found(monkeypatch, namespace): mock_client = MagicMock(name='client') pykube_pod = MagicMock() pykube_pod_objects = MagicMock() pykube_pod.objects.return_value = pykube_pod_objects pykube_pod_objects.get_by_name.side_effect = pykube.exceptions.ObjectDoesNotExist( ) monkeypatch.setattr('kube_log_watcher.kube.get_client', lambda: mock_client) monkeypatch.setattr('pykube.Pod', pykube_pod) with pytest.raises(PodNotFound): get_pod('my-pod', namespace=namespace) pykube_pod.objects.assert_called_once() pykube_pod.objects.assert_called_with(api=mock_client, namespace=namespace) pykube_pod_objects.get_by_name.assert_called_once() pykube_pod_objects.get_by_name.assert_called_with('my-pod')
def test_get_pod_url(monkeypatch, namespace): get = MagicMock() res = [1] get.return_value.json.return_value = {'items': res} monkeypatch.setattr('requests.get', get) result = get_pod('my-pod', namespace=namespace, kube_url=KUBE_URL) assert res[0] == result get.assert_called_with( 'https://my-kube-api/api/v1/namespaces/{}/pods/my-pod'.format( namespace))
def test_get_pod_pykube(monkeypatch, namespace): get = MagicMock() pod = MagicMock() res = [1] pod.objects.return_value.filter.return_value = res monkeypatch.setattr('kube_log_watcher.kube.get_client', get) monkeypatch.setattr('pykube.Pod', pod) result = get_pod('my-pod', namespace=namespace) assert res[0] == result get.assert_called_once() pod.objects.return_value.filter.assert_called_with( namespace=namespace, field_selector={'metadata.name': 'my-pod'})
def test_get_pod_pykube(monkeypatch, namespace): mock_pod = MagicMock(name='pod') mock_client = MagicMock(name='client') pykube_pod = MagicMock() pykube_pod_objects = MagicMock() pykube_pod.objects.return_value = pykube_pod_objects pykube_pod_objects.get_by_name.return_value = mock_pod monkeypatch.setattr('kube_log_watcher.kube.get_client', lambda: mock_client) monkeypatch.setattr('pykube.Pod', pykube_pod) result = get_pod('my-pod', namespace=namespace) assert result == mock_pod pykube_pod.objects.assert_called_once() pykube_pod.objects.assert_called_with(api=mock_client, namespace=namespace) pykube_pod_objects.get_by_name.assert_called_once() pykube_pod_objects.get_by_name.assert_called_with('my-pod')
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