Merge lp:~dreamhosters/txaws/921352-get-bucket-versioning-method into lp:txaws

Proposed by Arsene Rei
Status: Merged
Approved by: Duncan McGreggor
Approved revision: 141
Merged at revision: 130
Proposed branch: lp:~dreamhosters/txaws/921352-get-bucket-versioning-method
Merge into: lp:txaws
Diff against target: 212 lines (+164/-1)
4 files modified
txaws/s3/client.py (+21/-1)
txaws/s3/model.py (+19/-0)
txaws/s3/tests/test_client.py (+110/-0)
txaws/testing/payload.py (+14/-0)
To merge this branch: bzr merge lp:~dreamhosters/txaws/921352-get-bucket-versioning-method
Reviewer Review Type Date Requested Status
Duncan McGreggor Approve
Review via email: mp+90552@code.launchpad.net

Description of the change

Add GET Bucket versioning functionality

To post a comment you must log in.
Revision history for this message
Duncan McGreggor (oubiwann) wrote :

[1] So, I was going to suggest not to use modeling for this one, since it's so simple... but it seems that Amazon has defined another element that needs to be added to the module: MfaDelete (self.mfa_delete is the attribute name I'd use).

I was going to suggest that you should only set the mfa_delete attr if root.findtext("MfaDelete") returned a value... but that would make working with this particular model more cumbersome. So:
 * mfa_delete = "Disabled" means the bucket has been configured with MfaDelete and it's disabled
 * mfa_delete = "Enabled" means the bucket has been configured with MfaDelete and it's enabled
 * mfa_delete = None means the bucket has not been configured with MfaDelete

That should probably go in the model's docstring ;-)

[2] For this, you'll want to add another payload example with "<MfaDelete>Enabled</MfaDelete>" in it. There's no need to also include an example Disabled in it, since no different/additional logic in the Python code is being exercised with that.

review: Needs Fixing
138. By Arsene Rei

remove test_get_bucket_versioning_config_suspended

As oubiwann pointed out, no additional logic in Python code is being exercised.

139. By Arsene Rei

add mfa_delete argument to VersioningConfiguration

* add corresponding test

140. By Arsene Rei

make pep8 fix

141. By Arsene Rei

update test docstring

Revision history for this message
Duncan McGreggor (oubiwann) wrote :

Looks good! +1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'txaws/s3/client.py'
2--- txaws/s3/client.py 2012-01-27 19:54:27 +0000
3+++ txaws/s3/client.py 2012-01-28 00:47:23 +0000
4@@ -23,7 +23,7 @@
5 from txaws.s3.model import (
6 Bucket, BucketItem, BucketListing, ItemOwner, LifecycleConfiguration,
7 LifecycleConfigurationRule, NotificationConfiguration, RequestPayment,
8- WebsiteConfiguration)
9+ VersioningConfiguration, WebsiteConfiguration)
10 from txaws.s3.exception import S3Error
11 from txaws.service import AWSServiceEndpoint, S3_ENDPOINT
12 from txaws.util import XML, calculate_md5
13@@ -253,6 +253,26 @@
14
15 return NotificationConfiguration(topic, event)
16
17+ def get_bucket_versioning_config(self, bucket):
18+ """
19+ Get the versioning configuration of a bucket.
20+
21+ @param bucket: The name of the bucket. @return: A C{Deferred} that
22+ will request the bucket's versioning configuration.
23+ """
24+ query = self.query_factory(
25+ action='GET', creds=self.creds, endpoint=self.endpoint,
26+ bucket=bucket, object_name='?versioning')
27+ return query.submit().addCallback(self._parse_versioning_config)
28+
29+ def _parse_versioning_config(self, xml_bytes):
30+ """Parse a C{VersioningConfiguration} XML document."""
31+ root = XML(xml_bytes)
32+ mfa_delete = root.findtext("MfaDelete")
33+ status = root.findtext("Status")
34+
35+ return VersioningConfiguration(mfa_delete=mfa_delete, status=status)
36+
37 def get_bucket_acl(self, bucket):
38 """
39 Get the access control policy for a bucket.
40
41=== modified file 'txaws/s3/model.py'
42--- txaws/s3/model.py 2012-01-27 19:47:22 +0000
43+++ txaws/s3/model.py 2012-01-28 00:47:23 +0000
44@@ -90,6 +90,25 @@
45 self.event = event
46
47
48+class VersioningConfiguration(object):
49+ """
50+ Container for the bucket versioning configuration.
51+
52+ According to Amazon:
53+
54+ C{MfaDelete}: This element is only returned if the bucket has been
55+ configured with C{MfaDelete}. If the bucket has never been so configured,
56+ this element is not returned. The possible values are None, "Disabled" or
57+ "Enabled".
58+
59+ C{Status}: If the bucket has never been so configured, this element is not
60+ returned. The possible values are None, "Suspended" or "Enabled".
61+ """
62+ def __init__(self, mfa_delete=None, status=None):
63+ self.mfa_delete = mfa_delete
64+ self.status = status
65+
66+
67 class FileChunk(object):
68 """
69 An Amazon S3 file chunk.
70
71=== modified file 'txaws/s3/tests/test_client.py'
72--- txaws/s3/tests/test_client.py 2012-01-27 20:44:11 +0000
73+++ txaws/s3/tests/test_client.py 2012-01-28 00:47:23 +0000
74@@ -462,6 +462,116 @@
75 d = s3.get_bucket_notification_config("mybucket")
76 return d.addCallback(check_results)
77
78+ def test_get_bucket_versioning_config(self):
79+ """
80+ L{S3Client.get_bucket_versioning_configuration} creates a L{Query} to
81+ get a bucket's versioning status. It parses the returned
82+ C{VersioningConfiguration} XML document and returns a C{Deferred} that
83+ requests the bucket's versioning configuration.
84+ """
85+
86+ class StubQuery(client.Query):
87+
88+ def __init__(query, action, creds, endpoint, bucket=None,
89+ object_name=None):
90+ super(StubQuery, query).__init__(action=action, creds=creds,
91+ bucket=bucket,
92+ object_name=object_name)
93+ self.assertEquals(action, "GET")
94+ self.assertEqual(creds.access_key, "foo")
95+ self.assertEqual(creds.secret_key, "bar")
96+ self.assertEqual(query.bucket, "mybucket")
97+ self.assertEqual(query.object_name, "?versioning")
98+ self.assertEqual(query.data, "")
99+ self.assertEqual(query.metadata, {})
100+ self.assertEqual(query.amz_headers, {})
101+
102+ def submit(query, url_context=None):
103+ return succeed(payload.sample_s3_get_bucket_versioning_result)
104+
105+ def check_results(versioning_config):
106+ self.assertEquals(versioning_config.status, None)
107+
108+ creds = AWSCredentials("foo", "bar")
109+ s3 = client.S3Client(creds, query_factory=StubQuery)
110+ d = s3.get_bucket_versioning_config("mybucket")
111+ return d.addCallback(check_results)
112+
113+ def test_get_bucket_versioning_config_enabled(self):
114+ """
115+ L{S3Client.get_bucket_versioning_config} creates a L{Query} to get a
116+ bucket's versioning configuration. It parses the returned
117+ C{VersioningConfiguration} XML document and returns a C{Deferred} that
118+ requests the bucket's versioning configuration that has a enabled
119+ C{Status}.
120+ """
121+
122+ class StubQuery(client.Query):
123+
124+ def __init__(query, action, creds, endpoint, bucket=None,
125+ object_name=None):
126+ super(StubQuery, query).__init__(action=action, creds=creds,
127+ bucket=bucket,
128+ object_name=object_name)
129+ self.assertEquals(action, "GET")
130+ self.assertEqual(creds.access_key, "foo")
131+ self.assertEqual(creds.secret_key, "bar")
132+ self.assertEqual(query.bucket, "mybucket")
133+ self.assertEqual(query.object_name, "?versioning")
134+ self.assertEqual(query.data, "")
135+ self.assertEqual(query.metadata, {})
136+ self.assertEqual(query.amz_headers, {})
137+
138+ def submit(query, url_context=None):
139+ return succeed(payload.
140+ sample_s3_get_bucket_versioning_enabled_result)
141+
142+ def check_results(versioning_config):
143+ self.assertEquals(versioning_config.status, 'Enabled')
144+
145+ creds = AWSCredentials("foo", "bar")
146+ s3 = client.S3Client(creds, query_factory=StubQuery)
147+ d = s3.get_bucket_versioning_config("mybucket")
148+ return d.addCallback(check_results)
149+
150+ def test_get_bucket_versioning_config_mfa_disabled(self):
151+ """
152+ L{S3Client.get_bucket_versioning_config} creates a L{Query} to get a
153+ bucket's versioning configuration. It parses the returned
154+ C{VersioningConfiguration} XML document and returns a C{Deferred} that
155+ requests the bucket's versioning configuration that has a disabled
156+ C{MfaDelete}.
157+ """
158+
159+ class StubQuery(client.Query):
160+
161+ def __init__(query, action, creds, endpoint, bucket=None,
162+ object_name=None):
163+ super(StubQuery, query).__init__(action=action, creds=creds,
164+ bucket=bucket,
165+ object_name=object_name)
166+ self.assertEquals(action, "GET")
167+ self.assertEqual(creds.access_key, "foo")
168+ self.assertEqual(creds.secret_key, "bar")
169+ self.assertEqual(query.bucket, "mybucket")
170+ self.assertEqual(query.object_name, "?versioning")
171+ self.assertEqual(query.data, "")
172+ self.assertEqual(query.metadata, {})
173+ self.assertEqual(query.amz_headers, {})
174+
175+ def submit(query, url_context=None):
176+ return succeed(
177+ payload.
178+ sample_s3_get_bucket_versioning_mfa_disabled_result)
179+
180+ def check_results(versioning_config):
181+ self.assertEquals(versioning_config.mfa_delete, 'Disabled')
182+
183+ creds = AWSCredentials("foo", "bar")
184+ s3 = client.S3Client(creds, query_factory=StubQuery)
185+ d = s3.get_bucket_versioning_config("mybucket")
186+ return d.addCallback(check_results)
187+
188 def test_delete_bucket(self):
189
190 class StubQuery(client.Query):
191
192=== modified file 'txaws/testing/payload.py'
193--- txaws/testing/payload.py 2012-01-27 20:08:20 +0000
194+++ txaws/testing/payload.py 2012-01-28 00:47:23 +0000
195@@ -1071,3 +1071,17 @@
196 <Event>s3:ReducedRedundancyLostObject</Event>
197 </TopicConfiguration>
198 </NotificationConfiguration>"""
199+
200+sample_s3_get_bucket_versioning_result = """\
201+<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"/>"""
202+
203+sample_s3_get_bucket_versioning_enabled_result = """\
204+<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
205+ <Status>Enabled</Status>
206+</VersioningConfiguration>"""
207+
208+sample_s3_get_bucket_versioning_mfa_disabled_result = """\
209+<VersioningConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
210+ <Status>Enabled</Status>
211+ <MfaDelete>Disabled</MfaDelete>
212+</VersioningConfiguration>"""

Subscribers

People subscribed via source and target branches