Exemplo n.º 1
0
 def test_get_auth_token(self):
     KubeUtil.AUTH_TOKEN_PATH = '/foo/bar'
     self.assertIsNone(KubeUtil.get_auth_token())
     KubeUtil.AUTH_TOKEN_PATH = Fixtures.file(
         'events.json',
         sdk_dir=FIXTURE_DIR,
     )  # any file could do the trick
     self.assertIsNotNone(KubeUtil.get_auth_token())
Exemplo n.º 2
0
    def test_extract_event_tags(self):
        events = json.loads(Fixtures.read_file("events.json", sdk_dir=FIXTURE_DIR, string_escape=False))['items']
        for ev in events:
            tags = KubeUtil().extract_event_tags(ev)
            # there should be 4 tags except for some events where source.host is missing
            self.assertTrue(len(tags) >= 3)

            tag_names = [tag.split(':')[0] for tag in tags]
            self.assertIn('reason', tag_names)
            self.assertIn('namespace', tag_names)
            self.assertIn('object_type', tag_names)
            if len(tags) == 4:
                self.assertIn('node_name', tag_names)
Exemplo n.º 3
0
    def test_namespaced_events(self, *args):
        # reset last event pulling time
        KubeUtil().last_event_collection_ts = 0

        # Verify that we are retro compatible with the old 'namespace' configuration key
        config = {'instances': [{'host': 'bar', 'collect_events': True, 'namespace': 'test-namespace-1'}]}
        self.run_check(config, force_reload=True)
        self.assertEvent('dd-agent-a769 SuccessfulDelete on Bar', count=1, exact_match=False)
        self.assertEvent('hello-node-47289321-91tfd Scheduled on Bar', count=1, exact_match=False)

        # reset last event pulling time
        KubeUtil().last_event_collection_ts = 0

        # Using 'namespaces' list
        config = {'instances': [{'host': 'bar', 'collect_events': True, 'namespaces': ['test-namespace-1', 'test-namespace-2']}]}
        self.run_check(config, force_reload=True)
        self.assertEvent('dd-agent-a769 SuccessfulDelete on Bar', count=1, exact_match=False)
        self.assertEvent('hello-node-47289321-91tfd Scheduled on Bar', count=0, exact_match=False)

        # reset last event pulling time
        KubeUtil().last_event_collection_ts = 0

        # Using 'namespace_name_regexp' (since 'namespaces' is not set it should
        # fallback to ['default'] and add any namespaces that matched with the regexp
        config = {'instances': [{'host': 'bar', 'collect_events': True, 'namespace_name_regexp': 'test-namespace.*'}]}
        self.run_check(config, force_reload=True)
        self.assertEvent('dd-agent-a769 SuccessfulDelete on Bar', count=1, exact_match=False)
        self.assertEvent('hello-node-47289321-91tfd Scheduled on Bar', count=1, exact_match=False)

        # reset last event pulling time
        KubeUtil().last_event_collection_ts = 0

        # muting the 'default' namespace
        config = {'instances': [{'host': 'bar', 'collect_events': True, 'namespaces': [], 'namespace_name_regexp': 'test-namespace.*'}]}
        self.run_check(config, force_reload=True)
        self.assertEvent('dd-agent-a769 SuccessfulDelete on Bar', count=1, exact_match=False)
        self.assertEvent('hello-node-47289321-91tfd Scheduled on Bar', count=0, exact_match=False)
Exemplo n.º 4
0
 def setUp(self, _locate_kubelet):
     self.kubeutil = KubeUtil()
Exemplo n.º 5
0
class TestKubeutil(unittest.TestCase):
    @mock.patch('utils.kubernetes.KubeUtil._locate_kubelet', return_value='http://172.17.0.1:10255')
    def setUp(self, _locate_kubelet):
        self.kubeutil = KubeUtil()

    @mock.patch('utils.kubernetes.KubeUtil.retrieve_pods_list', side_effect=['foo'])
    @mock.patch('utils.kubernetes.KubeUtil.extract_kube_labels')
    def test_get_kube_labels(self, extract_kube_labels, retrieve_pods_list):
        self.kubeutil.get_kube_labels(excluded_keys='bar')
        retrieve_pods_list.assert_called_once()
        extract_kube_labels.assert_called_once_with('foo', excluded_keys='bar')

    @mock.patch('os.path.exists', return_value=True)
    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_auth_token', return_value='tkn')
    def test_init_tls_settings(self, *args):
        # kubelet
        instances = [
            # (instance, expected_result)
            ({}, {'kubelet_verify': True, 'bearer_token': 'tkn'}),
            ({'kubelet_tls_verify': False}, {'kubelet_verify': False, 'bearer_token': 'tkn'}),
            ({'kubelet_tls_verify': True}, {'kubelet_verify': True, 'bearer_token': 'tkn'}),
            ({'kubelet_tls_verify': 'foo.pem'}, {'kubelet_verify': 'foo.pem', 'bearer_token': 'tkn'}),
            ({'kubelet_cert': 'foo.pem'}, {'kubelet_verify': 'foo.pem', 'bearer_token': 'tkn'}),
            ({'kubelet_client_crt': 'client.crt', 'kubelet_client_key': 'client.key'},
                {'kubelet_verify': True, 'kubelet_client_cert': ('client.crt', 'client.key'), 'bearer_token': 'tkn'}),
            ({'kubelet_tls_verify': True, 'kubelet_client_crt': 'client.crt'}, {'kubelet_verify': True, 'bearer_token': 'tkn'}),
            ({'kubelet_client_crt': 'client.crt'}, {'kubelet_verify': True, 'bearer_token': 'tkn'})
        ]
        for instance, result in instances:
            self.assertEqual(self.kubeutil._init_tls_settings(instance), result)

        # apiserver
        instance = {'apiserver_client_crt': 'foo.crt', 'apiserver_client_key': 'foo.key'}
        expected_res = {'apiserver_client_cert': ('foo.crt', 'foo.key'), 'kubelet_verify': True, 'bearer_token': 'tkn'}
        self.assertEqual(self.kubeutil._init_tls_settings(instance), expected_res)
        with mock.patch('utils.kubernetes.kubeutil.os.path.exists', return_value=False):
            self.assertEqual(self.kubeutil._init_tls_settings(instance), {'kubelet_verify': True, 'bearer_token': 'tkn'})

        self.assertEqual(self.kubeutil._init_tls_settings(
            {'apiserver_client_crt': 'foo.crt'}), {'kubelet_verify': True, 'bearer_token': 'tkn'})

    ##### Test _locate_kubelet #####

    # we support connection to kubelet in 3 modes
    # -  no auth/no  ssl  --> over the --no-auth port
    # -  no auth/yes ssl (no verify)  --> over the port used by apiserver if anonymous requests are accepted
    # -  yes auth/yes ssl (yes verify)  --> same, but the user provided a way to verify kubelet's
    #                                       cert and we attach a bearer token if available

    @mock.patch('utils.kubernetes.kubeutil.DockerUtil.get_hostname', return_value='test_docker_host')
    def test_locate_kubelet_no_auth_no_ssl(self, _get_hostname):
        no_auth_no_ssl_instances = [
            # instance, expected_result
            ({}, 'http://*****:*****@mock.patch('utils.kubernetes.kubeutil.DockerUtil.get_hostname', return_value='test_docker_host')
    def test_locate_kubelet_no_auth_no_verify(self, _get_hostname):
        no_auth_no_verify_instances = [
            # instance, expected_result
            ({}, 'https://*****:*****@mock.patch('utils.kubernetes.kubeutil.DockerUtil.get_hostname', return_value='test_docker_host')
    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_node_hostname', return_value='test_k8s_host')
    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_auth_token', return_value='foo')
    def test_locate_kubelet_verify_and_auth(self, *args):
        """
        Test kubelet connection with TLS. Also look for auth token.
        """
        no_auth_instances = [
            # instance, tls_settings, expected_result
            ({}, {'kubelet_verify': True}, 'https://*****:*****@mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_auth_token', return_value='foo')
    def test_get_node_hostname(self, _get_auth_tkn):
        node_lists = [
            (json.loads(Fixtures.read_file('filtered_node_list_1_4.json', sdk_dir=FIXTURE_DIR, string_escape=False)), 'ip-10-0-0-179'),
            ({'items': [{'foo': 'bar'}]}, None),
            ({'items': []}, None),
            ({'items': [{'foo': 'bar'}, {'bar': 'foo'}]}, None)
        ]

        for node_list, expected_result in node_lists:
            with mock.patch('utils.kubernetes.kubeutil.KubeUtil.retrieve_json_auth', return_value=node_list):
                self.assertEqual(self.kubeutil.get_node_hostname('ip-10-0-0-179'), expected_result)

    def test_extract_kube_labels(self):
        """
        Test with both 1.1 and 1.2 version payloads
        """
        res = self.kubeutil.extract_kube_labels({}, ['foo'])
        self.assertEqual(len(res), 0)

        pods = json.loads(Fixtures.read_file("pods_list_1.1.json", sdk_dir=FIXTURE_DIR, string_escape=False))
        res = self.kubeutil.extract_kube_labels(pods, ['foo'])
        labels = set(inn for out in res.values() for inn in out)
        self.assertEqual(len(labels), 8)
        res = self.kubeutil.extract_kube_labels(pods, ['k8s-app'])
        labels = set(inn for out in res.values() for inn in out)
        self.assertEqual(len(labels), 6)

        pods = json.loads(Fixtures.read_file("pods_list_1.2.json", sdk_dir=FIXTURE_DIR, string_escape=False))
        res = self.kubeutil.extract_kube_labels(pods, ['foo'])
        labels = set(inn for out in res.values() for inn in out)
        self.assertEqual(len(labels), 3)
        res = self.kubeutil.extract_kube_labels(pods, ['k8s-app'])
        labels = set(inn for out in res.values() for inn in out)
        self.assertEqual(len(labels), 3)

    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.perform_kubelet_query')
    def test_retrieve_pods_list(self, retrieve_pods):
        self.kubeutil.retrieve_pods_list()
        self.assertTrue(retrieve_pods.call_args_list[0].endswith('/pods/'))

    @mock.patch('utils.kubernetes.kubeutil.retrieve_json')
    def test_retrieve_machine_info(self, retrieve_json):
        self.kubeutil.retrieve_machine_info()
        retrieve_json.assert_called_once_with(self.kubeutil.machine_info_url)

    @mock.patch('utils.kubernetes.kubeutil.retrieve_json')
    def test_retrieve_metrics(self, retrieve_json):
        self.kubeutil.retrieve_metrics()
        retrieve_json.assert_called_once_with(self.kubeutil.metrics_url)

    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_auth_token', return_value='foo')
    @mock.patch('utils.kubernetes.kubeutil.requests')
    def test_perform_kubelet_query(self, req, _get_auth_tkn):
        base_params = {'timeout': 10, 'verify': False,
            'params': {'verbose': True}, 'cert': None, 'headers': None}

        auth_token_header = {'headers': {'Authorization': 'Bearer %s' % self.kubeutil.get_auth_token()}}
        verify_true = {'verify': True}
        verify_cert = {'verify': 'kubelet.pem'}
        client_cert = {'cert': ('client.crt', 'client.key')}

        instances = [
            ('http://test.com', {}, dict(base_params.items() + verify_true.items())),
            ('https://test.com', {}, dict(base_params.items() + verify_true.items() + auth_token_header.items())),
            ('https://test.com', {'kubelet_verify': True}, dict(base_params.items() + verify_true.items() + auth_token_header.items())),
            ('https://test.com', {'kubelet_verify': 'kubelet.pem'}, dict(base_params.items() + verify_cert.items() + auth_token_header.items())),
            ('https://test.com', {'kubelet_client_cert': ('client.crt', 'client.key')},
                dict(base_params.items() + verify_true.items() + client_cert.items())),
        ]
        for url, ssl_context, expected_params in instances:
            req.get.reset_mock()
            self.kubeutil.tls_settings = ssl_context
            self.kubeutil.perform_kubelet_query(url)
            req.get.assert_called_with(url, **expected_params)

    @mock.patch('utils.kubernetes.kubeutil.requests')
    def test_retrieve_json_auth(self, r):
        instances = [
            # tls_settings, expected_params
            ({}, {'verify': False, 'timeout': 10, 'headers': None, 'cert': None}),
            ({'bearer_token': 'foo_tok'}, {'verify': False, 'timeout': 10, 'headers': {'Authorization': 'Bearer foo_tok'}, 'cert': None}),
            (
                {'bearer_token': 'foo_tok', 'apiserver_client_cert': ('foo.crt', 'foo.key')},
                {'verify': False, 'timeout': 10, 'headers': None, 'cert': ('foo.crt', 'foo.key')}
            ),
        ]

        for tls_settings, expected_params in instances:
            r.get.reset_mock()
            self.kubeutil.tls_settings = tls_settings
            self.kubeutil.retrieve_json_auth('url')
            r.get.assert_called_once_with('url', **expected_params)

        r.get.reset_mock()
        self.kubeutil.tls_settings = {'bearer_token': 'foo_tok'}
        self.kubeutil.CA_CRT_PATH = __file__
        self.kubeutil.retrieve_json_auth('url')
        r.get.assert_called_with('url', verify=__file__, timeout=10, headers={'Authorization': 'Bearer foo_tok'}, cert=None)

    def test_get_node_info(self):
        with mock.patch('utils.kubernetes.KubeUtil._fetch_host_data') as f:
            self.kubeutil._node_ip = None
            self.kubeutil._node_name = None
            self.kubeutil.get_node_info()
            f.assert_called_once()

            f.reset_mock()

            self.kubeutil._node_ip = 'foo'
            self.kubeutil._node_name = 'bar'
            ip, name = self.kubeutil.get_node_info()
            self.assertEqual(ip, 'foo')
            self.assertEqual(name, 'bar')
            f.assert_not_called()

    def test__fetch_host_data(self):
        """
        Test with both 1.1 and 1.2 version payloads
        """
        with mock.patch('utils.kubernetes.KubeUtil.retrieve_pods_list') as mock_pods:
            self.kubeutil.host_name = 'dd-agent-1rxlh'
            mock_pods.return_value = json.loads(Fixtures.read_file("pods_list_1.2.json", sdk_dir=FIXTURE_DIR, string_escape=False))
            self.kubeutil._fetch_host_data()
            self.assertEqual(self.kubeutil._node_ip, '10.240.0.9')
            self.assertEqual(self.kubeutil._node_name, 'kubernetes-massi-minion-k23m')

            self.kubeutil.host_name = 'heapster-v11-l8sh1'
            mock_pods.return_value = json.loads(Fixtures.read_file("pods_list_1.1.json", sdk_dir=FIXTURE_DIR, string_escape=False))
            self.kubeutil._fetch_host_data()
            self.assertEqual(self.kubeutil._node_ip, '10.240.0.9')
            self.assertEqual(self.kubeutil._node_name, 'gke-cluster-1-8046fdfa-node-ld35')

    def test_get_auth_token(self):
        KubeUtil.AUTH_TOKEN_PATH = '/foo/bar'
        self.assertIsNone(KubeUtil.get_auth_token())
        KubeUtil.AUTH_TOKEN_PATH = Fixtures.file('events.json', sdk_dir=FIXTURE_DIR,)  # any file could do the trick
        self.assertIsNotNone(KubeUtil.get_auth_token())

    def test_is_k8s(self):
        os.unsetenv('KUBERNETES_PORT')
        self.assertFalse(Platform.is_k8s())
        os.environ['KUBERNETES_PORT'] = '999'
        self.assertTrue(Platform.is_k8s())

    def test_extract_event_tags(self):
        events = json.loads(Fixtures.read_file("events.json", sdk_dir=FIXTURE_DIR, string_escape=False))['items']
        for ev in events:
            tags = KubeUtil().extract_event_tags(ev)
            # there should be 4 tags except for some events where source.host is missing
            self.assertTrue(len(tags) >= 3)

            tag_names = [tag.split(':')[0] for tag in tags]
            self.assertIn('reason', tag_names)
            self.assertIn('namespace', tag_names)
            self.assertIn('object_type', tag_names)
            if len(tags) == 4:
                self.assertIn('node_name', tag_names)
 def test_get_auth_token(self):
     KubeUtil.AUTH_TOKEN_PATH = '/foo/bar'
     self.assertIsNone(KubeUtil.get_auth_token())
     KubeUtil.AUTH_TOKEN_PATH = Fixtures.file('events.json', sdk_dir=FIXTURE_DIR,)  # any file could do the trick
     self.assertIsNotNone(KubeUtil.get_auth_token())
 def setUp(self, _locate_kubelet):
     self.kubeutil = KubeUtil()
class TestKubeutil(unittest.TestCase):
    @mock.patch('utils.kubernetes.KubeUtil._locate_kubelet', return_value='http://172.17.0.1:10255')
    def setUp(self, _locate_kubelet):
        self.kubeutil = KubeUtil()

    @mock.patch('utils.kubernetes.KubeUtil.retrieve_pods_list', side_effect=['foo'])
    @mock.patch('utils.kubernetes.KubeUtil.extract_kube_pod_tags')
    def test_get_kube_pod_tags(self, extract_kube_pod_tags, retrieve_pods_list):
        self.kubeutil.get_kube_pod_tags(excluded_keys='bar')
        retrieve_pods_list.assert_called_once()
        extract_kube_pod_tags.assert_called_once_with('foo', excluded_keys='bar')

    @mock.patch('os.path.exists', return_value=True)
    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_auth_token', return_value='tkn')
    def test_init_tls_settings(self, *args):
        # kubelet
        instances = [
            # (instance, expected_result)
            ({}, {'kubelet_verify': True, 'bearer_token': 'tkn'}),
            ({'kubelet_tls_verify': False}, {'kubelet_verify': False, 'bearer_token': 'tkn'}),
            ({'kubelet_tls_verify': True}, {'kubelet_verify': True, 'bearer_token': 'tkn'}),
            ({'kubelet_tls_verify': 'foo.pem'}, {'kubelet_verify': 'foo.pem', 'bearer_token': 'tkn'}),
            ({'kubelet_cert': 'foo.pem'}, {'kubelet_verify': 'foo.pem', 'bearer_token': 'tkn'}),
            ({'kubelet_client_crt': 'client.crt', 'kubelet_client_key': 'client.key'},
                {'kubelet_verify': True, 'kubelet_client_cert': ('client.crt', 'client.key'), 'bearer_token': 'tkn'}),
            ({'kubelet_tls_verify': True, 'kubelet_client_crt': 'client.crt'}, {'kubelet_verify': True, 'bearer_token': 'tkn'}),
            ({'kubelet_client_crt': 'client.crt'}, {'kubelet_verify': True, 'bearer_token': 'tkn'})
        ]
        for instance, result in instances:
            self.assertEqual(self.kubeutil._init_tls_settings(instance), result)

        # apiserver
        instance = {'apiserver_client_crt': 'foo.crt', 'apiserver_client_key': 'foo.key'}
        expected_res = {'apiserver_client_cert': ('foo.crt', 'foo.key'), 'kubelet_verify': True, 'bearer_token': 'tkn'}
        self.assertEqual(self.kubeutil._init_tls_settings(instance), expected_res)
        with mock.patch('utils.kubernetes.kubeutil.os.path.exists', return_value=False):
            self.assertEqual(self.kubeutil._init_tls_settings(instance), {'kubelet_verify': True, 'bearer_token': 'tkn'})

        self.assertEqual(self.kubeutil._init_tls_settings(
            {'apiserver_client_crt': 'foo.crt'}), {'kubelet_verify': True, 'bearer_token': 'tkn'})

    ##### Test _locate_kubelet #####

    # we support connection to kubelet in 3 modes
    # -  no auth/no  ssl  --> over the --no-auth port
    # -  no auth/yes ssl (no verify)  --> over the port used by apiserver if anonymous requests are accepted
    # -  yes auth/yes ssl (yes verify)  --> same, but the user provided a way to verify kubelet's
    #                                       cert and we attach a bearer token if available

    @mock.patch('utils.kubernetes.kubeutil.DockerUtil.get_hostname', return_value='test_docker_host')
    def test_locate_kubelet_no_auth_no_ssl(self, _get_hostname):
        no_auth_no_ssl_instances = [
            # instance, expected_result
            ({}, 'http://*****:*****@mock.patch('utils.kubernetes.kubeutil.DockerUtil.get_hostname', return_value='test_docker_host')
    def test_locate_kubelet_no_auth_no_verify(self, _get_hostname):
        no_auth_no_verify_instances = [
            # instance, expected_result
            ({}, 'https://*****:*****@mock.patch('utils.kubernetes.kubeutil.DockerUtil.get_hostname', return_value='test_docker_host')
    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_node_hostname', return_value='test_k8s_host')
    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_auth_token', return_value='foo')
    def test_locate_kubelet_verify_and_auth(self, *args):
        """
        Test kubelet connection with TLS. Also look for auth token.
        """
        no_auth_instances = [
            # instance, tls_settings, expected_result
            ({}, {'kubelet_verify': True}, 'https://*****:*****@mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_auth_token', return_value='foo')
    def test_get_node_hostname(self, _get_auth_tkn):
        node_lists = [
            (json.loads(Fixtures.read_file('filtered_node_list_1_4.json', sdk_dir=FIXTURE_DIR, string_escape=False)), 'ip-10-0-0-179'),
            ({'items': [{'foo': 'bar'}]}, None),
            ({'items': []}, None),
            ({'items': [{'foo': 'bar'}, {'bar': 'foo'}]}, None)
        ]

        for node_list, expected_result in node_lists:
            with mock.patch('utils.kubernetes.kubeutil.KubeUtil.retrieve_json_auth', return_value=node_list):
                self.assertEqual(self.kubeutil.get_node_hostname('ip-10-0-0-179'), expected_result)

    def test_extract_kube_pod_tags(self):
        """
        Test kube_pod_tags with both 1.1 and 1.2 version payloads
        """
        res = self.kubeutil.extract_kube_pod_tags({}, ['foo'])
        self.assertEqual(len(res), 0)

        pods = json.loads(Fixtures.read_file("pods_list_1.1.json", sdk_dir=FIXTURE_DIR, string_escape=False))
        res = self.kubeutil.extract_kube_pod_tags(pods, ['foo'])
        labels = set(inn for out in res.values() for inn in out)
        self.assertEqual(len(labels), 8 + 4)
        res = self.kubeutil.extract_kube_pod_tags(pods, ['k8s-app'])
        labels = set(inn for out in res.values() for inn in out)
        self.assertEqual(len(labels), 6 + 4)

        pods = json.loads(Fixtures.read_file("pods_list_1.2.json", sdk_dir=FIXTURE_DIR, string_escape=False))
        res = self.kubeutil.extract_kube_pod_tags(pods, ['foo'])
        labels = set(inn for out in res.values() for inn in out)
        self.assertEqual(len(labels), 3 + 1)
        res = self.kubeutil.extract_kube_pod_tags(pods, ['k8s-app'])
        labels = set(inn for out in res.values() for inn in out)
        self.assertEqual(len(labels), 3 + 1)

    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.perform_kubelet_query')
    def test_retrieve_pods_list(self, retrieve_pods):
        self.kubeutil.retrieve_pods_list()
        self.assertTrue(retrieve_pods.call_args_list[0].endswith('/pods/'))

    @mock.patch('utils.kubernetes.kubeutil.retrieve_json')
    def test_retrieve_machine_info(self, retrieve_json):
        self.kubeutil.retrieve_machine_info()
        retrieve_json.assert_called_once_with(self.kubeutil.machine_info_url)

    @mock.patch('utils.kubernetes.kubeutil.retrieve_json')
    def test_retrieve_metrics(self, retrieve_json):
        self.kubeutil.retrieve_metrics()
        retrieve_json.assert_called_once_with(self.kubeutil.metrics_url)

    @mock.patch('utils.kubernetes.kubeutil.KubeUtil.get_auth_token', return_value='foo')
    @mock.patch('utils.kubernetes.kubeutil.requests')
    def test_perform_kubelet_query(self, req, _get_auth_tkn):
        base_params = {'timeout': 10, 'verify': False,
            'params': {'verbose': True}, 'cert': None, 'headers': None}

        auth_token_header = {'headers': {'Authorization': 'Bearer %s' % self.kubeutil.get_auth_token()}}
        verify_true = {'verify': True}
        verify_cert = {'verify': 'kubelet.pem'}
        client_cert = {'cert': ('client.crt', 'client.key')}

        instances = [
            ('http://test.com', {}, dict(base_params.items() + verify_true.items())),
            ('https://test.com', {}, dict(base_params.items() + verify_true.items() + auth_token_header.items())),
            ('https://test.com', {'kubelet_verify': True}, dict(base_params.items() + verify_true.items() + auth_token_header.items())),
            ('https://test.com', {'kubelet_verify': 'kubelet.pem'}, dict(base_params.items() + verify_cert.items() + auth_token_header.items())),
            ('https://test.com', {'kubelet_client_cert': ('client.crt', 'client.key')},
                dict(base_params.items() + verify_true.items() + client_cert.items())),
        ]
        for url, ssl_context, expected_params in instances:
            req.get.reset_mock()
            self.kubeutil.tls_settings = ssl_context
            self.kubeutil.perform_kubelet_query(url)
            req.get.assert_called_with(url, **expected_params)

    @mock.patch('utils.kubernetes.kubeutil.requests')
    def test_retrieve_json_auth(self, r):
        instances = [
            # tls_settings, expected_params
            (
                {},
                {'verify': False, 'timeout': 10, 'params': None, 'headers': None, 'cert': None}
            ), (
                {'bearer_token': 'foo_tok'},
                {'verify': False, 'timeout': 10, 'params': None, 'headers': {'Authorization': 'Bearer foo_tok'}, 'cert': None}
            ), (
                {'bearer_token': 'foo_tok','apiserver_client_cert': ('foo.crt', 'foo.key')},
                {'verify': False, 'timeout': 10, 'params': None, 'headers': None, 'cert': ('foo.crt', 'foo.key')}
            ),
        ]

        for tls_settings, expected_params in instances:
            r.get.reset_mock()
            self.kubeutil.tls_settings = tls_settings
            self.kubeutil.retrieve_json_auth('url')
            r.get.assert_called_once_with('url', **expected_params)

        r.get.reset_mock()
        self.kubeutil.tls_settings = {'bearer_token': 'foo_tok'}
        self.kubeutil.CA_CRT_PATH = __file__
        self.kubeutil.retrieve_json_auth('url')
        r.get.assert_called_with('url', verify=__file__, timeout=10, params=None, headers={'Authorization': 'Bearer foo_tok'}, cert=None)

    def test_get_node_info(self):
        with mock.patch('utils.kubernetes.KubeUtil._fetch_host_data') as f:
            self.kubeutil._node_ip = None
            self.kubeutil._node_name = None
            self.kubeutil.get_node_info()
            f.assert_called_once()

            f.reset_mock()

            self.kubeutil._node_ip = 'foo'
            self.kubeutil._node_name = 'bar'
            ip, name = self.kubeutil.get_node_info()
            self.assertEqual(ip, 'foo')
            self.assertEqual(name, 'bar')
            f.assert_not_called()

    def test__fetch_host_data(self):
        """
        Test with both 1.1 and 1.2 version payloads
        """
        with mock.patch('utils.kubernetes.KubeUtil.retrieve_pods_list') as mock_pods:
            self.kubeutil.host_name = 'dd-agent-1rxlh'
            mock_pods.return_value = json.loads(Fixtures.read_file("pods_list_1.2.json", sdk_dir=FIXTURE_DIR, string_escape=False))
            self.kubeutil._fetch_host_data()
            self.assertEqual(self.kubeutil._node_ip, '10.240.0.9')
            self.assertEqual(self.kubeutil._node_name, 'kubernetes-massi-minion-k23m')

            self.kubeutil.host_name = 'heapster-v11-l8sh1'
            mock_pods.return_value = json.loads(Fixtures.read_file("pods_list_1.1.json", sdk_dir=FIXTURE_DIR, string_escape=False))
            self.kubeutil._fetch_host_data()
            self.assertEqual(self.kubeutil._node_ip, '10.240.0.9')
            self.assertEqual(self.kubeutil._node_name, 'gke-cluster-1-8046fdfa-node-ld35')

    def test_get_auth_token(self):
        KubeUtil.AUTH_TOKEN_PATH = '/foo/bar'
        self.assertIsNone(KubeUtil.get_auth_token())
        KubeUtil.AUTH_TOKEN_PATH = Fixtures.file('events.json', sdk_dir=FIXTURE_DIR,)  # any file could do the trick
        self.assertIsNotNone(KubeUtil.get_auth_token())

    def test_is_k8s(self):
        os.unsetenv('KUBERNETES_PORT')
        self.assertFalse(Platform.is_k8s())
        os.environ['KUBERNETES_PORT'] = '999'
        self.assertTrue(Platform.is_k8s())

    def test_extract_event_tags(self):
        events = json.loads(Fixtures.read_file("events.json", sdk_dir=FIXTURE_DIR, string_escape=False))['items']
        for ev in events:
            tags = KubeUtil().extract_event_tags(ev)
            # there should be 4 tags except for some events where source.host is missing
            self.assertTrue(len(tags) >= 3)

            tag_names = [tag.split(':')[0] for tag in tags]
            self.assertIn('reason', tag_names)
            self.assertIn('namespace', tag_names)
            self.assertIn('object_type', tag_names)
            if len(tags) == 4:
                self.assertIn('node_name', tag_names)