def delete(self, id): """Deletes a pool from a load balancer.""" context = pecan.request.context.get('octavia_context') db_pool = self._get_db_pool(context.session, id, show_deleted=False) if db_pool.l7policies: raise exceptions.PoolInUseByL7Policy( id=db_pool.id, l7policy_id=db_pool.l7policies[0].id) project_id, provider = self._get_lb_project_id_provider( context.session, db_pool.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, lb_id=db_pool.load_balancer_id, listener_ids=self._get_affected_listener_ids(db_pool)) self.repositories.pool.update( lock_session, db_pool.id, provisioning_status=constants.PENDING_DELETE) LOG.info("Sending delete Pool %s to provider %s", id, driver.name) provider_pool = (driver_utils.db_pool_to_provider_pool(db_pool)) driver_utils.call_provider(driver.name, driver.pool_delete, provider_pool)
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 delete(self, id): """Deletes a pool from a load balancer.""" context = pecan.request.context.get('octavia_context') db_pool = self._get_db_pool(context.session, id, show_deleted=False) if db_pool.l7policies: raise exceptions.PoolInUseByL7Policy( id=db_pool.id, l7policy_id=db_pool.l7policies[0].id) project_id, provider = self._get_lb_project_id_provider( context.session, db_pool.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, lb_id=db_pool.load_balancer_id, listener_ids=self._get_affected_listener_ids(db_pool)) self.repositories.pool.update( lock_session, db_pool.id, provisioning_status=constants.PENDING_DELETE) LOG.info("Sending delete Pool %s to provider %s", id, driver.name) provider_pool = ( driver_utils.db_pool_to_provider_pool(db_pool)) driver_utils.call_provider(driver.name, driver.pool_delete, provider_pool)
def put(self, id, pool_): """Updates a pool on a load balancer.""" pool = pool_.pool context = pecan_request.context.get('octavia_context') db_pool = self._get_db_pool(context.session, id, show_deleted=False) project_id, provider = self._get_lb_project_id_provider( context.session, db_pool.load_balancer_id) self._auth_validate_action(context, project_id, constants.RBAC_PUT) if pool.tls_versions is None: pool.tls_versions = CONF.api_settings.default_pool_tls_versions if pool.tls_ciphers is None: pool.tls_ciphers = CONF.api_settings.default_pool_ciphers if (pool.session_persistence and not pool.session_persistence.type and db_pool.session_persistence and db_pool.session_persistence.type): pool.session_persistence.type = db_pool.session_persistence.type self._validate_pool_PUT(pool, db_pool) # 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( context.session, lb_id=db_pool.load_balancer_id, listener_ids=self._get_affected_listener_ids(db_pool)) # Prepare the data for the driver data model pool_dict = pool.to_dict(render_unsets=False) pool_dict['id'] = id provider_pool_dict = ( driver_utils.pool_dict_to_provider_dict(pool_dict)) # Also prepare the baseline object data old_provider_pool = driver_utils.db_pool_to_provider_pool( db_pool, for_delete=True) # Dispatch to the driver LOG.info("Sending update Pool %s to provider %s", id, driver.name) driver_utils.call_provider( driver.name, driver.pool_update, old_provider_pool, driver_dm.Pool.from_dict(provider_pool_dict)) # Update the database to reflect what the driver just accepted pool.provisioning_status = constants.PENDING_UPDATE db_pool_dict = pool.to_dict(render_unsets=False) self.repositories.update_pool_and_sp(lock_session, id, db_pool_dict) # Force SQL alchemy to query the DB, otherwise we get inconsistent # results context.session.expire_all() db_pool = self._get_db_pool(context.session, id) result = self._convert_db_to_type(db_pool, pool_types.PoolResponse) return pool_types.PoolRootResponse(pool=result)
def put(self, id, pool_): """Updates a pool on a load balancer.""" pool = pool_.pool context = pecan.request.context.get('octavia_context') db_pool = self._get_db_pool(context.session, id, show_deleted=False) project_id, provider = self._get_lb_project_id_provider( context.session, db_pool.load_balancer_id) self._auth_validate_action(context, project_id, constants.RBAC_PUT) if (pool.session_persistence and not pool.session_persistence.type and db_pool.session_persistence and db_pool.session_persistence.type): pool.session_persistence.type = db_pool.session_persistence.type self._validate_pool_PUT(pool, db_pool) # 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( context.session, lb_id=db_pool.load_balancer_id, listener_ids=self._get_affected_listener_ids(db_pool)) # Prepare the data for the driver data model pool_dict = pool.to_dict(render_unsets=False) pool_dict['id'] = id provider_pool_dict = ( driver_utils.pool_dict_to_provider_dict(pool_dict)) # Also prepare the baseline object data old_provider_pool = driver_utils.db_pool_to_provider_pool( db_pool) # Dispatch to the driver LOG.info("Sending update Pool %s to provider %s", id, driver.name) driver_utils.call_provider( driver.name, driver.pool_update, old_provider_pool, driver_dm.Pool.from_dict(provider_pool_dict)) # Update the database to reflect what the driver just accepted pool.provisioning_status = constants.PENDING_UPDATE db_pool_dict = pool.to_dict(render_unsets=False) self.repositories.update_pool_and_sp(lock_session, id, db_pool_dict) # Force SQL alchemy to query the DB, otherwise we get inconsistent # results context.session.expire_all() db_pool = self._get_db_pool(context.session, id) result = self._convert_db_to_type(db_pool, pool_types.PoolResponse) return pool_types.PoolRootResponse(pool=result)
def test_db_pool_to_provider_pool(self, mock_load_cert, mock_secret): pool_cert = data_models.TLSContainer(certificate='pool cert') mock_load_cert.return_value = {'tls_cert': pool_cert, 'sni_certs': None, 'client_ca_cert': None} mock_secret.side_effect = ['X509 POOL CA CERT FILE', 'X509 POOL CRL FILE'] provider_pool = utils.db_pool_to_provider_pool( self.sample_data.db_pool1) self.assertEqual(self.sample_data.provider_pool1, provider_pool)
def get_pools_on_lb(db_lb): """Get a list of the pools on a load balancer. :param db_lb: A load balancer database model object. :returns: A list of provider dict format pools. """ pool_dicts = [] for pool in db_lb.pools: prov_pool = provider_utils.db_pool_to_provider_pool(pool) pool_dicts.append(prov_pool.to_dict()) return pool_dicts
def test_db_pool_to_provider_pool(self, mock_load_cert, mock_secret): pool_cert = data_models.TLSContainer(certificate='pool cert') mock_load_cert.return_value = { 'tls_cert': pool_cert, 'sni_certs': None, 'client_ca_cert': None } mock_secret.side_effect = [ 'X509 POOL CA CERT FILE', 'X509 POOL CRL FILE' ] provider_pool = utils.db_pool_to_provider_pool( self.sample_data.db_pool1) # TODO(johnsom) Remove when versions and ciphers are implemented expect_prov_pool = copy.deepcopy(self.sample_data.provider_pool1) delattr(expect_prov_pool, lib_constants.TLS_VERSIONS) self.assertEqual(expect_prov_pool, provider_pool)
def _get_pool_dict(self, pool_id): if not pool_id: return db_pool = self.repositories.pool.get(db_apis.get_session(), id=pool_id) if not db_pool: return pool_obj = oct_utils.db_pool_to_provider_pool(db_pool) pool_dict = pool_obj.to_dict(recurse=True, render_unsets=True) pool_dict['id'] = pool_id # Get the load balancer object if pool_dict.get('loadbalancer_id'): # Generate a loadbalancer object pool_dict['loadbalancer'] = self._get_load_balancer_dict( pool_dict['loadbalancer_id']) if 'listener' not in pool_dict: self._get_listener_in_pool_dict(pool_dict) return pool_dict
def _get_pool_dict(self, pool_id, is_update): if not pool_id: return {} db_pool = self.repositories.pool.get(db_apis.get_session(), id=pool_id) if not db_pool: return {} pool_obj = oct_utils.db_pool_to_provider_pool(db_pool) pool_dict = pool_obj.to_dict(recurse=True, render_unsets=True) pool_dict['id'] = pool_id # Get the load balancer object if pool_dict.get('loadbalancer_id'): # Generate a loadbalancer object pool_dict['loadbalancer'] = self._get_load_balancer_dict( pool_dict['loadbalancer_id']) if 'listener' not in pool_dict: self._get_listener_in_pool_dict(pool_dict, is_update) return pool_dict
def post(self, pool_): """Creates a pool on a load balancer or listener. Note that this can optionally take a listener_id with which the pool should be associated as the listener's default_pool. If specified, the pool creation will fail if the listener specified already has a default_pool. """ # For some API requests the listener_id will be passed in the # pool_dict: pool = pool_.pool context = pecan.request.context.get('octavia_context') if pool.loadbalancer_id: pool.project_id, provider = self._get_lb_project_id_provider( context.session, pool.loadbalancer_id) elif pool.listener_id: listener = self.repositories.listener.get(context.session, id=pool.listener_id) pool.loadbalancer_id = listener.load_balancer_id pool.project_id, provider = self._get_lb_project_id_provider( context.session, pool.loadbalancer_id) else: msg = _("Must provide at least one of: " "loadbalancer_id, listener_id") raise exceptions.ValidationException(detail=msg) self._auth_validate_action(context, pool.project_id, constants.RBAC_POST) if pool.session_persistence: sp_dict = pool.session_persistence.to_dict(render_unsets=False) validate.check_session_persistence(sp_dict) # 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.Pool, pool.project_id): raise exceptions.QuotaException( resource=data_models.Pool._name()) listener_repo = self.repositories.listener pool_dict = db_prepare.create_pool( pool.to_dict(render_unsets=True)) listener_id = pool_dict.pop('listener_id', None) if listener_id: if listener_repo.has_default_pool(lock_session, listener_id): raise exceptions.DuplicatePoolEntry() self._test_lb_and_listener_statuses( lock_session, lb_id=pool_dict['load_balancer_id'], listener_ids=[listener_id] if listener_id else []) db_pool = self._validate_create_pool(lock_session, pool_dict, listener_id) # Prepare the data for the driver data model provider_pool = (driver_utils.db_pool_to_provider_pool(db_pool)) # Dispatch to the driver LOG.info("Sending create Pool %s to provider %s", db_pool.id, driver.name) driver_utils.call_provider(driver.name, driver.pool_create, provider_pool) lock_session.commit() except Exception: with excutils.save_and_reraise_exception(): lock_session.rollback() db_pool = self._get_db_pool(context.session, db_pool.id) result = self._convert_db_to_type(db_pool, pool_types.PoolResponse) return pool_types.PoolRootResponse(pool=result)
def put(self, id, pool_): """Updates a pool on a load balancer.""" pool = pool_.pool context = pecan.request.context.get('octavia_context') db_pool = self._get_db_pool(context.session, id, show_deleted=False) project_id, provider = self._get_lb_project_id_provider( context.session, db_pool.load_balancer_id) if (pool.session_persistence and not pool.session_persistence.type and db_pool.session_persistence and db_pool.session_persistence.type): pool.session_persistence.type = db_pool.session_persistence.type self._auth_validate_action(context, project_id, constants.RBAC_PUT) if db_pool.protocol == constants.PROTOCOL_UDP: self._validate_pool_request_for_udp(pool) else: if (pool.session_persistence and (pool.session_persistence.persistence_timeout or pool.session_persistence.persistence_granularity)): raise exceptions.ValidationException( detail=_("persistence_timeout and persistence_granularity " "is only for UDP protocol pools.")) if pool.session_persistence: sp_dict = pool.session_persistence.to_dict(render_unsets=False) validate.check_session_persistence(sp_dict) # 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( context.session, lb_id=db_pool.load_balancer_id, listener_ids=self._get_affected_listener_ids(db_pool)) # Prepare the data for the driver data model pool_dict = pool.to_dict(render_unsets=False) pool_dict['id'] = id provider_pool_dict = ( driver_utils.pool_dict_to_provider_dict(pool_dict)) # Also prepare the baseline object data old_provider_pool = driver_utils.db_pool_to_provider_pool(db_pool) # Dispatch to the driver LOG.info("Sending update Pool %s to provider %s", id, driver.name) driver_utils.call_provider( driver.name, driver.pool_update, old_provider_pool, driver_dm.Pool.from_dict(provider_pool_dict)) # Update the database to reflect what the driver just accepted pool.provisioning_status = constants.PENDING_UPDATE db_pool_dict = pool.to_dict(render_unsets=False) self.repositories.update_pool_and_sp(lock_session, id, db_pool_dict) # Force SQL alchemy to query the DB, otherwise we get inconsistent # results context.session.expire_all() db_pool = self._get_db_pool(context.session, id) result = self._convert_db_to_type(db_pool, pool_types.PoolResponse) return pool_types.PoolRootResponse(pool=result)
def test_db_pool_to_provider_pool_partial(self): test_db_pool = self.sample_data.db_pool1 test_db_pool.members = [self.sample_data.db_member1] provider_pool = utils.db_pool_to_provider_pool(test_db_pool) self.assertEqual(self.sample_data.provider_pool1, provider_pool)
def test_db_pool_to_provider_pool(self): provider_pool = utils.db_pool_to_provider_pool( self.sample_data.db_pool1) self.assertEqual(self.sample_data.provider_pool1, provider_pool)
def post(self, pool_): """Creates a pool on a load balancer or listener. Note that this can optionally take a listener_id with which the pool should be associated as the listener's default_pool. If specified, the pool creation will fail if the listener specified already has a default_pool. """ # For some API requests the listener_id will be passed in the # pool_dict: pool = pool_.pool context = pecan.request.context.get('octavia_context') if pool.protocol == constants.PROTOCOL_UDP: self._validate_pool_request_for_udp(pool) else: if (pool.session_persistence and ( pool.session_persistence.persistence_timeout or pool.session_persistence.persistence_granularity)): raise exceptions.ValidationException(detail=_( "persistence_timeout and persistence_granularity " "is only for UDP protocol pools.")) if pool.loadbalancer_id: pool.project_id, provider = self._get_lb_project_id_provider( context.session, pool.loadbalancer_id) elif pool.listener_id: listener = self.repositories.listener.get( context.session, id=pool.listener_id) pool.loadbalancer_id = listener.load_balancer_id pool.project_id, provider = self._get_lb_project_id_provider( context.session, pool.loadbalancer_id) else: msg = _("Must provide at least one of: " "loadbalancer_id, listener_id") raise exceptions.ValidationException(detail=msg) self._auth_validate_action(context, pool.project_id, constants.RBAC_POST) if pool.session_persistence: sp_dict = pool.session_persistence.to_dict(render_unsets=False) validate.check_session_persistence(sp_dict) # 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.Pool, pool.project_id): raise exceptions.QuotaException( resource=data_models.Pool._name()) listener_repo = self.repositories.listener pool_dict = db_prepare.create_pool( pool.to_dict(render_unsets=True)) listener_id = pool_dict.pop('listener_id', None) if listener_id: if listener_repo.has_default_pool(lock_session, listener_id): raise exceptions.DuplicatePoolEntry() self._test_lb_and_listener_statuses( lock_session, lb_id=pool_dict['load_balancer_id'], listener_ids=[listener_id] if listener_id else []) db_pool = self._validate_create_pool( lock_session, pool_dict, listener_id) # Prepare the data for the driver data model provider_pool = ( driver_utils.db_pool_to_provider_pool(db_pool)) # Dispatch to the driver LOG.info("Sending create Pool %s to provider %s", db_pool.id, driver.name) driver_utils.call_provider( driver.name, driver.pool_create, provider_pool) lock_session.commit() except Exception: with excutils.save_and_reraise_exception(): lock_session.rollback() db_pool = self._get_db_pool(context.session, db_pool.id) result = self._convert_db_to_type(db_pool, pool_types.PoolResponse) return pool_types.PoolRootResponse(pool=result)