def create_pool_member(self, context, member, pool_id): subnet_db = self._core_plugin.get_subnet(context, member['subnet_id']) try: with context.session.begin(subtransactions=True): pool_dbs = self._get_resource(context, models.PoolV2, pool_id) if pool_dbs.subnet_id: if pool_dbs.subnet_id!=subnet_db['id']: raise loadbalancerv2.PoolMemberSubnetIDMismatch( pool_subnet_id = pool_dbs.subnet_id, member_subnet_id = subnet_db['id']) else: if pool_dbs.network_id!=subnet_db['network_id']: raise loadbalancerv2.PoolMemberNetworkIDMismatch( pool_network_id = pool_dbs.network_id, member_network_id = subnet_db['network_id']) if not self._resource_exists(context, models.PoolV2, pool_id): raise loadbalancerv2.EntityNotFound( name=models.PoolV2.NAME, id=pool_id) self._load_id_and_tenant_id(context, member) member['pool_id'] = pool_id member['status'] = constants.PENDING_CREATE member_db = models.MemberV2(**member) context.session.add(member_db) except exception.DBDuplicateEntry: raise loadbalancerv2.MemberExists(address=member['address'], port=member['protocol_port'], pool=pool_id) return data_models.Member.from_sqlalchemy_model(member_db)
def create_l7policy_rule(self, context, rule, l7policy_id): with context.session.begin(subtransactions=True): if not self._resource_exists(context, models.L7Policy, l7policy_id): raise loadbalancerv2.EntityNotFound( name=models.L7Policy.NAME, id=l7policy_id) self._load_id_and_tenant_id(context, rule) rule['l7policy_id'] = l7policy_id rule['status'] = constants.PENDING_CREATE rule_db = models.L7Rule(**rule) context.session.add(rule_db) return data_models.L7Rule.from_sqlalchemy_model(rule_db)
def _delete_loadbalancer_stats(self, context, loadbalancer_id): # This is internal method to delete pool statistics. It won't # be exposed to API with context.session.begin(subtransactions=True): stats_qry = context.session.query(models.LoadBalancerStatistics) try: stats = stats_qry.filter_by( loadbalancer_id=loadbalancer_id).one() except exc.NoResultFound: raise loadbalancerv2.EntityNotFound( name=models.LoadBalancerStatistics.NAME, id=loadbalancer_id) context.session.delete(stats)
def update_status(self, context, model, id, status): LOG.debug(_("update_status for_%(model)s id %(id)s %(status)s"), {'model':model, 'id':id, 'status':status } ) with context.session.begin(subtransactions=True): if issubclass(model, models.LoadBalancer): try: model_db = (self._model_query(context, model). filter(model.id == id). options(orm.noload('vip_port')). one()) except exc.NoResultFound: raise loadbalancerv2.EntityNotFound( name=models.LoadBalancer.NAME, id=id) else: model_db = self._get_resource(context, model, id) if model_db.status != status: model_db.status = status
def _get_resource(self, context, model, id, for_update=False): resource = None try: if for_update: query = self._model_query(context, model).filter( model.id == id).with_lockmode('update') resource = query.one() else: resource = self._get_by_id(context, model, id) except exc.NoResultFound: with excutils.save_and_reraise_exception(reraise=False) as ctx: if issubclass(model, (models.LoadBalancer, models.Listener, models.PoolV2, models.MemberV2, models.HealthMonitorV2, models.LoadBalancerStatistics, models.SessionPersistenceV2, models.L7Policy, models.L7Rule)): raise loadbalancerv2.EntityNotFound(name=model.NAME, id=id) ctx.reraise = True return resource
def update_l7policy(self, context, id, l7policy): l7policy['action'] = l7policy.get('action',attributes.ATTR_NOT_SPECIFIED) if l7policy['action'] == attributes.ATTR_NOT_SPECIFIED: l7policy_db = self._get_resource(context, models.L7Policy, id) l7policy['action'] = l7policy_db.action l7policy['redirect_pool_id'] = l7policy.get('redirect_pool_id',attributes.ATTR_NOT_SPECIFIED) l7policy['redirect_url'] = l7policy.get('redirect_url',attributes.ATTR_NOT_SPECIFIED) l7policy['redirect_url_code'] = l7policy.get('redirect_url_code',attributes.ATTR_NOT_SPECIFIED) l7policy['redirect_url_drop_query'] = l7policy.get('redirect_url_drop_query',attributes.ATTR_NOT_SPECIFIED) if l7policy['redirect_pool_id'] == attributes.ATTR_NOT_SPECIFIED: l7policy['redirect_pool_id'] = None if l7policy['redirect_url'] == attributes.ATTR_NOT_SPECIFIED: l7policy['redirect_url'] = None if l7policy['redirect_url_code'] == attributes.ATTR_NOT_SPECIFIED: l7policy['redirect_url_code'] = None if l7policy['redirect_url_drop_query'] == attributes.ATTR_NOT_SPECIFIED: l7policy['redirect_url_drop_query'] = None if (l7policy['action'] != lb_const.L7_POLICY_ACTION_REDIRECT_TO_URL and (l7policy['redirect_url'] is not None or l7policy['redirect_url_code'] is not None or l7policy['redirect_url_drop_query'] is not None)): LOG.debug('Not L7_POLICY_ACTION_REDIRECT_TO_URL L7PolicyActionNotCorresponding') raise loadbalancerv2.L7PolicyActionNotCorresponding() if (l7policy['action'] == lb_const.L7_POLICY_ACTION_REDIRECT_TO_URL and (l7policy['redirect_url'] is None or (l7policy['redirect_url_code'] is None) or (l7policy['redirect_url_drop_query'] is None) )): LOG.debug('L7_POLICY_ACTION_REDIRECT_TO_URL L7PolicyRedirectUrlMissing') raise loadbalancerv2.L7PolicyRedirectUrlMissing() if (l7policy['action'] != lb_const.L7_POLICY_ACTION_REDIRECT_TO_POOL and l7policy['redirect_pool_id'] is not None): LOG.debug('not L7_POLICY_ACTION_REDIRECT_TO_POOL L7PolicyActionNotCorresponding') raise loadbalancerv2.L7PolicyActionNotCorresponding() if l7policy['action'] == lb_const.L7_POLICY_ACTION_REDIRECT_TO_POOL: if not l7policy['redirect_pool_id']: raise loadbalancerv2.L7PolicyRedirectPoolIdMissing() if not self._resource_exists( context, models.PoolV2, l7policy['redirect_pool_id']): raise loadbalancerv2.EntityNotFound( name=models.PoolV2.NAME, id=l7policy['redirect_pool_id']) l7policy_db = self._get_resource(context, models.L7Policy, id) pool_db = self._get_by_id(context, models.PoolV2, l7policy['redirect_pool_id']) if l7policy_db.listener.loadbalancer.vip_network_id!=pool_db.network_id: raise loadbalancerv2.LoadBalancerPoolNetworkMismatch() if l7policy_db.listener.loadbalancer.vip_subnet_id!=pool_db.subnet_id: raise loadbalancerv2.LoadBalancerPoolSubnetMismatch() if pool_db.listener: raise loadbalancerv2.EntityInUse( entity_using=models.Listener.NAME, id=pool_db.listener.id, entity_in_use=models.PoolV2.NAME) if pool_db.l7policy: if pool_db.l7policy.id != id: raise loadbalancerv2.EntityInUse( entity_using=models.L7Policy.NAME, id=pool_db.l7policy.id, entity_in_use=models.PoolV2.NAME) if pool_db.protocol != lb_const.PROTOCOL_HTTP: raise loadbalancerv2.PoolProtocolMismatchForL7Policy() if (l7policy['action']== attributes.ATTR_NOT_SPECIFIED): l7policy.pop('action') l7policy.pop('redirect_pool_id') l7policy.pop('redirect_url') with context.session.begin(subtransactions=True): l7policy_db = self._get_resource(context, models.L7Policy, id) l7polcicy_position = l7policy.get('position',sys.maxint) if l7polcicy_position == sys.maxint: l7policy['position'] = l7policy_db.position if l7polcicy_position < 0: l7policy['position'] = sys.maxint listener_id = l7policy_db.listener_id listener_db = self._get_resource( context, models.Listener, listener_id) l7policy_db = listener_db.l7_policies.pop(l7policy_db.position) l7policy_db.update(l7policy) listener_db.l7_policies.insert(l7policy['position'], l7policy_db) context.session.refresh(l7policy_db) return data_models.L7Policy.from_sqlalchemy_model(l7policy_db)
def create_l7policy(self, context, l7policy): if l7policy['redirect_pool_id'] == attributes.ATTR_NOT_SPECIFIED: l7policy['redirect_pool_id'] = None if l7policy['redirect_url'] == attributes.ATTR_NOT_SPECIFIED: l7policy['redirect_url'] = None if l7policy['redirect_url_code'] == attributes.ATTR_NOT_SPECIFIED: l7policy['redirect_url_code'] = None if l7policy['redirect_url_drop_query'] == attributes.ATTR_NOT_SPECIFIED: l7policy['redirect_url_drop_query'] = None if (l7policy['action'] != lb_const.L7_POLICY_ACTION_REDIRECT_TO_POOL and l7policy['redirect_pool_id'] is not None ): raise loadbalancerv2.L7PolicyActionNotCorresponding() if (l7policy['action'] != lb_const.L7_POLICY_ACTION_REDIRECT_TO_URL and (l7policy['redirect_url'] is not None or l7policy['redirect_url_code'] is not None or l7policy['redirect_url_drop_query'] is not None)): raise loadbalancerv2.L7PolicyActionNotCorresponding() if (l7policy['action'] == lb_const.L7_POLICY_ACTION_REDIRECT_TO_URL and ( (l7policy['redirect_url'] is None) or (l7policy['redirect_url_code'] is None) or (l7policy['redirect_url_drop_query'] is None))): raise loadbalancerv2.L7PolicyRedirectUrlMissing() if l7policy['action'] == lb_const.L7_POLICY_ACTION_REDIRECT_TO_POOL: if not l7policy['redirect_pool_id']: raise loadbalancerv2.L7PolicyRedirectPoolIdMissing() if not self._resource_exists( context, models.PoolV2, l7policy['redirect_pool_id']): raise loadbalancerv2.EntityNotFound( name=models.PoolV2.NAME, id=l7policy['redirect_pool_id']) pool_db = self._get_by_id(context, models.PoolV2, l7policy['redirect_pool_id']) if pool_db.listener: raise loadbalancerv2.EntityInUse( entity_using=models.Listener.NAME, id=pool_db.listener.id, entity_in_use=models.PoolV2.NAME) if pool_db.l7policy: raise loadbalancerv2.EntityInUse( entity_using=models.L7Policy.NAME, id=pool_db.l7policy.id, entity_in_use=models.PoolV2.NAME) if pool_db.protocol != lb_const.PROTOCOL_HTTP: raise loadbalancerv2.PoolProtocolMismatchForL7Policy() with context.session.begin(subtransactions=True): listener_id = l7policy.get('listener_id') listener_db = self._get_resource( context, models.Listener, listener_id) if not listener_db: raise loadbalancerv2.EntityNotFound( name=models.Listener.NAME, id=listener_id) #Not allow user config l7policy for TCP if listener_db.protocol != lb_const.PROTOCOL_HTTP: raise loadbalancerv2.ListenerProtocolMismatchForL7Policy() if l7policy['action'] == lb_const.L7_POLICY_ACTION_REDIRECT_TO_POOL: if listener_db.loadbalancer.vip_network_id!=pool_db.network_id: raise loadbalancerv2.LoadBalancerPoolNetworkMismatch() if listener_db.loadbalancer.vip_subnet_id!=pool_db.subnet_id: raise loadbalancerv2.LoadBalancerPoolSubnetMismatch() self._load_id_and_tenant_id(context, l7policy) l7policy['status'] = constants.PENDING_CREATE if l7policy['position'] < 0: l7policy['position'] = sys.maxint l7policy['created_at'] = timeutils.utcnow() l7policy_db = models.L7Policy(**l7policy) listener_db.l7_policies.insert(l7policy['position'], l7policy_db) return data_models.L7Policy.from_sqlalchemy_model(l7policy_db)
def update_listener(self, context, id, listener): with contextlib.nested(lockutils.lock('db-access'), context.session.begin(subtransactions=True)): listener_db = self._get_resource(context, models.Listener, id) admin_enable = listener.get('admin_state_up') if (admin_enable is not None and admin_enable==False and listener_db.admin_state_up==True): filters = {'loadbalancer_id': [listener_db.loadbalancer_id], 'admin_state_up': [True]} up_listeners = self._get_resources(context, models.Listener, filters=filters) if len(up_listeners)<=1 : raise loadbalancerv2.OneListenerAdminStateUpAtLeast( lb_id=listener_db.loadbalancer_id) pool_id = listener.get('default_pool_id') lb_id = listener.get('loadbalancer_id') # Do not allow changing loadbalancer ids if listener_db.loadbalancer_id and lb_id: raise loadbalancerv2.AttributeIDImmutable( attribute='loadbalancer_id') # Do not allow changing pool ids #if listener_db.default_pool_id and pool_id: # raise loadbalancerv2.AttributeIDImmutable( # attribute='default_pool_id') if lb_id: if not self._resource_exists(context, models.LoadBalancer, lb_id): raise loadbalancerv2.EntityNotFound( name=models.LoadBalancer.NAME, id=lb_id) loadbalancer_db = listener_db.loadbalancer if pool_id: if not self._resource_exists(context, models.PoolV2, pool_id): raise loadbalancerv2.EntityNotFound( name=models.PoolV2.NAME, id=pool_id) pool = self._get_resource(context, models.PoolV2, pool_id) if pool.subnet_id: if loadbalancer_db.vip_subnet_id != pool.subnet_id: raise loadbalancerv2.LoadBalancerPoolSubnetMismatch() else: if loadbalancer_db.vip_subnet_id: raise loadbalancerv2.LoadBalancerPoolSubnetMismatch() elif loadbalancer_db.vip_network_id!=pool.network_id: raise loadbalancerv2.LoadBalancerPoolNetworkMismatch() protocol = listener.get('protocol') or listener_db.protocol if pool.protocol != protocol: raise loadbalancerv2.ListenerPoolProtocolMismatch( listener_proto=protocol, pool_proto=pool.protocol) filters = {'default_pool_id': [pool_id]} listenerpools = self._get_resources(context, models.Listener, filters=filters) if listenerpools: if listenerpools[0].id!=id: raise loadbalancerv2.EntityInUse( entity_using=models.Listener.NAME, id=listenerpools[0].id, entity_in_use=models.PoolV2.NAME) filters = {'redirect_pool_id': [pool_id]} l7policypools = self._get_resources(context, models.L7Policy, filters=filters) if l7policypools: raise loadbalancerv2.EntityInUse( entity_using=models.L7Policy.NAME, id=l7policypools[0].id, entity_in_use=models.PoolV2.NAME) if (listener_db.default_pool_id and listener_db.default_pool_id != pool_id): self.update_status(context, models.PoolV2, listener_db.default_pool_id, constants.DEFERRED) else: #Only if the default_pool_id exists and set to None if 'default_pool_id' in listener: listener['default_pool_id'] = None listener['default_pool'] = None listener_db.update(listener) context.session.refresh(listener_db) return data_models.Listener.from_sqlalchemy_model(listener_db)
def create_listener(self, context, listener): try: with contextlib.nested(lockutils.lock('db-access'), context.session.begin(subtransactions=True)): self._load_id_and_tenant_id(context, listener) listener['status'] = constants.PENDING_CREATE # Check for unspecified loadbalancer_id and listener_id and # set to None for id in ['loadbalancer_id', 'default_pool_id']: if listener.get(id) == attributes.ATTR_NOT_SPECIFIED: listener[id] = None pool_id = listener.get('default_pool_id') lb_id = listener.get('loadbalancer_id') if lb_id: if not self._resource_exists(context, models.LoadBalancer, lb_id): raise loadbalancerv2.EntityNotFound( name=models.LoadBalancer.NAME, id=lb_id) loadbalancer_db = self._get_resource(context, models.LoadBalancer, lb_id) if pool_id: if not self._resource_exists(context, models.PoolV2, pool_id): raise loadbalancerv2.EntityNotFound( name=models.PoolV2.NAME, id=pool_id) pool = self._get_resource(context, models.PoolV2, pool_id) if pool.subnet_id: if loadbalancer_db.vip_subnet_id != pool.subnet_id: raise loadbalancerv2.LoadBalancerPoolSubnetMismatch() else: if loadbalancer_db.subnet_id: raise loadbalancerv2.LoadBalancerPoolSubnetMismatch() elif loadbalancer_db.network_id!=pool.network_id: raise loadbalancerv2.LoadBalancerPoolNetworkMismatch() if ((pool.protocol, listener.get('protocol')) not in lb_const.LISTENER_POOL_COMPATIBLE_PROTOCOLS): raise loadbalancerv2.ListenerPoolProtocolMismatch( listener_proto=listener['protocol'], pool_proto=pool.protocol) filters = {'default_pool_id': [pool_id]} listenerpools = self._get_resources(context, models.Listener, filters=filters) if listenerpools: raise loadbalancerv2.EntityInUse( entity_using=models.Listener.NAME, id=listenerpools[0].id, entity_in_use=models.PoolV2.NAME) filters = {'redirect_pool_id': [pool_id]} l7policypools = self._get_resources(context, models.L7Policy, filters=filters) if l7policypools: raise loadbalancerv2.EntityInUse( entity_using=models.L7Policy.NAME, id=l7policypools[0].id, entity_in_use=models.PoolV2.NAME) listener['created_at'] = timeutils.utcnow() listener_db_entry = models.Listener(**listener) context.session.add(listener_db_entry) except exception.DBDuplicateEntry: raise loadbalancerv2.LoadBalancerListenerProtocolPortExists( lb_id=listener['loadbalancer_id'], protocol_port=listener['protocol_port']) return data_models.Listener.from_sqlalchemy_model(listener_db_entry)