Ejemplo n.º 1
0
    def test_execute_bad_update(self, mock_get):
        # Mock the API response, returning an error
        def _get(url, params=None, **kwargs):
            resp = requests.Response()

            if params:
                resp = requests.Response()
                resp.status_code = 200
                resp.raw = io.BytesIO(dumps(GET_PODS_RESPONSE).encode('utf-8'))
            else:
                resp.status_code = 403
                resp.raw = io.BytesIO(dumps({}).encode('utf-8'))
            return resp

        mock_get.side_effect = _get

        # Emulate the k8s environment and run the service
        with patch.dict(PATCH_PATH.format('os.environ'), self.test_env):
            inst = KubernetesWatcher()
            inst.api = MagicMock(inst.api)
            inst.execute()

        # Since the initial check succeeded, a second GET should be made.
        # No Observable API calls should be made
        self.assertEqual(mock_get.call_count, 2)
        self.assertEqual(inst.api.call_count, 0)
Ejemplo n.º 2
0
    def test_should_not_execute(self, mock_get):
        # When the hostname isn't the first, we shouldn't do any further
        # querying.

        # Mock the API response, returning the test data
        def _get(url, params=None, **kwargs):
            from ona_service.kubernetes_watcher import requests as r
            host = urlparse(url).hostname
            r.packages.urllib3.connection.match_hostname({None: None}, host)

            self.assertTrue(params)

            resp = requests.Response()
            resp.status_code = 200
            resp.raw = io.BytesIO(dumps(GET_PODS_RESPONSE).encode('utf-8'))
            return resp

        mock_get.side_effect = _get

        # Emulate the k8s environment and run the service
        with patch.dict(PATCH_PATH.format('os.environ'), self.test_env):
            inst = KubernetesWatcher()
            inst.api = MagicMock(inst.api)
            inst.execute()

        inst.api.send_file.assert_not_called()
        inst.api.send_signal.assert_not_called()
Ejemplo n.º 3
0
 def test_execute_missing_env(self, mock_get):
     # No API calls to Kubernetes or Observable should be made if there's
     # any missing environment variables
     for key in self.test_env.iterkeys():
         env = self.test_env.copy()
         env.pop(key)
         with patch.dict(PATCH_PATH.format('os.environ'), env):
             inst = KubernetesWatcher()
             inst.api = MagicMock(inst.api)
             inst.execute()
             self.assertEqual(mock_get.call_count, 0)
             self.assertEqual(inst.api.call_count, 0)
Ejemplo n.º 4
0
    def test_execute(self, mock_get):
        # Mock the API response, returning the test data
        def _get(url, params=None, **kwargs):
            from ona_service.kubernetes_watcher import requests as r
            host = urlparse(url).hostname
            r.packages.urllib3.connection.match_hostname({None: None}, host)

            headers = kwargs['headers']
            self.assertEqual(headers['Authorization'], 'Bearer Token!')
            self.assertEqual(headers['Accept'], 'application/json')

            resp = requests.Response()
            resp.status_code = 200
            resp.raw = io.BytesIO(dumps(GET_PODS_RESPONSE).encode('utf-8'))
            return resp

        mock_get.side_effect = _get

        # Intercept the upload, and check for expected output
        def _send_file(data_type, path, now, suffix=None):
            self.assertEqual(data_type, 'logs')
            with open(path, 'rt') as infile:
                actual = json_load(infile)

            self.assertEqual(actual, GET_PODS_RESPONSE)

            return 'file://{}/mock-ona_k8s-pods'.format(self.tempdir)

        # Emulate the k8s environment and run the service
        with patch.dict(PATCH_PATH.format('os.environ'), self.test_env):
            inst = KubernetesWatcher()
            inst.api = MagicMock(inst.api)
            inst.api.send_file.side_effect = _send_file
            inst.execute()

        # The first call should be filtered; the second shouldn't be filtered.
        self.assertEqual(mock_get.call_count, 2)
        self.assertEqual(
            mock_get.call_args_list[0][1].get('params'),
            {'labelSelector': 'name={}'.format(DEFAULT_KUBERNETES_LABEL)},
        )
        self.assertEqual(mock_get.call_args_list[1][1].get('params'), None)

        # The site signal should indicate the type and path
        inst.api.send_signal.assert_called_once_with(
            'logs', {
                'log_type': 'k8s-pods',
                'path': 'file://{}/mock-ona_k8s-pods'.format(self.tempdir),
            })
Ejemplo n.º 5
0
    def test_execute(self, mock_get):
        # Mock the API response, returning the test data
        # Ensure that the hostname matches expecations
        def _get(url, params=None, **kwargs):
            from ona_service.kubernetes_watcher import requests as r
            host = urlparse(url).hostname
            r.packages.urllib3.connection.match_hostname({None: None}, host)

            resp = requests.Response()
            resp.status_code = 200
            resp._content = json.dumps(GET_PODS_RESPONSE)
            return resp

        mock_get.side_effect = _get

        # Intercept the hostname upload, and check for expected output
        def _send_file(data_type, path, now, suffix=None):
            self.assertEqual(data_type, 'hostnames')
            with open(path, 'rt') as infile:
                actual = json.load(infile)

            expected = {
                '192.0.2.1': 'pod-01.default',
                '192.0.2.2': 'pod-02.custom',
                '192.0.2.6': 'node-01',
            }
            self.assertEqual(actual, expected)

            return 'file://{}/hostnames.json'.format(self.tempdir)

        # Emulate the k8s environment and run the service
        env = {
            'KUBERNETES_SERVICE_HOST': '127.0.0.1',
            'KUBERNETES_SERVICE_PORT': '8080',
            'K8S_CA_CERT_PATH': self.k8s_ca_cert_path,
            'KUBERNETES_TOKEN_PATH': self.k8s_token_path,
        }
        with patch.dict(PATCH_PATH.format('os.environ'), env):
            inst = KubernetesWatcher()
            inst.api = MagicMock(inst.api)
            inst.api.send_file.side_effect = _send_file
            inst.execute()

        inst.api.send_signal.assert_called_once_with(
            'hostnames',
            {'path': 'file://{}/hostnames.json'.format(self.tempdir)})
Ejemplo n.º 6
0
 def test_execute_missing_env(self, mock_get):
     # No API calls to Kubernetes or Observable should be made if there's
     # any missing environment variables
     base_env = {
         'KUBERNETES_SERVICE_HOST': '127.0.0.1',
         'KUBERNETES_SERVICE_PORT': '8080',
         'K8S_CA_CERT_PATH': self.k8s_ca_cert_path,
         'KUBERNETES_TOKEN_PATH': self.k8s_token_path,
     }
     for key in base_env.iterkeys():
         env = base_env.copy()
         env.pop(key)
         with patch.dict(PATCH_PATH.format('os.environ'), env):
             inst = KubernetesWatcher()
             inst.api = MagicMock(inst.api)
             inst.execute()
             self.assertEqual(mock_get.call_count, 0)
             self.assertEqual(inst.api.call_count, 0)
Ejemplo n.º 7
0
    def test_execute_bad_status(self, mock_get):
        # Mock the API response, returning an error
        def _get(url, params=None, **kwargs):
            resp = requests.Response()
            resp.status_code = 403
            resp._content = json.dumps({})
            return resp

        mock_get.side_effect = _get

        # Emulate the k8s environment and run the service
        env = {
            'KUBERNETES_SERVICE_HOST': '127.0.0.1',
            'KUBERNETES_SERVICE_PORT': '8080',
            'K8S_CA_CERT_PATH': self.k8s_ca_cert_path,
            'KUBERNETES_TOKEN_PATH': self.k8s_token_path,
        }
        with patch.dict(PATCH_PATH.format('os.environ'), env):
            inst = KubernetesWatcher()
            inst.api = MagicMock(inst.api)
            inst.execute()

        # No Observable API calls should be made
        self.assertEqual(inst.api.call_count, 0)