NestedVIFPool: React when status.hostIP is missing

Seems like there's a race condition or bug in K8s that on DELETE events
we can end up with annotated pod that doesn't have `status.hostIP` field
set. This is problematic for NestedVIFPool driver that used it as one of
the pool key elements.

This patch solves that by looking up host IP through Neutron and trunks
info if the field is missing from the pod.

Change-Id: Ib477213bab7e09bf6520f60b31d7d30584d90199
Closes-Bug: 1848172
This commit is contained in:
Michał Dulko 2019-10-15 12:12:04 +02:00
parent 8fa6d4471d
commit 5fb1f5908a
1 changed files with 39 additions and 2 deletions

View File

@ -245,8 +245,10 @@ class BaseVIFPool(base.VIFPoolDriver):
pool_key, {}).setdefault(
security_groups, []).append(vif.id)
def release_vif(self, pod, vif, project_id, security_groups):
host_addr = self._get_host_addr(pod)
def release_vif(self, pod, vif, project_id, security_groups,
host_addr=None):
if not host_addr:
host_addr = self._get_host_addr(pod)
pool_key = self._get_pool_key(host_addr, project_id, vif.network.id,
None)
@ -687,6 +689,41 @@ class NestedVIFPool(BaseVIFPool):
def set_vif_driver(self, driver):
self._drv_vif = driver
def _get_parent_port_id(self, vif):
neutron = clients.get_neutron_client()
args = {}
if config.CONF.neutron_defaults.resource_tags:
args['tags'] = config.CONF.neutron_defaults.resource_tags
trunks = neutron.list_trunks(**args)
for trunk in trunks['trunks']:
for sp in trunk['sub_ports']:
if sp['port_id'] == vif.id:
return trunk['port_id']
return None
def release_vif(self, pod, vif, project_id, security_groups):
try:
host_addr = self._get_host_addr(pod)
except KeyError:
name = pod['metadata']['name']
LOG.warning("Pod %s does not have status.hostIP field set when "
"getting deleted. This is unusual. Trying to "
"determine the IP by calling Neutron.",
name)
parent_id = self._get_parent_port_id(vif)
if not parent_id:
LOG.warning("Port %s not found, ignoring its release request.",
vif.id)
return
host_addr = self._get_parent_port_ip(parent_id)
LOG.debug("Determined hostIP for pod %s is %s", name, host_addr)
super(NestedVIFPool, self).release_vif(
pod, vif, project_id, security_groups, host_addr=host_addr)
def _get_port_from_pool(self, pool_key, pod, subnets, security_groups):
try:
pool_ports = self._available_ports_pools[pool_key]