def __init__(self, path='/'): self.path = path zk_client = KazooClient(hosts=ZOOKEEPER_SERVERS, read_only=True, timeout=TIMEOUT) try: zk_client.start() self.data, stat = zk_client.get(path) self.stat = _convert_stat(stat) self.children = zk_client.get_children(path) or [] self.acls = _convert_acls(zk_client.get_acls(path)[0]) finally: zk_client.stop()
class ZKClient(object): def __init__(self, servers, timeout): self.connected = False print("Connecting to %s" % (servers)) self.zk_client = KazooClient(hosts=servers) self.zk_client.start(timeout=timeout) def close(self): self.zk_client.stop() def get(self, path, watcher=None): return self.zk_client.get(path, watcher) def get_children(self, path, watcher=None): return self.zk_client.get_children(path, watcher) def get_acls(self, path): return self.zk_client.get_acls(path)
class ZooKeeper(object): def __init__(self, hosts, user=None, password=None): self._zookeeper = KazooClient(hosts=hosts) self._zookeeper.start() if user and password: self._zookeeper.add_auth('digest', '{}:{}'.format(user, password)) def stop(self): if self._zookeeper: self._zookeeper.stop() self._zookeeper.close() self._zookeeper = None def list(self, path): try: return self._zookeeper.get_children(path) except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) except NoAuthError: raise ZooKeeperException("No access to list node: {}".format(path)) def get(self, path): try: value, _ = self._zookeeper.get(path) if value: value = value.decode('utf-8') else: value = "" return value except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) except NoAuthError: raise ZooKeeperException("No access to get node: {}".format(path)) def set(self, path, data): try: self._zookeeper.set(path, data.encode()) except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) except NoAuthError: raise ZooKeeperException("No access to set data on node: {}".format(path)) def create(self, path, data=None, ephemeral=False, sequence=False, makepath=False): if data: data = data.encode() else: data = b"" try: self._zookeeper.create(path, value=data, ephemeral=ephemeral, sequence=sequence, makepath=makepath) except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) except NodeExistsError: raise ZooKeeperException("Node already exists: {}".format(path)) except NoAuthError: raise ZooKeeperException("No access to create node: {}".format(path)) def delete(self, path, recursive=False): try: self._zookeeper.delete(path, recursive=recursive) except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) except NotEmptyError: raise ZooKeeperException("Node contains sub-nodes") except NoAuthError: raise ZooKeeperException("No access to delete node: {}".format(path)) def stat(self, path): try: _, stat = self._zookeeper.get(path) return stat except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) def get_acl(self, path): try: acl, _ = self._zookeeper.get_acls(path) return acl except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) def add_acl(self, path, permissions, scheme, id): perms = get_permissions(permissions) if scheme == "digest": username, password = id.split(":") acl = make_digest_acl(username, password, **perms) else: acl = make_acl(scheme, id, **perms) current_acls = self.get_acl(path) current_acls.append(acl) try: self._zookeeper.set_acls(path, current_acls) except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) except InvalidACLError as exc: raise ZooKeeperException("Invalid ACL format: {}".format(str(exc))) except NoAuthError: raise ZooKeeperException("No access to add acl on node: {}".format(path)) def delete_acl(self, path, index): current_acls = self.get_acl(path) deleted = current_acls.pop(index) try: self._zookeeper.set_acls(path, current_acls) except NoNodeError: raise ZooKeeperException("No such node: {}".format(path)) except NoAuthError: raise ZooKeeperException("No access to delete acl from node: {}".format(path)) return deleted
def test_init_hierarchy(self): auth = ('digest', 'aa', 'pw_aa') hosts = '127.0.0.1:21811' users = {'aa': 'pw_aa', 'bb': 'pw_bb', 'cc': 'pw_cc'} hierarchy = { 'node1': { '__val__': 'node1_val', '__acl__': { 'aa': 'cdrwa', 'bb': 'rw' }, 'node11': { '__val__': 'node11_val', '__acl__': { 'aa': 'cdrwa', 'cc': 'r' }, }, 'node12': { '__val__': 'node12_val', 'node121': { '__val__': 'node121_val' } }, 'node13': { '__acl__': { 'aa': 'cdrwa' } } }, 'node2': { '__val__': 'node2_val', 'node21': { '__val__': 'node21_val' }, 'node22': { '__acl__': { 'aa': 'rwa' } } }, 'node3': { '__acl__': { 'aa': 'carw', 'cc': 'r' }, 'node31': { 'node311': { 'node3111': {}, 'node3112': {} } } } } zkutil.init_hierarchy(hosts, hierarchy, users, auth) zkcli = KazooClient(hosts) zkcli.start() zkcli.add_auth('digest', 'aa:pw_aa') expected_nodes = ( ('/node1', '"node1_val"', [('digest', 'aa', 'cdrwa'), ('digest', 'bb', 'rw')], set(['node11', 'node12', 'node13'])), ('/node1/node11', '"node11_val"', [('digest', 'aa', 'cdrwa'), ('digest', 'cc', 'r')], set([])), ('/node1/node12', '"node12_val"', [('digest', 'aa', 'cdrwa'), ('digest', 'bb', 'rw')], set(['node121'])), ('/node1/node12/node121', '"node121_val"', [('digest', 'aa', 'cdrwa'), ('digest', 'bb', 'rw')], set([])), ('/node1/node13', '{}', [('digest', 'aa', 'cdrwa')], set([])), ('/node2', '"node2_val"', [('world', 'anyone', 'cdrwa')], set(['node21', 'node22'])), ('/node2/node21', '"node21_val"', [('world', 'anyone', 'cdrwa')], set([])), ('/node2/node22', '{}', [('digest', 'aa', 'rwa')], set([])), ('/node3', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set(['node31'])), ('/node3/node31', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set(['node311'])), ('/node3/node31/node311', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set(['node3111', 'node3112'])), ('/node3/node31/node311/node3111', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set([])), ('/node3/node31/node311/node3112', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set([])), ) for node, val, acl, children in expected_nodes: actual_acl = zkutil.parse_kazoo_acl(zkcli.get_acls(node)[0]) self.assertEqual(val, zkcli.get(node)[0]) self.assertEqual(acl, actual_acl) self.assertEqual(children, set(zkcli.get_children(node))) zkcli.stop()
class TestZKLock(unittest.TestCase): @classmethod def setUpClass(cls): utdocker.pull_image(zk_test_tag) def setUp(self): config.zk_acl = zk_test_acl config.zk_auth = zk_test_auth self.counter = 0 self.running = True utdocker.create_network() utdocker.start_container( zk_test_name, zk_test_tag, env={ "ZOO_MY_ID": 1, "ZOO_SERVERS": "server.1=0.0.0.0:2888:3888", }, port_bindings={ 2181: 21811, } ) self.zk = KazooClient(hosts='127.0.0.1:21811') self.zk.start() scheme, name, passw = zk_test_auth self.zk.add_auth(scheme, name + ':' + passw) # create lock base dir acl = zkutil.make_kazoo_digest_acl(zk_test_acl) self.zk.create('lock/', acl=acl) self.lck = zkutil.ZKLock('foo_name', zkclient=self.zk) def tearDown(self): self.zk.stop() utdocker.remove_container(zk_test_name) def _on_conn_change(self, state): self.lsn_count += 1 def test_bounded_listener(self): # ensure that adding a bounded listener(self.on_xxx) is ok self.lsn_count = 0 self.zk.add_listener(self._on_conn_change) self.zk.add_listener(self._on_conn_change) self.zk.stop() self.assertEqual(1, self.lsn_count) def _loop_acquire(self, n, ident): zk = KazooClient(hosts='127.0.0.1:21811') zk.start() scheme, name, passw = zk_test_auth zk.add_auth(scheme, name + ':' + passw) for ii in range(n): l = zkutil.ZKLock('foo_name', zkclient=zk) with l: self.total += 1 self.counter += 1 self.assertTrue(self.counter == 1) time.sleep(0.01) self.counter -= 1 dd("id={ident:0>2} n={ii:0>2} got and released lock: {holder}".format( ident=ident, ii=ii, holder=l.lock_holder)) zk.stop() def test_concurrent(self): self.running = True self.total = 0 n_repeat = 40 n_thread = 5 ths = [] for ii in range(n_thread): t = threadutil.start_daemon_thread(self._loop_acquire, args=(n_repeat, ii,)) ths.append(t) for th in ths: th.join() self.running = False self.assertEqual(n_repeat * n_thread, self.total) def test_persistent(self): l = zkutil.ZKLock('foo_name', ephemeral=False, on_lost=lambda: True) try: with l: l.zkclient.stop() except ConnectionClosedError: pass self.assertRaises(zkutil.LockTimeout, self.lck.acquire, timeout=0.2) def test_timeout(self): l1 = zkutil.ZKLock('foo_name', on_lost=lambda: True) l2 = zkutil.ZKLock('foo_name', on_lost=lambda: True) with l1: with ututil.Timer() as t: self.assertRaises(zkutil.LockTimeout, l2.acquire, timeout=0.2) self.assertAlmostEqual(0.2, t.spent(), places=1) with ututil.Timer() as t: self.assertRaises(zkutil.LockTimeout, l2.acquire, timeout=-1) self.assertAlmostEqual(0.0, t.spent(), delta=0.01) try: l2.acquire(timeout=-1) except zkutil.LockTimeout: self.fail('timeout<0 should could acquire') def test_lock_holder(self): a = zkutil.ZKLock('foo_name', on_lost=lambda: True) b = zkutil.ZKLock('foo_name', on_lost=lambda: True) with a: self.assertEqual((a.identifier, 0), a.lock_holder) val, zstate = self.zk.get(a.lock_path) self.assertEqual((val, zstate.version), a.lock_holder) locked, holder, ver = b.try_acquire() self.assertFalse(locked) self.assertEqual((a.identifier, 0), (holder, ver)) self.assertEqual((val, zstate.version), (holder, ver)) def test_watch_acquire(self): a = zkutil.ZKLock('foo', on_lost=lambda: True) b = zkutil.ZKLock('foo', on_lost=lambda: True) # no one locked n = 0 for holder, ver in a.acquire_loop(): n += 1 self.assertEqual(0, n, 'acquired directly') # watch node change it = b.acquire_loop() holder, ver = it.next() self.assertEqual((a.identifier, 0), (holder, ver)) self.zk.set(a.lock_path, 'xx') holder, ver = it.next() self.assertEqual(('xx', 1), (holder, ver), 'watched node change') a.release() try: holder, ver = it.next() self.fail('should not have next yield') except StopIteration: pass self.assertTrue(b.is_locked()) def test_try_lock(self): l1 = zkutil.ZKLock('foo_name', on_lost=lambda: True) l2 = zkutil.ZKLock('foo_name', on_lost=lambda: True) with l1: with ututil.Timer() as t: locked, holder, ver = l2.try_acquire() self.assertFalse(locked) self.assertEqual(l1.identifier, holder) self.assertGreaterEqual(ver, 0) self.assertAlmostEqual(0.0, t.spent(), delta=0.05) with ututil.Timer() as t: locked, holder, ver = l2.try_acquire() self.assertTrue(locked) self.assertEqual(l2.identifier, holder) self.assertEqual(ver, 0) self.assertAlmostEqual(0.0, t.spent(), delta=0.05) def test_try_release(self): l1 = zkutil.ZKLock('foo_name', on_lost=lambda: True) l2 = zkutil.ZKLock('foo_name', on_lost=lambda: True) released, holder, ver = l1.try_release() self.assertEqual((True, l1.identifier, -1), (released, holder, ver)) with l2: released, holder, ver = l1.try_release() self.assertEqual((False, l2.identifier, 0), (released, holder, ver)) released, holder, ver = l2.try_release() self.assertEqual((True, l2.identifier, 0), (released, holder, ver)) def test_zk_lost(self): sess = {'acquired': True} def watch(state): dd('zk node state changed to: ', state) sess['acquired'] = False self.zk.add_listener(watch) # test zk close l = zkutil.ZKLock('foo_name', zkclient=self.zk) l.acquire() self.zk.stop() time.sleep(0.1) self.assertFalse(sess['acquired']) # test node delete sess['acquired'] = True self.zk.start() self.zk.add_listener(watch) l = zkutil.ZKLock('foo_name', zkclient=self.zk) with l: time.sleep(0.1) self.zk.delete(l.zkconf.lock('foo_name')) time.sleep(0.1) self.assertFalse(sess['acquired']) def test_node_change_after_acquired(self): sess = {'acquired': True} def on_lost(): sess['acquired'] = False l = zkutil.ZKLock('foo_name', zkclient=self.zk, on_lost=on_lost) with l: sess['acquired'] = True self.zk.delete(l.zkconf.lock('foo_name')) time.sleep(0.1) self.assertFalse(sess['acquired']) l = zkutil.ZKLock('foo_name', zkclient=self.zk, on_lost=on_lost) with l: sess['acquired'] = True self.zk.set(l.zkconf.lock('foo_name'), 'xxx') time.sleep(0.1) self.assertFalse(sess['acquired']) def test_node_change_after_released(self): sess = {'acquired': True} def on_lost(): sess['acquired'] = False l = zkutil.ZKLock('foo_name', zkclient=self.zk, on_lost=on_lost) with l: sess['acquired'] = True time.sleep(0.1) self.assertTrue(sess['acquired']) def test_is_locked(self): l = zkutil.ZKLock('foo_name', zkclient=self.zk) with l: pass self.assertFalse(l.is_locked()) l = zkutil.ZKLock('foo_name', zkclient=self.zk) l.acquire() self.assertTrue(l.is_locked()) l.try_release() self.assertFalse(l.is_locked()) def test_conn_lost_when_blocking_acquiring(self): l2 = zkutil.ZKLock('foo_name', on_lost=lambda: True) th = threadutil.start_daemon(target=self.zk.stop, after=0.5) with l2: try: self.lck.acquire(timeout=1) self.fail('expected connection error') except ConnectionClosedError: pass th.join() def test_internal_zkclient(self): sess = {'acquired': True} def on_lost(): sess['acquired'] = False # There must be a listener specified to watch connection issue self.assertRaises(ValueError, zkutil.ZKLock, 'foo_name') l = zkutil.ZKLock('foo_name', on_lost=on_lost) with l: self.zk.delete(l.zkconf.lock('foo_name')) time.sleep(0.1) self.assertFalse(sess['acquired']) def test_acl(self): with self.lck: acls, zstat = self.zk.get_acls(self.lck.lock_path) dd(acls) self.assertEqual(1, len(acls)) acl = acls[0] expected = zkutil.perm_to_long(zk_test_acl[0][2], lower=False) self.assertEqual(set(expected), set(acl.acl_list)) self.assertEqual('digest', acl.id.scheme) self.assertEqual(zk_test_acl[0][0], acl.id.id.split(':')[0]) def test_config(self): old = (config.zk_acl, config.zk_auth, config.zk_node_id) config.zk_acl = (('foo', 'bar', 'cd'), ('xp', '123', 'cdrwa')) config.zk_auth = ('digest', 'xp', '123') config.zk_node_id = 'abc' l = zkutil.ZKLock('foo_name', on_lost=lambda: True) dd(l.zkconf.acl()) def _check_ac(ac): self.assertEqual('digest', ac.id.scheme) self.assertEqual('foo', ac.id.id.split(':')[0]) self.assertEqual(set(['CREATE', 'DELETE']), set(ac.acl_list)) _check_ac(l.zkconf.kazoo_digest_acl()[0]) with l: # should have created lock node data, zstate = self.zk.get(l.lock_path) dd(data) self.assertEqual('abc', data.split('-')[0]) acls, zstate = self.zk.get_acls(l.lock_path) dd(acls) _check_ac(acls[0]) (config.zk_acl, config.zk_auth, config.zk_node_id) = old def test_hosts(self): l = zkutil.ZKLock('foo_name', zkconf=dict( hosts='127.0.0.1:21811', ), on_lost=lambda: True) with l: self.assertEqual('127.0.0.1:21811', l._hosts) def test_specify_identifier(self): a = zkutil.ZKLock('foo_name', zkconf=dict( hosts='127.0.0.1:21811', ), identifier='faked', on_lost=lambda: True) b = zkutil.ZKLock('foo_name', zkconf=dict( hosts='127.0.0.1:21811', ), identifier='faked', on_lost=lambda: True) a.acquire() b.acquire() dd('a and b has the same identifier thus they both can acquire the lock') def test_release_listener_removed(self): self.lck.release() self.assertNotIn(self.lck.on_connection_change, self.zk.state_listeners) def test_release_owning_client_stopped(self): l = zkutil.ZKLock('foo_name', zkconf=dict( hosts='127.0.0.1:21811', ), on_lost=lambda: True) l.release() self.assertTrue(l.zkclient._stopped.is_set())
def test_init_hierarchy(self): auth = ('digest', 'aa', 'pw_aa') hosts = '127.0.0.1:21811' users = {'aa': 'pw_aa', 'bb': 'pw_bb', 'cc': 'pw_cc'} hierarchy = { 'node1': { '__val__': 'node1_val', '__acl__': {'aa': 'cdrwa', 'bb': 'rw'}, 'node11': { '__val__': 'node11_val', '__acl__': {'aa': 'cdrwa', 'cc': 'r'}, }, 'node12': { '__val__': 'node12_val', 'node121': {'__val__': 'node121_val'} }, 'node13': { '__acl__': {'aa': 'cdrwa'} } }, 'node2': { '__val__': 'node2_val', 'node21': {'__val__': 'node21_val'}, 'node22': {'__acl__': {'aa': 'rwa'}} }, 'node3': { '__acl__': {'aa': 'carw', 'cc': 'r'}, 'node31': {'node311': {'node3111': {}, 'node3112': {}}} } } zkutil.init_hierarchy(hosts, hierarchy, users, auth) zkcli = KazooClient(hosts) zkcli.start() zkcli.add_auth('digest', 'aa:pw_aa') expected_nodes = ( ('/node1', '"node1_val"', [('digest', 'aa', 'cdrwa'), ('digest', 'bb', 'rw')], set(['node11', 'node12', 'node13'])), ('/node1/node11', '"node11_val"', [('digest', 'aa', 'cdrwa'), ('digest', 'cc', 'r')], set([])), ('/node1/node12', '"node12_val"', [('digest', 'aa', 'cdrwa'), ('digest', 'bb', 'rw')], set(['node121'])), ('/node1/node12/node121', '"node121_val"', [('digest', 'aa', 'cdrwa'), ('digest', 'bb', 'rw')], set([])), ('/node1/node13', '{}', [('digest', 'aa', 'cdrwa')], set([])), ('/node2', '"node2_val"', [('world', 'anyone', 'cdrwa')], set(['node21', 'node22'])), ('/node2/node21', '"node21_val"', [('world', 'anyone', 'cdrwa')], set([])), ('/node2/node22', '{}', [('digest', 'aa', 'rwa')], set([])), ('/node3', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set(['node31'])), ('/node3/node31', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set(['node311'])), ('/node3/node31/node311', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set(['node3111', 'node3112'])), ('/node3/node31/node311/node3111', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set([])), ('/node3/node31/node311/node3112', '{}', [('digest', 'aa', 'rwca'), ('digest', 'cc', 'r')], set([])), ) for node, val, acl, children in expected_nodes: actual_acl = zkutil.parse_kazoo_acl(zkcli.get_acls(node)[0]) self.assertEqual(val, zkcli.get(node)[0]) self.assertEqual(acl, actual_acl) self.assertEqual(children, set(zkcli.get_children(node))) zkcli.stop()
class WebWindow(object): def setupUi(self, Window): Window.setObjectName("Window") self.centralwidget = QtWidgets.QWidget(Window) self.centralwidget.setObjectName("centralwidget") self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") self.zk = None self.webView = QtWebKitWidgets.QWebView(self.centralwidget) self.webView.setObjectName("webView") self.webView.setRenderHint(QPainter.Antialiasing, True) self.webView.setRenderHint(QPainter.TextAntialiasing, True) self.webView.setRenderHint(QPainter.SmoothPixmapTransform, True) self.webView.setRenderHint(QPainter.HighQualityAntialiasing, True) self.webView.setPage(WebPage()) frame = self.webView.page().mainFrame() frame.javaScriptWindowObjectCleared.connect(self.initJsComm) self.verticalLayout.addWidget(self.webView) Window.setCentralWidget(self.centralwidget) self.retranslateUi(Window) QtCore.QMetaObject.connectSlotsByName(Window) self.loadDefaultAcl() def retranslateUi(self, Window): _translate = QtCore.QCoreApplication.translate Window.setWindowTitle(_translate("Window", "Zookeeper GUI")) def loadLocalFile(self, filename): localdir = os.path.abspath(sys.path[0]) if os.path.isfile(localdir): localdir = os.path.dirname(localdir) self.webView.setUrl( QtCore.QUrl.fromLocalFile(localdir+'/'+filename) ) def getCfgVar(self, name): localdir = os.path.abspath(sys.path[0]) if os.path.isfile(localdir): localdir = os.path.dirname(localdir) cfg = {} obj = None try: obj = open(localdir+'/cfg.json','r') cfg = json.loads(obj.read()) except Exception as e: logging.info(str(e)) finally: if obj is not None: obj.close() if name in cfg: return str(cfg[name]) return '' def setCfgVar(self, name, value): localdir = os.path.abspath(sys.path[0]) if os.path.isfile(localdir): localdir = os.path.dirname(localdir) cfg = {} obj = None try: obj = open(localdir+'/cfg.json','r') cfg = json.loads(obj.read()) except Exception as e: pass finally: if obj is not None: obj.close() cfg[name] = value obj = None try: obj = open(localdir+'/cfg.json','w') obj.truncate() obj.write(json.dumps(cfg)) except Exception as e: logging.info(str(e)) finally: if obj is not None: obj.close() def makeDigestCred(self, user, plain_pass): m = hashlib.sha1( bytes(user,'utf8') + b':' + bytes(plain_pass,'utf8') ).digest() return user+':'+base64.b64encode(m).strip().decode('utf8') def initJsComm(self): frame = self.webView.page().mainFrame() frame.addToJavaScriptWindowObject('py',self) @pyqtSlot(str) def jsSetWinTitle(self, title): _translate = QtCore.QCoreApplication.translate self.setWindowTitle(_translate("Window", title)) @pyqtSlot(str, result=str) def jsCheckYaml(self, s): try: a = yaml.load(s) except Exception as e: return str(e) if a is None: return 'Failed' return '' @pyqtSlot(str,result=str) def jsGetCfg(self, name): return self.getCfgVar(name) @pyqtSlot(str,str) def jsSetCfg(self, name, value): self.setCfgVar(name, value) def loadDefaultAcl(self): self.updateDefaultAclCache( self.getCfgVar('defaultacl') ) def updateDefaultAclCache(self, list_str): if list_str is not None and len(list_str)>0: cache = json.loads(list_str) self.default_acl_plain = [] self.default_acl = [] for one in cache: if(one['scheme']=='world'): self.default_acl_plain.append(one) acl = kazoo.security.ACL( one['perm'], kazoo.security.Id('world', 'anyone') ) self.default_acl.append(acl) elif(one['scheme']=='digest'): self.default_acl_plain.append(one) if 'id' in one: acl = kazoo.security.ACL( one['perm'], kazoo.security.Id('digest', one['id']) ) else: acl = kazoo.security.ACL( one['perm'], kazoo.security.Id('digest', self.makeDigestCred(one['user'],one['pass'])) ) self.default_acl.append(acl) elif(one['scheme']=='ip'): self.default_acl_plain.append(one) acl = kazoo.security.ACL( one['perm'], kazoo.security.Id('ip', one['ip']) ) self.default_acl.append(acl) else: self.default_acl_plain = [] self.default_acl = None @pyqtSlot(str,result=str) def jsSetDefaultAcl(self, list_str): self.updateDefaultAclCache(list_str) self.setCfgVar('defaultacl', json.dumps(self.default_acl_plain)) @pyqtSlot(result=str) def jsGetDefaultAcl(self): return json.dumps(self.default_acl_plain) @pyqtSlot() def jsGetZk(self): return self.zk @pyqtSlot(result=int) def jsZkIsConnected(self): if self.zk is not None: return int(self.zk.state=='CONNECTED') return 0 @pyqtSlot(str, str, result=str) def jsZkConnect(self,host, auth_list_str): try: if self.zk is not None: #self.zk.remove_listener(self.onZkStateChange) self.zk.stop() self.zk.close() self.zk = KazooClient(hosts=host) #self.zk.add_listener(self.onZkStateChange) self.zk.start(15) auth_list = json.loads(auth_list_str) for one in auth_list: cred = self.makeDigestCred(one['user'], one['pass']) self.zk.add_auth('digest', one['user']+':'+one['pass']) except Exception as e: logging.error("jsZkConnect, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) return '' #def onZkStateChange(self,state): # frame = self.webView.page().mainFrame() # frame.evaluateJavaScript("onPyZkStateChange('"+state+"')") @pyqtSlot(str, result=QVariant) def jsZkGetChildren(self, path): try: logging.info("jsZkGetChildren, path="+path) children = self.zk.get_children(path) except NoNodeError: logging.error("jsZkGetChildren, NoNodeError") return QVariant({"err":"node not exists"}) except Exception as e: logging.error("jsZkGetChildren, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return QVariant({"err":str(e)+', traceback='+str(strlist)}) return QVariant({"err":"", "children":children}) @pyqtSlot(str, result=QVariant) def jsZkGet(self, path): try: logging.info("jsZkGet, path="+path) ret = self.zk.get(path) except NoNodeError: logging.error("jsZkGet, NoNodeError") return QVariant({"err":"node not exists"}) except Exception as e: logging.error("jsZkGet, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return QVariant({"err":str(e)+', traceback='+str(strlist)}) ctime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ret[1].ctime/1000)) mtime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ret[1].mtime/1000)) stat = {'ctime':ctime,'mtime':mtime,'version':ret[1].version} data = '' if ret[0] is not None: data = ret[0].decode('utf8') else: logging.info('jsZkGet data None, path='+path) return QVariant({"err":"", "data":data, "stat":QVariant(stat)}) @pyqtSlot(str, str, int, result=str) def jsZkSet(self, path, data, ver): try: logging.info("jsZkSet, path="+path+',ver='+str(ver)) self.zk.set(path, bytes(data, 'utf8'),ver) except NoNodeError as e: logging.error("jsZkSet, NoNodeError") return "node not exists" except BadVersionError as e: logging.error("jsZkSet, BadVersionError") return "bad version" except Exception as e: logging.error("jsZkSet, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) return '' @pyqtSlot(str, result=QVariant) def jsZkGetAcl(self, path): try: logging.info("jsZkGetAcl, path="+path) ret = self.zk.get_acls(path) except NoNodeError as e: logging.error("jsZkGetAcl, NoNodeError") return QVariant({"err":"node not exists"}) except Exception as e: logging.error("jsZkGetAcl, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return QVariant({"err":str(e)+', traceback='+str(strlist)}) lst = [] for acl in ret[0]: dacl = {"perm":acl.perms,'scheme':acl.id.scheme,'id':acl.id.id} lst.append(QVariant(dacl)) stat = {'ctime':ret[1].ctime,'mtime':ret[1].mtime,'version':ret[1].version} return QVariant({"err":"", "acl_list":QVariant(lst), "stat":QVariant(stat)}) @pyqtSlot(str, str, result=str) def jsZkSetAcl(self, path, list_str): try: acl_list = None if list_str is not None and len(list_str)>0: cache = json.loads(list_str) acl_list = [] for one in cache: if(one['scheme']=='world'): acl = kazoo.security.ACL( one['perm'], kazoo.security.Id('world', 'anyone') ) acl_list.append(acl) elif(one['scheme']=='digest'): if 'id' in one: acl = kazoo.security.ACL( one['perm'], kazoo.security.Id('digest', one['id']) ) else: acl = kazoo.security.ACL( one['perm'], kazoo.security.Id('digest', self.makeDigestCred(one['user'],one['pass'])) ) acl_list.append(acl) elif(one['scheme']=='ip'): acl = kazoo.security.ACL( one['perm'], kazoo.security.Id('ip', one['ip']) ) acl_list.append(acl) self.zk.set_acls(path, acl_list) except NoNodeError as e: logging.error("jsZkSetAcl, NoNodeError") return "node not exists" except InvalidACLError as e: logging.error("jsZkSetAcl, InvalidACLError") t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return "invalid acl, traceback: "+str(strlist) except BadVersionError as e: logging.error("jsZkSetAcl, BadVersionError") return "bad version error" except Exception as e: logging.error("jsZkSetAcl, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) return '' @pyqtSlot(str,str,int,int,result=str) def jsZkCreate(self, path, data, ephem, seq): try: logging.info("jsZkCreate, path="+path) self.zk.create(path=path, value=bytes(data,'utf8'), ephemeral=bool(ephem), sequence=bool(seq)) if self.default_acl is not None and len(self.default_acl)>0: self.zk.set_acls(path, self.default_acl) except NoNodeError as e: logging.error("jsZkCreate, NoNodeError") return "node not exists" except NodeExistsError as e: logging.error("jsZkCreate, NodeExistsError") return "node already exists" except NoChildrenForEphemeralsError as e: logging.error("jsZkCreate, NoChildrenForEphemeralsError") return "ephemeral node can not have child" except Exception as e: logging.error("jsZkCreate, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) return '' @pyqtSlot(str, int, int, result=str) def jsZkDelete(self, path, ver, recursive): try: logging.info("jsZkDelete, path="+path+',ver='+str(ver)+', recursive='+str(recursive)) self.zk.delete(path, ver, bool(recursive)) except NoNodeError as e: logging.error("jsZkDelete, NoNodeError") return "node not exists" except BadVersionError as e: logging.error("jsZkDelete, BadVersionError") return "bad version" except NotEmptyError as e: logging.error("jsZkDelete, NotEmptyError") return "node not empty" except Exception as e: logging.error("jsZkDelete, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) return '' @pyqtSlot(str, str, int, int, result=str) def jsZkCopy(self, dest_path, ori_path, max_depth, children_only): logging.info("jsZkCopy, dest_path="+dest_path+", ori_path="+ori_path+", children_only="+str(children_only)) #copy node first if children_only==0: try: ori_data = self.zk.get(ori_path) if self.zk.exists(dest_path) is None: self.zk.create(dest_path, ori_data[0], acl=self.default_acl) else: self.zk.set(dest_path, ori_data[0]) except NoNodeError as e: logging.error("jsZkCopy, node, NoNodeError, ori_path="+ori_path+', dest_path='+dest_path) return "node not exists" except Exception as e: logging.error("jsZkCopy, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) #copy children path = '' try: max_depth -= 1 path = ori_path ori_children = self.zk.get_children(ori_path) for child in ori_children: path = ori_path+'/'+child ret = self.jsZkCopy(dest_path+'/'+child, ori_path+'/'+child, max_depth, 0) if isinstance(ret, QVariant): return ret elif len(ret)>0: return ret except NoNodeError as e: logging.error("jsZkCopy, child, NoNodeError") return "node not exists, path="+path except Exception as e: logging.error("jsZkCopy, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) return '' ''' @pyqtSlot(str, str, int, result=str) def jsZkCopyChildren(self, dest_path, ori_path, max_depth): path = '' try: max_depth -= 1; logging.info("jsZkCopyChildren, dest_path="+dest_path+", ori_path="+ori_path) path = ori_path ori_children = self.zk.get_children(ori_path) path = dest_path dest_children = self.zk.get_children(dest_path) for child in ori_children: if child in dest_children: return 'child ['+child+'] is found in both path' for child in ori_children: path = ori_path+'/'+child data = self.zk.get(path)[0] path = dest_path+'/'+child self.zk.create(path, data, acl=self.default_acl) if max_depth>0: ret = self.jsZkCopyChildren(dest_path+'/'+child, ori_path+'/'+child, max_depth) if len(ret)>0: return ret except NoNodeError as e: logging.info("jsZkCopyChildren, NoNodeError") return "node not exists, path="+path except ZookeeperError as e: logging.info("jsZkCopyChildren, ZookeeperError") return str(e)+', path='+path return '' ''' @pyqtSlot(str, int, result=str) def jsZkDeleteChildren(self, main_path, max_depth): path = '' try: max_depth -= 1 path = main_path logging.info("jsZkDeleteChildren, path="+main_path) children = self.zk.get_children(path) for child in children: path = main_path+'/'+child if max_depth>0: ret = self.jsZkDeleteChildren(path, max_depth) if len(ret)>0: return ret self.zk.delete(path) except NoNodeError as e: logging.error("jsZkDeleteChildren, NoNodeError") return "node not exists, path="+path except Exception as e: logging.error("jsZkDeleteChildren, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) return '' @pyqtSlot(str, str, int, int, result=str) def jsZkExport(self, local_dir, main_path, max_depth, without_acl): path = '' try: max_depth -= 1 path = main_path logging.info("jsZkExport, path="+main_path+' to local dir '+local_dir) data = self.zk.get(main_path) p = pathlib.Path(local_dir) if not p.exists(): p.mkdir(parents=True) elif not p.is_dir(): return 'local '+local_dir+' exists, but not a directory' for child in p.iterdir(): return 'local path '+local_dir+' is not empty, clear it first' p = pathlib.Path(local_dir+'/____data') p.touch() obj = open(str(p),'wb') try: if data[0] is not None: obj.write(data[0]) finally: obj.close() if not without_acl: ret = self.zk.get_acls(path) lst = [] if ret is not None: for acl in ret[0]: lst.append( {"perm":acl.perms,'scheme':acl.id.scheme,'id':acl.id.id} ) p = pathlib.Path(local_dir+'/____acl') p.touch() obj = open(str(p),'w') try: obj.write(json.dumps(lst)) finally: obj.close() children = self.zk.get_children(path) if children is not None: for child in children: if child=='zookeeper': continue path = main_path+'/'+child if max_depth>0: ret = self.jsZkExport(local_dir+'/'+child, path, max_depth, without_acl) if len(ret)>0: return ret except NoNodeError as e: logging.error("jsZkExport, NoNodeError") return "node not exists, path="+path except Exception as e: logging.error("jsZkExport, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) return '' @pyqtSlot(str, str, int, int, result=str) def jsZkImport(self, local_dir, main_path, max_depth, without_acl): path = '' try: max_depth -= 1 path = main_path logging.info("jsZkImport, path="+main_path+' from local dir '+local_dir) obj = open(local_dir+'/____data', 'rb') if self.zk.exists(path) is None: self.zk.create(path, obj.read(), acl=self.default_acl) else: self.zk.set(path, obj.read()) if not without_acl: obj = open(local_dir+'/____acl', 'r') acl_list = None list_str = obj.read() if list_str is not None and len(list_str)>0: cache = json.loads(list_str) acl_list = [] for one in cache: acl = kazoo.security.ACL( one['perm'], kazoo.security.Id(one['scheme'], one['id']) ) acl_list.append(acl) self.zk.set_acls(path, acl_list) p = pathlib.Path(local_dir) for child in p.iterdir(): if not child.is_dir(): continue if child.name=='zookeeper': continue ret = self.jsZkImport(str(child), path+'/'+child.name, max_depth, without_acl) if len(ret)>0: return ret except NoNodeError as e: logging.error("jsZkImport, NoNodeError") return "node not exists, path="+path except Exception as e: logging.error("jsZkImport, "+str(e)) t,v,tb = sys.exc_info() strlist = traceback.format_tb(tb) return str(e)+', traceback='+str(strlist) return ''