[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