Пример #1
0
    def test_on_present_rollback(self):
        lbaas_spec = mock.sentinel.lbaas_spec
        lbaas_spec.type = 'ClusterIp'
        lbaas_spec.lb_ip = '1.2.3.4'
        lbaas_spec.project_id = '12345678'
        lbaas_state = mock.sentinel.lbaas_state
        lbaas_state.service_pub_ip_info = None
        loadbalancer = mock.Mock()
        loadbalancer.port_id = 12345678
        lbaas_state.loadbalancer = loadbalancer
        m_drv_service_pub_ip = mock.Mock()
        m_drv_service_pub_ip.acquire_service_pub_ip_info.return_value = None
        m_drv_service_pub_ip.associate_pub_ip.return_value = True

        endpoints = mock.sentinel.endpoints

        m_handler = mock.Mock(spec=h_lbaas.LoadBalancerHandler)
        m_handler._get_lbaas_spec.return_value = lbaas_spec
        m_handler._should_ignore.return_value = False
        m_handler._get_lbaas_state.return_value = lbaas_state
        m_handler._sync_lbaas_members.return_value = True
        m_handler._set_lbaas_state.side_effect = (
            k_exc.K8sResourceNotFound('ep'))
        m_handler._drv_service_pub_ip = m_drv_service_pub_ip
        h_lbaas.LoadBalancerHandler.on_present(m_handler, endpoints)

        m_handler._get_lbaas_spec.assert_called_once_with(endpoints)
        m_handler._should_ignore.assert_called_once_with(endpoints, lbaas_spec)
        m_handler._get_lbaas_state.assert_called_once_with(endpoints)
        m_handler._sync_lbaas_members.assert_called_once_with(
            endpoints, lbaas_state, lbaas_spec)
        m_handler._set_lbaas_state.assert_called_once_with(
            endpoints, lbaas_state)
        m_handler.on_deleted.assert_called_once_with(
            endpoints, lbaas_state)
Пример #2
0
    def annotate(self, path, annotations, resource_version=None):
        """Pushes a resource annotation to the K8s API resource

        The annotate operation is made with a PATCH HTTP request of kind:
        application/merge-patch+json as described in:

        https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#patch-operations  # noqa
        """
        LOG.debug("Annotate %(path)s: %(names)s", {
            'path': path,
            'names': list(annotations)
        })

        content_type = 'application/merge-patch+json'
        url, header = self._get_url_and_header(path, content_type)

        while itertools.count(1):
            metadata = {"annotations": annotations}
            if resource_version:
                metadata['resourceVersion'] = resource_version
            data = jsonutils.dumps({"metadata": metadata}, sort_keys=True)
            response = requests.patch(url,
                                      data=data,
                                      headers=header,
                                      cert=self.cert,
                                      verify=self.verify_server)
            if response.ok:
                return response.json()['metadata']['annotations']
            if response.status_code == requests.codes.conflict:
                resource = self.get(path)
                new_version = resource['metadata']['resourceVersion']
                retrieved_annotations = resource['metadata'].get(
                    'annotations', {})

                for k, v in annotations.items():
                    if v != retrieved_annotations.get(k, v):
                        break
                else:
                    # No conflicting annotations found. Retry patching
                    resource_version = new_version
                    continue
                LOG.debug(
                    "Annotations for %(path)s already present: "
                    "%(names)s", {
                        'path': path,
                        'names': retrieved_annotations
                    })

            LOG.error(
                "Exception response, headers: %(headers)s, "
                "content: %(content)s, text: %(text)s" % {
                    'headers': response.headers,
                    'content': response.content,
                    'text': response.text
                })

            if response.status_code == requests.codes.not_found:
                raise exc.K8sResourceNotFound(response.text)
            else:
                raise exc.K8sClientException(response.text)
Пример #3
0
    def test_get_vifs_pod_not_found(self, ged, k8s):
        ged.return_value = [self._driver]
        kp = kuryrport.KuryrPortHandler()
        kp.k8s.get.side_effect = k_exc.K8sResourceNotFound(self._pod)

        self.assertRaises(k_exc.K8sResourceNotFound, kp.get_vifs, self._kp)

        kp.k8s.get.assert_called_once_with(self._pod_uri)
        kp.k8s.remove_finalizer.assert_called_once_with(
            self._kp, constants.KURYRPORT_FINALIZER)
Пример #4
0
 def _raise_from_response(self, response):
     if response.status_code == requests.codes.not_found:
         raise exc.K8sResourceNotFound(response.text)
     if response.status_code == requests.codes.conflict:
         raise exc.K8sConflict(response.text)
     if response.status_code == requests.codes.forbidden:
         if 'because it is being terminated' in response.json()['message']:
             raise exc.K8sNamespaceTerminating(response.text)
         raise exc.K8sForbidden(response.text)
     if not response.ok:
         raise exc.K8sClientException(response.text)
Пример #5
0
    def test_get_namespace_not_found(self):
        namespace_name = mock.sentinel.namespace_name
        kubernetes = self.useFixture(k_fix.MockK8sClient()).client
        kubernetes.get.side_effect = exceptions.K8sResourceNotFound(
            mock.sentinel.resource)

        resp = utils.get_namespace(namespace_name)

        self.assertIsNone(resp)
        kubernetes.get.assert_called_once_with('{}/namespaces/{}'.format(
            constants.K8S_API_BASE, namespace_name))
Пример #6
0
    def test_on_present_pod_not_found(self, ged, get_k8s_client, activate_vif):
        ged.return_value = [self._driver]
        kp = kuryrport.KuryrPortHandler()
        self._kp['status']['vifs'] = self._vifs_primitive

        with mock.patch.object(kp, 'k8s') as k8s:
            k8s.get.side_effect = k_exc.K8sResourceNotFound(self._pod)

            self.assertRaises(k_exc.K8sResourceNotFound, kp.on_present,
                              self._kp)

            k8s.get.assert_called_once_with(self._pod_uri)
Пример #7
0
    def test_on_finalize_crd_not_found(self):
        self._handler.k8s.get.return_value = self._kp
        (self._handler.k8s.delete.side_effect) = k_exc.K8sResourceNotFound(
            self._pod)

        h_vif.VIFHandler.on_finalize(self._handler, self._pod)

        self._handler.k8s.delete.assert_called_once_with(
            h_vif.KURYRPORT_URI.format(ns=self._pod["metadata"]["namespace"],
                                       crd=self._pod["metadata"]["name"]))
        (self._handler.k8s.remove_finalizer.assert_called_once_with(
            self._pod, k_const.POD_FINALIZER))
Пример #8
0
    def test_on_finalize_exception_on_pod(self, ged, k8s):
        ged.return_value = [self._driver]
        kp = kuryrport.KuryrPortHandler()
        self._kp['status']['vifs'] = self._vifs_primitive

        with mock.patch.object(kp, 'k8s') as k8s:
            k8s.get.side_effect = k_exc.K8sResourceNotFound(self._pod)

            self.assertIsNone(kp.on_finalize(self._kp))

            k8s.get.assert_called_once_with(self._pod_uri)
            k8s.remove_finalizer.assert_called_once_with(
                self._kp, constants.KURYRPORT_FINALIZER)
Пример #9
0
    def test_call_outdated_event(self, m_sleep, m_count):
        m_handler = mock.Mock()
        m_count.return_value = list(range(1, 5))
        obj = {'metadata': {'selfLink': mock.sentinel.selflink}}
        event = {'type': 'MODIFIED', 'object': obj}
        self.k8s.get.side_effect = exceptions.K8sResourceNotFound(obj)

        retry = h_retry.Retry(m_handler)
        retry(event)

        self.k8s.get.assert_called_once_with(obj['metadata']['selfLink'])
        m_handler.assert_not_called()
        m_sleep.assert_not_called()
Пример #10
0
    def test_on_finalize_crd_not_found(self, m_get_kuryrport,
                                       m_get_k8s_client):
        m_get_kuryrport.return_value = self._kp
        k8s = mock.MagicMock()
        m_get_k8s_client.return_value = k8s
        k8s.delete.side_effect = k_exc.K8sResourceNotFound(self._pod)

        h_vif.VIFHandler.on_finalize(self._handler, self._pod)

        k8s.delete.assert_called_once_with(
            h_vif.KURYRPORT_URI.format(ns=self._pod["metadata"]["namespace"],
                                       crd=self._pod["metadata"]["name"]))
        (k8s.remove_finalizer.assert_called_once_with(self._pod,
                                                      k_const.POD_FINALIZER))
Пример #11
0
    def delete(self, path):
        LOG.debug("Delete %(path)s", {'path': path})
        url = self._base_url + path
        header = {'Content-Type': 'application/json'}
        if self.token:
            header.update({'Authorization': 'Bearer %s' % self.token})

        response = self.session.delete(url, cert=self.cert,
                                       verify=self.verify_server,
                                       headers=header)
        if response.ok:
            return response.json()
        else:
            if response.status_code == requests.codes.not_found:
                raise exc.K8sResourceNotFound(response.text)
            raise exc.K8sClientException(response)
Пример #12
0
    def test_on_present_fail_update_crd(self, ged, get_k8s_client,
                                        activate_vif, update_crd, get_project,
                                        get_sg, release_vif):
        ged.return_value = [self._driver]
        kp = kuryrport.KuryrPortHandler()
        self._kp['status']['vifs'] = self._vifs_primitive
        update_crd.side_effect = k_exc.K8sResourceNotFound(self._kp)
        get_project.return_value = self._project_id
        get_sg.return_value = self._security_groups

        with mock.patch.object(kp, 'k8s') as k8s:
            k8s.get.return_value = self._pod

            kp.on_present(self._kp)

            k8s.get.assert_called_once_with(self._pod_uri)
Пример #13
0
    def test_call_outdated_event(self, m_sleep, m_count):
        m_handler = mock.Mock()
        m_count.return_value = list(range(1, 5))
        self_link = '/api/v1/namespaces/ns1/services/srv1'
        obj = {'apiVersion': 'v1',
               'kind': 'Service',
               'metadata': {'name': 'srv1',
                            'namespace': 'ns1'}}
        event = {'type': 'MODIFIED', 'object': obj}
        self.k8s.get.side_effect = exceptions.K8sResourceNotFound(obj)

        retry = h_retry.Retry(m_handler)
        retry(event)

        self.k8s.get.assert_called_once_with(self_link)
        m_handler.assert_not_called()
        m_sleep.assert_not_called()
Пример #14
0
 def get(self, path, json=True, headers=None):
     LOG.debug("Get %(path)s", {'path': path})
     url = self._base_url + path
     header = {}
     if self.token:
         header.update({'Authorization': 'Bearer %s' % self.token})
     if headers:
         header.update(headers)
     response = self.session.get(url, cert=self.cert,
                                 verify=self.verify_server,
                                 headers=header)
     if response.status_code == requests.codes.not_found:
         raise exc.K8sResourceNotFound(response.text)
     if not response.ok:
         raise exc.K8sClientException(response.text)
     result = response.json() if json else response.text
     return result
Пример #15
0
 def _raise_from_response(self, response):
     if response.status_code == requests.codes.not_found:
         raise exc.K8sResourceNotFound(response.text)
     if response.status_code == requests.codes.conflict:
         raise exc.K8sConflict(response.text)
     if response.status_code == requests.codes.forbidden:
         if 'because it is being terminated' in response.json()['message']:
             raise exc.K8sNamespaceTerminating(response.text)
         raise exc.K8sForbidden(response.text)
     if response.status_code == requests.codes.unprocessable_entity:
         # NOTE(gryf): on k8s API code 422 is also Forbidden, but specified
         # to FieldValueForbidden. Perhaps there are other usages for
         # throwing unprocessable entity errors in different cases.
         if ('FieldValueForbidden' in response.text
                 and 'Forbidden' in response.json()['message']):
             raise exc.K8sFieldValueForbidden(response.text)
         raise exc.K8sUnprocessableEntity(response.text)
     if not response.ok:
         raise exc.K8sClientException(response.text)
Пример #16
0
 def test_bump_nps(self, get_client):
     m_k8s = mock.Mock()
     get_client.return_value = m_k8s
     m_k8s.get.return_value = {
         'items': [
             {'metadata': {'annotations': {
                 'networkPolicyLink': mock.sentinel.link1}}},
             {'metadata': {'annotations': {
                 'networkPolicyLink': mock.sentinel.link2}}},
             {'metadata': {'annotations': {
                 'networkPolicyLink': mock.sentinel.link3}}},
         ]
     }
     m_k8s.annotate.side_effect = (
         None, exceptions.K8sResourceNotFound('NP'), None)
     self.handler._bump_nps()
     m_k8s.get.assert_called_once_with(
         constants.K8S_API_CRD_KURYRNETWORKPOLICIES)
     m_k8s.annotate.assert_has_calls([
         mock.call(mock.sentinel.link1, mock.ANY),
         mock.call(mock.sentinel.link2, mock.ANY),
         mock.call(mock.sentinel.link3, mock.ANY),
     ])
Пример #17
0
    def test_on_present_rollback(self):
        lbaas_spec = mock.sentinel.lbaas_spec
        lbaas_state = mock.sentinel.lbaas_state
        endpoints = mock.sentinel.endpoints

        m_handler = mock.Mock(spec=h_lbaas.LoadBalancerHandler)
        m_handler._get_lbaas_spec.return_value = lbaas_spec
        m_handler._should_ignore.return_value = False
        m_handler._get_lbaas_state.return_value = lbaas_state
        m_handler._sync_lbaas_members.return_value = True
        m_handler._set_lbaas_state.side_effect = (
            k_exc.K8sResourceNotFound('ep'))

        h_lbaas.LoadBalancerHandler.on_present(m_handler, endpoints)

        m_handler._get_lbaas_spec.assert_called_once_with(endpoints)
        m_handler._should_ignore.assert_called_once_with(endpoints, lbaas_spec)
        m_handler._get_lbaas_state.assert_called_once_with(endpoints)
        m_handler._sync_lbaas_members.assert_called_once_with(
            endpoints, lbaas_state, lbaas_spec)
        m_handler._set_lbaas_state.assert_called_once_with(
            endpoints, lbaas_state)
        m_handler.on_deleted.assert_called_once_with(endpoints, lbaas_state)
Пример #18
0
 def test__remove_endpoints_not_found(self, log):
     m_handler = mock.Mock()
     m_handler.k8s.patch_crd.side_effect = k_exc.K8sResourceNotFound('foo')
     h_lbaas.EndpointsHandler._remove_endpoints(m_handler, self._ep)
     log.assert_called_once()
Пример #19
0
 def _raise_from_response(self, response):
     if response.status_code == requests.codes.not_found:
         raise exc.K8sResourceNotFound(response.text)
     if not response.ok:
         raise exc.K8sClientException(response.text)