KuryrPort cleanup: Fix issue of subport not found

It can happen that during the cleanup of KuryrPort when Pod is already
gone we'll fail trying to find the parent port ID. We have a bug that in
this case finalizing of KuryrPort fails.

This commit changes the way we look for the hostIP of the pod to
actually look up a node using the info from KuryrPort CRD. If this fails
(node removed?) we try querying OpenStack API to get this information.
If this fails too, we just don't pass hostIP to mocked Pod.

Change-Id: I72aea5713f90c8df2f5d0269fa83b8fdd5220c59
This commit is contained in:
Michał Dulko 2023-04-20 12:55:23 +02:00
parent 2b69e039a8
commit 2141dba99c
3 changed files with 30 additions and 4 deletions

View File

@ -48,6 +48,8 @@ K8S_POD_STATUS_PENDING = 'Pending'
K8S_POD_STATUS_SUCCEEDED = 'Succeeded'
K8S_POD_STATUS_FAILED = 'Failed'
K8S_NODE_ADDRESS_INTERNAL = 'InternalIP'
K8S_ANNOTATION_PREFIX = 'openstack.org/kuryr'
K8S_ANNOTATION_VIF = K8S_ANNOTATION_PREFIX + '-vif'
K8S_ANNOTATION_LABEL = K8S_ANNOTATION_PREFIX + '-pod-label'

View File

@ -156,9 +156,31 @@ class KuryrPortHandler(k8s_base.ResourceEventHandler):
main_vif = objects.base.VersionedObject.obj_from_primitive(
kuryrport_crd['status']['vifs'][constants.DEFAULT_IFNAME]
['vif'])
port_id = utils.get_parent_port_id(main_vif)
host_ip = utils.get_parent_port_ip(port_id)
pod['status'] = {'hostIP': host_ip}
# Let's try to get the node's address using nodeName saved in CRD
host_ip = None
try:
node = self.k8s.get(f"{constants.K8S_API_BASE}/nodes/"
f"{kuryrport_crd['spec']['podNodeName']}")
for address in node['status']['addresses']:
if address['type'] == constants.K8S_NODE_ADDRESS_INTERNAL:
host_ip = address['address']
break
except k_exc.K8sClientException:
LOG.warning('Could not find node %s when cleaning up port.',
kuryrport_crd['spec']['podNodeName'])
if not host_ip:
# We can still try to use OpenStack API if this is nested VIF
port_id = utils.get_parent_port_id(main_vif)
if port_id:
host_ip = utils.get_parent_port_ip(port_id)
if host_ip:
pod['status'] = {'hostIP': host_ip}
# If we failed to find host_ip we still allow cleanup to follow, we
# catch all exceptions from release_vif anyway.
return pod
def on_finalize(self, kuryrport_crd, *args, **kwargs):

View File

@ -97,6 +97,7 @@ class TestKuryrPortHandler(test_base.TestCase):
f"/{self._kp['metadata']['namespace']}/pods/"
f"{self._kp['metadata']['name']}")
self._kp_uri = utils.get_res_link(self._kp)
self._node_uri = f"{constants.K8S_API_BASE}/nodes/{self._host}"
self.useFixture(k_fix.MockNetworkClient())
self._driver = multi_vif.NoopMultiVIFDriver()
@ -337,7 +338,8 @@ class TestKuryrPortHandler(test_base.TestCase):
self.assertIsNone(kp.on_finalize(self._kp))
k8s.get.assert_called_once_with(self._pod_uri)
k8s.get.assert_has_calls([mock.call(self._pod_uri),
mock.call(self._node_uri)])
k8s.remove_finalizer.assert_has_calls(
(mock.call(mock.ANY, constants.POD_FINALIZER),
mock.call(self._kp, constants.KURYRPORT_FINALIZER)))