def _get_pod_subnet(self, pod, ip): project_id = self._drv_pod_project.get_project(pod) subnets_map = self._drv_pod_subnets.get_subnets(pod, project_id) subnet_ids = [subnet_id for subnet_id, network in subnets_map.items() for subnet in network.subnets.objects if ip in subnet.cidr] if subnet_ids: return subnet_ids[0] else: # NOTE(ltomasbo): We are assuming that if IP is not on the # pod subnet it's because the member is using hostNetworking. In # this case we look for the IP in worker_nodes_subnets. subnet = utils.get_subnet_by_ip(self._get_nodes_subnets(), ip) if subnet: return subnet[0] else: # This shouldn't ever happen but let's return just the first # worker_nodes_subnet id. return self._get_nodes_subnets()[0][0]
def _get_subnet_by_octavia_mode(self, target_pod, target_ip, lb_crd): # TODO(apuimedo): Do not pass subnet_id at all when in # L3 mode once old neutron-lbaasv2 is not supported, as # octavia does not require it subnet_id = None if (CONF.octavia_defaults.member_mode == k_const.OCTAVIA_L2_MEMBER_MODE ): if target_pod: subnet_id = self._get_pod_subnet(target_pod, target_ip) else: subnet = utils.get_subnet_by_ip(self._get_nodes_subnets(), target_ip) if subnet: subnet_id = subnet[0] else: # We use the service subnet id so that the connectivity # from VIP to pods happens in layer 3 mode, i.e., # routed. subnet_id = lb_crd['status']['loadbalancer']['subnet_id'] return subnet_id
def _add_new_members(self, loadbalancer_crd): changed = False if loadbalancer_crd['status'].get('loadbalancer'): loadbalancer_crd = self._sync_lbaas_sgs(loadbalancer_crd) if not loadbalancer_crd: return changed lsnr_by_id = { l['id']: l for l in loadbalancer_crd['status'].get('listeners', []) } pool_by_lsnr_port = { (lsnr_by_id[p['listener_id']]['protocol'], lsnr_by_id[p['listener_id']]['port']): p for p in loadbalancer_crd['status'].get('pools', []) } # NOTE(yboaron): Since LBaaSv2 doesn't support UDP load balancing, # the LBaaS driver will return 'None' in case of UDP port # listener creation. # we should consider the case in which # 'pool_by_lsnr_port[p.protocol, p.port]' is missing pool_by_tgt_name = {} for p in loadbalancer_crd['spec'].get('ports', []): try: pool_by_tgt_name[p['name']] = pool_by_lsnr_port[p['protocol'], p['port']] except KeyError: continue current_targets = [ (str(m['ip']), m['port'], m['pool_id']) for m in loadbalancer_crd['status'].get('members', []) ] for ep_slice in loadbalancer_crd['spec']['endpointSlices']: ep_slices_ports = ep_slice.get('ports', []) for endpoint in ep_slice.get('endpoints', []): try: target_ip = endpoint['addresses'][0] target_ref = endpoint.get('targetRef') target_namespace = None if target_ref: target_namespace = target_ref['namespace'] # Avoid to point to a Pod on hostNetwork # that isn't the one to be added as Member. if not target_ref and utils.get_subnet_by_ip( self._get_nodes_subnets(), target_ip): target_pod = {} else: target_pod = utils.get_pod_by_ip( target_ip, target_namespace) except KeyError: continue if not pool_by_tgt_name: continue for ep_slice_port in ep_slices_ports: target_port = ep_slice_port['port'] port_name = ep_slice_port.get('name') try: pool = pool_by_tgt_name[port_name] except KeyError: LOG.debug("No pool found for port: %r", port_name) continue if (target_ip, target_port, pool['id']) in current_targets: continue member_subnet_id = self._get_subnet_by_octavia_mode( target_pod, target_ip, loadbalancer_crd) if not member_subnet_id: LOG.warning("Skipping member creation for %s", target_ip) continue target_name, target_namespace = self._get_target_info( target_ref, loadbalancer_crd) first_member_of_the_pool = True for member in loadbalancer_crd['status'].get( 'members', []): if pool['id'] == member['pool_id']: first_member_of_the_pool = False break if first_member_of_the_pool: listener_port = lsnr_by_id[pool['listener_id']]['port'] else: listener_port = None loadbalancer = loadbalancer_crd['status']['loadbalancer'] member = self._drv_lbaas.ensure_member( loadbalancer=loadbalancer, pool=pool, subnet_id=member_subnet_id, ip=target_ip, port=target_port, target_ref_namespace=target_namespace, target_ref_name=target_name, listener_port=listener_port) if not member: continue members = loadbalancer_crd['status'].get('members', []) if members: loadbalancer_crd['status'].get('members', []).append(member) else: loadbalancer_crd['status']['members'] = [] loadbalancer_crd['status'].get('members', []).append(member) if not self._patch_status(loadbalancer_crd): return False changed = True return changed