Example #1
0
    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)
Example #2
0
    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)
Example #3
0
 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)
Example #4
0
 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)
Example #5
0
 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
Example #6
0
    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 _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)
Example #8
0
 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'])
Example #9
0
    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
Example #10
0
 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