예제 #1
0
    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)
예제 #2
0
 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)
예제 #3
0
 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)
예제 #4
0
 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
예제 #5
0
 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
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
    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)
예제 #9
0
    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)