def create(self, context, vip):
        """
        Create a VIP.
        """
        v = vip['vip']
        tenant_id = self._get_tenant_id_for_create(context, v)

        project = self._project_read(project_id=tenant_id)

        if v['pool_id']:
            try:
                pool = self._api.loadbalancer_pool_read(id=v['pool_id'])
            except NoIdError:
                raise loadbalancer.PoolNotFound(pool_id=v['pool_id'])
            project_id = pool.parent_uuid
            if str(uuid.UUID(tenant_id)) != project_id:
                raise NotAuthorized()
            protocol = pool.get_loadbalancer_pool_properties().get_protocol()
            if protocol != v['protocol']:
                raise loadbalancer.ProtocolMismatch(
                    vip_proto=v['protocol'], pool_proto=protocol)
            if pool.get_virtual_ip_back_refs():
                raise loadbalancer.VipExists(pool_id=v['pool_id'])
        else:
            pool = None

        obj_uuid = uuidutils.generate_uuid()
        name = self._get_resource_name('virtual-ip', project, v['name'], obj_uuid)
        id_perms = IdPermsType(enable=True,
                               description=v['description'])
        vip = VirtualIp(name, project, id_perms=id_perms,
                        display_name=v['name'])
        vip.uuid = obj_uuid

        if pool:
            vip.set_loadbalancer_pool(pool)

        vmi, vip_address = self._create_virtual_interface(project,
            obj_uuid, v['subnet_id'], v.get('address'))
        vip.set_virtual_machine_interface(vmi)

        props = self.make_properties(v)
        props.set_address(vip_address)
        vip.set_virtual_ip_properties(props)

        self._api.virtual_ip_create(vip)
        return self.make_dict(vip)
Ejemplo n.º 2
0
    def update_vip(self, context, id, vip):
        v = vip['vip']

        sess_persist = v.pop('session_persistence', None)
        with context.session.begin(subtransactions=True):
            vip_db = self._get_resource(context, Vip, id)

            self.assert_modification_allowed(vip_db)

            if sess_persist:
                self._update_vip_session_persistence(context, id, sess_persist)
            else:
                self._delete_session_persistence(context, id)

            if v:
                try:
                    # in case new pool already has a vip
                    # update will raise integrity error at first query
                    old_pool_id = vip_db['pool_id']
                    vip_db.update(v)
                    # If the pool_id is changed, we need to update
                    # the associated pools
                    if 'pool_id' in v:
                        new_pool = self._get_resource(context, Pool,
                                                      v['pool_id'])
                        self.assert_modification_allowed(new_pool)

                        # check that the pool matches the tenant_id
                        if new_pool['tenant_id'] != vip_db['tenant_id']:
                            raise q_exc.NotAuthorized()
                        # validate that the pool has same protocol
                        if new_pool['protocol'] != vip_db['protocol']:
                            raise loadbalancer.ProtocolMismatch(
                                vip_proto=vip_db['protocol'],
                                pool_proto=new_pool['protocol'])

                        if old_pool_id:
                            old_pool = self._get_resource(
                                context, Pool, old_pool_id)
                            old_pool['vip_id'] = None

                        new_pool['vip_id'] = vip_db['id']
                except exception.DBDuplicateEntry:
                    raise loadbalancer.VipExists(pool_id=v['pool_id'])

        return self._make_vip_dict(vip_db)
Ejemplo n.º 3
0
    def create_vip(self, context, vip):
        v = vip['vip']
        tenant_id = self._get_tenant_id_for_create(context, v)

        with context.session.begin(subtransactions=True):
            if v['pool_id']:
                pool = self._get_resource(context, Pool, v['pool_id'])
                # validate that the pool has same tenant
                if pool['tenant_id'] != tenant_id:
                    raise n_exc.NotAuthorized()
                # validate that the pool has same protocol
                if pool['protocol'] != v['protocol']:
                    raise loadbalancer.ProtocolMismatch(
                        vip_proto=v['protocol'], pool_proto=pool['protocol'])
                if pool['status'] == constants.PENDING_DELETE:
                    raise loadbalancer.StateInvalid(state=pool['status'],
                                                    id=pool['id'])
            vip_db = Vip(id=uuidutils.generate_uuid(),
                         tenant_id=tenant_id,
                         name=v['name'],
                         description=v['description'],
                         port_id=None,
                         protocol_port=v['protocol_port'],
                         protocol=v['protocol'],
                         pool_id=v['pool_id'],
                         connection_limit=v['connection_limit'],
                         admin_state_up=v['admin_state_up'],
                         status=constants.PENDING_CREATE)

            session_info = v['session_persistence']

            if session_info:
                s_p = self._create_session_persistence_db(
                    session_info, vip_db['id'])
                vip_db.session_persistence = s_p

            try:
                context.session.add(vip_db)
                context.session.flush()
            except exception.DBDuplicateEntry:
                raise loadbalancer.VipExists(pool_id=v['pool_id'])
        if cfg.CONF.lbaas_vip_create_port:
            try:
                # create a port to reserve address for IPAM
                # do it outside the transaction to avoid rpc calls
                self._create_port_for_vip(context, vip_db, v['subnet_id'],
                                          v.get('address'))
            except Exception:
                # catch any kind of exceptions
                with excutils.save_and_reraise_exception():
                    context.session.delete(vip_db)
                    context.session.flush()
        else:
            try:
                if v.get('address') == attributes.ATTR_NOT_SPECIFIED:
                    raise loadbalancer.VipAddressNotAssigned()

                filters = {
                    'fixed_ips': {
                        'subnet_id': [v['subnet_id']],
                        'ip_address': [v.get('address')]
                    }
                }
                vip_ports = self._core_plugin.get_ports(context,
                                                        filters=filters)
                if not vip_ports:
                    raise loadbalancer.VipPortNotFound(
                        address=v.get('address'), subnet_id=v['subnet_id'])
                vip_port = vip_ports[0]

                filters = {
                    'port_id': [vip_port['id']],
                    'protocol_port': [v['protocol_port']]
                }
                vips = self.get_vips(context, filters=filters)
                if vips:
                    raise loadbalancer.VipProtocolPortInUse(
                        address=v.get('address'),
                        protocol_port=v['protocol_port'])
                vip_db.port_id = vip_port['id']
                # explicitly sync session with db
                context.session.flush()
            except Exception:
                # catch any kind of exceptions
                with excutils.save_and_reraise_exception():
                    context.session.delete(vip_db)
                    context.session.flush()

        if v['pool_id']:
            # fetching pool again
            pool = self._get_resource(context, Pool, v['pool_id'])
            # (NOTE): we rely on the fact that pool didn't change between
            # above block and here
            vip_db['pool_id'] = v['pool_id']
            pool['vip_id'] = vip_db['id']
            # explicitly flush changes as we're outside any transaction
            context.session.flush()

        return self._make_vip_dict(vip_db)
Ejemplo n.º 4
0
    def create_vip(self, context, vip):
        v = vip['vip']
        tenant_id = self._get_tenant_id_for_create(context, v)

        with context.session.begin(subtransactions=True):
            if v['pool_id']:
                pool = self._get_resource(context, Pool, v['pool_id'])
                # validate that the pool has same tenant
                if pool['tenant_id'] != tenant_id:
                    raise n_exc.NotAuthorized()
                # validate that the pool has same protocol
                if pool['protocol'] != v['protocol']:
                    raise loadbalancer.ProtocolMismatch(
                        vip_proto=v['protocol'], pool_proto=pool['protocol'])
                if pool['status'] == constants.PENDING_DELETE:
                    raise loadbalancer.StateInvalid(state=pool['status'],
                                                    id=pool['id'])
            vip_db = Vip(id=uuidutils.generate_uuid(),
                         tenant_id=tenant_id,
                         name=v['name'],
                         description=v['description'],
                         port_id=None,
                         protocol_port=v['protocol_port'],
                         protocol=v['protocol'],
                         pool_id=v['pool_id'],
                         connection_limit=v['connection_limit'],
                         admin_state_up=v['admin_state_up'],
                         status=constants.PENDING_CREATE)

            session_info = v['session_persistence']

            if session_info:
                s_p = self._create_session_persistence_db(
                    session_info, vip_db['id'])
                vip_db.session_persistence = s_p

            try:
                context.session.add(vip_db)
                context.session.flush()
            except exception.DBDuplicateEntry:
                raise loadbalancer.VipExists(pool_id=v['pool_id'])

        try:
            # create a port to reserve address for IPAM
            # do it outside the transaction to avoid rpc calls
            self._create_port_for_vip(context, vip_db, v['subnet_id'],
                                      v.get('address'))
        except Exception:
            # catch any kind of exceptions
            with excutils.save_and_reraise_exception():
                context.session.delete(vip_db)
                context.session.flush()

        if v['pool_id']:
            # fetching pool again
            pool = self._get_resource(context, Pool, v['pool_id'])
            # (NOTE): we rely on the fact that pool didn't change between
            # above block and here
            vip_db['pool_id'] = v['pool_id']
            pool['vip_id'] = vip_db['id']
            # explicitly flush changes as we're outside any transaction
            context.session.flush()

        return self._make_vip_dict(vip_db)