Statistics
| Branch: | Tag: | Revision:

root / pithos / backends / base.py @ 5d4c3f84

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