Exemplo n.º 1
0
 def test_db_listener_to_provider_listener(self):
     test_db_list = data_models.Listener(id=1)
     provider_list = utils.db_listener_to_provider_listener(test_db_list)
     ref_provider_list = driver_dm.Listener(listener_id=1,
                                            insert_headers={})
     self.assertEqual(ref_provider_list.to_dict(render_unsets=True),
                      provider_list.to_dict(render_unsets=True))
Exemplo n.º 2
0
 def test_db_listener_to_provider_listener(self):
     test_db_list = data_models.Listener(id=1)
     provider_list = utils.db_listener_to_provider_listener(test_db_list)
     ref_provider_list = driver_dm.Listener(listener_id=1,
                                            insert_headers={})
     self.assertEqual(ref_provider_list.to_dict(render_unsets=True),
                      provider_list.to_dict(render_unsets=True))
Exemplo n.º 3
0
    def post(self, listener_):
        """Creates a listener on a load balancer."""
        listener = listener_.listener
        context = pecan.request.context.get('octavia_context')

        load_balancer_id = listener.loadbalancer_id
        listener.project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

        self._auth_validate_action(context, listener.project_id,
                                   constants.RBAC_POST)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(provider)

        lock_session = db_api.get_session(autocommit=False)
        try:
            if self.repositories.check_quota_met(context.session, lock_session,
                                                 data_models.Listener,
                                                 listener.project_id):
                raise exceptions.QuotaException(
                    resource=data_models.Listener._name())

            listener_dict = db_prepare.create_listener(
                listener.to_dict(render_unsets=True), None)

            if listener_dict['default_pool_id']:
                self._validate_pool(context.session, load_balancer_id,
                                    listener_dict['default_pool_id'],
                                    listener.protocol)

            self._test_lb_and_listener_statuses(lock_session,
                                                lb_id=load_balancer_id)

            db_listener = self._validate_create_listener(
                lock_session, listener_dict)

            # Prepare the data for the driver data model
            provider_listener = (
                driver_utils.db_listener_to_provider_listener(db_listener))

            # re-inject the sni container references lost due to SNI
            # being a separate table in the DB
            provider_listener.sni_container_refs = listener.sni_container_refs

            # Dispatch to the driver
            LOG.info("Sending create Listener %s to provider %s",
                     db_listener.id, driver.name)
            driver_utils.call_provider(driver.name, driver.listener_create,
                                       provider_listener)

            lock_session.commit()
        except Exception:
            with excutils.save_and_reraise_exception():
                lock_session.rollback()

        db_listener = self._get_db_listener(context.session, db_listener.id)
        result = self._convert_db_to_type(db_listener,
                                          listener_types.ListenerResponse)
        return listener_types.ListenerRootResponse(listener=result)
Exemplo n.º 4
0
 def _get_listener_in_pool_dict(self, pool_dict, is_update):
     if 'listener' not in pool_dict:
         if pool_dict.get('listener_id'):
             db_listener = self.repositories.listener.get(
                 db_apis.get_session(), id=pool_dict['listener_id'])
             listener_obj = oct_utils.db_listener_to_provider_listener(
                 db_listener)
             listener_dict = listener_obj.to_dict(
                 recurse=False, render_unsets=True)
             listener_dict['id'] = listener_dict['listener_id']
             listener_dict['l7_policies'] = listener_dict['l7policies']
             # Add the loadbalancer to the listener dict
             if pool_dict.get('loadbalancer_id'):
                 # Generate a loadbalancer object
                 listener_dict['loadbalancer'] = (
                     self._get_load_balancer_dict(
                         pool_dict['loadbalancer_id']))
             pool_dict['listener'] = listener_dict
             if 'listeners' not in pool_dict:
                 # multiple listeners is not really supported yet
                 pool_dict['listeners'] = [listener_dict]
         # Do not add listener in update situation, as we want to use
         # the original listener of this pool
         elif not is_update:
             pool_dict['listener'] = None
             if 'listeners' not in pool_dict:
                 pool_dict['listeners'] = []
Exemplo n.º 5
0
def process_get(get_data):
    session = db_api.get_session()

    if get_data[constants.OBJECT] == lib_consts.LOADBALANCERS:
        lb_repo = repositories.LoadBalancerRepository()
        db_lb = lb_repo.get(session, id=get_data[lib_consts.ID],
                            show_deleted=False)
        if db_lb:
            provider_lb = (
                driver_utils.db_loadbalancer_to_provider_loadbalancer(db_lb))
            return provider_lb.to_dict(recurse=True, render_unsets=True)
    elif get_data[constants.OBJECT] == lib_consts.LISTENERS:
        listener_repo = repositories.ListenerRepository()
        db_listener = listener_repo.get(
            session, id=get_data[lib_consts.ID], show_deleted=False)
        if db_listener:
            provider_listener = (
                driver_utils.db_listener_to_provider_listener(db_listener))
            return provider_listener.to_dict(recurse=True, render_unsets=True)
    elif get_data[constants.OBJECT] == lib_consts.POOLS:
        pool_repo = repositories.PoolRepository()
        db_pool = pool_repo.get(session, id=get_data[lib_consts.ID],
                                show_deleted=False)
        if db_pool:
            provider_pool = (
                driver_utils.db_pool_to_provider_pool(db_pool))
            return provider_pool.to_dict(recurse=True, render_unsets=True)
    elif get_data[constants.OBJECT] == lib_consts.MEMBERS:
        member_repo = repositories.MemberRepository()
        db_member = member_repo.get(session, id=get_data[lib_consts.ID],
                                    show_deleted=False)
        if db_member:
            provider_member = (
                driver_utils.db_member_to_provider_member(db_member))
            return provider_member.to_dict(recurse=True, render_unsets=True)
    elif get_data[constants.OBJECT] == lib_consts.HEALTHMONITORS:
        hm_repo = repositories.HealthMonitorRepository()
        db_hm = hm_repo.get(session, id=get_data[lib_consts.ID],
                            show_deleted=False)
        if db_hm:
            provider_hm = (
                driver_utils.db_HM_to_provider_HM(db_hm))
            return provider_hm.to_dict(recurse=True, render_unsets=True)
    elif get_data[constants.OBJECT] == lib_consts.L7POLICIES:
        l7policy_repo = repositories.L7PolicyRepository()
        db_l7policy = l7policy_repo.get(session, id=get_data[lib_consts.ID],
                                        show_deleted=False)
        if db_l7policy:
            provider_l7policy = (
                driver_utils.db_l7policy_to_provider_l7policy(db_l7policy))
            return provider_l7policy.to_dict(recurse=True, render_unsets=True)
    elif get_data[constants.OBJECT] == lib_consts.L7RULES:
        l7rule_repo = repositories.L7RuleRepository()
        db_l7rule = l7rule_repo.get(session, id=get_data[lib_consts.ID],
                                    show_deleted=False)
        if db_l7rule:
            provider_l7rule = (
                driver_utils.db_l7rule_to_provider_l7rule(db_l7rule))
            return provider_l7rule.to_dict(recurse=True, render_unsets=True)
    return {}
Exemplo n.º 6
0
 def _get_listener_in_pool_dict(self, pool_dict, is_update):
     if 'listener' not in pool_dict:
         if pool_dict.get('listener_id'):
             db_listener = self.repositories.listener.get(
                 db_apis.get_session(), id=pool_dict['listener_id'])
             listener_obj = oct_utils.db_listener_to_provider_listener(
                 db_listener)
             listener_dict = listener_obj.to_dict(recurse=False,
                                                  render_unsets=True)
             listener_dict['id'] = listener_dict['listener_id']
             listener_dict['l7_policies'] = listener_dict['l7policies']
             # Add the loadbalancer to the listener dict
             if pool_dict.get('loadbalancer_id'):
                 # Generate a loadbalancer object
                 listener_dict['loadbalancer'] = (
                     self._get_load_balancer_dict(
                         pool_dict['loadbalancer_id']))
             pool_dict['listener'] = listener_dict
             if 'listeners' not in pool_dict:
                 # multiple listeners is not really supported yet
                 pool_dict['listeners'] = [listener_dict]
         # Do not add listener in update situation, as we want to use
         # the original listener of this pool
         elif not is_update:
             pool_dict['listener'] = None
             if 'listeners' not in pool_dict:
                 pool_dict['listeners'] = []
Exemplo n.º 7
0
    def create_listener(self, listener):
        """Creates a listener.

        :param listener: A listener provider dictionary.
        :returns: None
        :raises NoResultFound: Unable to find the object
        """
        db_listener = self._listener_repo.get(
            db_apis.get_session(), id=listener[constants.LISTENER_ID])
        if not db_listener:
            LOG.warning('Failed to fetch %s %s from DB. Retrying for up to '
                        '60 seconds.', 'listener',
                        listener[constants.LISTENER_ID])
            raise db_exceptions.NoResultFound

        load_balancer = db_listener.load_balancer
        listeners = load_balancer.listeners
        dict_listeners = []
        for li in listeners:
            dict_listeners.append(
                provider_utils.db_listener_to_provider_listener(li).to_dict())
        provider_lb = provider_utils.db_loadbalancer_to_provider_loadbalancer(
            load_balancer).to_dict()

        store = {constants.LISTENERS: dict_listeners,
                 constants.LOADBALANCER: provider_lb,
                 constants.LOADBALANCER_ID: load_balancer.id}

        self.services_controller.run_poster(
            flow_utils.get_create_listener_flow,
            store=store)
Exemplo n.º 8
0
    def put(self, id, listener_):
        """Updates a listener on a load balancer."""
        listener = listener_.listener
        context = pecan_request.context.get('octavia_context')
        db_listener = self._get_db_listener(context.session,
                                            id,
                                            show_deleted=False)
        load_balancer_id = db_listener.load_balancer_id

        project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

        self._auth_validate_action(context, project_id, constants.RBAC_PUT)

        self._validate_listener_PUT(listener, db_listener)

        self._set_default_on_none(listener)

        if listener.default_pool_id:
            self._validate_pool(context.session, load_balancer_id,
                                listener.default_pool_id, db_listener.protocol)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(provider)

        with db_api.get_lock_session() as lock_session:
            self._test_lb_and_listener_statuses(lock_session,
                                                load_balancer_id,
                                                id=id)

            # Prepare the data for the driver data model
            listener_dict = listener.to_dict(render_unsets=False)
            listener_dict['id'] = id

            provider_listener_dict = (
                driver_utils.listener_dict_to_provider_dict(listener_dict))

            # Also prepare the baseline object data
            old_provider_listener = (
                driver_utils.db_listener_to_provider_listener(db_listener,
                                                              for_delete=True))

            # Dispatch to the driver
            LOG.info("Sending update Listener %s to provider %s", id,
                     driver.name)
            driver_utils.call_provider(
                driver.name, driver.listener_update, old_provider_listener,
                driver_dm.Listener.from_dict(provider_listener_dict))

            # Update the database to reflect what the driver just accepted
            self.repositories.listener.update(
                lock_session, id, **listener.to_dict(render_unsets=False))

        # Force SQL alchemy to query the DB, otherwise we get inconsistent
        # results
        context.session.expire_all()
        db_listener = self._get_db_listener(context.session, id)
        result = self._convert_db_to_type(db_listener,
                                          listener_types.ListenerResponse)
        return listener_types.ListenerRootResponse(listener=result)
Exemplo n.º 9
0
    def delete(self, id):
        """Deletes a listener from a load balancer."""
        context = pecan.request.context.get('octavia_context')
        db_listener = self._get_db_listener(context.session, id,
                                            show_deleted=False)
        load_balancer_id = db_listener.load_balancer_id

        project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

        self._auth_validate_action(context, project_id, constants.RBAC_DELETE)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(provider)

        with db_api.get_lock_session() as lock_session:

            self._test_lb_and_listener_statuses(
                lock_session, load_balancer_id,
                id=id, listener_status=constants.PENDING_DELETE)

            LOG.info("Sending delete Listener %s to provider %s", id,
                     driver.name)
            provider_listener = (
                driver_utils.db_listener_to_provider_listener(db_listener))
            driver_utils.call_provider(driver.name, driver.listener_delete,
                                       provider_listener)
Exemplo n.º 10
0
    def create_listener(self, listener):
        """Creates a listener.

        :param listener: A listener provider dictionary.
        :returns: None
        :raises NoResultFound: Unable to find the object
        """
        db_listener = self._listener_repo.get(
            db_apis.get_session(), id=listener[constants.LISTENER_ID])
        if not db_listener:
            LOG.warning(
                'Failed to fetch %s %s from DB. Retrying for up to '
                '60 seconds.', 'listener', listener[constants.LISTENER_ID])
            raise db_exceptions.NoResultFound

        load_balancer = db_listener.load_balancer
        listeners = load_balancer.listeners
        dict_listeners = []
        for l in listeners:
            dict_listeners.append(
                provider_utils.db_listener_to_provider_listener(l).to_dict())
        provider_lb = provider_utils.db_loadbalancer_to_provider_loadbalancer(
            load_balancer).to_dict()

        create_listener_tf = self._taskflow_load(
            self._listener_flows.get_create_listener_flow(),
            store={
                constants.LISTENERS: dict_listeners,
                constants.LOADBALANCER: provider_lb,
                constants.LOADBALANCER_ID: load_balancer.id
            })
        with tf_logging.DynamicLoggingListener(create_listener_tf, log=LOG):
            create_listener_tf.run()
Exemplo n.º 11
0
    def delete(self, id):
        """Deletes a listener from a load balancer."""
        context = pecan.request.context.get('octavia_context')
        db_listener = self._get_db_listener(context.session,
                                            id,
                                            show_deleted=False)
        load_balancer_id = db_listener.load_balancer_id

        project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

        self._auth_validate_action(context, project_id, constants.RBAC_DELETE)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(provider)

        with db_api.get_lock_session() as lock_session:

            self._test_lb_and_listener_statuses(
                lock_session,
                load_balancer_id,
                id=id,
                listener_status=constants.PENDING_DELETE)

            LOG.info("Sending delete Listener %s to provider %s", id,
                     driver.name)
            provider_listener = (
                driver_utils.db_listener_to_provider_listener(db_listener))
            driver_utils.call_provider(driver.name, driver.listener_delete,
                                       provider_listener)
Exemplo n.º 12
0
    def put(self, id, listener_):
        """Updates a listener on a load balancer."""
        listener = listener_.listener
        context = pecan.request.context.get('octavia_context')
        db_listener = self._get_db_listener(context.session, id,
                                            show_deleted=False)
        load_balancer_id = db_listener.load_balancer_id

        project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

        self._auth_validate_action(context, project_id, constants.RBAC_PUT)

        self._validate_listener_PUT(listener, db_listener)

        self._set_default_on_none(listener)

        if listener.default_pool_id:
            self._validate_pool(context.session, load_balancer_id,
                                listener.default_pool_id, db_listener.protocol)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(provider)

        with db_api.get_lock_session() as lock_session:
            self._test_lb_and_listener_statuses(lock_session,
                                                load_balancer_id, id=id)

            # Prepare the data for the driver data model
            listener_dict = listener.to_dict(render_unsets=False)
            listener_dict['id'] = id
            provider_listener_dict = (
                driver_utils.listener_dict_to_provider_dict(listener_dict))

            # Also prepare the baseline object data
            old_provider_llistener = (
                driver_utils.db_listener_to_provider_listener(db_listener))

            # Dispatch to the driver
            LOG.info("Sending update Listener %s to provider %s", id,
                     driver.name)
            driver_utils.call_provider(
                driver.name, driver.listener_update,
                old_provider_llistener,
                driver_dm.Listener.from_dict(provider_listener_dict))

            # Update the database to reflect what the driver just accepted
            self.repositories.listener.update(
                lock_session, id, **listener.to_dict(render_unsets=False))

        # Force SQL alchemy to query the DB, otherwise we get inconsistent
        # results
        context.session.expire_all()
        db_listener = self._get_db_listener(context.session, id)
        result = self._convert_db_to_type(db_listener,
                                          listener_types.ListenerResponse)
        return listener_types.ListenerRootResponse(listener=result)
Exemplo n.º 13
0
def get_listeners_on_lb(db_lb):
    """Get a list of the listeners on a load balancer.

    :param db_lb: A load balancer database model object.
    :returns: A list of provider dict format listeners.
    """
    listener_dicts = []
    for listener in db_lb.listeners:
        prov_listener = provider_utils.db_listener_to_provider_listener(
            listener)
        listener_dicts.append(prov_listener.to_dict())
    return listener_dicts
Exemplo n.º 14
0
 def get_delete_listeners_store(self, lb):
     store = {}
     for listener in lb.listeners:
         listener_name = 'listener_' + listener.id
         prov_listener = provider_utils.db_listener_to_provider_listener(
             listener)
         store[listener_name] = prov_listener.to_dict()
         store.update({
             constants.LOADBALANCER_ID: lb.id,
             constants.PROJECT_ID: lb.project_id
         })
     return store
Exemplo n.º 15
0
 def update_policy_dict(self, policy_dict, policy_obj, is_update=False):
     if policy_dict.get('listener_id'):
         db_list = self.repositories.listener.get(
             db_apis.get_session(), id=policy_dict['listener_id'])
         list_obj = oct_utils.db_listener_to_provider_listener(db_list)
         list_dict = list_obj.to_dict(recurse=True, render_unsets=True)
         list_dict['id'] = policy_dict['listener_id']
         policy_dict['listener'] = list_dict
     if policy_obj.rules:
         policy_dict['rules'] = []
         for rule in policy_obj.rules:
             rule_dict = rule.to_dict(recurse=False, render_unsets=True)
             rule_dict['id'] = rule_dict['l7rule_id']
             policy_dict['rules'].append(rule_dict)
     elif not is_update:
         policy_dict['rules'] = []
Exemplo n.º 16
0
 def _get_listener_in_pool_dict(self, pool_dict):
     if 'listener' not in pool_dict:
         if pool_dict.get('listener_id'):
             db_listener = self.repositories.listener.get(
                 db_apis.get_session(), id=pool_dict['listener_id'])
             listener_obj = oct_utils.db_listener_to_provider_listener(
                 db_listener)
             listener_dict = listener_obj.to_dict(
                 recurse=False, render_unsets=True)
             listener_dict['id'] = listener_dict['listener_id']
             listener_dict['l7_policies'] = listener_dict['l7policies']
             pool_dict['listener'] = listener_dict
             if 'listeners' not in pool_dict:
                 # multiple listeners is not really supported yet
                 pool_dict['listeners'] = [listener_dict]
         else:
             pool_dict['listener'] = None
             if 'listeners' not in pool_dict:
                 pool_dict['listeners'] = []
Exemplo n.º 17
0
 def update_policy_dict(self, policy_dict, policy_obj, is_update=False):
     if policy_dict.get('listener_id'):
         db_list = self.repositories.listener.get(
             db_apis.get_session(), id=policy_dict['listener_id'])
         list_obj = oct_utils.db_listener_to_provider_listener(db_list)
         list_dict = list_obj.to_dict(recurse=True, render_unsets=True)
         list_dict['id'] = policy_dict['listener_id']
         policy_dict['listener'] = list_dict
     if policy_obj.rules:
         policy_dict['rules'] = []
         for rule in policy_obj.rules:
             if isinstance(rule, dict):
                 rule_dict = rule
             else:
                 rule_dict = rule.to_dict(recurse=False, render_unsets=True)
             rule_dict['id'] = rule_dict['l7rule_id']
             policy_dict['rules'].append(rule_dict)
     elif not is_update:
         policy_dict['rules'] = []
Exemplo n.º 18
0
    def _get_delete_listeners_flow(self, lb):
        """Sets up an internal delete flow

        Because task flow doesn't support loops we store each listener
        we want to delete in the store part and then rebind
        :param lb: load balancer
        :return: (flow, store) -- flow for the deletion and store with all
                    the listeners stored properly
        """
        listeners_delete_flow = unordered_flow.Flow('listener_delete_flow')
        store = {}
        for listener in lb.listeners:
            listener_name = 'listener_' + listener.id
            prov_listener = provider_utils.db_listener_to_provider_listener(
                listener)
            store[listener_name] = prov_listener.to_dict()
            listeners_delete_flow.add(
                self.listener_flows.get_delete_listener_internal_flow(
                    listener_name))
        store.update({constants.LOADBALANCER_ID: lb.id,
                      constants.PROJECT_ID: lb.project_id})
        return (listeners_delete_flow, store)
Exemplo n.º 19
0
    def delete(self, id):
        """Deletes a listener from a load balancer."""
        context = pecan.request.context.get('octavia_context')
        db_listener = self._get_db_listener(context.session, id,
                                            show_deleted=False)
        load_balancer_id = db_listener.load_balancer_id

        project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

        self._auth_validate_action(context, project_id, constants.RBAC_DELETE)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(provider)

        with db_api.get_lock_session() as lock_session:

            self._test_lb_and_listener_statuses(
                lock_session, load_balancer_id,
                id=id, listener_status=constants.PENDING_DELETE)

            LOG.info("Sending delete Listener %s to provider %s", id,
                     driver.name)
            provider_listener = (
                driver_utils.db_listener_to_provider_listener(db_listener))
            driver_utils.call_provider(driver.name, driver.listener_delete,
                                       provider_listener)

        # Revoke access of octavia service user to certificates
        tls_refs = []

        for sni in db_listener.sni_containers:
            filters = {'tls_container_id': sni.tls_container_id}
            snis = self.repositories.sni.get_all(context.session, **filters)[0]

            if len(snis) == 1:
                # referred only once, enqueue for access revoking
                tls_refs.append(sni.tls_container_id)
            else:
                blocking_listeners = [s.listener_id for s in snis if
                                      s.listener_id != id]
                LOG.debug("Listeners %s using TLS ref %s. Access to TLS ref "
                          "will not be revoked.", blocking_listeners,
                          sni.tls_container_id)

        if db_listener.tls_certificate_id:
            filters = {'tls_certificate_id': db_listener.tls_certificate_id}
            # Note get_all returns the list and links. We only want the list.
            listeners = self.repositories.listener.get_all(
                context.session, show_deleted=False, **filters)[0]

            if len(listeners) == 1:
                # referred only once, enqueue for access revoking
                tls_refs.append(db_listener.tls_certificate_id)
            else:
                blocking_listeners = [l.id for l in listeners if l.id != id]
                LOG.debug("Listeners %s using TLS ref %s. Access to TLS ref "
                          "will not be revoked.", blocking_listeners,
                          db_listener.tls_certificate_id)

        for ref in tls_refs:
            try:
                self.cert_manager.unset_acls(context, ref)
            except Exception:
                # certificate may have been removed already
                pass
Exemplo n.º 20
0
    def put(self, id, listener_):
        """Updates a listener on a load balancer."""
        listener = listener_.listener
        context = pecan.request.context.get('octavia_context')
        db_listener = self._get_db_listener(context.session, id,
                                            show_deleted=False)
        load_balancer_id = db_listener.load_balancer_id

        project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

        self._auth_validate_action(context, project_id, constants.RBAC_PUT)

        # TODO(rm_work): Do we need something like this? What do we do on an
        # empty body for a PUT?
        if not listener:
            raise exceptions.ValidationException(
                detail='No listener object supplied.')

        if (db_listener.protocol == constants.PROTOCOL_UDP and
                self._is_tls_or_insert_header(listener)):
            raise exceptions.ValidationException(detail=_(
                "%s protocol listener does not support TLS or header "
                "insertion.") % constants.PROTOCOL_UDP)

        if listener.default_pool_id:
            self._validate_pool(context.session, load_balancer_id,
                                listener.default_pool_id, db_listener.protocol)

        sni_containers = listener.sni_container_refs or []
        tls_refs = [sni for sni in sni_containers]
        if listener.default_tls_container_ref:
            tls_refs.append(listener.default_tls_container_ref)
        self._validate_tls_refs(tls_refs)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(provider)

        with db_api.get_lock_session() as lock_session:
            self._test_lb_and_listener_statuses(lock_session,
                                                load_balancer_id, id=id)

            # Prepare the data for the driver data model
            listener_dict = listener.to_dict(render_unsets=False)
            listener_dict['id'] = id
            provider_listener_dict = (
                driver_utils.listener_dict_to_provider_dict(listener_dict))

            # Also prepare the baseline object data
            old_provider_llistener = (
                driver_utils.db_listener_to_provider_listener(db_listener))

            # Dispatch to the driver
            LOG.info("Sending update Listener %s to provider %s", id,
                     driver.name)
            driver_utils.call_provider(
                driver.name, driver.listener_update,
                old_provider_llistener,
                driver_dm.Listener.from_dict(provider_listener_dict))

            # Update the database to reflect what the driver just accepted
            self.repositories.listener.update(
                lock_session, id, **listener.to_dict(render_unsets=False))

        # Force SQL alchemy to query the DB, otherwise we get inconsistent
        # results
        context.session.expire_all()
        db_listener = self._get_db_listener(context.session, id)
        result = self._convert_db_to_type(db_listener,
                                          listener_types.ListenerResponse)
        return listener_types.ListenerRootResponse(listener=result)
Exemplo n.º 21
0
    def post(self, listener_):
        """Creates a listener on a load balancer."""
        listener = listener_.listener
        context = pecan.request.context.get('octavia_context')

        load_balancer_id = listener.loadbalancer_id
        listener.project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

        self._auth_validate_action(context, listener.project_id,
                                   constants.RBAC_POST)
        if (listener.protocol == constants.PROTOCOL_UDP
                and self._is_tls_or_insert_header(listener)):
            raise exceptions.ValidationException(
                detail=_("%s protocol listener does not support TLS or header "
                         "insertion.") % constants.PROTOCOL_UDP)
        if (not CONF.api_settings.allow_tls_terminated_listeners
                and listener.protocol == constants.PROTOCOL_TERMINATED_HTTPS):
            raise exceptions.DisabledOption(
                value=constants.PROTOCOL_TERMINATED_HTTPS, option='protocol')

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(provider)

        lock_session = db_api.get_session(autocommit=False)
        try:
            if self.repositories.check_clusterquota_met(
                    lock_session,
                    data_models.Listener,
                    base_res_id=load_balancer_id):
                raise exceptions.ClusterQuotaException(
                    resource=data_models.Listener._name())
            if self.repositories.check_quota_met(context.session, lock_session,
                                                 data_models.Listener,
                                                 listener.project_id):
                raise exceptions.QuotaException(
                    resource=data_models.Listener._name())

            listener_dict = db_prepare.create_listener(
                listener.to_dict(render_unsets=True), None)

            if listener_dict['default_pool_id']:
                self._validate_pool(context.session, load_balancer_id,
                                    listener_dict['default_pool_id'],
                                    listener.protocol)

            self._test_lb_and_listener_statuses(lock_session,
                                                lb_id=load_balancer_id)

            db_listener = self._validate_create_listener(
                lock_session, listener_dict)

            # Prepare the data for the driver data model
            provider_listener = (
                driver_utils.db_listener_to_provider_listener(db_listener))

            # re-inject the sni container references lost due to SNI
            # being a separate table in the DB
            provider_listener.sni_container_refs = listener.sni_container_refs

            # Dispatch to the driver
            LOG.info("Sending create Listener %s to provider %s",
                     db_listener.id, driver.name)
            driver_utils.call_provider(driver.name, driver.listener_create,
                                       provider_listener)

            lock_session.commit()
        except Exception:
            with excutils.save_and_reraise_exception():
                lock_session.rollback()

        db_listener = self._get_db_listener(context.session, db_listener.id)
        result = self._convert_db_to_type(db_listener,
                                          listener_types.ListenerResponse)
        return listener_types.ListenerRootResponse(listener=result)
Exemplo n.º 22
0
    def post(self, listener_):
        """Creates a listener on a load balancer."""
        listener = listener_.listener
        context = pecan.request.context.get('octavia_context')

        load_balancer_id = listener.loadbalancer_id
        listener.project_id, provider = self._get_lb_project_id_provider(
            context.session, load_balancer_id)

        self._auth_validate_action(context, listener.project_id,
                                   constants.RBAC_POST)

        # Load the driver early as it also provides validation
        driver = driver_factory.get_driver(provider)

        lock_session = db_api.get_session(autocommit=False)
        try:
            if self.repositories.check_quota_met(
                    context.session,
                    lock_session,
                    data_models.Listener,
                    listener.project_id):
                raise exceptions.QuotaException(
                    resource=data_models.Listener._name())

            listener_dict = db_prepare.create_listener(
                listener.to_dict(render_unsets=True), None)

            if listener_dict['default_pool_id']:
                self._validate_pool(context.session, load_balancer_id,
                                    listener_dict['default_pool_id'],
                                    listener.protocol)

            self._test_lb_and_listener_statuses(
                lock_session, lb_id=load_balancer_id)

            db_listener = self._validate_create_listener(
                lock_session, listener_dict)

            # Prepare the data for the driver data model
            provider_listener = (
                driver_utils.db_listener_to_provider_listener(db_listener))

            # re-inject the sni container references lost due to SNI
            # being a separate table in the DB
            provider_listener.sni_container_refs = listener.sni_container_refs

            # Dispatch to the driver
            LOG.info("Sending create Listener %s to provider %s",
                     db_listener.id, driver.name)
            driver_utils.call_provider(
                driver.name, driver.listener_create, provider_listener)

            lock_session.commit()
        except Exception:
            with excutils.save_and_reraise_exception():
                lock_session.rollback()

        db_listener = self._get_db_listener(context.session, db_listener.id)
        result = self._convert_db_to_type(db_listener,
                                          listener_types.ListenerResponse)
        return listener_types.ListenerRootResponse(listener=result)