def _create_listeners(self, namespace, lb, ports): for port in ports: listener_found = False for ll_id in lb.loadbalancer_listeners: ll = LoadbalancerListenerKM.get(ll_id) if not ll: continue if not ll.params['protocol_port']: continue if not ll.params['protocol']: continue if ll.params['protocol_port'] == port['port'] and \ ll.params['protocol'] == port['protocol']: listener_found = True break if not listener_found: ll_obj = self._vnc_create_listener(namespace, lb, port) ll = LoadbalancerListenerKM.locate(ll_obj._uuid) pool_id = ll.loadbalancer_pool if pool_id: pool = LoadbalancerPoolKM.get(pool_id) # SAS FIXME: If pool_id present, check for targetPort value if not pool_id or not pool: pool_obj = self._vnc_create_pool(namespace, ll, port) LoadbalancerPoolKM.locate(pool_obj._uuid)
def _vnc_delete_listeners(self, lb): listeners = lb.loadbalancer_listeners.copy() for ll_id in listeners or []: ll = LoadbalancerListenerKM.get(ll_id) if not ll: continue pool_id = ll.loadbalancer_pool if pool_id: pool = LoadbalancerPoolKM.get(pool_id) if pool: members = pool.members.copy() for member_id in members or []: member = LoadbalancerMemberKM.get(member_id) if member: self.service_lb_member_mgr.delete(member_id) self.logger.debug("Deleting LB member %s" % member.name) LoadbalancerMemberKM.delete(member_id) self._vnc_delete_pool(pool_id) self.logger.debug("Deleting LB pool %s" % pool.name) LoadbalancerPoolKM.delete(pool_id) self.logger.debug("Deleting LB listener %s" % ll.name) self._vnc_delete_listener(ll_id) LoadbalancerListenerKM.delete(ll_id)
def _create_listener_pool_member(self, ns_name, lb, backend): pool_port = {} listener_port = {} listener_port['port'] = '80' listener_port['protocol'] = backend['listener']['protocol'] if listener_port['protocol'] == 'TERMINATED_HTTPS': listener_port['port'] = '443' if 'default_tls_container' in backend['listener']: listener_port['default_tls_container'] = backend['listener'][ 'default_tls_container'] if 'sni_containers' in backend['listener']: listener_port['sni_containers'] = backend['listener'][ 'sni_containers'] ll = self._create_listener(ns_name, lb, listener_port) annotations = {} for key in backend['annotations']: annotations[key] = backend['annotations'][key] lb_algorithm = "ROUND_ROBIN" pool_port['port'] = '80' pool_port['protocol'] = backend['pool']['protocol'] pool = self._create_pool(ns_name, ll, pool_port, lb_algorithm, annotations) backend_member = backend['member'] member = self._create_member(ns_name, backend_member, pool) if member is None: self._logger.error("%s - Deleting Listener %s and Pool %s" % (self._name, ll.name, pool.name)) self._vnc_delete_pool(pool.uuid) LoadbalancerPoolKM.delete(pool.uuid) self._vnc_delete_listener(ll.uuid) LoadbalancerListenerKM.delete(ll.uuid)
def _delete_listener(self, ll_id): ll = LoadbalancerListenerKM.get(ll_id) pool_id = ll.loadbalancer_pool if pool_id: pool = LoadbalancerPoolKM.get(pool_id) member_list = pool.members.copy() for member_id in member_list: self._vnc_delete_member(member_id) LoadbalancerMemberKM.delete(member_id) self._vnc_delete_pool(pool_id) LoadbalancerPoolKM.delete(pool_id) self._vnc_delete_listener(ll_id) LoadbalancerListenerKM.delete(ll_id)
def _create_listener(self, ns_name, lb, port): ll_obj = self._vnc_create_listeners(ns_name, lb, port) if ll_obj: ll = LoadbalancerListenerKM.locate(ll_obj.uuid) else: self._logger.error("%s - %s Listener for Port %s Not Created" % (self._name, lb.name, str(port))) return ll
def _get_loadbalancer_pool(lb_listener_id, port=None): lb_listener = LoadbalancerListenerKM.get(lb_listener_id) if not lb_listener: return None if not lb_listener.params['protocol_port']: return None if port: if lb_listener.params['protocol'] != port['protocol']: return None if lb_listener.port_name and port.get('name') and \ lb_listener.port_name != port['name']: return None return LoadbalancerPoolKM.get(lb_listener.loadbalancer_pool)
def _assert_loadbalancer(self, srv_uuid, ports): lb = LoadbalancerKM.locate(srv_uuid) self.assertIsNotNone(lb) ll = LoadbalancerListenerKM.locate(list(lb.loadbalancer_listeners)[0]) self.assertIsNotNone(ll) self.assertEquals(ports[0]['port'], ll.params['protocol_port'])
def _create_lb(self, uid, name, ns_name, event): annotations = event['object']['metadata'].get('annotations') ingress_controller = 'opencontrail' if annotations: if 'kubernetes.io/ingress.class' in annotations: ingress_controller = annotations['kubernetes.io/ingress.class'] if ingress_controller != 'opencontrail': self._logger.warning( "%s - ingress controller is not opencontrail for ingress %s" % (self._name, name)) self._delete_ingress(uid) return lb = LoadbalancerKM.get(uid) if not lb: lb_obj = self._vnc_create_lb(uid, name, ns_name, annotations) if lb_obj is None: return lb = LoadbalancerKM.locate(uid) else: external_ip = None if annotations and 'externalIP' in annotations: external_ip = annotations['externalIP'] specified_fip_pool_fq_name_str = None if annotations and 'opencontrail.org/fip-pool' in annotations: specified_fip_pool_fq_name_str = annotations[ 'opencontrail.org/fip-pool'] if external_ip != lb.external_ip: self._deallocate_floating_ip(lb) lb_obj = self._vnc_lib.loadbalancer_read(id=lb.uuid) fip = self._update_floating_ip(name, ns_name, external_ip, lb_obj, specified_fip_pool_fq_name_str) if fip: lb.external_ip = external_ip self._update_kube_api_server(name, ns_name, lb_obj, fip) self._clear_ingress_cache_uuid(self._ingress_label_cache, uid) spec = event['object']['spec'] new_backend_list = self._get_new_backend_list(spec, ns_name) old_backend_list = self._get_old_backend_list(lb) # find the unchanged backends for new_backend in new_backend_list[:] or []: self._update_ingress_cache(self._ingress_label_cache, ns_name, new_backend['member']['serviceName'], uid) for old_backend in old_backend_list[:] or []: if (new_backend['annotations'] == old_backend['annotations'] and new_backend['listener'] == old_backend['listener'] and new_backend['pool'] == old_backend['pool'] and new_backend['member'] == old_backend['member']): # Create a firewall rule for this member. fw_uuid = VncIngress.add_ingress_to_service_rule( ns_name, name, new_backend['member']['serviceName']) lb.add_firewall_rule(fw_uuid) old_backend_list.remove(old_backend) new_backend_list.remove(new_backend) break if len(old_backend_list) == 0 and len(new_backend_list) == 0: return lb # find the updated backends and update backend_update_list = [] for new_backend in new_backend_list[:] or []: for old_backend in old_backend_list[:] or []: if (new_backend['annotations'] == old_backend['annotations'] and new_backend['listener'] == old_backend['listener'] and new_backend['pool'] == old_backend['pool']): backend = old_backend backend['member']['member_id'] = old_backend['member_id'] backend['member']['serviceName'] = new_backend['member'][ 'serviceName'] backend['member']['servicePort'] = new_backend['member'][ 'servicePort'] backend_update_list.append(backend) old_backend_list.remove(old_backend) new_backend_list.remove(new_backend) for backend in backend_update_list or []: ll = LoadbalancerListenerKM.get(backend['listener_id']) pool = LoadbalancerPoolKM.get(backend['pool_id']) backend_member = backend['member'] member = self._update_member(ns_name, backend_member, pool) if member is None: self._logger.error("%s - Deleting Listener %s and Pool %s" % (self._name, ll.name, pool.name)) self._vnc_delete_pool(pool.uuid) LoadbalancerPoolKM.delete(pool.uuid) self._vnc_delete_listener(ll.uuid) LoadbalancerListenerKM.delete(ll.uuid) if len(old_backend_list) == 0 and len(new_backend_list) == 0: return lb # delete the old backends for backend in old_backend_list or []: self._delete_listener(backend['listener_id']) deleted_fw_rule_uuid =\ VncIngress.delete_ingress_to_service_rule( ns_name, name, backend['member']['serviceName']) lb.remove_firewall_rule(deleted_fw_rule_uuid) # create the new backends for backend in new_backend_list: # Create a firewall rule for this member. fw_uuid = VncIngress.add_ingress_to_service_rule( ns_name, name, backend['member']['serviceName']) lb.add_firewall_rule(fw_uuid) self._create_listener_pool_member(ns_name, lb, backend) return lb
def _get_old_backend_list(self, lb): backend_list = [] listener_list = lb.loadbalancer_listeners for ll_id in listener_list: backend = {} backend['listener_id'] = ll_id ll = LoadbalancerListenerKM.get(ll_id) backend['listener'] = {} backend['listener']['protocol'] = ll.params['protocol'] if backend['listener']['protocol'] == 'TERMINTED_HTTPS': if ll.params['default_tls_container']: backend['listener']['default_tls_container'] = \ ll.params['default_tls_container'] if ll.params['sni_containers']: backend['listener']['sni_containers'] = \ ll.params['sni_containers'] pool_id = ll.loadbalancer_pool if pool_id: pool = LoadbalancerPoolKM.get(pool_id) if pool.annotations is None: annotations = {} kvps = [] pool_obj = self._vnc_lib.loadbalancer_pool_read(id=pool_id) pool_obj_kvp = pool_obj.annotations.key_value_pair kvps_len = len(pool_obj_kvp) for count in range(0, kvps_len): kvp = {} kvp['key'] = pool_obj_kvp[count].key kvp['value'] = pool_obj_kvp[count].value kvps.append(kvp) annotations['key_value_pair'] = kvps else: annotations = pool.annotations backend['pool_id'] = pool_id backend['annotations'] = {} for kvp in annotations['key_value_pair'] or []: key = kvp['key'] value = kvp['value'] backend['annotations'][key] = value backend['pool'] = {} backend['pool']['protocol'] = pool.params['protocol'] backend['member'] = {} if len(pool.members) == 0: continue member_id = list(pool.members)[0] member = LoadbalancerMemberKM.get(member_id) if member.annotations is None: annotations = {} kvps = [] member_obj = self._vnc_lib.loadbalancer_member_read( id=member_id) member_obj_kvp = member_obj.annotations.key_value_pair kvps_len = len(member_obj_kvp) for count in range(0, kvps_len): kvp = {} kvp['key'] = member_obj_kvp[count].key kvp['value'] = member_obj_kvp[count].value kvps.append(kvp) annotations['key_value_pair'] = kvps else: annotations = member.annotations backend['member_id'] = member_id protocol_port = member.params['protocol_port'] for kvp in annotations['key_value_pair'] or []: if kvp['key'] == 'serviceName': backend['member']['serviceName'] = kvp['value'] backend['member']['servicePort'] = protocol_port break backend_list.append(backend) return backend_list