Add support for listeners on the same port but different protocol

Due to a bug in Octavia this was previously avoided. This is now
supported for the amphora provider, so it won't be blocked on the
kuryr side

Change-Id: If7d32023e467d1a63812057e1d151901ce462c7f
This commit is contained in:
Luis Tomas Bolivar 2020-01-13 16:57:14 +01:00
parent 9790b1f3f5
commit 3196021b9e
2 changed files with 22 additions and 13 deletions

View File

@ -55,6 +55,7 @@ _L7_POLICY_ACT_REDIRECT_TO_POOL = 'REDIRECT_TO_POOL'
_LB_STS_POLL_FAST_INTERVAL = 1
_LB_STS_POLL_SLOW_INTERVAL = 3
_OCTAVIA_TAGGING_VERSION = 2, 5
_OCTAVIA_DL_VERSION = 2, 11
_OCTAVIA_ACL_VERSION = 2, 12
@ -66,6 +67,7 @@ class LBaaSv2Driver(base.LBaaSDriver):
self._octavia_tags = False
self._octavia_acls = False
self._octavia_double_listeners = False
# Check if Octavia API supports tagging.
# TODO(dulek): *Maybe* this can be replaced with
# lbaas.get_api_major_version(version=_OCTAVIA_TAGGING_VERSION)
@ -75,6 +77,14 @@ class LBaaSv2Driver(base.LBaaSDriver):
if v >= _OCTAVIA_ACL_VERSION:
self._octavia_acls = True
LOG.info('Octavia supports ACLs for Amphora provider.')
if v >= _OCTAVIA_DL_VERSION:
# FIXME(ltomasbo): ovn-octavia driver does not yet support double
# listeners. Remove when it does, considering the right
# octavia microversion
if CONF.kubernetes.endpoints_driver_octavia_provider != 'ovn':
self._octavia_double_listeners = True
LOG.info('Octavia supports double listeners (different '
'protocol, same port) for Amphora provider.')
if v >= _OCTAVIA_TAGGING_VERSION:
LOG.info('Octavia supports resource tags.')
self._octavia_tags = True
@ -85,6 +95,9 @@ class LBaaSv2Driver(base.LBaaSDriver):
'will put requested tags in the description field of '
'Octavia resources.', v_str)
def double_listeners_supported(self):
return self._octavia_double_listeners
def get_octavia_version(self):
lbaas = clients.get_loadbalancer_client()
region_name = getattr(CONF.neutron, 'region_name', None)

View File

@ -541,17 +541,19 @@ class LoadBalancerHandler(k8s_base.ResourceEventHandler):
for port_spec in lbaas_spec_ports:
protocol = port_spec.protocol
port = port_spec.port
name = "%s:%s" % (lbaas_state.loadbalancer.name, protocol)
listener = [l for l in lbaas_state.listeners
if l.port == port and l.protocol == protocol]
if listener:
continue
# FIXME (maysams): Due to a bug in Octavia, which does
# not allows listeners with same port but different
# protocols to co-exist, we need to skip the creation of
# listeners that have the same port as an existing one.
name = "%s:%s" % (lbaas_state.loadbalancer.name, protocol)
listener = self._get_listener_with_same_port(lbaas_state, port)
if listener:
if listener.protocol != protocol:
LOG.warning("Skipping listener creation for %s "
"as another one already exists with port %r",
name, port)
listener = [l for l in lbaas_state.listeners if l.port == port]
if listener and not self._drv_lbaas.double_listeners_supported():
LOG.warning("Skipping listener creation for %s as another one"
" already exists with port %s", name, port)
continue
listener = self._drv_lbaas.ensure_listener(
loadbalancer=lbaas_state.loadbalancer,
@ -563,12 +565,6 @@ class LoadBalancerHandler(k8s_base.ResourceEventHandler):
changed = True
return changed
def _get_listener_with_same_port(self, lbaas_state, port):
for listener in lbaas_state.listeners:
if listener.port == port:
return listener
return None
def _remove_unused_listeners(self, endpoints, lbaas_state, lbaas_spec):
current_listeners = {p.listener_id for p in lbaas_state.pools}