Example #1
0
from kazoo.client import KazooClient
from kazoo.security import ACL, make_acl

client = KazooClient(hosts='127.0.0.1:2181')
try:
    client.start()
    # world auth digest ip
    scheme = ''
    # anyone
    # addauth digest user:pwd
    # username:base64
    #
    ID = ''
    # r = client.add_auth('digest', 'xjj:123456')
    # print(r, type(r))
    r = client.set_acls('/a', [make_acl('auth', 'xyj:123123', all=True)])
    # r = client.get_acls('/a')
    print(r, type(r), len(r))
finally:
    client.stop()
Example #2
0
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
Example #3
0
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 ''