def unpack_handshake_packet(buf): idx = skip_header() handshake = { "protocol_version": None, "server_version": None, "thread_id": None, "scramble_1": None, "server_capabilities": None, "language": None, "server_status": None, "scramble_2": None, "native_password": None, "scramble": None } try: handshake["protocol_version"], idx = unpack_int8(buf, idx) handshake["server_version"], idx = unpack_string_null(buf, idx) if idx == -1: sys.exit(0) handshake["thread_id"], idx = unpack_int32(buf, idx) handshake["scramble_1"], idx = unpack_string(buf, 8, idx) idx = skip_packetn(1, idx) handshake["server_capabilities"], idx = unpack_int16(buf, idx) handshake["language"], idx = unpack_int8(buf, idx) handshake["server_status"], idx = unpack_int16(buf, idx) idx = skip_packetn(13, idx) if handshake[ "server_capabilities"] & ServerCapability.CLIENT_SECURE_CONNECTION: handshake["scramble_2"], idx = unpack_string(buf, 12, idx) idx = skip_packetn(1, idx) if idx < len(buf): handshake["native_password"], idx = unpack_string_null(buf, idx) except Exception, msg: utils.err(utils.cur(), msg)
def unpack_auth_packet(buf): """ analyze authentication packet from client """ idx = skip_header() auth = { "client_flags": None, "max_packet_size": None, "charset_number": None, "user": None, "scramble_buff": None, "database": None } try: auth["client_flags"], idx = unpack_int32(buf, idx) auth["max_packet_size"], idx = unpack_int32(buf, idx) auth["charset_number"], idx = unpack_int8(buf, idx) idx = skip_packetn(23, idx) auth["user"], idx = unpack_string_null(buf, idx) scramble_len, idx = unpack_lenenc(buf, idx) auth["scramble_buff"], idx = unpack_string(buf, scramble_len, idx) if idx < len(buf): auth["database"], idx = unpack_string_null(buf, idx) except Exception, err: utils.err(utils.cur(), err)
def mqCallback(self, channel, method_frame, header_frame, body): try: if not self.zk.is_proxy_master(): return # master's business data_dict = cjson.decode(body) # ** MUST ** ack channel.basic_ack(method_frame.delivery_tag) utils.log(utils.cur(), body, data_dict) if not isinstance(data_dict, dict): return for db, forbid in data_dict.iteritems(): if not forbid[Forbid.KEY_TYPE] in (Forbid.FORBID_WORKING, Forbid.FORBID_FOREVER): return forbid[Forbid.KEY_START] = time.time() path = os.path.join(ZKConf.ZK_PATH_FORBID, db) orig = self.get_path(path) if orig is False: self.zk.mknode(path, cjson.encode(forbid)) else: old = cjson.decode(orig) if ( old[Forbid.KEY_TYPE] == forbid[Forbid.KEY_TYPE] and old[Forbid.KEY_TYPE] == Forbid.FORBID_WORKING and old[Forbid.KEY_START] + old[Forbid.KEY_DURATION] > time.time() ): utils.log(utils.cur(), "still forbidding") else: utils.log(utils.cur(), "change forbid") # change /database/forbid/db self.forbidinfo[db] = forbid self.zk.set(path, cjson.encode(forbid)) except Exception, err: utils.err(utils.cur(), err)
def _zookeeperAuth(self, auth): is_legal = True """ 1. check whether client IP is authorized """ try: ippath = os.path.join(ZKConf.ZK_PATH_DB, auth["database"], ZKConf.KEY_IP) # utils.log(utils.cur(), ippath) is_legal = self.factory.get_path(ippath) # utils.log(utils.cur(), is_legal) if is_legal is not False: ip_json = is_legal is_legal = True # utils.log(utils.cur(), ip_json) try: self.ips = ip_helper.IpRangeList(*tuple(cjson.decode(ip_json))) except: self.ips = None peer = self.transport.getPeer() utils.log(utils.cur(), peer, self.ips, self.factory.ips) if not ((self.ips and peer.host in self.ips) or (self.factory.ips and peer.host in self.factory.ips)): is_legal = False ip_error = dict(ErrorCode.IP_RESTRICTED) ip_error["message"] = ip_error["message"] % {"ip":peer.host} self._write(self._goWrong(ip_error, self.next_idx)) # 2 return is_legal except Exception, err: utils.err(utils.cur(), traceback.format_exc()) is_legal = False
def register_watches(self): # 1. listen /database/db_info # reset zkdbinfo # close connections which are related to deleted nodes under db_info dbs = self.get_path(ZKConf.ZK_PATH_DB, child=True) self.zk.watch_child(ZKConf.ZK_PATH_DB, self.watcher_db_info) dbs = dbs.keys() if dbs else [] self.dbs = dbs for db in dbs: path_authed_ip = os.path.join(ZKConf.ZK_PATH_DB, db, ZKConf.KEY_IP) # 2. listen /database/db_info/xxx/authed_ips # reset zkdbinfo self.zk.watch_node(path_authed_ip, self.watcher_authed_ip) path_dbconf = os.path.join(ZKConf.ZK_PATH_DB, db, ZKConf.KEY_DBCONF) # 3. listen /database/db_info/xxx/dbconf/db_host_r # listen /database/db_info/xxx/dbconf/db_host_w # reset zkdbinfo # reset busy_proobj rwclient connections # reset idle_rwclient connections self.zk.watch_node(os.path.join(path_dbconf, ZKConf.KEY_READ), self.watcher_rw_ip) self.zk.watch_node(os.path.join(path_dbconf, ZKConf.KEY_WRITE), self.watcher_rw_ip) # 4. listen /database/authed_ips # reset zkdbinfo # reset self.ips ip_json = self.get_path(ZKConf.ZK_PATH_IPS) try: if ip_json: self.ips = ip_helper.IpRangeList(*tuple(cjson.decode(ip_json))) except Exception, err: utils.err(utils.cur(), err) self.ips = None
def unpack_auth_packet(buf): """ analyze authentication packet from client """ idx = skip_header() auth = { "client_flags" : None, "max_packet_size" : None, "charset_number" : None, "user" : None, "scramble_buff" : None, "database" : None } try: auth["client_flags"], idx = unpack_int32(buf, idx) auth["max_packet_size"], idx = unpack_int32(buf, idx) auth["charset_number"], idx = unpack_int8(buf, idx) idx = skip_packetn(23, idx) auth["user"], idx = unpack_string_null(buf, idx) scramble_len, idx = unpack_lenenc(buf, idx) auth["scramble_buff"], idx = unpack_string(buf, scramble_len, idx) if idx < len(buf): auth["database"], idx = unpack_string_null(buf, idx) except Exception, err: utils.err(utils.cur(), err)
def mqCallback(self, channel, method_frame, header_frame, body): try: if not self.zk.is_proxy_master(): return # master's business data_dict = cjson.decode(body) # ** MUST ** ack channel.basic_ack(method_frame.delivery_tag) utils.log(utils.cur(), body, data_dict) if not isinstance(data_dict, dict): return for db, forbid in data_dict.iteritems(): if not forbid[Forbid.KEY_TYPE] in (Forbid.FORBID_WORKING, Forbid.FORBID_FOREVER): return forbid[Forbid.KEY_START] = time.time() path = os.path.join(ZKConf.ZK_PATH_FORBID, db) orig = self.get_path(path) if orig is False: self.zk.mknode(path, cjson.encode(forbid)) else: old = cjson.decode(orig) if old[Forbid.KEY_TYPE] == forbid[Forbid.KEY_TYPE] and \ old[Forbid.KEY_TYPE] == Forbid.FORBID_WORKING and \ old[Forbid.KEY_START] + old[Forbid.KEY_DURATION] > time.time(): utils.log(utils.cur(), "still forbidding") else: utils.log(utils.cur(), "change forbid") # change /database/forbid/db self.forbidinfo[db] = forbid self.zk.set(path, cjson.encode(forbid)) except Exception, err: utils.err(utils.cur(), err)
def unpack_handshake_packet(buf): idx = skip_header() handshake = { "protocol_version" : None, "server_version" : None, "thread_id" : None, "scramble_1" : None, "server_capabilities" : None, "language" : None, "server_status" : None, "scramble_2" : None, "native_password" : None, "scramble" : None } try: handshake["protocol_version"], idx = unpack_int8(buf, idx) handshake["server_version"], idx = unpack_string_null(buf, idx) if idx == -1: sys.exit(0) handshake["thread_id"], idx = unpack_int32(buf, idx) handshake["scramble_1"], idx = unpack_string(buf, 8, idx) idx = skip_packetn(1, idx) handshake["server_capabilities"], idx = unpack_int16(buf, idx) handshake["language"], idx = unpack_int8(buf, idx) handshake["server_status"], idx = unpack_int16(buf, idx) idx = skip_packetn(13, idx) if handshake["server_capabilities"] & ServerCapability.CLIENT_SECURE_CONNECTION: handshake["scramble_2"], idx = unpack_string(buf, 12, idx) idx = skip_packetn(1, idx) if idx < len(buf): handshake["native_password"], idx = unpack_string_null(buf, idx) except Exception, msg: utils.err(utils.cur(), msg)
def watcher_ip(self, event, true_path): self.reload_zkdbinfo() ip_json = self.get_path(true_path) try: self.ips = ip_helper.IpRangeList(*tuple(cjson.decode(ip_json))) except Exception, err: utils.err(utils.cur(), err) self.ips = None
def unpack_error_packet(buf): idx = skip_header() field_count, idx = unpack_int8(buf, idx) errno, idx = unpack_int16(buf, idx) sqlstate, idx = unpack_string(buf, 6, idx) # "#state" message, idx = unpack_string(buf, len(buf)-idx, idx) utils.err(utils.cur(), "%s|%s|%s|%s" % (field_count, errno, sqlstate, message)) return (field_count, errno, sqlstate, message)
def unpack_error_packet(buf): idx = skip_header() field_count, idx = unpack_int8(buf, idx) errno, idx = unpack_int16(buf, idx) sqlstate, idx = unpack_string(buf, 6, idx) # "#state" message, idx = unpack_string(buf, len(buf) - idx, idx) utils.err(utils.cur(), "%s|%s|%s|%s" % (field_count, errno, sqlstate, message)) return (field_count, errno, sqlstate, message)
def watcher_forbid(self, event, true_path): self.reload_zkdbinfo() dbs_forbid = self.get_path(true_path, child=True) forbidinfo = collections.defaultdict(dict) for db in dbs_forbid: try: forbid_db = self.get_path(os.path.join(true_path, db)) forbidinfo[db] = cjson.decode(forbid_db) except Exception, err: utils.err(utils.cur(), err)
def _trans(cur, *args): try: keys = ",".join(["`%s`" % k for k in dbinfo.keys()]) vals = ",".join(["'%s'" % v for v in dbinfo.values()]) sql = "INSERT INTO `%s` (%s) VALUES(%s)" % ( DBConf.TABLE_DBINFO, keys, vals) utils.log(utils.cur(), keys, vals, sql) cur.execute(sql) cur.execute("COMMIT") except Exception, e: cur.execute("ROLLBACK") utils.err(utils.cur(), e) raise Exception(e)
def _trans(cur, *args): try: keys = ",".join(["`%s`" % k for k in dbinfo.keys()]) vals = ",".join(["'%s'" % v for v in dbinfo.values()]) sql = "INSERT INTO `%s` (%s) VALUES(%s)" % (DBConf.TABLE_DBINFO, keys, vals) utils.log(utils.cur(), keys, vals, sql) cur.execute(sql) cur.execute("COMMIT") except Exception, e: cur.execute("ROLLBACK") utils.err(utils.cur(), e) raise Exception(e)
def unpack_ok_packet(buf): idx = skip_header() val, idx = unpack_int8(buf, idx) if val is not AuthConf.OK_STATUS: return False ok = { "affected_rows" : None, "insert_id" : None, "server_status" : None, "warning_count" : None, } try: ok["affected_rows"], idx = unpack_lenenc(buf, idx) ok["insert_id"], idx = unpack_lenenc(buf, idx) ok["server_status"], idx = unpack_int16(buf, idx) ok["warning_count"], idx = unpack_int16(buf, idx) except Exception, err: utils.err(utils.cur(), err)
def unpack_ok_packet(buf): idx = skip_header() val, idx = unpack_int8(buf, idx) if val is not AuthConf.OK_STATUS: return False ok = { "affected_rows": None, "insert_id": None, "server_status": None, "warning_count": None, } try: ok["affected_rows"], idx = unpack_lenenc(buf, idx) ok["insert_id"], idx = unpack_lenenc(buf, idx) ok["server_status"], idx = unpack_int16(buf, idx) ok["warning_count"], idx = unpack_int16(buf, idx) except Exception, err: utils.err(utils.cur(), err)
class ServerFactory(protocol.Factory): def __init__(self, port): self.port = port self.conns = 0 self.pool_size = 1 self.servers = threads.ConnsPool("pool-connections") self.packets = None self.initPackets(self) # set packets self.ips = None # IpRangeList object self.dbs = [] # database name self.zk = None self.zk_dbinfo = {} self.forbidinfo = collections.defaultdict(dict) self.busy_proobj = collections.defaultdict(list) def _init_zk(): # zk_helper self.zk = zk_helper.ZooKeeper("db_proxy", self.register_watches, "register_service", "proxy", self.port) self.zk_dbinfo = self.zk.get_dict() self.register_watches() self.servers.start() # mq_helper blocking thread self.mq = mq_helper.PikaRecvThread(servers=MQConf.SERVERS, exchange = MQConf.EXCHANGE_FORBID, queue = utils.getip() + MQConf.PROXY_SUFFIX, callback = self.mqCallback) self.mq.start() self.monitor = threads.ForbidMonitor(self) self.monitor.start() self.proxy_stats_log = threads.ProxyStatsLog(self.servers) self.proxy_stats_log.start() reactor.callLater(1, _init_zk) def reload_zkdbinfo(self): try: tmp = dict(self.zk_dbinfo) self.zk_dbinfo = self.zk.get_dict() except: self.zk_dbinfo = dict(tmp) def get_path(self, path, child=False): db_root_path = ZKConf.ZK_PATH_ROOT if path.startswith(db_root_path): path = path[len(db_root_path):] parts = path.split("/") tmp = dict(self.zk_dbinfo) for part in parts: if not part: continue if part in tmp: tmp = tmp[part] else: return False if child: if "__v__" in tmp: del tmp["__v__"] return tmp else: return tmp["__v__"] def register_watches(self): # 1. listen /database/db_info # reset zkdbinfo # close connections which are related to deleted nodes under db_info dbs = self.get_path(ZKConf.ZK_PATH_DB, child=True) self.zk.watch_child(ZKConf.ZK_PATH_DB, self.watcher_db_info) dbs = dbs.keys() if dbs else [] self.dbs = dbs for db in dbs: path_authed_ip = os.path.join(ZKConf.ZK_PATH_DB, db, ZKConf.KEY_IP) # 2. listen /database/db_info/xxx/authed_ips # reset zkdbinfo self.zk.watch_node(path_authed_ip, self.watcher_authed_ip) path_dbconf = os.path.join(ZKConf.ZK_PATH_DB, db, ZKConf.KEY_DBCONF) # 3. listen /database/db_info/xxx/dbconf/db_host_r # listen /database/db_info/xxx/dbconf/db_host_w # reset zkdbinfo # reset busy_proobj rwclient connections # reset idle_rwclient connections self.zk.watch_node(os.path.join(path_dbconf, ZKConf.KEY_READ), self.watcher_rw_ip) self.zk.watch_node(os.path.join(path_dbconf, ZKConf.KEY_WRITE), self.watcher_rw_ip) # 4. listen /database/authed_ips # reset zkdbinfo # reset self.ips ip_json = self.get_path(ZKConf.ZK_PATH_IPS) try: if ip_json: self.ips = ip_helper.IpRangeList(*tuple(cjson.decode(ip_json))) except Exception, err: utils.err(utils.cur(), err) self.ips = None self.zk.watch_node(ZKConf.ZK_PATH_IPS, self.watcher_ip) # 5. listen /database/forbid # reset zkdbinfo # reset self.forbidinfo dbs_forbid = self.get_path(ZKConf.ZK_PATH_FORBID, child=True) self.zk.watch_child(ZKConf.ZK_PATH_FORBID, self.watcher_forbid) dbs_forbid = dbs_forbid.keys() if dbs_forbid else [] for db in dbs_forbid: try: data, meta = self.zk.get(os.path.join(ZKConf.ZK_PATH_FORBID, db), None) self.forbidinfo[db] = cjson.decode(data) except Exception, err: utils.err(utils.cur(), err)
class ServerProtocol(protocol.Protocol): def __init__(self): self.client_authed = False self.server = None self.database = None self.dbname = None # self.node_listen = True # SQL parser self.sql_parser = sql_parser.SQLVerify() # force read/write self.rwsplit = True self.timeout = threads.WaitTimeout(self.close_proobj, self) self.timeout.start() # ip whitelist self.ips = None self.idx = -1 self.dbtype = "" # prepared statement id self.stmt_id = 0 # requests self.requests = 0 # first.request self.req_1st = True # receiving trunk self.in_trunk = False self.buffer = "" self.pack_len = 0 def reset_requests(self): self.requests = 0 @property def next_idx(self): self.idx += 1 self.idx %= 256 return self.idx def close_proobj(self): # utils.log(utils.cur(), "close_proobj") self.transport.loseConnection() @reset_log def connectionLost(self, reason): utils.reset_logconf() self.factory.conns -= 1 utils.log(utils.cur(), "client is losing proxy %s" % self.factory.conns, self.requests) # mysql_stmt_close if self.stmt_id: self.server.mysql_stmt_close(self.stmt_id) # reclaim connection self.factory.takeServer(self.server, self) # clean connection self.server = None self.timeout.stop() @change_log def connectionMade(self): self._write(self.factory.getHandshakeRaw()) def _checkForbid(self, opts, dbtype): if dbtype == ZKConf.INTERNAL or (self.database not in self.factory.forbidinfo): return False db = self.database msg = self.factory.forbidinfo[db] if msg["type"] == Forbid.FORBID_FOREVER: return self.sendForbid(msg, db, opts) elif msg["type"] == Forbid.FORBID_WORKING: start, duration = msg["start"], msg["duration"] if start + duration > time.time(): return self.sendForbid(msg, db, opts) self.factory.zk.erase_forbid(db) return False def sendConnectionTimeout(self): timeout_error = dict(ErrorCode.BACKEND_TIMEOUT) self._write(self._goWrong(timeout_error, self.next_idx)) return True def sendForbid(self, data, db, opts): """ check contraints of databases, tables and operations """ assert isinstance(data, dict) assert "object" in data and data["object"] in (Forbid.FORBID_DATABASE, Forbid.FORBID_TABLE) def _realForbid(crud, dbtb, errmsg, isDB=True): forbid_duration = int(data["start"] + data["duration"] - time.time()) if data["type"] == Forbid.FORBID_WORKING else sys.maxint forbid_error = dict(ErrorCode.QUOTA_EXCEEDED) forbid_error["message"] = forbid_error["message"] % (crud, "Database" if isDB else "Table", dbtb, errmsg, forbid_duration) self._write(self._goWrong(forbid_error, self.next_idx)) return True crud = data["crud"] utils.log(utils.cur(), crud) if not crud: return False if data["object"] == Forbid.FORBID_DATABASE: allopts = opts["db"] utils.log(utils.cur(), allopts) assert type(allopts) is list if Forbid.OPERATION_DEFAULT in crud: return _realForbid([Forbid.OPERATION_DEFAULT], db, data["errmsg"], True) else: if set(allopts).intersection(set(crud)): return _realForbid(crud, db, data["errmsg"], True) else: allopts = opts["tb"] utils.log(utils.cur(), allopts) assert type(allopts) is dict for tbl, tbopts in allopts.iteritems(): if tbl in crud: if Forbid.OPERATION_DEFAULT in crud[tbl]: return _realForbid([Forbid.OPERATION_DEFAULT], tbl, data["errmsg"], False) if set(tbopts).intersection(set(crud[tbl])): return _realForbid(crud[tbl], tbl, data["errmsg"], False) return False @set_idx(1) @change_log def dataReceived(self, data): # client auth first if not self.client_authed: return self._clientAuth(data) # normal sql request, if quit packet return if not data or len(data) == 0 or is_quit_packet(data): return def _r_(request): self.requests += 1 if self.req_1st: reactor.callLater(ProxyServer.CONN_TIMEOUT, self.checkFirstReq) self._dealQuery(request) if self.in_trunk: self.buffer += data if len(self.buffer) == self.pack_len + 4: self.in_trunk = False _r_(self.buffer) else: self.pack_len, _ = unpack_packet_length(data) if self.pack_len + 4 > len(data): self.in_trunk = True self.buffer = data elif self.pack_len + 4 == len(data): _r_(data) def checkFirstReq(self): if self.req_1st: self.server.close_rw() self.sendConnectionTimeout() def _clientAuth(self, data): """ 1. parse auth packet, db is mandatory """ auth = analyze_packet(data) if auth == -1 or not auth["database"]: self._write(self._goWrong(ErrorCode.PACKET_WRONG, self.next_idx)) return """ 2. retrieve database info from zookeeper and auth """ is_legal = self._zookeeperAuth(auth) utils.log(utils.cur(), "after zkauth", is_legal) """ 3. assign a pair of read/write connections when passed """ if is_legal: self.database = auth["database"] self.dbname = self.getDBname() utils.log(utils.cur(), self.database) def callback(me, old=False): # utils.log(utils.cur(), "auth inside") pkts = me.server.writeClient.protocol.packets if old: me._write(me._goRight(me.next_idx)) me.client_authed = True stats_conns.incr(self.database) utils.log(utils.cur(), stats_conns) return if pkts["err"]: me._write(pkts["err"]) else: """ ** NOTICE ** be care of index in pkts["ok"] and pkts["err"] """ # utils.log(utils.cur(), pkts) p = pkts["ok"][:3] + "\x02" + pkts["ok"][4:] me._write(p) me.client_authed = True stats_conns.incr(self.database) utils.log(utils.cur(), stats_conns) self.factory.getServer(self.database, callback, self) def _goWrong(self, errstate, idx = 1): return pack_err_packet(errstate["errno"], errstate["sqlstate"], errstate["message"], idx) def pool_error(self, err): error = dict(ErrorCode.POOL_ERROR) error["message"] = error["message"] % str(err) self._write(self._goWrong(error, self.next_idx)) def service_error(self, host): error = dict(ErrorCode.SERVICE_ERROR) error["message"] = error["message"] % str(host) self._write(self._goWrong(error, self.next_idx)) def _goRight(self, idx = 1): return pack_ok_packet(idx=idx) def _zookeeperAuth(self, auth): is_legal = True """ 1. check whether client IP is authorized """ try: ippath = os.path.join(ZKConf.ZK_PATH_DB, auth["database"], ZKConf.KEY_IP) # utils.log(utils.cur(), ippath) is_legal = self.factory.get_path(ippath) # utils.log(utils.cur(), is_legal) if is_legal is not False: ip_json = is_legal is_legal = True # utils.log(utils.cur(), ip_json) try: self.ips = ip_helper.IpRangeList(*tuple(cjson.decode(ip_json))) except: self.ips = None peer = self.transport.getPeer() utils.log(utils.cur(), peer, self.ips, self.factory.ips) if not ((self.ips and peer.host in self.ips) or (self.factory.ips and peer.host in self.factory.ips)): is_legal = False ip_error = dict(ErrorCode.IP_RESTRICTED) ip_error["message"] = ip_error["message"] % {"ip":peer.host} self._write(self._goWrong(ip_error, self.next_idx)) # 2 return is_legal except Exception, err: utils.err(utils.cur(), traceback.format_exc()) is_legal = False # utils.log(utils.cur(), "ip disabled", is_legal) """ 1.1 check whether DB is forbidden """ try: if is_legal: dis_path = os.path.join(ZKConf.ZK_PATH_DB, auth["database"], ZKConf.KEY_DISABLED) is_legal = self.factory.get_path(dis_path) if is_legal is not False: disabled = is_legal is_legal = True if int(disabled) == ZKConf.DISABLED: is_legal = False db_error = dict(ErrorCode.DB_DISABLED) db_error["message"] = db_error["message"] % {"db":auth["database"]} self._write(self._goWrong(db_error, self.next_idx)) return is_legal except Exception, err: utils.err(utils.cur(), err) is_legal = False
except Exception, err: utils.err(utils.cur(), err) is_legal = False # utils.log(utils.cur(), "db disabled", is_legal) try: if is_legal: dbtype_path = os.path.join(ZKConf.ZK_PATH_DB, auth["database"], ZKConf.KEY_DBTYPE) # utils.log(utils.cur(), dbtype_path) is_legal = self.factory.get_path(dbtype_path) if is_legal is not False: self.dbtype = is_legal is_legal = True except Exception, err: utils.err(utils.cur(), traceback.format_exc()) is_legal = False # utils.log(utils.cur(), "db forbidden", is_legal) """ 2. find /DB_INFO/database node and retrieve DB_PASS, DB_USER, DB_DB """ try: if is_legal: dbpath = os.path.join(ZKConf.ZK_PATH_DB, auth["database"], ZKConf.KEY_DBCONF) is_legal = self.factory.get_path(dbpath) if is_legal is not False: is_legal = True info = {"passwd": "", "user": "", "database":""} info["passwd"] = self.factory.get_path(dbpath + "/" + ZKConf.KEY_PASSWORD) info["user"] = self.factory.get_path(dbpath + "/" + ZKConf.KEY_USER)