Exemple #1
0
 def status_database(self, database_id, **kwargs):
     session = endpoint_session(readonly=True)
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id == database_id)
     _database = query.one()
     return self._status_database(_database, **kwargs)
Exemple #2
0
 def ready_relation(self, database_id, **kwargs):
     slave_id = kwargs.pop('slave')
     force = kwargs.pop('force')
     session = endpoint_session()
     query = model_query(session,
                         GopSalveRelation,
                         filter=and_(
                             GopSalveRelation.master_id == database_id,
                             GopSalveRelation.slave_id == slave_id))
     with session.begin(subtransactions=True):
         relation = query.one_or_none()
         if not relation:
             raise InvalidArgument(
                 'Can not find relation of master %d slave %d' %
                 (database_id, slave_id))
         if relation.ready:
             return None
         if force:
             relation.ready = True
             return None
         query = model_query(session,
                             GopDatabase,
                             filter=GopDatabase.database_id.in_(
                                 [database_id, slave_id]))
         query = query.options(
             joinedload(GopDatabase.schemas, innerjoin=False))
         for database in query:
             if database.database_id == database_id:
                 master = database
             elif database.database_id == slave_id:
                 slave = database
         return self._ready_relation(session, master, slave, relation,
                                     **kwargs)
Exemple #3
0
def _address(database_ids):
    IMPLMAP = {}
    NOT_CACHED = []
    for database_id in database_ids:
        if database_id in MANAGERCACHE:
            try:
                IMPLMAP[MANAGERCACHE[database_id]].append(database_id)
            except KeyError:
                IMPLMAP[MANAGERCACHE[database_id]] = [
                    database_id,
                ]
        else:
            NOT_CACHED.append(database_id)
    if NOT_CACHED:
        session = endpoint_session(readonly=True)
        query = model_query(session,
                            (GopDatabase.database_id, GopDatabase.impl),
                            filter=GopDatabase.database_id.in_(NOT_CACHED))
        for r in query:
            dbmanager = utils.impl_cls('wsgi', r[1])
            try:
                IMPLMAP[dbmanager].append(r[0])
            except KeyError:
                IMPLMAP[dbmanager] = [
                    r[0],
                ]
        session.close()
    maps = dict()
    for dbmanager in IMPLMAP:
        maps.update(dbmanager.address(IMPLMAP[dbmanager]))
    return maps
Exemple #4
0
 def quote(self, req, quote_id, body=None):
     """show schema quote info"""
     body = body or {}
     session = endpoint_session(readonly=True)
     query = model_query(session,
                         SchemaQuote,
                         filter=SchemaQuote.quote_id == quote_id)
     schema_quote = query.one()
     data = dict(
         quote_id=quote_id,
         schema_id=schema_quote.schema_id,
         qdatabase_id=schema_quote.qdatabase_id,
         entity=schema_quote.entity,
         endpoint=schema_quote.endpoint,
     )
     if body.get('schema', False):
         schema = schema_quote.schema
         data.setdefault(
             'schema',
             dict(schema=schema.schema,
                  character_set=schema.character_set,
                  collation_type=schema.collation_type))
     if body.get('database', False):
         database = schema_quote.database
         data.setdefault(
             'database',
             dict(impl=database.impl,
                  reflection_id=database.reflection_id,
                  slave=database.slave,
                  dbtype=database.dbtype,
                  dbversion=database.dbversion))
     return resultutils.results(result='get quote success', data=[
         data,
     ])
Exemple #5
0
    def index(self, req, database_id, body=None):
        body = body or {}
        database_id = int(database_id)
        order = body.pop('order', None)
        desc = body.pop('desc', False)
        page_num = int(body.pop('page_num', 0))

        session = endpoint_session(readonly=True)
        results = resultutils.bulk_results(
            session,
            model=GopSchema,
            columns=[
                GopSchema.schema_id,
                GopSchema.schema,
                GopSchema.database_id,
                GopSchema.schema,
                GopSchema.character_set,
                GopSchema.collation_type,
            ],
            counter=GopSchema.schema_id,
            order=order,
            desc=desc,
            filter=GopSchema.database_id == database_id,
            page_num=page_num)
        return results
Exemple #6
0
 def create_database(self, user, passwd, dbtype, dbversion, affinity,
                     **kwargs):
     """create new database intance"""
     session = endpoint_session()
     with session.begin():
         bond = kwargs.pop('bond', None)
         if bond:
             query = model_query(session,
                                 GopDatabase,
                                 filter=GopDatabase.database_id == bond)
             bond = query.one_or_none()
             if not bond:
                 raise InvalidArgument(
                     'Target slave databse can not be found, can not bond to slave databases'
                 )
             if not bond.slave:
                 raise InvalidArgument(
                     'Target database is not salve database')
             if bond.status != common.OK:
                 raise InvalidArgument('Targe slave database is not active')
             count = model_count_with_key(
                 session,
                 GopSalveRelation,
                 filter=GopSalveRelation.slave_id == bond.database_id)
             if count >= bond.slave:
                 raise InvalidArgument('Target slave database is full')
         else:
             bond = None
         _database = GopDatabase(user=user,
                                 passwd=passwd,
                                 slave=kwargs.pop('slave'),
                                 dbtype=dbtype,
                                 dbversion=dbversion,
                                 affinity=affinity,
                                 desc=kwargs.pop('desc', None))
         _result = dict(dbversion=_database.dbversion,
                        slave=_database.slave,
                        dbtype=_database.dbtype)
         with self._create_database(session, _database, bond,
                                    **kwargs) as address:
             host = address[0]
             port = address[1]
             _result.setdefault('host', host)
             _result.setdefault('port', port)
             _result.setdefault('affinity', affinity)
             session.add(_database)
             session.flush()
             if bond:
                 LOG.info('Add GopSalveRelation for database')
                 relation = GopSalveRelation(
                     master_id=_database.database_id,
                     slave_id=bond.database_id)
                 session.add(relation)
                 session.flush()
     self._esure_create(_database, **kwargs)
     _result.setdefault('database_id', _database.database_id)
     return _result
Exemple #7
0
 def start_database(self, database_id, **kwargs):
     session = endpoint_session(readonly=True)
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id == database_id)
     _database = query.one()
     if _database.status != common.OK:
         raise exceptions.AcceptableDbError('Database is not OK now')
     return self._start_database(_database, **kwargs)
Exemple #8
0
 def address(self, databases):
     session = endpoint_session(readonly=True)
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id.in_(databases))
     databases = query.all()
     maps = dict()
     for database in databases:
         maps[database.reflection_id] = database.database_id
     return self._address(session, maps)
Exemple #9
0
 def slave_database(self, database_id, **kwargs):
     slave_id = kwargs.pop('slave')
     file = kwargs.get('file')
     position = kwargs.get('position')
     master = None
     slave = None
     session = endpoint_session()
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id.in_(
                             [database_id, slave_id]))
     query = query.options(joinedload(GopDatabase.slaves, innerjoin=False))
     with session.begin(subtransactions=True):
         for database in query:
             if database.database_id == database_id:
                 master = database
             elif database.database_id == slave_id:
                 slave = database
         # 校验主从
         if slave is None or slave.slave <= 0:
             raise InvalidArgument(
                 'slave database with id %d can not be found' % slave_id)
         if slave.status != common.OK:
             raise InvalidArgument('Slave database is not active')
         if master is None or master.slave > 0:
             raise InvalidArgument(
                 'Master database with id %d can not be found' %
                 database_id)
         if master.impl != slave.impl or master.dbtype != slave.dbtype:
             raise InvalidArgument(
                 'Master and slave not the same type or impl')
         schemas = [schema.schema for schema in master.schemas]
         # master中有schemas
         if schemas:
             if not file or not position:
                 raise InvalidArgument(
                     'Can not bond slave without file and position')
         for _relation in master.slaves:
             # 找到绑定关系
             if _relation.slave_id == slave_id:
                 raise InvalidArgument('Slave already in master slave list')
         # 没有绑定关系, 确认从库上限
         count = model_count_with_key(
             session,
             GopSalveRelation,
             filter=GopSalveRelation.slave_id == slave_id)
         if count >= slave.slave:
             raise InvalidArgument('Target slave database is full')
         kwargs['schemas'] = schemas
         return self._slave_database(session, master, slave, **kwargs)
Exemple #10
0
    def show_schema(self, database_id, schema, **kwargs):
        """show schema info"""
        session = endpoint_session()
        query = model_query(session,
                            GopSchema,
                            filter=and_(GopSchema.database_id == database_id,
                                        GopSchema.schema == schema))
        secret = kwargs.pop('secret', False)
        show_quotes = kwargs.pop('quotes', False)
        if show_quotes:
            query = query.options(joinedload(GopSchema.quotes,
                                             innerjoin=False))
        _schema = query.one_or_none()
        if not _schema:
            raise exceptions.AcceptableSchemaError(
                'Schema not not be found in %d' % database_id)

        _database = _schema.database
        if _database.slave:
            raise exceptions.AcceptableDbError(
                'Database is slave, can not get schema')

        _result = dict(database_id=database_id,
                       impl=_database.impl,
                       dbtype=_database.dbtype,
                       dbversion=_database.dbversion,
                       schema=_schema.schema,
                       schema_id=_schema.schema_id,
                       desc=_schema.desc)

        if show_quotes:
            _result.setdefault('quotes', [
                dict(quote_id=_quote.quote_id, desc=_quote.desc)
                for _quote in _schema.quotes
            ])

        if secret:
            _result.update({
                'user': _schema.user,
                'passwd': _schema.passwd,
                'ro_user': _schema.ro_user,
                'ro_passwd': _schema.ro_passwd
            })
        with self._show_schema(session, _database, _schema,
                               **kwargs) as address:
            host = address[0]
            port = address[1]
            _result.setdefault('host', host)
            _result.setdefault('port', port)
        return _result
Exemple #11
0
def _impl(database_id):
    try:
        return MANAGERCACHE[database_id]
    except KeyError:
        session = endpoint_session(readonly=True)
        try:
            database = model_query(
                session, GopDatabase,
                GopDatabase.database_id == database_id).one()
            if database_id not in MANAGERCACHE:
                dbmanager = utils.impl_cls('wsgi', database.impl)
                MANAGERCACHE.setdefault(database_id, dbmanager)
            return MANAGERCACHE[database_id]
        finally:
            session.close()
Exemple #12
0
 def reflect_database(self, **kwargs):
     session = endpoint_session(readonly=True)
     _result = []
     with self._reflect_database(session, **kwargs) as filters:
         key = filters[0]
         _filter = filters[1]
         if _filter is None:
             return _result
         query = model_query(session, GopDatabase, filter=_filter)
         for _database in query:
             dbinfo = dict(database_id=_database.database_id,
                           dbtype=_database.dbtype,
                           slave=_database.slave)
             dbinfo.setdefault(key, _database.reflection_id)
             _result.append(dbinfo)
     return _result
Exemple #13
0
    def quotes(self, req, body=None):
        body = body or {}
        session = endpoint_session(readonly=True)
        endpoint = body.pop('endpoint')
        entitys = argutils.map_to_int(body.pop('entitys'))
        if len(entitys) > 5:
            raise InvalidArgument('This api can not get entitys more then 5')
        query = session.query(
            SchemaQuote.quote_id,
            SchemaQuote.schema_id,
            SchemaQuote.qdatabase_id,
            SchemaQuote.entity,
            SchemaQuote.endpoint,
            GopSchema.database_id,
            GopSchema.schema,
            GopSchema.user,
            GopSchema.passwd,
            GopSchema.ro_user,
            GopSchema.ro_passwd,
            GopSchema.character_set,
            GopSchema.collation_type,
        ).join(GopSchema, and_(GopSchema.schema_id == SchemaQuote.schema_id))
        query = query.filter(
            and_(SchemaQuote.endpoint == endpoint,
                 SchemaQuote.entity.in_(entitys)))
        quotes = []
        database_ids = set()
        for quote in query:
            database_ids.add(quote.qdatabase_id)
            quotes.append(
                dict(quote_id=quote.quote_id,
                     schema_id=quote.schema_id,
                     qdatabase_id=quote.qdatabase_id,
                     database_id=quote.database_id,
                     schema=quote.schema,
                     user=quote.user,
                     passwd=quote.passwd,
                     ro_user=quote.ro_user,
                     ro_passwd=quote.ro_passwd,
                     character_set=quote.character_set,
                     collation_type=quote.collation_type))
        # get all address
        alladdress = _address(database_ids)
        for quote in quotes:
            quote.update(alladdress[quote.get('qdatabase_id')])

        return resultutils.results(result='list quotes success', data=quotes)
Exemple #14
0
    def index(self, req, body=None):
        body = body or {}
        order = body.pop('order', None)
        desc = body.pop('desc', False)
        page_num = int(body.pop('page_num', 0))

        slaves = body.pop('slaves', False)
        # schemas = body.pop('schemas', False)
        # quotes = body.pop('quotes', False)
        impl = body.get('impl', None)
        session = endpoint_session(readonly=True)
        _filter = None
        if impl:
            _filter = GopDatabase.impl == impl

        columns = [
            GopDatabase.database_id, GopDatabase.slave, GopDatabase.impl,
            GopDatabase.dbtype, GopDatabase.dbversion,
            GopDatabase.reflection_id, GopDatabase.status,
            GopDatabase.affinity, GopDatabase.desc
        ]

        option = None
        if slaves:
            columns.append(GopDatabase.slaves)
            option = joinedload(GopDatabase.slaves, innerjoin=False)

        results = resultutils.bulk_results(session,
                                           model=GopDatabase,
                                           columns=columns,
                                           counter=GopDatabase.database_id,
                                           order=order,
                                           desc=desc,
                                           option=option,
                                           filter=_filter,
                                           page_num=page_num)
        for column in results['data']:

            slaves = column.get('slaves', [])
            column['slaves'] = []
            for slave in slaves:
                column['slaves'].append(
                    dict(slave_id=slave.slave_id,
                         master_id=column.get('database_id'),
                         readonly=slave.readonly,
                         ready=slave.ready))
        return results
Exemple #15
0
 def phpadmin(self, req, database_id, schema, body=None):
     body = body or {}
     slave = body.get('slave', True)
     name = body.get('name') or ('unkonwn %s' %
                                 'slave' if slave else 'master')
     session = endpoint_session(readonly=True)
     query = model_query(session,
                         GopDatabase,
                         filter=and_(GopDatabase.database_id == database_id,
                                     GopDatabase.slave == 0))
     query = query.options(joinedload(GopDatabase.schemas, innerjoin=False))
     _database = query.one()
     _schema = None
     for __schema in _database.schemas:
         if __schema.schema == schema:
             _schema = __schema
             break
     if not _schema:
         raise InvalidArgument('Schema %s not found' % schema)
     target = _database.database_id
     user = _schema.user
     passwd = _schema.passwd
     if slave:
         slaves = [
             _slave.slave_id for _slave in _database.slaves if _slave.ready
         ]
         if slaves:
             target = slaves[0]
         else:
             LOG.warning('Not slave database, use master database as slave')
         user = _schema.ro_user
         passwd = _schema.ro_passwd
     address = _address([
         target,
     ]).get(target)
     port = address.get('port')
     host = address.get('host')
     return cache_controller.create(req,
                                    body=dict(host=host,
                                              port=port,
                                              user=user,
                                              passwd=passwd,
                                              schema=schema,
                                              client=req.client_addr,
                                              name=name))
Exemple #16
0
 def unbond_database(self, database_id, **kwargs):
     master_id = kwargs.pop('master')
     force = kwargs.get('force')
     master = None
     slave = None
     relation = None
     session = endpoint_session()
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id.in_(
                             [database_id, master_id]))
     query = query.options(joinedload(GopDatabase.slaves, innerjoin=False))
     with session.begin(subtransactions=True):
         for database in query:
             if database.database_id == database_id:
                 slave = database
             elif database.database_id == master_id:
                 master = database
         # 校验主从
         if slave is None or slave.slave <= 0:
             raise InvalidArgument(
                 'slave database with id %d can not be found' % database_id)
         if slave.status != common.OK:
             raise InvalidArgument('Slave database is not active')
         if master is None or master.slave > 0:
             raise InvalidArgument(
                 'Master database with id %d can not be found' % master_id)
         if master.impl != slave.impl or master.dbtype != slave.dbtype:
             raise InvalidArgument(
                 'Master and slave not the same type or impl')
         for _relation in master.slaves:
             if _relation.slave_id == database_id:
                 # 找到绑定关系
                 relation = _relation
                 break
         if not relation:
             raise InvalidArgument(
                 'Target slave database no relation with %d' %
                 master.database_id)
         if master.schemas and not force:
             raise InvalidArgument(
                 'Schemas in master database, can not unbond without argv force'
             )
         return self._unbond_database(session, master, slave, relation,
                                      **kwargs)
Exemple #17
0
 def update(self, req, database_id, body=None):
     body = body or {}
     status = body.get('status', common.UNACTIVE)
     if status not in (common.UNACTIVE, common.OK):
         raise InvalidArgument('Status value error')
     database_id = int(database_id)
     session = endpoint_session()
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id == database_id)
     with session.begin():
         updata = {'status': status}
         if body.get('dbversion'):
             updata.setdefault('dbversion', body.get('dbversion'))
         count = query.update(updata)
         if not count:
             LOG.warning('Update not match, no database has been updated')
     return resultutils.results(result='Update %s database success' %
                                database_id)
Exemple #18
0
 def unquote(self, req, quote_id, body=None):
     """schema unquote"""
     body = body or {}
     session = endpoint_session()
     query = model_query(session,
                         SchemaQuote,
                         filter=SchemaQuote.quote_id == quote_id)
     with session.begin():
         schema_quote = query.one()
         query.delete()
     return resultutils.results(
         result='unquote from %s.%d success' % (
             schema_quote.qdatabase_id,
             schema_quote.schema_id,
         ),
         data=[
             dict(quote_id=schema_quote.quote_id,
                  schema_id=schema_quote.schema_id,
                  qdatabase_id=schema_quote.qdatabase_id,
                  entity=schema_quote.entity,
                  endpoint=schema_quote.endpoint)
         ])
Exemple #19
0
 def slaves_address(self, databases):
     """get slve database connect info"""
     databases = set(databases)
     session = endpoint_session(readonly=True)
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id.in_(databases))
     databases = query.all()
     slaves = set([
         slave.slave_id for database in databases
         for slave in database.slaves
     ])
     address_maps = self.address(slaves)
     results = {}
     for database in databases:
         results[database.database_id] = []
         for slave in database.slaves:
             results[database.database_id].append({
                 'database_id':
                 slave.slave_id,
                 'address':
                 address_maps[slave.slave_id]
             })
     return results
Exemple #20
0
 def select_database(self, **kwargs):
     dbtype = kwargs.pop('dbtype', 'mysql')
     filters = [
         GopDatabase.status == common.OK, GopDatabase.dbtype == dbtype
     ]
     affinitys = kwargs.get('affinitys')
     if affinitys:
         affinitys = argutils.map_with(affinitys, int)
         ors = []
         # 通过位运算匹配亲和性
         for affinity in affinitys:
             ors.append(GopDatabase.affinity.op('&')(affinity) > 0)
         if len(ors) > 1:
             filters.append(or_(*ors))
         else:
             filters.append(ors[0])
     session = endpoint_session(readonly=True)
     query = model_query(session, GopDatabase, filter=and_(*filters))
     query = query.options(joinedload(GopDatabase.schemas, innerjoin=False))
     results = self._select_database(session, query, dbtype, **kwargs)
     # 结果按照亲和性从小到大排序
     # 亲和性数值越大,匹配范围越广
     results.sort(key=lambda x: x['affinity'])
     return results
Exemple #21
0
 def delete_schema(self, database_id, schema, **kwargs):
     """delete schema intance on reflection_id"""
     unquotes = set(kwargs.get('unquotes', []))
     ignores = set(kwargs.get('ignores', []))
     force = kwargs.get('force', False)
     session = endpoint_session()
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id == database_id)
     query = query.options(joinedload(GopDatabase.schemas, innerjoin=False))
     with session.begin():
         _database = query.one()
         _result = dict(database_id=_database.database_id,
                        impl=_database.impl,
                        dbtype=_database.dbtype,
                        dbversion=_database.dbversion)
         if _database.slave:
             raise exceptions.AcceptableDbError(
                 'can not delete schema from slave database')
         squery = model_query(session,
                              GopSchema,
                              filter=and_(
                                  GopSchema.schema == schema,
                                  GopSchema.database_id == database_id))
         squery = squery.options(
             joinedload(GopSchema.quotes, innerjoin=False))
         _schema = squery.one()
         _result.setdefault('schema_id', _schema.schema_id)
         _slaves = [_slave.slave_id for _slave in _database.slaves]
         _slaves_q_query = model_query(
             session,
             SchemaQuote,
             filter=and_(SchemaQuote.schema_id == _schema.schema_id,
                         SchemaQuote.qdatabase_id.in_(_slaves)))
         quotes = {}
         # quote of slave
         slave_quotes = _slaves_q_query.all()
         for _quotes_list in (slave_quotes, _schema.quotes):
             if _quotes_list:
                 for _quote in _quotes_list:
                     quotes[_quote.quote_id] = _quote.desc
         # check quotes
         for quote_id, desc in quotes.items():
             if quote_id in unquotes:
                 quotes.pop(quote_id, None)
             if desc in ignores:
                 quotes.pop(quote_id, None)
         if quotes:
             if force:
                 for quote_id, desc in quotes.items():
                     LOG.warning('Quote %d: [%s] force delete' %
                                 (quote_id, desc))
             else:
                 raise exceptions.AcceptableSchemaError(
                     'Schema in quote, can not be delete')
         with self._delete_schema(session, _database, _schema,
                                  **kwargs) as address:
             host = address[0]
             port = address[1]
             _result.setdefault('host', host)
             _result.setdefault('port', port)
             _result.setdefault('schema', schema)
             squery.delete()
     return _result
Exemple #22
0
 def copy_schema(self, src_database_id, src_schema, dst_database_id,
                 dst_schema, auth, **kwargs):
     """create a schema"""
     auths = privilegeutils.mysql_privileges(auth)
     session = endpoint_session()
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id.in_(
                             [src_database_id, dst_database_id]))
     query = query.options(joinedload(GopDatabase.schemas, innerjoin=False))
     src_database, dst_database = None, None
     for _database in query.all():
         if _database.database_id == src_database_id:
             if _database.slave:
                 raise exceptions.AcceptableDbError(
                     'Source database is not master')
             if not _database.passwd:
                 raise exceptions.AcceptableDbError(
                     'Source database has no passwd, can not copy')
             schemas = [_schema.name for _schema in _database.schemas]
             if src_schema not in schemas:
                 raise exceptions.AcceptableSchemaError(
                     'Source schemas %s not exist' % src_schema)
             src_database = _database
         elif _database.database_id == dst_database_id:
             if _database.slave:
                 raise exceptions.AcceptableDbError(
                     'Destination database is not master')
             if not _database.passwd:
                 raise exceptions.AcceptableDbError(
                     'Destination database has no passwd, can not copy')
             schemas = [_schema.name for _schema in _database.schemas]
             if dst_schema in schemas:
                 raise exceptions.AcceptableSchemaError(
                     'Destination schemas %s alreday exist' % dst_schema)
             dst_database = _database
     if not src_database or not dst_database:
         raise
     _result = dict(database_id=dst_database.database_id,
                    impl=dst_database.impl,
                    dbtype=dst_database.dbtype,
                    dbversion=dst_database.dbversion)
     with session.begin():
         with self._copy_schema(session, src_database, src_schema,
                                dst_database, dst_schema, auths,
                                **kwargs) as options:
             character_set = options[0] or 'utf8'
             collation_type = options[1]
             gop_schema = GopSchema(schema=dst_schema,
                                    database_id=dst_database.database_id,
                                    user=auth.get('user'),
                                    passwd=auth.get('passwd'),
                                    ro_user=auth.get('ro_user'),
                                    ro_passwd=auth.get('ro_passwd'),
                                    source=auth.get('source'),
                                    character_set=character_set,
                                    collation=collation_type)
             session.add(gop_schema)
             session.flush()
             _result.setdefault('schema_id', gop_schema.schema_id)
             _result.setdefault('schema', gop_schema.schema)
     return _result
Exemple #23
0
 def create_schema(self, database_id, schema, auth, options, **kwargs):
     """create new schema intance on reflection_id"""
     auths = privilegeutils.mysql_privileges(auth)
     bond = kwargs.get('bond')
     affinity = kwargs.get('affinity', None)
     session = endpoint_session()
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id == database_id)
     query = query.options(joinedload(GopDatabase.schemas, innerjoin=False))
     quote_id = 0
     with session.begin():
         _database = query.one()
         _result = dict(database_id=database_id,
                        impl=_database.impl,
                        dbtype=_database.dbtype,
                        dbversion=_database.dbversion)
         if _database.slave:
             raise exceptions.AcceptableDbError(
                 'Database is slave, can not create schema')
         if _database.status != common.OK:
             raise exceptions.AcceptableDbError('Database is not OK now')
         if affinity is not None and (_database.affinity & affinity) == 0:
             raise exceptions.AcceptableDbError(
                 'Database affinity not match')
         schemas = [_schema.schema for _schema in _database.schemas]
         if schema in schemas:
             raise exceptions.AcceptableDbError('Duplicate schema name %s' %
                                                schema)
         options = options or {'character_set': 'utf8'}
         with self._create_schema(session, _database, schema, auths,
                                  options, **kwargs) as address:
             gop_schema = GopSchema(
                 schema=schema,
                 database_id=_database.database_id,
                 user=auth.get('user'),
                 passwd=auth.get('passwd'),
                 ro_user=auth.get('ro_user'),
                 ro_passwd=auth.get('ro_passwd'),
                 source=auth.get('source') or '%',
                 rosource=auth.get('rosource') or '%',
                 character_set=options.get('character_set'),
                 collation_type=options.get('collation_type'))
             session.add(gop_schema)
             session.flush()
             if bond:
                 _quote = SchemaQuote(schema_id=gop_schema.schema_id,
                                      qdatabase_id=_database.database_id,
                                      entity=bond.get('entity'),
                                      endpoint=bond.get('endpoint'),
                                      desc=bond.get('desc'))
                 session.add(_quote)
                 session.flush()
                 quote_id = _quote.quote_id
             host = address[0]
             port = address[1]
             _result.setdefault('host', host)
             _result.setdefault('port', port)
             _result.setdefault('character_set',
                                options.get('character_set'))
             _result.setdefault('collation_type',
                                options.get('collation_type'))
             _result.setdefault('schema_id', gop_schema.schema_id)
             _result.setdefault('schema', gop_schema.schema)
             _result.setdefault('quote_id', quote_id)
     return _result
Exemple #24
0
 def bond(self, req, database_id, schema, body=None):
     """schema quote"""
     body = body or {}
     database_id = int(database_id)
     slave = body.get('slave', True)
     slave_id = body.get('slave_id')
     desc = body.get('desc')
     esure = body.get('esure', True)
     quote_id = body.get('quote_id')
     entity = body.pop('entity', None)
     entity = int(entity) if entity is not None else None
     endpoint = body.pop(common.ENDPOINTKEY, None)
     if esure:
         if not endpoint or not entity:
             raise InvalidArgument(
                 'No endpoint info or entity, esure should be flase')
         # TODO log entity info
         entity_info = entity_controller.show(req=req,
                                              endpoint=endpoint,
                                              entity=entity)['data'][0]
     session = endpoint_session()
     query = model_query(session,
                         GopDatabase,
                         filter=and_(GopDatabase.database_id == database_id,
                                     GopDatabase.slave == 0))
     query = query.options(joinedload(GopDatabase.schemas, innerjoin=False))
     _database = query.one()
     _schema = None
     for __schema in _database.schemas:
         if __schema.schema == schema:
             _schema = __schema
             break
     if not _schema:
         raise exceptions.AcceptableSchemaError('Schema %s not found' %
                                                schema)
     quote_database_id = _database.database_id
     user = _schema.user
     passwd = _schema.passwd
     # glock = get_global().lock('entitys')
     # with glock(common.DB, [entity, ]):
     if slave:
         slaves = [
             _slave.slave_id for _slave in _database.slaves if _slave.ready
         ]
         if slave_id:
             if slave_id not in slaves:
                 raise exceptions.AcceptableDbError(
                     'Slave %d not found or not ready' % slave)
             quote_database_id = slave_id
         else:
             if slaves:
                 quote_database_id = slaves[0]
             else:
                 LOG.warning(
                     'Not slave database, use master database as slave')
         user = _schema.ro_user
         passwd = _schema.ro_passwd
     address = _address([
         quote_database_id,
     ]).get(quote_database_id)
     with session.begin():
         schema_quote = SchemaQuote(quote_id=quote_id,
                                    schema_id=_schema.schema_id,
                                    qdatabase_id=quote_database_id,
                                    entity=entity,
                                    endpoint=endpoint,
                                    desc=desc)
         session.add(schema_quote)
         session.flush()
     port = address.get('port')
     host = address.get('host')
     return resultutils.results(
         result='quote to %s.%d success' %
         (schema_quote.qdatabase_id, schema_quote.schema_id),
         data=[
             dict(schema_id=schema_quote.schema_id,
                  quote_id=schema_quote.quote_id,
                  qdatabase_id=quote_database_id,
                  host=host,
                  port=port,
                  user=user,
                  passwd=passwd,
                  schema=schema)
         ])
Exemple #25
0
 def bond_database(self, database_id, **kwargs):
     master_id = kwargs.pop('master')
     file = kwargs.get('file')
     position = kwargs.get('position')
     schemas = kwargs.get('schemas')
     if not file or not position:
         raise InvalidArgument(
             'Can not bond slave without file and position')
     master = None
     slave = None
     relation = None
     session = endpoint_session()
     query = model_query(session,
                         GopDatabase,
                         filter=GopDatabase.database_id.in_(
                             [database_id, master_id]))
     query = query.options(joinedload(GopDatabase.slaves, innerjoin=False))
     with session.begin(subtransactions=True):
         for database in query:
             if database.database_id == database_id:
                 slave = database
             elif database.database_id == master_id:
                 master = database
         # 校验主从
         if slave is None or slave.slave <= 0:
             raise InvalidArgument(
                 'slave database with id %d can not be found' % database_id)
         if slave.status != common.OK:
             raise InvalidArgument('Slave database is not active')
         if master is None or master.slave > 0:
             raise InvalidArgument(
                 'Master database with id %d can not be found' % master_id)
         if master.impl != slave.impl or master.dbtype != slave.dbtype:
             raise InvalidArgument(
                 'Master and slave not the same type or impl')
         _schemas = set([schema.schema for schema in master.schemas])
         # 校验master中的schemas是否正确
         if set(_schemas) != set(schemas):
             raise ValueError('Master schemas info error')
         for _relation in master.slaves:
             if _relation.slave_id == database_id:
                 # 找到绑定关系
                 if _relation.ready:
                     raise InvalidArgument(
                         'Slave already in master slave list')
                 relation = _relation
                 break
         # 没有绑定关系, 确认从库上限
         if not relation:
             count = model_count_with_key(
                 session,
                 GopSalveRelation,
                 filter=GopSalveRelation.slave_id == database_id)
             if count >= slave.slave:
                 raise InvalidArgument('Target slave database is full')
             relation = GopSalveRelation(master_id=master.database_id,
                                         slave_id=slave.database_id)
             session.add(relation)
             session.flush()
         return self._bond_database(session, master, slave, relation,
                                    **kwargs)
Exemple #26
0
    def show_database(self, database_id, **kwargs):
        """show database info"""
        session = endpoint_session(readonly=True)
        quotes = kwargs.pop('quotes', False)
        query = model_query(session,
                            GopDatabase,
                            filter=GopDatabase.database_id == database_id)
        _database = query.one()
        if _database.slave:
            schemas = []
            # slave will find  masters schemas to show
            master_ids = model_query(
                session,
                GopSalveRelation.master_id,
                filter=GopSalveRelation.slave_id == database_id).all()
            if master_ids:
                query = model_query(session,
                                    GopDatabase,
                                    filter=and_(
                                        GopDatabase.database_id.in_(
                                            [m[0] for m in master_ids]),
                                        GopDatabase.slave == 0))
                query = query.options(
                    joinedload(GopDatabase.schemas, innerjoin=False))
                for m_database in query.all():
                    schemas.extend(m_database.schemas)
        else:
            schemas = _database.schemas

        if quotes:
            quotes = [
                dict(entity=quote.entity,
                     endpoint=quote.endpoint,
                     quote_id=quote.quote_id,
                     schema_id=quote.schema_id) for quote in _database.quotes
            ]
        else:
            quotes = []

        _result = dict(database_id=database_id,
                       impl=_database.impl,
                       dbtype=_database.dbtype,
                       dbversion=_database.dbversion,
                       status=_database.status,
                       reflection_id=_database.reflection_id,
                       slave=_database.slave,
                       affinity=_database.affinity,
                       schemas=[
                           dict(schema=schema.schema,
                                schema_id=schema.schema_id)
                           for schema in schemas
                       ],
                       quotes=quotes)
        if _database.slave:
            _result.setdefault('masters', master_ids)
        else:
            # show master database slaves
            _result.setdefault('slaves', _database.slaves)

        with self._show_database(session, _database, **kwargs) as address:
            host = address[0]
            port = address[1]
            _result.setdefault('host', host)
            _result.setdefault('port', port)
        return _result
Exemple #27
0
    def delete_database(self, database_id, master, **kwargs):
        """delete master database intance"""
        session = endpoint_session()
        query = model_query(session,
                            GopDatabase,
                            filter=GopDatabase.database_id == database_id)
        if master:
            query = query.options(
                joinedload(GopDatabase.schemas, innerjoin=False))
        else:
            query = query.options(
                joinedload(GopDatabase.quotes, innerjoin=False))

        with session.begin():
            _database = query.one()
            _result = dict(database_id=_database.database_id,
                           slave=_database.slave,
                           impl=_database.impl,
                           dbtype=_database.dbtype,
                           dbversion=_database.dbversion)
            # 删除主库
            if master:
                if _database.slave:
                    raise exceptions.AcceptableDbError(
                        'Target database is a salve database')
                if _database.schemas or _database.slaves:
                    raise exceptions.AcceptableDbError(
                        'can not delete master database, slaves or schemas exist'
                    )
                if model_count_with_key(session,
                                        SchemaQuote.qdatabase_id,
                                        filter=SchemaQuote.qdatabase_id ==
                                        _database.database_id):
                    raise exceptions.AcceptableDbError(
                        'Database in schema quote list')
                with self._delete_database(session, _database,
                                           **kwargs) as address:
                    host = address[0]
                    port = address[1]
                    _result.setdefault('host', host)
                    _result.setdefault('port', port)
                    query.delete()
            # 删除从库
            else:
                if not _database.slave:
                    raise exceptions.AcceptableDbError(
                        'Target database is not a slave database')
                if _database.quotes:
                    raise exceptions.AcceptableDbError(
                        'Target slave database in schema quote list')
                _masters = [
                    m[0] for m in model_query(session,
                                              GopSalveRelation.master_id,
                                              filter=GopSalveRelation.slave_id
                                              == database_id).all()
                ]
                if _masters:
                    masters = model_query(
                        session,
                        GopDatabase,
                        filter=and_(GopDatabase.database_id.in_(_masters),
                                    GopDatabase.slave == 0))
                    if len(_masters) != len(masters):
                        raise exceptions.UnAcceptableDbError(
                            'Target slave database master missed')
                    raise exceptions.AcceptableDbError(
                        'Slave is bond to masters, unbond before delete')

                with self._delete_database(session, _database,
                                           **kwargs) as address:
                    query.delete()
                    host = address[0]
                    port = address[1]
                    _result.setdefault('host', host)
                    _result.setdefault('port', port)
        return _result