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))
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))
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)
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'] = []
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 {}
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'] = []
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)
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)
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)
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()
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)
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)
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
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
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'] = []
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'] = []
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'] = []
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)
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
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)
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)
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)