Merge "Add finalizer for the pod as soon as possible."
This commit is contained in:
commit
31770d7ada
|
@ -63,6 +63,12 @@ class VIFHandler(k8s_base.ResourceEventHandler):
|
|||
drivers.ServiceSecurityGroupsDriver.get_instance())
|
||||
|
||||
def on_present(self, pod):
|
||||
# NOTE(gryf): Set the finalizer as soon, as we have pod created. On
|
||||
# subsequent updates of the pod, add_finalizer will ignore this if
|
||||
# finalizer exists.
|
||||
k8s = clients.get_kubernetes_client()
|
||||
k8s.add_finalizer(pod, constants.POD_FINALIZER)
|
||||
|
||||
if self._move_annotations_to_crd(pod):
|
||||
return
|
||||
|
||||
|
@ -88,14 +94,15 @@ class VIFHandler(k8s_base.ResourceEventHandler):
|
|||
if not kp:
|
||||
try:
|
||||
self._add_kuryrport_crd(pod)
|
||||
except k_exc.K8sNamespaceTerminating:
|
||||
# The underlying namespace is being terminated, we can
|
||||
# ignore this and let `on_finalize` handle this now.
|
||||
return
|
||||
except k_exc.K8sClientException as ex:
|
||||
LOG.exception("Kubernetes Client Exception creating "
|
||||
"KuryrPort CRD: %s", ex)
|
||||
raise k_exc.ResourceNotReady(pod)
|
||||
|
||||
k8s = clients.get_kubernetes_client()
|
||||
k8s.add_finalizer(pod, constants.POD_FINALIZER)
|
||||
|
||||
def on_finalize(self, pod):
|
||||
k8s = clients.get_kubernetes_client()
|
||||
try:
|
||||
|
@ -193,6 +200,11 @@ class VIFHandler(k8s_base.ResourceEventHandler):
|
|||
|
||||
try:
|
||||
self._add_kuryrport_crd(pod, vifs)
|
||||
except k_exc.K8sNamespaceTerminating:
|
||||
# The underlying namespace is being terminated, we can
|
||||
# ignore this and let `on_finalize` handle this now. Still
|
||||
# returning True to make sure `on_present` won't continue.
|
||||
return True
|
||||
except k_exc.K8sClientException as ex:
|
||||
LOG.exception("Kubernetes Client Exception recreating "
|
||||
"KuryrPort CRD from annotation: %s", ex)
|
||||
|
|
|
@ -39,6 +39,19 @@ class K8sConflict(K8sClientException):
|
|||
super(K8sConflict, self).__init__("Conflict: %r" % message)
|
||||
|
||||
|
||||
class K8sForbidden(K8sClientException):
|
||||
def __init__(self, message):
|
||||
super(K8sForbidden, self).__init__("Forbidden: %r" % message)
|
||||
|
||||
|
||||
class K8sNamespaceTerminating(K8sForbidden):
|
||||
# This is raised when K8s complains about operation failing because
|
||||
# namespace is being terminated.
|
||||
def __init__(self, message):
|
||||
super(K8sNamespaceTerminating, self).__init__(
|
||||
"Namespace already terminated: %r" % message)
|
||||
|
||||
|
||||
class InvalidKuryrNetworkAnnotation(Exception):
|
||||
pass
|
||||
|
||||
|
|
|
@ -83,6 +83,10 @@ class K8sClient(object):
|
|||
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)
|
||||
|
||||
|
|
|
@ -168,59 +168,83 @@ class TestVIFHandler(test_base.TestCase):
|
|||
self.assertTrue(h_vif.VIFHandler._is_pod_completed({'status': {'phase':
|
||||
k_const.K8S_POD_STATUS_FAILED}}))
|
||||
|
||||
@mock.patch('kuryr_kubernetes.clients.get_kubernetes_client')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.is_host_network')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.get_kuryrport')
|
||||
def test_on_present_host_network(self, m_get_kuryrport, m_host_network):
|
||||
def test_on_present_host_network(self, m_get_kuryrport, m_host_network,
|
||||
m_get_k8s_client):
|
||||
m_get_kuryrport.return_value = self._kp
|
||||
m_host_network.return_value = True
|
||||
self._matc.return_value = False
|
||||
k8s = mock.MagicMock()
|
||||
m_get_k8s_client.return_value = k8s
|
||||
|
||||
h_vif.VIFHandler.on_present(self._handler, self._pod)
|
||||
|
||||
k8s.add_finalizer.assert_called_once_with(self._pod,
|
||||
k_const.POD_FINALIZER)
|
||||
self._matc.assert_called_once_with(self._pod)
|
||||
m_get_kuryrport.assert_called_once()
|
||||
self._request_vif.assert_not_called()
|
||||
self._request_additional_vifs.assert_not_called()
|
||||
self._activate_vif.assert_not_called()
|
||||
|
||||
@mock.patch('kuryr_kubernetes.clients.get_kubernetes_client')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.is_host_network')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.get_kuryrport')
|
||||
def test_on_present_not_pending(self, m_get_kuryrport, m_host_network):
|
||||
def test_on_present_not_pending(self, m_get_kuryrport, m_host_network,
|
||||
m_get_k8s_client):
|
||||
m_get_kuryrport.return_value = self._kp
|
||||
m_host_network.return_value = False
|
||||
self._is_pod_scheduled.return_value = False
|
||||
self._matc.return_value = False
|
||||
k8s = mock.MagicMock()
|
||||
m_get_k8s_client.return_value = k8s
|
||||
|
||||
h_vif.VIFHandler.on_present(self._handler, self._pod)
|
||||
|
||||
k8s.add_finalizer.assert_called_once_with(self._pod,
|
||||
k_const.POD_FINALIZER)
|
||||
self._matc.assert_called_once_with(self._pod)
|
||||
m_get_kuryrport.assert_called_once()
|
||||
self._request_vif.assert_not_called()
|
||||
self._request_additional_vifs.assert_not_called()
|
||||
self._activate_vif.assert_not_called()
|
||||
|
||||
@mock.patch('kuryr_kubernetes.clients.get_kubernetes_client')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.get_kuryrport')
|
||||
def test_on_present_on_completed_with_annotation(self, m_get_kuryrport):
|
||||
def test_on_present_on_completed_with_annotation(self, m_get_kuryrport,
|
||||
m_get_k8s_client):
|
||||
self._is_pod_completed.return_value = True
|
||||
m_get_kuryrport.return_value = self._kp
|
||||
self._matc.return_value = False
|
||||
k8s = mock.MagicMock()
|
||||
m_get_k8s_client.return_value = k8s
|
||||
|
||||
h_vif.VIFHandler.on_present(self._handler, self._pod)
|
||||
|
||||
k8s.add_finalizer.assert_called_once_with(self._pod,
|
||||
k_const.POD_FINALIZER)
|
||||
self._matc.assert_called_once_with(self._pod)
|
||||
self._handler.on_finalize.assert_called_once_with(self._pod)
|
||||
self._request_vif.assert_not_called()
|
||||
self._request_additional_vifs.assert_not_called()
|
||||
self._activate_vif.assert_not_called()
|
||||
|
||||
@mock.patch('kuryr_kubernetes.clients.get_kubernetes_client')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.get_kuryrport')
|
||||
def test_on_present_on_completed_without_annotation(self, m_get_kuryrport):
|
||||
def test_on_present_on_completed_without_annotation(self, m_get_kuryrport,
|
||||
m_get_k8s_client):
|
||||
self._is_pod_completed.return_value = True
|
||||
m_get_kuryrport.return_value = None
|
||||
self._matc.return_value = False
|
||||
k8s = mock.MagicMock()
|
||||
m_get_k8s_client.return_value = k8s
|
||||
|
||||
h_vif.VIFHandler.on_present(self._handler, self._pod)
|
||||
|
||||
k8s.add_finalizer.assert_called_once_with(self._pod,
|
||||
k_const.POD_FINALIZER)
|
||||
self._matc.assert_called_once_with(self._pod)
|
||||
self._handler.on_finalize.assert_not_called()
|
||||
self._request_vif.assert_not_called()
|
||||
|
@ -240,34 +264,46 @@ class TestVIFHandler(test_base.TestCase):
|
|||
|
||||
h_vif.VIFHandler.on_present(self._handler, self._pod)
|
||||
|
||||
k8s.add_finalizer.assert_called_once_with(self._pod,
|
||||
k_const.POD_FINALIZER)
|
||||
m_get_kuryrport.assert_called_once_with(self._pod)
|
||||
self._matc.assert_called_once_with(self._pod)
|
||||
self._handler._add_kuryrport_crd.assert_called_once_with(self._pod)
|
||||
k8s.add_finalizer.assert_called_once_with(self._pod,
|
||||
k_const.POD_FINALIZER)
|
||||
|
||||
@mock.patch('kuryr_kubernetes.clients.get_kubernetes_client')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.is_host_network')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.get_kuryrport')
|
||||
def test_on_present_update(self, m_get_kuryrport, m_host_network):
|
||||
def test_on_present_update(self, m_get_kuryrport, m_host_network,
|
||||
m_get_k8s_client):
|
||||
m_get_kuryrport.return_value = self._kp
|
||||
m_host_network.return_value = False
|
||||
self._matc.return_value = False
|
||||
k8s = mock.MagicMock()
|
||||
m_get_k8s_client.return_value = k8s
|
||||
|
||||
h_vif.VIFHandler.on_present(self._handler, self._pod)
|
||||
|
||||
k8s.add_finalizer.assert_called_once_with(self._pod,
|
||||
k_const.POD_FINALIZER)
|
||||
self._matc.assert_called_once_with(self._pod)
|
||||
m_get_kuryrport.assert_called_once_with(self._pod)
|
||||
self._handler._add_kuryrport_crd.assert_not_called()
|
||||
|
||||
@mock.patch('kuryr_kubernetes.clients.get_kubernetes_client')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.is_host_network')
|
||||
@mock.patch('kuryr_kubernetes.controller.drivers.utils.get_kuryrport')
|
||||
def test_on_present_upgrade(self, m_get_kuryrport, m_host_network):
|
||||
def test_on_present_upgrade(self, m_get_kuryrport, m_host_network,
|
||||
m_get_k8s_client):
|
||||
m_get_kuryrport.return_value = self._kp
|
||||
m_host_network.return_value = True
|
||||
self._matc.return_value = True
|
||||
k8s = mock.MagicMock()
|
||||
m_get_k8s_client.return_value = k8s
|
||||
|
||||
h_vif.VIFHandler.on_present(self._handler, self._pod)
|
||||
|
||||
k8s.add_finalizer.assert_called_once_with(self._pod,
|
||||
k_const.POD_FINALIZER)
|
||||
self._matc.assert_called_once_with(self._pod)
|
||||
m_get_kuryrport.assert_not_called()
|
||||
self._request_vif.assert_not_called()
|
||||
|
|
Loading…
Reference in New Issue