Statistics
| Branch: | Tag: | Revision:

root / pithos / backends / base.py @ f6c97079

History | View | Annotate | Download (15 kB)

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
class NotAllowedError(Exception):
35
    pass
36

    
37
class BaseBackend(object):
38
    """Abstract backend class that serves as a reference for actual implementations.
39
    
40
    The purpose of the backend is to provide the necessary functions for handling data
41
    and metadata. It is responsible for the actual storage and retrieval of information.
42
    
43
    Note that the account level is always valid as it is checked from another subsystem.
44
    
45
    When not replacing metadata/groups/policy, keys with empty values should be deleted.
46
    
47
    The following variables should be available:
48
        'hash_algorithm': Suggested is 'sha256'
49
        'block_size': Suggested is 4MB
50
    """
51
    
52
    def list_accounts(self, user, marker=None, limit=10000):
53
        """Return a list of accounts the user can access.
54
        
55
        Parameters:
56
            'marker': Start list from the next item after 'marker'
57
            'limit': Number of containers to return
58
        """
59
        return []
60
    
61
    def get_account_meta(self, user, account, until=None):
62
        """Return a dictionary with the account metadata.
63
        
64
        The keys returned are all user-defined, except:
65
            'name': The account name
66
            'count': The number of containers (or 0)
67
            'bytes': The total data size (or 0)
68
            'modified': Last modification timestamp (overall)
69
            'until_timestamp': Last modification until the timestamp provided
70
        
71
        Raises:
72
            NotAllowedError: Operation not permitted
73
        """
74
        return {}
75
    
76
    def update_account_meta(self, user, account, meta, replace=False):
77
        """Update the metadata associated with the account.
78
        
79
        Parameters:
80
            'meta': Dictionary with metadata to update
81
            'replace': Replace instead of update
82
        
83
        Raises:
84
            NotAllowedError: Operation not permitted
85
        """
86
        return
87
    
88
    def get_account_groups(self, user, account):
89
        """Return a dictionary with the user groups defined for this account.
90
        
91
        Raises:
92
            NotAllowedError: Operation not permitted
93
        """
94
        return {}
95
    
96
    def update_account_groups(self, user, account, groups, replace=False):
97
        """Update the groups associated with the account.
98
        
99
        Raises:
100
            NotAllowedError: Operation not permitted
101
            ValueError: Invalid data in groups
102
        """
103
        return
104
    
105
    def delete_account(self, user, account):
106
        """Delete the account with the given name.
107
        
108
        Raises:
109
            NotAllowedError: Operation not permitted
110
            IndexError: Account is not empty
111
        """
112
        return
113
    
114
    def list_containers(self, user, account, marker=None, limit=10000, until=None):
115
        """Return a list of container names existing under an account.
116
        
117
        Parameters:
118
            'marker': Start list from the next item after 'marker'
119
            'limit': Number of containers to return
120
        
121
        Raises:
122
            NotAllowedError: Operation not permitted
123
        """
124
        return []
125
    
126
    def get_container_meta(self, user, account, container, until=None):
127
        """Return a dictionary with the container metadata.
128
        
129
        The keys returned are all user-defined, except:
130
            'name': The container name
131
            'count': The number of objects
132
            'bytes': The total data size
133
            'modified': Last modification timestamp (overall)
134
            'until_timestamp': Last modification until the timestamp provided
135
        
136
        Raises:
137
            NotAllowedError: Operation not permitted
138
            NameError: Container does not exist
139
        """
140
        return {}
141
    
142
    def update_container_meta(self, user, account, container, meta, replace=False):
143
        """Update the metadata associated with the container.
144
        
145
        Parameters:
146
            'meta': Dictionary with metadata to update
147
            'replace': Replace instead of update
148
        
149
        Raises:
150
            NotAllowedError: Operation not permitted
151
            NameError: Container does not exist
152
        """
153
        return
154
    
155
    def get_container_policy(self, user, account, container):
156
        """Return a dictionary with the container policy.
157
        
158
        The keys returned are:
159
            'quota': The maximum bytes allowed (default is 0 - unlimited)
160
            'versioning': Can be 'auto', 'manual' or 'none' (default is 'manual')
161
        
162
        Raises:
163
            NotAllowedError: Operation not permitted
164
            NameError: Container does not exist
165
        """
166
        return {}
167
    
168
    def update_container_policy(self, user, account, container, policy, replace=False):
169
        """Update the policy associated with the account.
170
        
171
        Raises:
172
            NotAllowedError: Operation not permitted
173
            NameError: Container does not exist
174
            ValueError: Invalid policy defined
175
        """
176
        return
177
    
178
    def put_container(self, user, account, container, policy=None):
179
        """Create a new container with the given name.
180
        
181
        Raises:
182
            NotAllowedError: Operation not permitted
183
            NameError: Container already exists
184
            ValueError: Invalid policy defined
185
        """
186
        return
187
    
188
    def delete_container(self, user, account, container, until=None):
189
        """Delete/purge the container with the given name.
190
        
191
        Raises:
192
            NotAllowedError: Operation not permitted
193
            NameError: Container does not exist
194
            IndexError: Container is not empty
195
        """
196
        return
197
    
198
    def list_objects(self, user, account, container, prefix='', delimiter=None, marker=None, limit=10000, virtual=True, keys=[], until=None):
199
        """Return a list of object (name, version_id) tuples existing under a container.
200
        
201
        Parameters:
202
            'prefix': List objects starting with 'prefix'
203
            'delimiter': Return unique names before 'delimiter' and after 'prefix'
204
            'marker': Start list from the next item after 'marker'
205
            'limit': Number of objects to return
206
            'virtual': If not set, the result will only include names starting\
207
                       with 'prefix' and ending without a 'delimiter' or with\
208
                       the first occurance of the 'delimiter' after 'prefix'.\
209
                       If set, the result will include all names after 'prefix',\
210
                       up to and including the 'delimiter' if it is found
211
            'keys': Include objects that have meta with the keys in the list
212
        
213
        Raises:
214
            NotAllowedError: Operation not permitted
215
            NameError: Container does not exist
216
        """
217
        return []
218
    
219
    def list_object_meta(self, user, account, container, until=None):
220
        """Return a list with all the container's object meta keys.
221
        
222
        Raises:
223
            NotAllowedError: Operation not permitted
224
            NameError: Container does not exist
225
        """
226
        return []
227
    
228
    def get_object_meta(self, user, account, container, name, version=None):
229
        """Return a dictionary with the object metadata.
230
        
231
        The keys returned are all user-defined, except:
232
            'name': The object name
233
            'bytes': The total data size
234
            'modified': Last modification timestamp (overall)
235
            'modified_by': The user that committed the object (version requested)
236
            'version': The version identifier
237
            'version_timestamp': The version's modification timestamp
238
        
239
        Raises:
240
            NotAllowedError: Operation not permitted
241
            NameError: Container/object does not exist
242
            IndexError: Version does not exist
243
        """
244
        return {}
245
    
246
    def update_object_meta(self, user, account, container, name, meta, replace=False):
247
        """Update the metadata associated with the object.
248
        
249
        Parameters:
250
            'meta': Dictionary with metadata to update
251
            'replace': Replace instead of update
252
        
253
        Raises:
254
            NotAllowedError: Operation not permitted
255
            NameError: Container/object does not exist
256
        """
257
        return
258
    
259
    def get_object_permissions(self, user, account, container, name):
260
        """Return the path from which this object gets its permissions from,\
261
        along with a dictionary containing the permissions.
262
        
263
        The keys are:
264
            'read': The object is readable by the users/groups in the list
265
            'write': The object is writable by the users/groups in the list
266
        
267
        Raises:
268
            NotAllowedError: Operation not permitted
269
            NameError: Container/object does not exist
270
        """
271
        return {}
272
    
273
    def update_object_permissions(self, user, account, container, name, permissions):
274
        """Update the permissions associated with the object.
275
        
276
        Parameters:
277
            'permissions': Dictionary with permissions to update
278
        
279
        Raises:
280
            NotAllowedError: Operation not permitted
281
            NameError: Container/object does not exist
282
            ValueError: Invalid users/groups in permissions
283
            AttributeError: Can not set permissions, as this object\
284
                is already shared/private by another object higher\
285
                in the hierarchy, or setting permissions here will\
286
                invalidate other permissions deeper in the hierarchy
287
        """
288
        return
289
    
290
    def get_object_public(self, user, account, container, name):
291
        """Return the public URL of the object if applicable.
292
        
293
        Raises:
294
            NotAllowedError: Operation not permitted
295
            NameError: Container/object does not exist
296
        """
297
        return None
298
    
299
    def update_object_public(self, user, account, container, name, public):
300
        """Update the public status of the object.
301
        
302
        Parameters:
303
            'public': Boolean value
304
        
305
        Raises:
306
            NotAllowedError: Operation not permitted
307
            NameError: Container/object does not exist
308
        """
309
        return
310
    
311
    def get_object_hashmap(self, user, account, container, name, version=None):
312
        """Return the object's size and a list with partial hashes.
313
        
314
        Raises:
315
            NotAllowedError: Operation not permitted
316
            NameError: Container/object does not exist
317
            IndexError: Version does not exist
318
        """
319
        return 0, []
320
    
321
    def update_object_hashmap(self, user, account, container, name, size, hashmap, meta={}, replace_meta=False, permissions=None):
322
        """Create/update an object with the specified size and partial hashes.
323
        
324
        Parameters:
325
            'dest_meta': Dictionary with metadata to change
326
            'replace_meta': Replace metadata instead of update
327
            'permissions': Updated object permissions
328
        
329
        Raises:
330
            NotAllowedError: Operation not permitted
331
            NameError: Container does not exist
332
            ValueError: Invalid users/groups in permissions
333
            AttributeError: Can not set permissions
334
        """
335
        return
336
    
337
    def copy_object(self, user, account, src_container, src_name, dest_container, dest_name, dest_meta={}, replace_meta=False, permissions=None, src_version=None):
338
        """Copy an object's data and metadata.
339
        
340
        Parameters:
341
            'dest_meta': Dictionary with metadata to change from source to destination
342
            'replace_meta': Replace metadata instead of update
343
            'permissions': New object permissions
344
            'src_version': Copy from the version provided
345
        
346
        Raises:
347
            NotAllowedError: Operation not permitted
348
            NameError: Container/object does not exist
349
            IndexError: Version does not exist
350
            ValueError: Invalid users/groups in permissions
351
            AttributeError: Can not set permissions
352
        """
353
        return
354
    
355
    def move_object(self, user, account, src_container, src_name, dest_container, dest_name, dest_meta={}, replace_meta=False, permissions=None):
356
        """Move an object's data and metadata.
357
        
358
        Parameters:
359
            'dest_meta': Dictionary with metadata to change from source to destination
360
            'replace_meta': Replace metadata instead of update
361
            'permissions': New object permissions
362
        
363
        Raises:
364
            NotAllowedError: Operation not permitted
365
            NameError: Container/object does not exist
366
            ValueError: Invalid users/groups in permissions
367
            AttributeError: Can not set permissions
368
        """
369
        return
370
    
371
    def delete_object(self, user, account, container, name, until=None):
372
        """Delete/purge an object.
373
        
374
        Raises:
375
            NotAllowedError: Operation not permitted
376
            NameError: Container/object does not exist
377
        """
378
        return
379
    
380
    def list_versions(self, user, account, container, name):
381
        """Return a list of all (version, version_timestamp) tuples for an object.
382
        
383
        Raises:
384
            NotAllowedError: Operation not permitted
385
        """
386
        return []
387
    
388
    def get_block(self, hash):
389
        """Return a block's data.
390
        
391
        Raises:
392
            NameError: Block does not exist
393
        """
394
        return ''
395
    
396
    def put_block(self, data):
397
        """Store a block and return the hash."""
398
        return 0
399
    
400
    def update_block(self, hash, data, offset=0):
401
        """Update a known block and return the hash.
402
        
403
        Raises:
404
            IndexError: Offset or data outside block limits
405
        """
406
        return 0