Revision 5e7485da

b/docs/source/backends.rst
33 33
   :members:
34 34
   :undoc-members:
35 35

  
36
Policy
37
~~~~~~
38

  
39
.. automodule:: pithos.backends.lib.sqlite.policy
40
   :show-inheritance:
41
   :members:
42
   :undoc-members:
43

  
44 36
Permissions
45 37
~~~~~~~~~~~
46 38

  
b/pithos/backends/lib/sqlalchemy/__init__.py
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
# 
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
# 
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
# 
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
1 34
from dbwrapper import DBWrapper
2 35
from node import Node
3 36
from permissions import Permissions
4
from policy import Policy
5 37

  
6
__all__ = ["DBWrapper", "Node", "Permissions", "Policy"]
38
__all__ = ["DBWrapper", "Node", "Permissions"]
7 39

  
b/pithos/backends/lib/sqlalchemy/node.py
119 119
        # place an index on path
120 120
        Index('idx_nodes_path', self.nodes.c.path)
121 121
        
122
        #create policy table
123
        columns=[]
124
        columns.append(Column('node', Integer,
125
                              ForeignKey('nodes.node',
126
                                         ondelete='CASCADE',
127
                                         onupdate='CASCADE'),
128
                              primary_key=True))
129
        columns.append(Column('key', String(255), primary_key=True))
130
        columns.append(Column('value', String(255)))
131
        self.policies = Table('policy', metadata, *columns, mysql_engine='InnoDB')
132
        
122 133
        #create statistics table
123 134
        columns=[]
124 135
        columns.append(Column('node', Integer,
......
366 377
        self.conn.execute(s).close()
367 378
        return True
368 379
    
380
    def policy_get(self, node):
381
        s = select([self.policies.c.key, self.policies.c.value],
382
            self.policies.c.node==node)
383
        r = self.conn.execute(s)
384
        d = dict(r.fetchall())
385
        r.close()
386
        return d
387
    
388
    def policy_set(self, node, policy):
389
        #insert or replace
390
        for k, v in policy.iteritems():
391
            s = self.policies.update().where(and_(self.policies.c.node == node,
392
                                                  self.policies.c.key == k))
393
            s = s.values(value = v)
394
            rp = self.conn.execute(s)
395
            rp.close()
396
            if rp.rowcount == 0:
397
                s = self.policies.insert()
398
                values = {'node':node, 'key':k, 'value':v}
399
                r = self.conn.execute(s, values)
400
                r.close()
401
    
369 402
    def statistics_get(self, node, cluster=0):
370 403
        """Return population, total size and last mtime
371 404
           for all versions under node that belong to the cluster.
/dev/null
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
# 
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
# 
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
# 
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
34
from sqlalchemy import Table, Column, String, MetaData
35
from sqlalchemy.sql import select
36
from sqlalchemy.sql import and_
37
from dbworker import DBWorker
38

  
39

  
40
class Policy(DBWorker):
41
    """Paths can be assigned key, value pairs, representing policy."""
42
    
43
    def __init__(self, **params):
44
        DBWorker.__init__(self, **params)
45
        metadata = MetaData()
46
        columns=[]
47
        columns.append(Column('path', String(2048), index=True))
48
        columns.append(Column('key', String(255)))
49
        columns.append(Column('value', String(255)))
50
        self.policies = Table('policy', metadata, *columns, mysql_engine='InnoDB')
51
        metadata.create_all(self.engine)
52
    
53
    def policy_set(self, path, policy):
54
        #insert or replace
55
        for k, v in policy.iteritems():
56
            s = self.policies.update().where(and_(self.policies.c.path == path,
57
                                                  self.policies.c.key == k))
58
            s = s.values(value = v)
59
            rp = self.conn.execute(s)
60
            rp.close()
61
            if rp.rowcount == 0:
62
                s = self.policies.insert()
63
                values = {'path':path, 'key':k, 'value':v}
64
                r = self.conn.execute(s, values)
65
                r.close()
66
    
67
    def policy_unset(self, path):
68
        s = self.policies.delete().where(self.policies.c.path==path)
69
        r = self.conn.execute(s)
70
        r.close()
71
    
72
    def policy_get(self, path):
73
        s = select([self.policies.c.key, self.policies.c.value],
74
            self.policies.c.path==self.policies.c.path==path)
75
        r = self.conn.execute(s)
76
        d = dict(r.fetchall())
77
        r.close()
78
        return d
b/pithos/backends/lib/sqlite/__init__.py
34 34
from dbwrapper import DBWrapper
35 35
from node import Node
36 36
from permissions import Permissions
37
from policy import Policy
38 37

  
39
__all__ = ["DBWrapper", "Node", "Permissions", "Policy"]
38
__all__ = ["DBWrapper", "Node", "Permissions"]
40 39

  
b/pithos/backends/lib/sqlite/node.py
111 111
                            foreign key (parent)
112 112
                            references nodes(node)
113 113
                            on update cascade
114
                            on delete cascade )""")
114
                            on delete cascade ) """)
115 115
        execute(""" create unique index if not exists idx_nodes_path
116 116
                    on nodes(path) """)
117 117
        
118
        execute(""" create table if not exists policy
119
                          ( node   integer,
120
                            key    text,
121
                            value  text,
122
                            primary key (node, key)
123
                            foreign key (node)
124
                            references nodes(node)
125
                            on update cascade
126
                            on delete cascade ) """)
127
        
118 128
        execute(""" create table if not exists statistics
119 129
                          ( node       integer,
120 130
                            population integer not null default 0,
......
125 135
                            foreign key (node)
126 136
                            references nodes(node)
127 137
                            on update cascade
128
                            on delete cascade )""")
138
                            on delete cascade ) """)
129 139
        
130 140
        execute(""" create table if not exists versions
131 141
                          ( serial     integer primary key,
......
323 333
        self.execute(q, (node,))
324 334
        return True
325 335
    
336
    def policy_get(self, node):
337
        q = "select key, value from policy where node = ?"
338
        self.execute(q, (node,))
339
        return dict(self.fetchall())
340
    
341
    def policy_set(self, node, policy):
342
        q = "insert or replace into policy (node, key, value) values (?, ?, ?)"
343
        self.executemany(q, ((node, k, v) for k, v in policy.iteritems()))
344
    
326 345
    def statistics_get(self, node, cluster=0):
327 346
        """Return population, total size and last mtime
328 347
           for all versions under node that belong to the cluster.
/dev/null
1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
# 
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
# 
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
# 
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

  
34
from dbworker import DBWorker
35

  
36

  
37
class Policy(DBWorker):
38
    """Paths can be assigned key, value pairs, representing policy."""
39
    
40
    def __init__(self, **params):
41
        DBWorker.__init__(self, **params)
42
        execute = self.execute
43
        
44
        execute(""" create table if not exists policy
45
                          ( path  text,
46
                            key   text,
47
                            value text,
48
                            primary key (path, key) ) """)
49
    
50
    def policy_set(self, path, policy):
51
        q = "insert or replace into policy (path, key, value) values (?, ?, ?)"
52
        self.executemany(q, ((path, k, v) for k, v in policy.iteritems()))
53
    
54
    def policy_unset(self, path):
55
        q = "delete from policy where path = ?"
56
        self.execute(q, (path,))
57
    
58
    def policy_get(self, path):
59
        q = "select key, value from policy where path = ?"
60
        self.execute(q, (path,))
61
        return dict(self.fetchall())
b/pithos/backends/modular.py
132 132
        self.permissions = self.mod.permissions.Permissions(**params)
133 133
        for x in ['READ', 'WRITE']:
134 134
            setattr(self, x, getattr(self.mod.permissions, x))
135
        self.policy = self.mod.policy.Policy(**params)
136 135
        self.node = self.mod.node.Node(**params)
137 136
        for x in ['ROOTNODE', 'SERIAL', 'HASH', 'SIZE', 'MTIME', 'MUSER', 'CLUSTER']:
138 137
            setattr(self, x, getattr(self.mod.node, x))
......
313 312
            if container not in self._allowed_containers(user, account):
314 313
                raise NotAllowedError
315 314
            return {}
316
        path = self._lookup_container(account, container)[0]
317
        return self.policy.policy_get(path)
315
        path, node = self._lookup_container(account, container)
316
        return self.node.policy_get(node)
318 317
    
319 318
    @backend_method
320 319
    def update_container_policy(self, user, account, container, policy, replace=False):
......
323 322
        logger.debug("update_container_policy: %s %s %s %s", account, container, policy, replace)
324 323
        if user != account:
325 324
            raise NotAllowedError
326
        path = self._lookup_container(account, container)[0]
325
        path, node = self._lookup_container(account, container)
327 326
        self._check_policy(policy)
328 327
        if replace:
329 328
            for k, v in self.default_policy.iteritems():
330 329
                if k not in policy:
331 330
                    policy[k] = v
332
        self.policy.policy_set(path, policy)
331
        self.node.policy_set(node, policy)
333 332
    
334 333
    @backend_method
335 334
    def put_container(self, user, account, container, policy=None):
......
347 346
        if policy:
348 347
            self._check_policy(policy)
349 348
        path = '/'.join((account, container))
350
        self._put_path(user, self._lookup_account(account, True)[1], path)
349
        node = self._put_path(user, self._lookup_account(account, True)[1], path)
351 350
        for k, v in self.default_policy.iteritems():
352 351
            if k not in policy:
353 352
                policy[k] = v
354
        self.policy.policy_set(path, policy)
353
        self.node.policy_set(node, policy)
355 354
    
356 355
    @backend_method
357 356
    def delete_container(self, user, account, container, until=None):
......
372 371
        self.node.node_purge_children(node, inf, CLUSTER_HISTORY)
373 372
        self.node.node_purge_children(node, inf, CLUSTER_DELETED)
374 373
        self.node.node_remove(node)
375
        self.policy.policy_unset(path)
376 374
    
377 375
    @backend_method
378 376
    def list_objects(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, keys=[], shared=False, until=None):

Also available in: Unified diff