diff --git a/kuryr_kubernetes/controller/drivers/lbaasv2.py b/kuryr_kubernetes/controller/drivers/lbaasv2.py index c1d1ef213..245686382 100644 --- a/kuryr_kubernetes/controller/drivers/lbaasv2.py +++ b/kuryr_kubernetes/controller/drivers/lbaasv2.py @@ -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) diff --git a/kuryr_kubernetes/controller/handlers/lbaas.py b/kuryr_kubernetes/controller/handlers/lbaas.py index 8d8d935d8..2b37c546a 100644 --- a/kuryr_kubernetes/controller/handlers/lbaas.py +++ b/kuryr_kubernetes/controller/handlers/lbaas.py @@ -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}