Implementation of bucket.list_versions
This commit is contained in:
parent
e972000bb4
commit
4cc45c3ac5
@ -3,6 +3,7 @@ import base64
|
|||||||
import datetime
|
import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
import copy
|
import copy
|
||||||
|
import itertools
|
||||||
|
|
||||||
from moto.core import BaseBackend
|
from moto.core import BaseBackend
|
||||||
from moto.core.utils import iso_8601_datetime, rfc_1123_datetime
|
from moto.core.utils import iso_8601_datetime, rfc_1123_datetime
|
||||||
@ -194,6 +195,18 @@ class S3Backend(BaseBackend):
|
|||||||
def get_bucket_versioning(self, bucket_name):
|
def get_bucket_versioning(self, bucket_name):
|
||||||
return self.buckets[bucket_name].versioning_status
|
return self.buckets[bucket_name].versioning_status
|
||||||
|
|
||||||
|
def get_bucket_versions(self, bucket_name, delimiter=None,
|
||||||
|
encoding_type=None,
|
||||||
|
key_marker=None,
|
||||||
|
max_keys=None,
|
||||||
|
version_id_marker=None):
|
||||||
|
bucket = self.buckets[bucket_name]
|
||||||
|
|
||||||
|
if any((delimiter, encoding_type, key_marker, version_id_marker)):
|
||||||
|
raise NotImplementedError(
|
||||||
|
"Called get_bucket_versions with some of delimiter, encoding_type, key_marker, version_id_marker")
|
||||||
|
|
||||||
|
return itertools.chain(*(l for _, l in bucket.keys.iterlists()))
|
||||||
def set_key(self, bucket_name, key_name, value, storage=None, etag=None):
|
def set_key(self, bucket_name, key_name, value, storage=None, etag=None):
|
||||||
key_name = clean_key_name(key_name)
|
key_name = clean_key_name(key_name)
|
||||||
|
|
||||||
@ -223,11 +236,16 @@ class S3Backend(BaseBackend):
|
|||||||
key.append_to_value(value)
|
key.append_to_value(value)
|
||||||
return key
|
return key
|
||||||
|
|
||||||
def get_key(self, bucket_name, key_name):
|
def get_key(self, bucket_name, key_name, version_id=None):
|
||||||
key_name = clean_key_name(key_name)
|
key_name = clean_key_name(key_name)
|
||||||
bucket = self.get_bucket(bucket_name)
|
bucket = self.get_bucket(bucket_name)
|
||||||
if bucket:
|
if bucket:
|
||||||
return bucket.keys.get(key_name)
|
if version_id is None:
|
||||||
|
return bucket.keys.get(key_name)
|
||||||
|
else:
|
||||||
|
for key in bucket.keys.getlist(key_name):
|
||||||
|
if str(key._version_id) == str(version_id):
|
||||||
|
return key
|
||||||
|
|
||||||
def initiate_multipart(self, bucket_name, key_name):
|
def initiate_multipart(self, bucket_name, key_name):
|
||||||
bucket = self.buckets[bucket_name]
|
bucket = self.buckets[bucket_name]
|
||||||
|
@ -77,6 +77,33 @@ class ResponseObject(object):
|
|||||||
versioning = self.backend.get_bucket_versioning(bucket_name)
|
versioning = self.backend.get_bucket_versioning(bucket_name)
|
||||||
template = Template(S3_BUCKET_GET_VERSIONING)
|
template = Template(S3_BUCKET_GET_VERSIONING)
|
||||||
return 200, headers, template.render(status=versioning)
|
return 200, headers, template.render(status=versioning)
|
||||||
|
elif 'versions' in querystring:
|
||||||
|
delimiter = querystring.get('delimiter', [None])[0]
|
||||||
|
encoding_type = querystring.get('encoding-type', [None])[0]
|
||||||
|
key_marker = querystring.get('key-marker', [None])[0]
|
||||||
|
max_keys = querystring.get('max-keys', [None])[0]
|
||||||
|
prefix = querystring.get('prefix', [None])[0]
|
||||||
|
version_id_marker = querystring.get('version-id-marker', [None])[0]
|
||||||
|
|
||||||
|
bucket = self.backend.get_bucket(bucket_name)
|
||||||
|
versions = self.backend.get_bucket_versions(
|
||||||
|
bucket_name,
|
||||||
|
delimiter=delimiter,
|
||||||
|
encoding_type=encoding_type,
|
||||||
|
key_marker=key_marker,
|
||||||
|
max_keys=max_keys,
|
||||||
|
version_id_marker=version_id_marker
|
||||||
|
)
|
||||||
|
template = Template(S3_BUCKET_GET_VERSIONS)
|
||||||
|
return 200, headers, template.render(
|
||||||
|
key_list=versions,
|
||||||
|
bucket=bucket,
|
||||||
|
prefix='',
|
||||||
|
max_keys='',
|
||||||
|
delimiter='',
|
||||||
|
is_truncated='false',
|
||||||
|
)
|
||||||
|
|
||||||
bucket = self.backend.get_bucket(bucket_name)
|
bucket = self.backend.get_bucket(bucket_name)
|
||||||
if bucket:
|
if bucket:
|
||||||
prefix = querystring.get('prefix', [None])[0]
|
prefix = querystring.get('prefix', [None])[0]
|
||||||
@ -236,7 +263,9 @@ class ResponseObject(object):
|
|||||||
count=len(parts),
|
count=len(parts),
|
||||||
parts=parts
|
parts=parts
|
||||||
)
|
)
|
||||||
key = self.backend.get_key(bucket_name, key_name)
|
version_id = query.get('versionId', [None])[0]
|
||||||
|
key = self.backend.get_key(
|
||||||
|
bucket_name, key_name, version_id=version_id)
|
||||||
if key:
|
if key:
|
||||||
headers.update(key.metadata)
|
headers.update(key.metadata)
|
||||||
return 200, headers, key.value
|
return 200, headers, key.value
|
||||||
@ -424,12 +453,14 @@ S3_DELETE_BUCKET_WITH_ITEMS_ERROR = """<?xml version="1.0" encoding="UTF-8"?>
|
|||||||
</Error>"""
|
</Error>"""
|
||||||
|
|
||||||
S3_BUCKET_VERSIONING = """
|
S3_BUCKET_VERSIONING = """
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
|
<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
|
||||||
<Status>{{ bucket_versioning_status }}</Status>
|
<Status>{{ bucket_versioning_status }}</Status>
|
||||||
</VersioningConfiguration>
|
</VersioningConfiguration>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
S3_BUCKET_GET_VERSIONING = """
|
S3_BUCKET_GET_VERSIONING = """
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
{% if status is none %}
|
{% if status is none %}
|
||||||
<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"/>
|
<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"/>
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -438,6 +469,32 @@ S3_BUCKET_GET_VERSIONING = """
|
|||||||
</VersioningConfiguration>
|
</VersioningConfiguration>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
S3_BUCKET_GET_VERSIONS = """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ListVersionsResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
|
||||||
|
<Name>{{ bucket.name }}</Name>
|
||||||
|
<Prefix>{{ prefix }}</Prefix>
|
||||||
|
<KeyMarker>{{ key_marker }}</KeyMarker>
|
||||||
|
<MaxKeys>{{ max_keys }}</MaxKeys>
|
||||||
|
<IsTruncated>{{ is_truncated }}</IsTruncated>
|
||||||
|
{% for key in key_list %}
|
||||||
|
<Version>
|
||||||
|
<Key>{{ key.name }}</Key>
|
||||||
|
<VersionId>{{ key._version_id }}</VersionId>
|
||||||
|
<IsLatest>false</IsLatest>
|
||||||
|
<LastModified>{{ key.last_modified_ISO8601 }}</LastModified>
|
||||||
|
<ETag>{{ key.etag }}</ETag>
|
||||||
|
<Size>{{ key.size }}</Size>
|
||||||
|
<StorageClass>{{ key.storage_class }}</StorageClass>
|
||||||
|
<Owner>
|
||||||
|
<ID>75aa57f09aa0c8caeab4f8c24e99d10f8e7faeebf76c078efc7c6caea54ba06a</ID>
|
||||||
|
<DisplayName>webfile</DisplayName>
|
||||||
|
</Owner>
|
||||||
|
</Version>
|
||||||
|
{% endfor %}
|
||||||
|
</ListVersionsResult>
|
||||||
|
"""
|
||||||
|
|
||||||
S3_DELETE_KEYS_RESPONSE = """<?xml version="1.0" encoding="UTF-8"?>
|
S3_DELETE_KEYS_RESPONSE = """<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
|
<DeleteResult xmlns="http://s3.amazonaws.com/doc/2006-03-01">
|
||||||
{% for k in deleted %}
|
{% for k in deleted %}
|
||||||
|
@ -543,3 +543,29 @@ def test_key_version():
|
|||||||
|
|
||||||
key = bucket.get_key('the-key')
|
key = bucket.get_key('the-key')
|
||||||
key.version_id.should.equal('1')
|
key.version_id.should.equal('1')
|
||||||
|
|
||||||
|
|
||||||
|
@mock_s3
|
||||||
|
def test_list_versions():
|
||||||
|
conn = boto.connect_s3('the_key', 'the_secret')
|
||||||
|
bucket = conn.create_bucket('foobar')
|
||||||
|
bucket.configure_versioning(versioning=True)
|
||||||
|
|
||||||
|
key = Key(bucket, 'the-key')
|
||||||
|
key.version_id.should.be.none
|
||||||
|
key.set_contents_from_string("Version 1")
|
||||||
|
key.version_id.should.equal('0')
|
||||||
|
key.set_contents_from_string("Version 2")
|
||||||
|
key.version_id.should.equal('1')
|
||||||
|
|
||||||
|
versions = list(bucket.list_versions())
|
||||||
|
|
||||||
|
versions.should.have.length_of(2)
|
||||||
|
|
||||||
|
versions[0].name.should.equal('the-key')
|
||||||
|
versions[0].version_id.should.equal('0')
|
||||||
|
versions[0].get_contents_as_string().should.equal("Version 1")
|
||||||
|
|
||||||
|
versions[1].name.should.equal('the-key')
|
||||||
|
versions[1].version_id.should.equal('1')
|
||||||
|
versions[1].get_contents_as_string().should.equal("Version 2")
|
||||||
|
Loading…
Reference in New Issue
Block a user