[Checkins] SVN: zc.zk/trunk/src/zc/zk/ - Added ``create_recursive`` method.
Jim Fulton
jim at zope.com
Fri Jan 27 21:08:06 UTC 2012
Log message for revision 124219:
- Added ``create_recursive`` method.
- Fixed testing: Added access-control fidelity to the testing
ZooKeeper stub.
Changed:
U zc.zk/trunk/src/zc/zk/README.txt
U zc.zk/trunk/src/zc/zk/__init__.py
U zc.zk/trunk/src/zc/zk/ephemeral_node_recovery_on_session_reestablishment.test
U zc.zk/trunk/src/zc/zk/testing.py
U zc.zk/trunk/src/zc/zk/tests.py
-=-
Modified: zc.zk/trunk/src/zc/zk/README.txt
===================================================================
--- zc.zk/trunk/src/zc/zk/README.txt 2012-01-27 18:00:02 UTC (rev 124218)
+++ zc.zk/trunk/src/zc/zk/README.txt 2012-01-27 21:08:05 UTC (rev 124219)
@@ -949,6 +949,10 @@
them up when they are no-longer used. If you only want to get the
list of children once, use ``get_children``.
+``create_recursive(path, data, acl)``
+ Create a non-ephemeral node at the given path, creating parent
+ nodes if necessary.
+
``close()``
Close the ZooKeeper session.
@@ -1164,8 +1168,11 @@
0.7.0 (2012-01-27)
------------------
-- Added ``walk`` and ``is_ephemeral`` methods.
+- Added ``walk``, ``is_ephemeral``, and ``create_recursive`` methods.
+- Fixed testing: Added access-control fidelity to the testing
+ ZooKeeper stub.
+
- Fixed testing: There were spurious errors when closing a testing
ZooKeeper connection in which ephemeral nodes were created and when
they were deleted by another session.
Modified: zc.zk/trunk/src/zc/zk/__init__.py
===================================================================
--- zc.zk/trunk/src/zc/zk/__init__.py 2012-01-27 18:00:02 UTC (rev 124218)
+++ zc.zk/trunk/src/zc/zk/__init__.py 2012-01-27 21:08:05 UTC (rev 124219)
@@ -380,6 +380,15 @@
def children(self, path):
return Children(self, path)
+ def create_recursive(self, path, data, acl):
+ if self.exists(path):
+ return
+ base, name = path.rsplit('/', 1)
+ if base:
+ self.create_recursive(base, data, acl)
+ if not self.exists(path):
+ self.create(path, data, acl)
+
def get_properties(self, path):
return decode(self.get(path)[0])
Modified: zc.zk/trunk/src/zc/zk/ephemeral_node_recovery_on_session_reestablishment.test
===================================================================
--- zc.zk/trunk/src/zc/zk/ephemeral_node_recovery_on_session_reestablishment.test 2012-01-27 18:00:02 UTC (rev 124218)
+++ zc.zk/trunk/src/zc/zk/ephemeral_node_recovery_on_session_reestablishment.test 2012-01-27 21:08:05 UTC (rev 124219)
@@ -27,7 +27,10 @@
First, some non-standard data and acl:
- >>> acl = [zc.zk.world_permission(3)]
+ >>> acl = [
+ ... zc.zk.world_permission(
+ ... zookeeper.PERM_READ | zookeeper.PERM_WRITE | zookeeper.PERM_ADMIN
+ ... )]
>>> zk.register_server('/fooservice/providers', 'test', acl, a=1)
>>> zk.print_tree('/fooservice/providers')
/providers
@@ -68,7 +71,9 @@
We track changes:
>>> _ = zk.set('/fooservice/providers/test', 'y')
- >>> acl2 = [zc.zk.world_permission(4)]
+ >>> acl2 = [zc.zk.world_permission(zookeeper.PERM_CREATE |
+ ... zookeeper.PERM_ADMIN |
+ ... zookeeper.PERM_READ)]
>>> _ = zk.set_acl('/fooservice/providers/test', 0, acl2)
>>> ZooKeeper.sessions[zk.handle].disconnect()
>>> ZooKeeper.sessions[zk.handle].expire()
@@ -101,7 +106,8 @@
>>> zk.aset('/fooservice/providers/test', 'y', -1, check_async(0))
0
>>> event.wait(1); assert_(event.is_set())
- >>> acl2 = [zc.zk.world_permission(4)]
+ >>> acl2 = [zc.zk.world_permission(zookeeper.PERM_CREATE |
+ ... zookeeper.PERM_READ)]
>>> _ = zk.aset_acl('/fooservice/providers/test', 0, acl2, check_async(0))
>>> event.wait(1); assert_(event.is_set())
>>> ZooKeeper.sessions[zk.handle].disconnect()
Modified: zc.zk/trunk/src/zc/zk/testing.py
===================================================================
--- zc.zk/trunk/src/zc/zk/testing.py 2012-01-27 18:00:02 UTC (rev 124218)
+++ zc.zk/trunk/src/zc/zk/testing.py 2012-01-27 21:08:05 UTC (rev 124219)
@@ -335,7 +335,7 @@
self.root.clear_watchers(session.handle, event, state)
for path in list(session.nodes):
try:
- self._delete(session.handle, path)
+ self._delete(session.handle, path, clear=True)
except zookeeper.NoNodeException:
pass # deleted in another session, perhaps
@@ -386,6 +386,9 @@
if base.endswith('/'):
raise zookeeper.BadArgumentsException('bad arguments')
node = self._traverse(base)
+ for p in node.acl:
+ if not (p['perms'] & zookeeper.PERM_CREATE):
+ raise zookeeper.NoAuthException('not authenticated')
if name in node.children:
raise zookeeper.NodeExistsException()
node.children[name] = newnode = Node(data)
@@ -400,7 +403,7 @@
return self._doasync(completion, handle, 1,
self.create, handle, path, data, acl, flags)
- def _delete(self, handle, path, version=-1):
+ def _delete(self, handle, path, version=-1, clear=False):
node = self._traverse(path)
if version != -1 and node.version != version:
raise zookeeper.BadVersionException('bad version')
@@ -408,6 +411,10 @@
raise zookeeper.NotEmptyException('not empty')
base, name = path.rsplit('/', 1)
bnode = self._traverse(base)
+ if not clear:
+ for p in bnode.acl:
+ if not (p['perms'] & zookeeper.PERM_DELETE):
+ raise zookeeper.NoAuthException('not authenticated', path)
del bnode.children[name]
node.deleted(handle, zookeeper.CONNECTED_STATE, path)
bnode.children_changed(handle, zookeeper.CONNECTED_STATE, base)
@@ -445,6 +452,9 @@
with self.lock:
self._check_handle(handle)
node = self._traverse(path)
+ for p in node.acl:
+ if not (p['perms'] & zookeeper.PERM_READ):
+ raise zookeeper.NoAuthException('not authenticated')
if watch:
node.child_watchers += ((handle, watch), )
return list(node.children)
@@ -457,6 +467,9 @@
with self.lock:
self._check_handle(handle)
node = self._traverse(path)
+ for p in node.acl:
+ if not (p['perms'] & zookeeper.PERM_READ):
+ raise zookeeper.NoAuthException('not authenticated')
if watch:
node.watchers += ((handle, watch), )
return node.data, node.meta()
@@ -473,6 +486,9 @@
with self.lock:
self._check_handle(handle)
node = self._traverse(path)
+ for p in node.acl:
+ if not (p['perms'] & zookeeper.PERM_WRITE):
+ raise zookeeper.NoAuthException('not authenticated')
if version != -1 and node.version != version:
raise zookeeper.BadVersionException('bad version')
node.data = data
@@ -500,6 +516,9 @@
with self.lock:
self._check_handle(handle)
node = self._traverse(path)
+ for p in node.acl:
+ if not (p['perms'] & zookeeper.PERM_ADMIN):
+ raise zookeeper.NoAuthException('not authenticated', path)
if aversion != node.aversion:
raise zookeeper.BadVersionException("bad version")
node.aversion += 1
Modified: zc.zk/trunk/src/zc/zk/tests.py
===================================================================
--- zc.zk/trunk/src/zc/zk/tests.py 2012-01-27 18:00:02 UTC (rev 124218)
+++ zc.zk/trunk/src/zc/zk/tests.py 2012-01-27 21:08:05 UTC (rev 124219)
@@ -1463,9 +1463,44 @@
>>> zk.close()
"""
-# XXX
-# deleting linked node
+def create_recursive():
+ """
+ >>> zk = zc.zk.ZooKeeper('zookeeper.example.com:2181')
+ >>> zk.create_recursive('/fooservice/a/b/c', '', zc.zk.OPEN_ACL_UNSAFE)
+ >>> acl = [dict(perms=zookeeper.PERM_CREATE |
+ ... zookeeper.PERM_READ |
+ ... zookeeper.PERM_DELETE,
+ ... scheme='world', id='anyone')]
+ >>> zk.create_recursive('/a/b/c', '{"z": 1}', acl)
+ >>> zk.print_tree()
+ /a
+ z = 1
+ /b
+ z = 1
+ /c
+ z = 1
+ /fooservice
+ database = u'/databases/foomain'
+ favorite_color = u'red'
+ threads = 1
+ /a
+ /b
+ /c
+ /providers
+
+ >>> for path in zk.walk('/fooservice/a'):
+ ... if zk.get_acl(path)[1] != zc.zk.OPEN_ACL_UNSAFE:
+ ... print 'oops'
+
+ >>> for path in zk.walk('/a'):
+ ... if zk.get_acl(path)[1] != acl:
+ ... print 'oops'
+
+ >>> zk.close()
+ """
+
+
event = threading.Event()
def check_async(show=True, expected_status=0):
event.clear()
More information about the checkins
mailing list