Merge lp:~franciscosouza/txaws/txaws-bundled-vpc into lp:txaws
- txaws-bundled-vpc
- Merge into trunk
Proposed by
Francisco Souza
Status: | Merged |
---|---|
Merged at revision: | 153 |
Proposed branch: | lp:~franciscosouza/txaws/txaws-bundled-vpc |
Merge into: | lp:txaws |
Diff against target: |
945 lines (+354/-95) 9 files modified
txaws/client/base.py (+24/-9) txaws/client/discover/tests/test_command.py (+8/-8) txaws/ec2/client.py (+55/-19) txaws/ec2/model.py (+2/-1) txaws/ec2/tests/test_client.py (+217/-35) txaws/ec2/tests/test_model.py (+6/-4) txaws/server/tests/test_call.py (+1/-1) txaws/testing/payload.py (+40/-17) txaws/version.py (+1/-1) |
To merge this branch: | bzr merge lp:~franciscosouza/txaws/txaws-bundled-vpc |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
txAWS Committers | Pending | ||
Review via email: mp+135397@code.launchpad.net |
Commit message
Description of the change
client, ec2: bundling changes needed for VPC
I use this CL for patching only, original CL's are:
https:/
https:/
https:/
https:/
This one also includes a change in parsing of instance sets.
To post a comment you must log in.
Revision history for this message
Chico (franciscossouza) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'txaws/client/base.py' | |||
2 | --- txaws/client/base.py 2012-05-16 02:35:26 +0000 | |||
3 | +++ txaws/client/base.py 2012-11-21 12:35:25 +0000 | |||
4 | @@ -1,3 +1,6 @@ | |||
5 | 1 | import os | ||
6 | 2 | import urlparse | ||
7 | 3 | |||
8 | 1 | try: | 4 | try: |
9 | 2 | from xml.etree.ElementTree import ParseError | 5 | from xml.etree.ElementTree import ParseError |
10 | 3 | except ImportError: | 6 | except ImportError: |
11 | @@ -6,16 +9,16 @@ | |||
12 | 6 | import warnings | 9 | import warnings |
13 | 7 | from StringIO import StringIO | 10 | from StringIO import StringIO |
14 | 8 | 11 | ||
15 | 12 | from twisted.internet.endpoints import TCP4ClientEndpoint | ||
16 | 9 | from twisted.internet.ssl import ClientContextFactory | 13 | from twisted.internet.ssl import ClientContextFactory |
17 | 10 | from twisted.internet.protocol import Protocol | 14 | from twisted.internet.protocol import Protocol |
18 | 11 | from twisted.internet.defer import Deferred, succeed, fail | 15 | from twisted.internet.defer import Deferred, succeed, fail |
19 | 12 | from twisted.python import failure | 16 | from twisted.python import failure |
20 | 13 | from twisted.web import http | 17 | from twisted.web import http |
21 | 14 | from twisted.web.iweb import UNKNOWN_LENGTH | 18 | from twisted.web.iweb import UNKNOWN_LENGTH |
24 | 15 | from twisted.web.client import HTTPClientFactory | 19 | from twisted.web.client import Agent, ProxyAgent |
23 | 16 | from twisted.web.client import Agent | ||
25 | 17 | from twisted.web.client import ResponseDone | 20 | from twisted.web.client import ResponseDone |
27 | 18 | from twisted.web.http import NO_CONTENT | 21 | from twisted.web.http import NO_CONTENT, PotentialDataLoss |
28 | 19 | from twisted.web.http_headers import Headers | 22 | from twisted.web.http_headers import Headers |
29 | 20 | from twisted.web.error import Error as TwistedWebError | 23 | from twisted.web.error import Error as TwistedWebError |
30 | 21 | try: | 24 | try: |
31 | @@ -130,7 +133,7 @@ | |||
32 | 130 | self._received += len(bytes) | 133 | self._received += len(bytes) |
33 | 131 | 134 | ||
34 | 132 | def connectionLost(self, reason): | 135 | def connectionLost(self, reason): |
36 | 133 | reason.trap(ResponseDone) | 136 | reason.trap(ResponseDone, PotentialDataLoss) |
37 | 134 | d = self.finished | 137 | d = self.finished |
38 | 135 | self.finished = None | 138 | self.finished = None |
39 | 136 | streaming = self.content_length is UNKNOWN_LENGTH | 139 | streaming = self.content_length is UNKNOWN_LENGTH |
40 | @@ -220,16 +223,28 @@ | |||
41 | 220 | if (self.body_producer is None) and (data is not None): | 223 | if (self.body_producer is None) and (data is not None): |
42 | 221 | self.body_producer = FileBodyProducer(StringIO(data)) | 224 | self.body_producer = FileBodyProducer(StringIO(data)) |
43 | 222 | if scheme == "https": | 225 | if scheme == "https": |
46 | 223 | if self.endpoint.ssl_hostname_verification: | 226 | proxy_endpoint = os.environ.get("https_proxy") |
47 | 224 | contextFactory = WebVerifyingContextFactory(host) | 227 | if proxy_endpoint: |
48 | 228 | proxy_url = urlparse.urlparse(proxy_endpoint) | ||
49 | 229 | endpoint = TCP4ClientEndpoint(self.reactor, proxy_url.hostname, proxy_url.port) | ||
50 | 230 | agent = ProxyAgent(endpoint) | ||
51 | 225 | else: | 231 | else: |
54 | 226 | contextFactory = WebClientContextFactory() | 232 | if self.endpoint.ssl_hostname_verification: |
55 | 227 | agent = Agent(self.reactor, contextFactory) | 233 | contextFactory = WebVerifyingContextFactory(host) |
56 | 234 | else: | ||
57 | 235 | contextFactory = WebClientContextFactory() | ||
58 | 236 | agent = Agent(self.reactor, contextFactory) | ||
59 | 228 | self.client.url = url | 237 | self.client.url = url |
60 | 229 | d = agent.request(method, url, self.request_headers, | 238 | d = agent.request(method, url, self.request_headers, |
61 | 230 | self.body_producer) | 239 | self.body_producer) |
62 | 231 | else: | 240 | else: |
64 | 232 | agent = Agent(self.reactor) | 241 | proxy_endpoint = os.environ.get("http_proxy") |
65 | 242 | if proxy_endpoint: | ||
66 | 243 | proxy_url = urlparse.urlparse(proxy_endpoint) | ||
67 | 244 | endpoint = TCP4ClientEndpoint(self.reactor, proxy_url.hostname, proxy_url.port) | ||
68 | 245 | agent = ProxyAgent(endpoint) | ||
69 | 246 | else: | ||
70 | 247 | agent = Agent(self.reactor) | ||
71 | 233 | d = agent.request(method, url, self.request_headers, | 248 | d = agent.request(method, url, self.request_headers, |
72 | 234 | self.body_producer) | 249 | self.body_producer) |
73 | 235 | d.addCallback(self._handle_response) | 250 | d.addCallback(self._handle_response) |
74 | 236 | 251 | ||
75 | === modified file 'txaws/client/discover/tests/test_command.py' | |||
76 | --- txaws/client/discover/tests/test_command.py 2012-01-27 02:10:24 +0000 | |||
77 | +++ txaws/client/discover/tests/test_command.py 2012-11-21 12:35:25 +0000 | |||
78 | @@ -74,9 +74,9 @@ | |||
79 | 74 | url = ( | 74 | url = ( |
80 | 75 | "http://endpoint?AWSAccessKeyId=key&" | 75 | "http://endpoint?AWSAccessKeyId=key&" |
81 | 76 | "Action=DescribeRegions&" | 76 | "Action=DescribeRegions&" |
83 | 77 | "Signature=3%2BHSkQQosF1Sr9AL3kdY31tEfTWQ2whjJOUSc3kvc2c%3D&" | 77 | "Signature=7fyxNidMkL%2B85udGOxqm%2BgM2o1gLyeLG2a0UOmfBOXQ%3D&" |
84 | 78 | "SignatureMethod=HmacSHA256&SignatureVersion=2&" | 78 | "SignatureMethod=HmacSHA256&SignatureVersion=2&" |
86 | 79 | "Timestamp=2010-06-04T23%3A40%3A00Z&Version=2009-11-30") | 79 | "Timestamp=2010-06-04T23%3A40%3A00Z&Version=2012-08-15") |
87 | 80 | self.assertEqual("GET", self.method) | 80 | self.assertEqual("GET", self.method) |
88 | 81 | self.assertEqual(url, self.url) | 81 | self.assertEqual(url, self.url) |
89 | 82 | self.assertEqual("URL: %s\n" | 82 | self.assertEqual("URL: %s\n" |
90 | @@ -99,9 +99,9 @@ | |||
91 | 99 | url = ( | 99 | url = ( |
92 | 100 | "http://endpoint?AWSAccessKeyId=key&" | 100 | "http://endpoint?AWSAccessKeyId=key&" |
93 | 101 | "Action=DescribeRegions&RegionName.0=us-west-1&" | 101 | "Action=DescribeRegions&RegionName.0=us-west-1&" |
95 | 102 | "Signature=6D8aCgSPQOYixowRHy26aRFzK2Vwgixl9uwegYX9nLA%3D&" | 102 | "Signature=FL4JjDKbWdg531q1KKUPild%2BvyqspA5wxSmOeWXWsJI%3D&" |
96 | 103 | "SignatureMethod=HmacSHA256&SignatureVersion=2&" | 103 | "SignatureMethod=HmacSHA256&SignatureVersion=2&" |
98 | 104 | "Timestamp=2010-06-04T23%3A40%3A00Z&Version=2009-11-30") | 104 | "Timestamp=2010-06-04T23%3A40%3A00Z&Version=2012-08-15") |
99 | 105 | self.assertEqual("GET", self.method) | 105 | self.assertEqual("GET", self.method) |
100 | 106 | self.assertEqual(url, self.url) | 106 | self.assertEqual(url, self.url) |
101 | 107 | self.assertEqual("URL: %s\n" | 107 | self.assertEqual("URL: %s\n" |
102 | @@ -128,9 +128,9 @@ | |||
103 | 128 | url = ( | 128 | url = ( |
104 | 129 | "http://endpoint?AWSAccessKeyId=key&" | 129 | "http://endpoint?AWSAccessKeyId=key&" |
105 | 130 | "Action=DescribeRegions&RegionName.0=us-west-1&" | 130 | "Action=DescribeRegions&RegionName.0=us-west-1&" |
107 | 131 | "Signature=6D8aCgSPQOYixowRHy26aRFzK2Vwgixl9uwegYX9nLA%3D&" | 131 | "Signature=FL4JjDKbWdg531q1KKUPild%2BvyqspA5wxSmOeWXWsJI%3D&" |
108 | 132 | "SignatureMethod=HmacSHA256&SignatureVersion=2&" | 132 | "SignatureMethod=HmacSHA256&SignatureVersion=2&" |
110 | 133 | "Timestamp=2010-06-04T23%3A40%3A00Z&Version=2009-11-30") | 133 | "Timestamp=2010-06-04T23%3A40%3A00Z&Version=2012-08-15") |
111 | 134 | self.assertEqual("GET", self.method) | 134 | self.assertEqual("GET", self.method) |
112 | 135 | self.assertEqual(url, self.url) | 135 | self.assertEqual(url, self.url) |
113 | 136 | self.assertEqual("URL: %s\n" | 136 | self.assertEqual("URL: %s\n" |
114 | @@ -185,9 +185,9 @@ | |||
115 | 185 | url = ( | 185 | url = ( |
116 | 186 | "http://endpoint?AWSAccessKeyId=key&" | 186 | "http://endpoint?AWSAccessKeyId=key&" |
117 | 187 | "Action=DescribeRegions&RegionName.0=us-west-1&" | 187 | "Action=DescribeRegions&RegionName.0=us-west-1&" |
119 | 188 | "Signature=6D8aCgSPQOYixowRHy26aRFzK2Vwgixl9uwegYX9nLA%3D&" | 188 | "Signature=FL4JjDKbWdg531q1KKUPild%2BvyqspA5wxSmOeWXWsJI%3D&" |
120 | 189 | "SignatureMethod=HmacSHA256&SignatureVersion=2&" | 189 | "SignatureMethod=HmacSHA256&SignatureVersion=2&" |
122 | 190 | "Timestamp=2010-06-04T23%3A40%3A00Z&Version=2009-11-30") | 190 | "Timestamp=2010-06-04T23%3A40%3A00Z&Version=2012-08-15") |
123 | 191 | self.assertEqual("GET", self.method) | 191 | self.assertEqual("GET", self.method) |
124 | 192 | self.assertEqual(url, self.url) | 192 | self.assertEqual(url, self.url) |
125 | 193 | self.assertEqual("URL: %s\n" | 193 | self.assertEqual("URL: %s\n" |
126 | 194 | 194 | ||
127 | === modified file 'txaws/ec2/client.py' | |||
128 | --- txaws/ec2/client.py 2012-05-05 00:17:02 +0000 | |||
129 | +++ txaws/ec2/client.py 2012-11-21 12:35:25 +0000 | |||
130 | @@ -48,7 +48,7 @@ | |||
131 | 48 | def run_instances(self, image_id, min_count, max_count, | 48 | def run_instances(self, image_id, min_count, max_count, |
132 | 49 | security_groups=None, key_name=None, instance_type=None, | 49 | security_groups=None, key_name=None, instance_type=None, |
133 | 50 | user_data=None, availability_zone=None, kernel_id=None, | 50 | user_data=None, availability_zone=None, kernel_id=None, |
135 | 51 | ramdisk_id=None): | 51 | ramdisk_id=None, subnet_id=None, security_group_ids=None): |
136 | 52 | """Run new instances. | 52 | """Run new instances. |
137 | 53 | 53 | ||
138 | 54 | TODO: blockDeviceMapping, monitoring, subnetId | 54 | TODO: blockDeviceMapping, monitoring, subnetId |
139 | @@ -57,9 +57,21 @@ | |||
140 | 57 | "MaxCount": str(max_count)} | 57 | "MaxCount": str(max_count)} |
141 | 58 | if key_name is not None: | 58 | if key_name is not None: |
142 | 59 | params["KeyName"] = key_name | 59 | params["KeyName"] = key_name |
144 | 60 | if security_groups is not None: | 60 | if subnet_id is not None: |
145 | 61 | params["SubnetId"] = subnet_id | ||
146 | 62 | if security_group_ids is not None: | ||
147 | 63 | for i, id in enumerate(security_group_ids): | ||
148 | 64 | params["SecurityGroupId.%d" % (i + 1)] = id | ||
149 | 65 | else: | ||
150 | 66 | msg = "You must specify the security_group_ids with the subnet_id" | ||
151 | 67 | raise ValueError(msg) | ||
152 | 68 | elif security_groups is not None: | ||
153 | 61 | for i, name in enumerate(security_groups): | 69 | for i, name in enumerate(security_groups): |
154 | 62 | params["SecurityGroup.%d" % (i + 1)] = name | 70 | params["SecurityGroup.%d" % (i + 1)] = name |
155 | 71 | else: | ||
156 | 72 | msg = ("You must specify either the subnet_id and " | ||
157 | 73 | "security_group_ids or security_groups") | ||
158 | 74 | raise ValueError(msg) | ||
159 | 63 | if user_data is not None: | 75 | if user_data is not None: |
160 | 64 | params["UserData"] = b64encode(user_data) | 76 | params["UserData"] = b64encode(user_data) |
161 | 65 | if instance_type is not None: | 77 | if instance_type is not None: |
162 | @@ -110,28 +122,37 @@ | |||
163 | 110 | d = query.submit() | 122 | d = query.submit() |
164 | 111 | return d.addCallback(self.parser.describe_security_groups) | 123 | return d.addCallback(self.parser.describe_security_groups) |
165 | 112 | 124 | ||
167 | 113 | def create_security_group(self, name, description): | 125 | def create_security_group(self, name, description, vpc_id=None): |
168 | 114 | """Create security group. | 126 | """Create security group. |
169 | 115 | 127 | ||
170 | 116 | @param name: Name of the new security group. | 128 | @param name: Name of the new security group. |
171 | 117 | @param description: Description of the new security group. | 129 | @param description: Description of the new security group. |
172 | 130 | @param vpc_id: ID of the VPC to which the security group will belong. | ||
173 | 118 | @return: A C{Deferred} that will fire with a truth value for the | 131 | @return: A C{Deferred} that will fire with a truth value for the |
174 | 119 | success of the operation. | 132 | success of the operation. |
175 | 120 | """ | 133 | """ |
176 | 121 | parameters = {"GroupName": name, "GroupDescription": description} | 134 | parameters = {"GroupName": name, "GroupDescription": description} |
177 | 135 | if vpc_id: | ||
178 | 136 | parameters["VpcId"] = vpc_id | ||
179 | 122 | query = self.query_factory( | 137 | query = self.query_factory( |
180 | 123 | action="CreateSecurityGroup", creds=self.creds, | 138 | action="CreateSecurityGroup", creds=self.creds, |
181 | 124 | endpoint=self.endpoint, other_params=parameters) | 139 | endpoint=self.endpoint, other_params=parameters) |
182 | 125 | d = query.submit() | 140 | d = query.submit() |
184 | 126 | return d.addCallback(self.parser.truth_return) | 141 | return d.addCallback(self.parser.create_security_group) |
185 | 127 | 142 | ||
187 | 128 | def delete_security_group(self, name): | 143 | def delete_security_group(self, name=None, id=None): |
188 | 129 | """ | 144 | """ |
190 | 130 | @param name: Name of the new security group. | 145 | @param name: Name of the security group. |
191 | 146 | @param id: Id of the security group. | ||
192 | 131 | @return: A C{Deferred} that will fire with a truth value for the | 147 | @return: A C{Deferred} that will fire with a truth value for the |
193 | 132 | success of the operation. | 148 | success of the operation. |
194 | 133 | """ | 149 | """ |
196 | 134 | parameter = {"GroupName": name} | 150 | if name: |
197 | 151 | parameter = {"GroupName": name} | ||
198 | 152 | elif id: | ||
199 | 153 | parameter = {"GroupId": id} | ||
200 | 154 | else: | ||
201 | 155 | raise ValueError("You must provide either the security group name or id") | ||
202 | 135 | query = self.query_factory( | 156 | query = self.query_factory( |
203 | 136 | action="DeleteSecurityGroup", creds=self.creds, | 157 | action="DeleteSecurityGroup", creds=self.creds, |
204 | 137 | endpoint=self.endpoint, other_params=parameter) | 158 | endpoint=self.endpoint, other_params=parameter) |
205 | @@ -139,7 +160,7 @@ | |||
206 | 139 | return d.addCallback(self.parser.truth_return) | 160 | return d.addCallback(self.parser.truth_return) |
207 | 140 | 161 | ||
208 | 141 | def authorize_security_group( | 162 | def authorize_security_group( |
210 | 142 | self, group_name, source_group_name="", source_group_owner_id="", | 163 | self, group_name=None, group_id=None, source_group_name="", source_group_owner_id="", |
211 | 143 | ip_protocol="", from_port="", to_port="", cidr_ip=""): | 164 | ip_protocol="", from_port="", to_port="", cidr_ip=""): |
212 | 144 | """ | 165 | """ |
213 | 145 | There are two ways to use C{authorize_security_group}: | 166 | There are two ways to use C{authorize_security_group}: |
214 | @@ -150,6 +171,8 @@ | |||
215 | 150 | 171 | ||
216 | 151 | @param group_name: The group you will be modifying with a new | 172 | @param group_name: The group you will be modifying with a new |
217 | 152 | authorization. | 173 | authorization. |
218 | 174 | @param group_id: The id of the group you will be modifying with | ||
219 | 175 | a new authorization. | ||
220 | 153 | 176 | ||
221 | 154 | Optionally, the following parameters: | 177 | Optionally, the following parameters: |
222 | 155 | @param source_group_name: Name of security group to authorize access to | 178 | @param source_group_name: Name of security group to authorize access to |
223 | @@ -188,7 +211,12 @@ | |||
224 | 188 | msg = ("You must specify either both group parameters or " | 211 | msg = ("You must specify either both group parameters or " |
225 | 189 | "all the ip parameters.") | 212 | "all the ip parameters.") |
226 | 190 | raise ValueError(msg) | 213 | raise ValueError(msg) |
228 | 191 | parameters["GroupName"] = group_name | 214 | if group_id: |
229 | 215 | parameters["GroupId"] = group_id | ||
230 | 216 | elif group_name: | ||
231 | 217 | parameters["GroupName"] = group_name | ||
232 | 218 | else: | ||
233 | 219 | raise ValueError("You must specify either the group name of the group id.") | ||
234 | 192 | query = self.query_factory( | 220 | query = self.query_factory( |
235 | 193 | action="AuthorizeSecurityGroupIngress", creds=self.creds, | 221 | action="AuthorizeSecurityGroupIngress", creds=self.creds, |
236 | 194 | endpoint=self.endpoint, other_params=parameters) | 222 | endpoint=self.endpoint, other_params=parameters) |
237 | @@ -224,7 +252,7 @@ | |||
238 | 224 | return d | 252 | return d |
239 | 225 | 253 | ||
240 | 226 | def revoke_security_group( | 254 | def revoke_security_group( |
242 | 227 | self, group_name, source_group_name="", source_group_owner_id="", | 255 | self, group_name=None, group_id=None, source_group_name="", source_group_owner_id="", |
243 | 228 | ip_protocol="", from_port="", to_port="", cidr_ip=""): | 256 | ip_protocol="", from_port="", to_port="", cidr_ip=""): |
244 | 229 | """ | 257 | """ |
245 | 230 | There are two ways to use C{revoke_security_group}: | 258 | There are two ways to use C{revoke_security_group}: |
246 | @@ -273,7 +301,12 @@ | |||
247 | 273 | msg = ("You must specify either both group parameters or " | 301 | msg = ("You must specify either both group parameters or " |
248 | 274 | "all the ip parameters.") | 302 | "all the ip parameters.") |
249 | 275 | raise ValueError(msg) | 303 | raise ValueError(msg) |
251 | 276 | parameters["GroupName"] = group_name | 304 | if group_id: |
252 | 305 | parameters["GroupId"] = group_id | ||
253 | 306 | elif group_name: | ||
254 | 307 | parameters["GroupName"] = group_name | ||
255 | 308 | else: | ||
256 | 309 | raise ValueError("You must specify either the group name of the group id.") | ||
257 | 277 | query = self.query_factory( | 310 | query = self.query_factory( |
258 | 278 | action="RevokeSecurityGroupIngress", creds=self.creds, | 311 | action="RevokeSecurityGroupIngress", creds=self.creds, |
259 | 279 | endpoint=self.endpoint, other_params=parameters) | 312 | endpoint=self.endpoint, other_params=parameters) |
260 | @@ -547,6 +580,10 @@ | |||
261 | 547 | ipAddress, stateReason, architecture, rootDeviceName, | 580 | ipAddress, stateReason, architecture, rootDeviceName, |
262 | 548 | blockDeviceMapping, instanceLifecycle, spotInstanceRequestId. | 581 | blockDeviceMapping, instanceLifecycle, spotInstanceRequestId. |
263 | 549 | """ | 582 | """ |
264 | 583 | for group_data in instance_data.find("groupSet"): | ||
265 | 584 | group_id = group_data.findtext("groupId") | ||
266 | 585 | group_name = group_data.findtext("groupName") | ||
267 | 586 | reservation.groups.append((group_id, group_name)) | ||
268 | 550 | instance_id = instance_data.findtext("instanceId") | 587 | instance_id = instance_data.findtext("instanceId") |
269 | 551 | instance_state = instance_data.find( | 588 | instance_state = instance_data.find( |
270 | 552 | "instanceState").findtext("name") | 589 | "instanceState").findtext("name") |
271 | @@ -599,16 +636,10 @@ | |||
272 | 599 | results = [] | 636 | results = [] |
273 | 600 | # May be a more elegant way to do this: | 637 | # May be a more elegant way to do this: |
274 | 601 | for reservation_data in root.find("reservationSet"): | 638 | for reservation_data in root.find("reservationSet"): |
275 | 602 | # Get the security group information. | ||
276 | 603 | groups = [] | ||
277 | 604 | for group_data in reservation_data.find("groupSet"): | ||
278 | 605 | group_id = group_data.findtext("groupId") | ||
279 | 606 | groups.append(group_id) | ||
280 | 607 | # Create a reservation object with the parsed data. | 639 | # Create a reservation object with the parsed data. |
281 | 608 | reservation = model.Reservation( | 640 | reservation = model.Reservation( |
282 | 609 | reservation_id=reservation_data.findtext("reservationId"), | 641 | reservation_id=reservation_data.findtext("reservationId"), |
285 | 610 | owner_id=reservation_data.findtext("ownerId"), | 642 | owner_id=reservation_data.findtext("ownerId")) |
284 | 611 | groups=groups) | ||
286 | 612 | # Get the list of instances. | 643 | # Get the list of instances. |
287 | 613 | instances = self.instances_set( | 644 | instances = self.instances_set( |
288 | 614 | reservation_data, reservation) | 645 | reservation_data, reservation) |
289 | @@ -670,6 +701,7 @@ | |||
290 | 670 | root = XML(xml_bytes) | 701 | root = XML(xml_bytes) |
291 | 671 | result = [] | 702 | result = [] |
292 | 672 | for group_info in root.findall("securityGroupInfo/item"): | 703 | for group_info in root.findall("securityGroupInfo/item"): |
293 | 704 | id = group_info.findtext("groupId") | ||
294 | 673 | name = group_info.findtext("groupName") | 705 | name = group_info.findtext("groupName") |
295 | 674 | description = group_info.findtext("groupDescription") | 706 | description = group_info.findtext("groupDescription") |
296 | 675 | owner_id = group_info.findtext("ownerId") | 707 | owner_id = group_info.findtext("ownerId") |
297 | @@ -709,11 +741,15 @@ | |||
298 | 709 | for user_id, group_name in allowed_groups] | 741 | for user_id, group_name in allowed_groups] |
299 | 710 | 742 | ||
300 | 711 | security_group = model.SecurityGroup( | 743 | security_group = model.SecurityGroup( |
302 | 712 | name, description, owner_id=owner_id, | 744 | id, name, description, owner_id=owner_id, |
303 | 713 | groups=allowed_groups, ips=allowed_ips) | 745 | groups=allowed_groups, ips=allowed_ips) |
304 | 714 | result.append(security_group) | 746 | result.append(security_group) |
305 | 715 | return result | 747 | return result |
306 | 716 | 748 | ||
307 | 749 | def create_security_group(self, xml_bytes): | ||
308 | 750 | root = XML(xml_bytes) | ||
309 | 751 | return root.findtext("groupId") | ||
310 | 752 | |||
311 | 717 | def truth_return(self, xml_bytes): | 753 | def truth_return(self, xml_bytes): |
312 | 718 | """Parse the XML for a truth value. | 754 | """Parse the XML for a truth value. |
313 | 719 | 755 | ||
314 | 720 | 756 | ||
315 | === modified file 'txaws/ec2/model.py' | |||
316 | --- txaws/ec2/model.py 2012-03-02 22:00:10 +0000 | |||
317 | +++ txaws/ec2/model.py 2012-11-21 12:35:25 +0000 | |||
318 | @@ -80,7 +80,8 @@ | |||
319 | 80 | @ivar allowed_ips: The sequence of L{IPPermission} instances for this | 80 | @ivar allowed_ips: The sequence of L{IPPermission} instances for this |
320 | 81 | security group. | 81 | security group. |
321 | 82 | """ | 82 | """ |
323 | 83 | def __init__(self, name, description, owner_id="", groups=None, ips=None): | 83 | def __init__(self, id, name, description, owner_id="", groups=None, ips=None): |
324 | 84 | self.id = id | ||
325 | 84 | self.name = name | 85 | self.name = name |
326 | 85 | self.description = description | 86 | self.description = description |
327 | 86 | self.owner_id = owner_id | 87 | self.owner_id = owner_id |
328 | 87 | 88 | ||
329 | === modified file 'txaws/ec2/tests/test_client.py' | |||
330 | --- txaws/ec2/tests/test_client.py 2012-03-02 22:00:10 +0000 | |||
331 | +++ txaws/ec2/tests/test_client.py 2012-11-21 12:35:25 +0000 | |||
332 | @@ -171,7 +171,8 @@ | |||
333 | 171 | self.assertEquals(reservation.owner_id, "123456789012") | 171 | self.assertEquals(reservation.owner_id, "123456789012") |
334 | 172 | # check groups | 172 | # check groups |
335 | 173 | group = reservation.groups[0] | 173 | group = reservation.groups[0] |
337 | 174 | self.assertEquals(group, "default") | 174 | self.assertEquals(group[0], "sg-64f9eb08") |
338 | 175 | self.assertEquals(group[1], "default") | ||
339 | 175 | # check instance | 176 | # check instance |
340 | 176 | self.assertEquals(instance.instance_id, "i-abcdef01") | 177 | self.assertEquals(instance.instance_id, "i-abcdef01") |
341 | 177 | self.assertEquals(instance.instance_state, "running") | 178 | self.assertEquals(instance.instance_state, "running") |
342 | @@ -201,7 +202,8 @@ | |||
343 | 201 | self.assertEquals(reservation.owner_id, "123456789012") | 202 | self.assertEquals(reservation.owner_id, "123456789012") |
344 | 202 | # check groups | 203 | # check groups |
345 | 203 | group = reservation.groups[0] | 204 | group = reservation.groups[0] |
347 | 204 | self.assertEquals(group, "default") | 205 | self.assertEquals(group[0], "sg-64f9eb08") |
348 | 206 | self.assertEquals(group[1], "default") | ||
349 | 205 | # check instance | 207 | # check instance |
350 | 206 | self.assertEquals(instance.instance_id, "i-abcdef01") | 208 | self.assertEquals(instance.instance_id, "i-abcdef01") |
351 | 207 | self.assertEquals(instance.instance_state, "running") | 209 | self.assertEquals(instance.instance_state, "running") |
352 | @@ -331,7 +333,8 @@ | |||
353 | 331 | self.assertEquals(reservation.owner_id, "495219933132") | 333 | self.assertEquals(reservation.owner_id, "495219933132") |
354 | 332 | # check groups | 334 | # check groups |
355 | 333 | group = reservation.groups[0] | 335 | group = reservation.groups[0] |
357 | 334 | self.assertEquals(group, "default") | 336 | self.assertEquals(group[0], "sg-64f9eb08") |
358 | 337 | self.assertEquals(group[1], "default") | ||
359 | 335 | # check instance | 338 | # check instance |
360 | 336 | self.assertEquals(instance.instance_id, "i-2ba64342") | 339 | self.assertEquals(instance.instance_id, "i-2ba64342") |
361 | 337 | self.assertEquals(instance.instance_state, "pending") | 340 | self.assertEquals(instance.instance_state, "pending") |
362 | @@ -377,6 +380,59 @@ | |||
363 | 377 | ramdisk_id=u"r-1234") | 380 | ramdisk_id=u"r-1234") |
364 | 378 | d.addCallback(self.check_parsed_run_instances) | 381 | d.addCallback(self.check_parsed_run_instances) |
365 | 379 | 382 | ||
366 | 383 | def test_run_instances_with_subnet(self): | ||
367 | 384 | class StubQuery(object): | ||
368 | 385 | def __init__(stub, action="", creds=None, endpoint=None, | ||
369 | 386 | other_params={}): | ||
370 | 387 | self.assertEqual(action, "RunInstances") | ||
371 | 388 | self.assertEqual(creds.access_key, "foo") | ||
372 | 389 | self.assertEqual(creds.secret_key, "bar") | ||
373 | 390 | self.assertEquals( | ||
374 | 391 | other_params, | ||
375 | 392 | {"ImageId": "ami-1234", "MaxCount": "2", "MinCount": "1", | ||
376 | 393 | "SecurityGroupId.1": u"sg-a72d9f92e", "KeyName": u"default", | ||
377 | 394 | "UserData": "Zm9v", "InstanceType": u"m1.small", | ||
378 | 395 | "Placement.AvailabilityZone": u"us-east-1b", | ||
379 | 396 | "KernelId": u"k-1234", "RamdiskId": u"r-1234", | ||
380 | 397 | "SubnetId": "subnet-a72d829f"}) | ||
381 | 398 | |||
382 | 399 | def submit(self): | ||
383 | 400 | return succeed( | ||
384 | 401 | payload.sample_run_instances_result) | ||
385 | 402 | |||
386 | 403 | creds = AWSCredentials("foo", "bar") | ||
387 | 404 | ec2 = client.EC2Client(creds, query_factory=StubQuery) | ||
388 | 405 | d = ec2.run_instances("ami-1234", 1, 2, security_group_ids=[u"sg-a72d9f92e"], | ||
389 | 406 | key_name=u"default", user_data=u"foo", instance_type=u"m1.small", | ||
390 | 407 | availability_zone=u"us-east-1b", kernel_id=u"k-1234", | ||
391 | 408 | ramdisk_id=u"r-1234", subnet_id="subnet-a72d829f") | ||
392 | 409 | d.addCallback(self.check_parsed_run_instances) | ||
393 | 410 | |||
394 | 411 | def test_run_instances_with_subnet_but_without_secgroup_id(self): | ||
395 | 412 | creds = AWSCredentials("foo", "bar") | ||
396 | 413 | ec2 = client.EC2Client(creds) | ||
397 | 414 | error = self.assertRaises(ValueError, ec2.run_instances, "ami-1234", 1, 2, | ||
398 | 415 | key_name=u"default", user_data=u"foo", instance_type=u"m1.small", | ||
399 | 416 | availability_zone=u"us-east-1b", kernel_id=u"k-1234", | ||
400 | 417 | ramdisk_id=u"r-1234", subnet_id="subnet-a72d829f") | ||
401 | 418 | self.assertEqual( | ||
402 | 419 | str(error), | ||
403 | 420 | "You must specify the security_group_ids with the subnet_id" | ||
404 | 421 | ) | ||
405 | 422 | |||
406 | 423 | def test_run_instances_without_subnet_and_secgroups(self): | ||
407 | 424 | creds = AWSCredentials("foo", "bar") | ||
408 | 425 | ec2 = client.EC2Client(creds) | ||
409 | 426 | error = self.assertRaises(ValueError, ec2.run_instances, "ami-1234", 1, 2, | ||
410 | 427 | key_name=u"default", user_data=u"foo", instance_type=u"m1.small", | ||
411 | 428 | availability_zone=u"us-east-1b", kernel_id=u"k-1234", | ||
412 | 429 | ramdisk_id=u"r-1234") | ||
413 | 430 | self.assertEqual( | ||
414 | 431 | str(error), | ||
415 | 432 | ("You must specify either the subnet_id and " | ||
416 | 433 | "security_group_ids or security_groups") | ||
417 | 434 | ) | ||
418 | 435 | |||
419 | 380 | 436 | ||
420 | 381 | class EC2ClientSecurityGroupsTestCase(TXAWSTestCase): | 437 | class EC2ClientSecurityGroupsTestCase(TXAWSTestCase): |
421 | 382 | 438 | ||
422 | @@ -400,6 +456,7 @@ | |||
423 | 400 | 456 | ||
424 | 401 | def check_results(security_groups): | 457 | def check_results(security_groups): |
425 | 402 | [security_group] = security_groups | 458 | [security_group] = security_groups |
426 | 459 | self.assertEquals(security_group.id, "sg-a1a1a1") | ||
427 | 403 | self.assertEquals(security_group.owner_id, | 460 | self.assertEquals(security_group.owner_id, |
428 | 404 | "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM") | 461 | "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM") |
429 | 405 | self.assertEquals(security_group.name, "WebServers") | 462 | self.assertEquals(security_group.name, "WebServers") |
430 | @@ -440,6 +497,7 @@ | |||
431 | 440 | security_group = security_groups[0] | 497 | security_group = security_groups[0] |
432 | 441 | self.assertEquals(security_group.owner_id, | 498 | self.assertEquals(security_group.owner_id, |
433 | 442 | "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM") | 499 | "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM") |
434 | 500 | self.assertEquals(security_group.id, "sg-a1a1a1") | ||
435 | 443 | self.assertEquals(security_group.name, "MessageServers") | 501 | self.assertEquals(security_group.name, "MessageServers") |
436 | 444 | self.assertEquals(security_group.description, "Message Servers") | 502 | self.assertEquals(security_group.description, "Message Servers") |
437 | 445 | self.assertEquals(security_group.allowed_groups, []) | 503 | self.assertEquals(security_group.allowed_groups, []) |
438 | @@ -451,6 +509,7 @@ | |||
439 | 451 | security_group = security_groups[1] | 509 | security_group = security_groups[1] |
440 | 452 | self.assertEquals(security_group.owner_id, | 510 | self.assertEquals(security_group.owner_id, |
441 | 453 | "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM") | 511 | "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM") |
442 | 512 | self.assertEquals(security_group.id, "sg-c3c3c3") | ||
443 | 454 | self.assertEquals(security_group.name, "WebServers") | 513 | self.assertEquals(security_group.name, "WebServers") |
444 | 455 | self.assertEquals(security_group.description, "Web Servers") | 514 | self.assertEquals(security_group.description, "Web Servers") |
445 | 456 | self.assertEquals([(pair.user_id, pair.group_name) | 515 | self.assertEquals([(pair.user_id, pair.group_name) |
446 | @@ -583,14 +642,45 @@ | |||
447 | 583 | def submit(self): | 642 | def submit(self): |
448 | 584 | return succeed(payload.sample_create_security_group) | 643 | return succeed(payload.sample_create_security_group) |
449 | 585 | 644 | ||
450 | 645 | def check_result(id): | ||
451 | 646 | self.assertEquals(id, "sg-1a2b3c4d") | ||
452 | 647 | |||
453 | 586 | creds = AWSCredentials("foo", "bar") | 648 | creds = AWSCredentials("foo", "bar") |
454 | 587 | ec2 = client.EC2Client(creds, query_factory=StubQuery) | 649 | ec2 = client.EC2Client(creds, query_factory=StubQuery) |
455 | 588 | d = ec2.create_security_group( | 650 | d = ec2.create_security_group( |
456 | 589 | "WebServers", | 651 | "WebServers", |
457 | 590 | "The group for the web server farm.") | 652 | "The group for the web server farm.") |
461 | 591 | return self.assertTrue(d) | 653 | return d.addCallback(check_result) |
462 | 592 | 654 | ||
463 | 593 | def test_delete_security_group(self): | 655 | def test_create_security_group_with_VPC(self): |
464 | 656 | class StubQuery(object): | ||
465 | 657 | |||
466 | 658 | def __init__(stub, action="", creds=None, endpoint=None, | ||
467 | 659 | other_params={}): | ||
468 | 660 | self.assertEqual(action, "CreateSecurityGroup") | ||
469 | 661 | self.assertEqual(creds.access_key, "foo") | ||
470 | 662 | self.assertEqual(creds.secret_key, "bar") | ||
471 | 663 | self.assertEqual(other_params, { | ||
472 | 664 | "GroupName": "WebServers", | ||
473 | 665 | "GroupDescription": "The group for the web server farm.", | ||
474 | 666 | "VpcId": "vpc-a4f2", | ||
475 | 667 | }) | ||
476 | 668 | |||
477 | 669 | def submit(self): | ||
478 | 670 | return succeed(payload.sample_create_security_group) | ||
479 | 671 | |||
480 | 672 | def check_result(id): | ||
481 | 673 | self.assertEquals(id, "sg-1a2b3c4d") | ||
482 | 674 | |||
483 | 675 | creds = AWSCredentials("foo", "bar") | ||
484 | 676 | ec2 = client.EC2Client(creds, query_factory=StubQuery) | ||
485 | 677 | d = ec2.create_security_group( | ||
486 | 678 | "WebServers", | ||
487 | 679 | "The group for the web server farm.", | ||
488 | 680 | "vpc-a4f2") | ||
489 | 681 | return d.addCallback(check_result) | ||
490 | 682 | |||
491 | 683 | def test_delete_security_group_using_name(self): | ||
492 | 594 | """ | 684 | """ |
493 | 595 | L{EC2Client.delete_security_group} returns a C{Deferred} that | 685 | L{EC2Client.delete_security_group} returns a C{Deferred} that |
494 | 596 | eventually fires with a true value, indicating the success of the | 686 | eventually fires with a true value, indicating the success of the |
495 | @@ -615,6 +705,40 @@ | |||
496 | 615 | d = ec2.delete_security_group("WebServers") | 705 | d = ec2.delete_security_group("WebServers") |
497 | 616 | return self.assertTrue(d) | 706 | return self.assertTrue(d) |
498 | 617 | 707 | ||
499 | 708 | def test_delete_security_group_using_id(self): | ||
500 | 709 | """ | ||
501 | 710 | L{EC2Client.delete_security_group} returns a C{Deferred} that | ||
502 | 711 | eventually fires with a true value, indicating the success of the | ||
503 | 712 | operation. | ||
504 | 713 | """ | ||
505 | 714 | class StubQuery(object): | ||
506 | 715 | |||
507 | 716 | def __init__(stub, action="", creds=None, endpoint=None, | ||
508 | 717 | other_params={}): | ||
509 | 718 | self.assertEqual(action, "DeleteSecurityGroup") | ||
510 | 719 | self.assertEqual(creds.access_key, "foo") | ||
511 | 720 | self.assertEqual(creds.secret_key, "bar") | ||
512 | 721 | self.assertEqual(other_params, { | ||
513 | 722 | "GroupId": "sg-a1a1a1", | ||
514 | 723 | }) | ||
515 | 724 | |||
516 | 725 | def submit(self): | ||
517 | 726 | return succeed(payload.sample_delete_security_group) | ||
518 | 727 | |||
519 | 728 | creds = AWSCredentials("foo", "bar") | ||
520 | 729 | ec2 = client.EC2Client(creds, query_factory=StubQuery) | ||
521 | 730 | d = ec2.delete_security_group(id="sg-a1a1a1") | ||
522 | 731 | return self.assertTrue(d) | ||
523 | 732 | |||
524 | 733 | def test_delete_security_group_without_id_and_name(self): | ||
525 | 734 | creds = AWSCredentials("foo", "bar") | ||
526 | 735 | ec2 = client.EC2Client(creds) | ||
527 | 736 | error = self.assertRaises(ValueError, ec2.delete_security_group) | ||
528 | 737 | self.assertEquals( | ||
529 | 738 | str(error), | ||
530 | 739 | "You must provide either the security group name or id", | ||
531 | 740 | ) | ||
532 | 741 | |||
533 | 618 | def test_delete_security_group_failure(self): | 742 | def test_delete_security_group_failure(self): |
534 | 619 | """ | 743 | """ |
535 | 620 | L{EC2Client.delete_security_group} returns a C{Deferred} that | 744 | L{EC2Client.delete_security_group} returns a C{Deferred} that |
536 | @@ -676,9 +800,42 @@ | |||
537 | 676 | creds = AWSCredentials("foo", "bar") | 800 | creds = AWSCredentials("foo", "bar") |
538 | 677 | ec2 = client.EC2Client(creds, query_factory=StubQuery) | 801 | ec2 = client.EC2Client(creds, query_factory=StubQuery) |
539 | 678 | d = ec2.authorize_security_group( | 802 | d = ec2.authorize_security_group( |
543 | 679 | "WebServers", source_group_name="AppServers", | 803 | group_name="WebServers", source_group_name="AppServers", |
544 | 680 | source_group_owner_id="123456789123") | 804 | source_group_owner_id="123456789123") |
545 | 681 | return self.assertTrue(d) | 805 | return self.assertTrue(d) |
546 | 806 | |||
547 | 807 | def test_authorize_security_group_using_group_id(self): | ||
548 | 808 | class StubQuery(object): | ||
549 | 809 | |||
550 | 810 | def __init__(stub, action="", creds=None, endpoint=None, | ||
551 | 811 | other_params={}): | ||
552 | 812 | self.assertEqual(action, "AuthorizeSecurityGroupIngress") | ||
553 | 813 | self.assertEqual(creds.access_key, "foo") | ||
554 | 814 | self.assertEqual(creds.secret_key, "bar") | ||
555 | 815 | self.assertEqual(other_params, { | ||
556 | 816 | "GroupId": "sg-a1b2c3d4e5f6", | ||
557 | 817 | "SourceSecurityGroupName": "AppServers", | ||
558 | 818 | "SourceSecurityGroupOwnerId": "123456789123", | ||
559 | 819 | }) | ||
560 | 820 | |||
561 | 821 | def submit(self): | ||
562 | 822 | return succeed(payload.sample_authorize_security_group) | ||
563 | 823 | |||
564 | 824 | creds = AWSCredentials("foo", "bar") | ||
565 | 825 | ec2 = client.EC2Client(creds, query_factory=StubQuery) | ||
566 | 826 | d = ec2.authorize_security_group( | ||
567 | 827 | group_id="sg-a1b2c3d4e5f6", source_group_name="AppServers", | ||
568 | 828 | source_group_owner_id="123456789123") | ||
569 | 829 | return self.assertTrue(d) | ||
570 | 830 | |||
571 | 831 | def test_authorize_security_group_without_group_id_and_group_name(self): | ||
572 | 832 | creds = AWSCredentials("foo", "bar") | ||
573 | 833 | ec2 = client.EC2Client(creds) | ||
574 | 834 | error = self.assertRaises(ValueError, ec2.authorize_security_group, | ||
575 | 835 | source_group_name="AppServers", source_group_owner_id="123456789123") | ||
576 | 836 | self.assertEquals( | ||
577 | 837 | str(error), | ||
578 | 838 | "You must specify either the group name of the group id.") | ||
579 | 682 | 839 | ||
580 | 683 | def test_authorize_security_group_with_ip_permissions(self): | 840 | def test_authorize_security_group_with_ip_permissions(self): |
581 | 684 | """ | 841 | """ |
582 | @@ -707,7 +864,7 @@ | |||
583 | 707 | creds = AWSCredentials("foo", "bar") | 864 | creds = AWSCredentials("foo", "bar") |
584 | 708 | ec2 = client.EC2Client(creds, query_factory=StubQuery) | 865 | ec2 = client.EC2Client(creds, query_factory=StubQuery) |
585 | 709 | d = ec2.authorize_security_group( | 866 | d = ec2.authorize_security_group( |
587 | 710 | "WebServers", ip_protocol="tcp", from_port="22", to_port="80", | 867 | group_name="WebServers", ip_protocol="tcp", from_port="22", to_port="80", |
588 | 711 | cidr_ip="0.0.0.0/0") | 868 | cidr_ip="0.0.0.0/0") |
589 | 712 | return self.assertTrue(d) | 869 | return self.assertTrue(d) |
590 | 713 | 870 | ||
591 | @@ -722,16 +879,12 @@ | |||
592 | 722 | """ | 879 | """ |
593 | 723 | creds = AWSCredentials("foo", "bar") | 880 | creds = AWSCredentials("foo", "bar") |
594 | 724 | ec2 = client.EC2Client(creds) | 881 | ec2 = client.EC2Client(creds) |
605 | 725 | self.assertRaises(ValueError, ec2.authorize_security_group, | 882 | error = self.assertRaises(ValueError, ec2.authorize_security_group, |
606 | 726 | "WebServers", ip_protocol="tcp", from_port="22") | 883 | group_name="WebServers", ip_protocol="tcp", from_port="22") |
607 | 727 | try: | 884 | self.assertEquals( |
608 | 728 | ec2.authorize_security_group( | 885 | str(error), |
609 | 729 | "WebServers", ip_protocol="tcp", from_port="22") | 886 | ("You must specify either both group parameters or all the " |
610 | 730 | except Exception, error: | 887 | "ip parameters.")) |
601 | 731 | self.assertEquals( | ||
602 | 732 | str(error), | ||
603 | 733 | ("You must specify either both group parameters or all the " | ||
604 | 734 | "ip parameters.")) | ||
611 | 735 | 888 | ||
612 | 736 | def test_authorize_group_permission(self): | 889 | def test_authorize_group_permission(self): |
613 | 737 | """ | 890 | """ |
614 | @@ -822,6 +975,30 @@ | |||
615 | 822 | source_group_owner_id="123456789123") | 975 | source_group_owner_id="123456789123") |
616 | 823 | return self.assertTrue(d) | 976 | return self.assertTrue(d) |
617 | 824 | 977 | ||
618 | 978 | def test_revoke_security_group_using_group_id(self): | ||
619 | 979 | class StubQuery(object): | ||
620 | 980 | |||
621 | 981 | def __init__(stub, action="", creds=None, endpoint=None, | ||
622 | 982 | other_params={}): | ||
623 | 983 | self.assertEqual(action, "RevokeSecurityGroupIngress") | ||
624 | 984 | self.assertEqual(creds.access_key, "foo") | ||
625 | 985 | self.assertEqual(creds.secret_key, "bar") | ||
626 | 986 | self.assertEqual(other_params, { | ||
627 | 987 | "GroupId": "sg-a1a1a1", | ||
628 | 988 | "SourceSecurityGroupName": "AppServers", | ||
629 | 989 | "SourceSecurityGroupOwnerId": "123456789123", | ||
630 | 990 | }) | ||
631 | 991 | |||
632 | 992 | def submit(self): | ||
633 | 993 | return succeed(payload.sample_revoke_security_group) | ||
634 | 994 | |||
635 | 995 | creds = AWSCredentials("foo", "bar") | ||
636 | 996 | ec2 = client.EC2Client(creds, query_factory=StubQuery) | ||
637 | 997 | d = ec2.revoke_security_group( | ||
638 | 998 | group_id="sg-a1a1a1", source_group_name="AppServers", | ||
639 | 999 | source_group_owner_id="123456789123") | ||
640 | 1000 | return self.assertTrue(d) | ||
641 | 1001 | |||
642 | 825 | def test_revoke_security_group_with_ip_permissions(self): | 1002 | def test_revoke_security_group_with_ip_permissions(self): |
643 | 826 | """ | 1003 | """ |
644 | 827 | L{EC2Client.revoke_security_group} returns a C{Deferred} that | 1004 | L{EC2Client.revoke_security_group} returns a C{Deferred} that |
645 | @@ -853,6 +1030,15 @@ | |||
646 | 853 | cidr_ip="0.0.0.0/0") | 1030 | cidr_ip="0.0.0.0/0") |
647 | 854 | return self.assertTrue(d) | 1031 | return self.assertTrue(d) |
648 | 855 | 1032 | ||
649 | 1033 | def test_revoke_security_group_without_group_id_and_group_name(self): | ||
650 | 1034 | creds = AWSCredentials("foo", "bar") | ||
651 | 1035 | ec2 = client.EC2Client(creds) | ||
652 | 1036 | error = self.assertRaises(ValueError, ec2.revoke_security_group, | ||
653 | 1037 | source_group_name="AppServers", source_group_owner_id="123456789123") | ||
654 | 1038 | self.assertEquals( | ||
655 | 1039 | str(error), | ||
656 | 1040 | "You must specify either the group name of the group id.") | ||
657 | 1041 | |||
658 | 856 | def test_revoke_security_group_with_missing_parameters(self): | 1042 | def test_revoke_security_group_with_missing_parameters(self): |
659 | 857 | """ | 1043 | """ |
660 | 858 | L{EC2Client.revoke_security_group} returns a C{Deferred} that | 1044 | L{EC2Client.revoke_security_group} returns a C{Deferred} that |
661 | @@ -864,16 +1050,12 @@ | |||
662 | 864 | """ | 1050 | """ |
663 | 865 | creds = AWSCredentials("foo", "bar") | 1051 | creds = AWSCredentials("foo", "bar") |
664 | 866 | ec2 = client.EC2Client(creds) | 1052 | ec2 = client.EC2Client(creds) |
675 | 867 | self.assertRaises(ValueError, ec2.authorize_security_group, | 1053 | error = self.assertRaises(ValueError, ec2.revoke_security_group, |
676 | 868 | "WebServers", ip_protocol="tcp", from_port="22") | 1054 | group_name="WebServers", ip_protocol="tcp", from_port="22") |
677 | 869 | try: | 1055 | self.assertEquals( |
678 | 870 | ec2.authorize_security_group( | 1056 | str(error), |
679 | 871 | "WebServers", ip_protocol="tcp", from_port="22") | 1057 | ("You must specify either both group parameters or all the " |
680 | 872 | except Exception, error: | 1058 | "ip parameters.")) |
671 | 873 | self.assertEquals( | ||
672 | 874 | str(error), | ||
673 | 875 | ("You must specify either both group parameters or all the " | ||
674 | 876 | "ip parameters.")) | ||
681 | 877 | 1059 | ||
682 | 878 | def test_revoke_group_permission(self): | 1060 | def test_revoke_group_permission(self): |
683 | 879 | """ | 1061 | """ |
684 | @@ -1561,7 +1743,7 @@ | |||
685 | 1561 | {"AWSAccessKeyId": "foo", | 1743 | {"AWSAccessKeyId": "foo", |
686 | 1562 | "Action": "DescribeInstances", | 1744 | "Action": "DescribeInstances", |
687 | 1563 | "SignatureVersion": "2", | 1745 | "SignatureVersion": "2", |
689 | 1564 | "Version": "2009-11-30"}) | 1746 | "Version": "2012-08-15"}) |
690 | 1565 | 1747 | ||
691 | 1566 | def test_init_other_args_are_params(self): | 1748 | def test_init_other_args_are_params(self): |
692 | 1567 | query = client.Query( | 1749 | query = client.Query( |
693 | @@ -1575,7 +1757,7 @@ | |||
694 | 1575 | "InstanceId.0": "12345", | 1757 | "InstanceId.0": "12345", |
695 | 1576 | "SignatureVersion": "2", | 1758 | "SignatureVersion": "2", |
696 | 1577 | "Timestamp": "2007-11-12T13:14:15Z", | 1759 | "Timestamp": "2007-11-12T13:14:15Z", |
698 | 1578 | "Version": "2009-11-30"}) | 1760 | "Version": "2012-08-15"}) |
699 | 1579 | 1761 | ||
700 | 1580 | def test_no_timestamp_if_expires_in_other_params(self): | 1762 | def test_no_timestamp_if_expires_in_other_params(self): |
701 | 1581 | """ | 1763 | """ |
702 | @@ -1593,7 +1775,7 @@ | |||
703 | 1593 | "Action": "DescribeInstances", | 1775 | "Action": "DescribeInstances", |
704 | 1594 | "SignatureVersion": "2", | 1776 | "SignatureVersion": "2", |
705 | 1595 | "Expires": "2007-11-12T13:14:15Z", | 1777 | "Expires": "2007-11-12T13:14:15Z", |
707 | 1596 | "Version": "2009-11-30"}) | 1778 | "Version": "2012-08-15"}) |
708 | 1597 | 1779 | ||
709 | 1598 | def test_sign(self): | 1780 | def test_sign(self): |
710 | 1599 | query = client.Query( | 1781 | query = client.Query( |
711 | @@ -1601,7 +1783,7 @@ | |||
712 | 1601 | endpoint=self.endpoint, | 1783 | endpoint=self.endpoint, |
713 | 1602 | time_tuple=(2007, 11, 12, 13, 14, 15, 0, 0, 0)) | 1784 | time_tuple=(2007, 11, 12, 13, 14, 15, 0, 0, 0)) |
714 | 1603 | query.sign() | 1785 | query.sign() |
716 | 1604 | self.assertEqual("G4c2NtQaFNhWWT8EWPVIIOpHVr0mGUYwJVYss9krsMU=", | 1786 | self.assertEqual("c0gbkemrGEJdqxWOl2UZYaygYiBLVjrpWBs7bTN7Ndo=", |
717 | 1605 | query.params["Signature"]) | 1787 | query.params["Signature"]) |
718 | 1606 | 1788 | ||
719 | 1607 | def test_old_sign(self): | 1789 | def test_old_sign(self): |
720 | @@ -1612,7 +1794,7 @@ | |||
721 | 1612 | other_params={"SignatureVersion": "1"}) | 1794 | other_params={"SignatureVersion": "1"}) |
722 | 1613 | query.sign() | 1795 | query.sign() |
723 | 1614 | self.assertEqual( | 1796 | self.assertEqual( |
725 | 1615 | "9xP+PIs/3QXW+4mWX6WGR4nGqfE=", query.params["Signature"]) | 1797 | "7tWrIC5VYvXOjVE+roVoyDUt2Yw=", query.params["Signature"]) |
726 | 1616 | 1798 | ||
727 | 1617 | def test_unsupported_sign(self): | 1799 | def test_unsupported_sign(self): |
728 | 1618 | query = client.Query( | 1800 | query = client.Query( |
729 | 1619 | 1801 | ||
730 | === modified file 'txaws/ec2/tests/test_model.py' | |||
731 | --- txaws/ec2/tests/test_model.py 2012-01-23 01:04:25 +0000 | |||
732 | +++ txaws/ec2/tests/test_model.py 2012-11-21 12:35:25 +0000 | |||
733 | @@ -8,7 +8,8 @@ | |||
734 | 8 | class SecurityGroupTestCase(TXAWSTestCase): | 8 | class SecurityGroupTestCase(TXAWSTestCase): |
735 | 9 | 9 | ||
736 | 10 | def test_creation_defaults(self): | 10 | def test_creation_defaults(self): |
738 | 11 | group = model.SecurityGroup("name", "desc") | 11 | group = model.SecurityGroup("sg-a3f2", "name", "desc") |
739 | 12 | self.assertEquals(group.id, "sg-a3f2") | ||
740 | 12 | self.assertEquals(group.name, "name") | 13 | self.assertEquals(group.name, "name") |
741 | 13 | self.assertEquals(group.description, "desc") | 14 | self.assertEquals(group.description, "desc") |
742 | 14 | self.assertEquals(group.owner_id, "") | 15 | self.assertEquals(group.owner_id, "") |
743 | @@ -18,14 +19,15 @@ | |||
744 | 18 | def test_creation_all_parameters(self): | 19 | def test_creation_all_parameters(self): |
745 | 19 | user = "somegal24" | 20 | user = "somegal24" |
746 | 20 | other_groups = [ | 21 | other_groups = [ |
749 | 21 | model.SecurityGroup("other1", "another group 1"), | 22 | model.SecurityGroup("sg-other1", "other1", "another group 1"), |
750 | 22 | model.SecurityGroup("other2", "another group 2")] | 23 | model.SecurityGroup("sg-other2", "other2", "another group 2")] |
751 | 23 | user_group_pairs = [ | 24 | user_group_pairs = [ |
752 | 24 | model.UserIDGroupPair(user, other_groups[0].name), | 25 | model.UserIDGroupPair(user, other_groups[0].name), |
753 | 25 | model.UserIDGroupPair(user, other_groups[1].name)] | 26 | model.UserIDGroupPair(user, other_groups[1].name)] |
754 | 26 | ips = [model.IPPermission("tcp", "80", "80", "10.0.1.0/24")] | 27 | ips = [model.IPPermission("tcp", "80", "80", "10.0.1.0/24")] |
755 | 27 | group = model.SecurityGroup( | 28 | group = model.SecurityGroup( |
757 | 28 | "name", "desc", owner_id="me", groups=user_group_pairs, ips=ips) | 29 | "id", "name", "desc", owner_id="me", groups=user_group_pairs, ips=ips) |
758 | 30 | self.assertEquals(group.id, "id") | ||
759 | 29 | self.assertEquals(group.name, "name") | 31 | self.assertEquals(group.name, "name") |
760 | 30 | self.assertEquals(group.description, "desc") | 32 | self.assertEquals(group.description, "desc") |
761 | 31 | self.assertEquals(group.owner_id, "me") | 33 | self.assertEquals(group.owner_id, "me") |
762 | 32 | 34 | ||
763 | === modified file 'txaws/server/tests/test_call.py' | |||
764 | --- txaws/server/tests/test_call.py 2012-01-27 02:10:24 +0000 | |||
765 | +++ txaws/server/tests/test_call.py 2012-11-21 12:35:25 +0000 | |||
766 | @@ -11,4 +11,4 @@ | |||
767 | 11 | 2009-11-30, which is the earliest version we support. | 11 | 2009-11-30, which is the earliest version we support. |
768 | 12 | """ | 12 | """ |
769 | 13 | call = Call() | 13 | call = Call() |
771 | 14 | self.assertEqual(call.version, "2009-11-30") | 14 | self.assertEqual(call.version, "2012-08-15") |
772 | 15 | 15 | ||
773 | === modified file 'txaws/testing/payload.py' | |||
774 | --- txaws/testing/payload.py 2012-05-16 02:47:12 +0000 | |||
775 | +++ txaws/testing/payload.py 2012-11-21 12:35:25 +0000 | |||
776 | @@ -9,11 +9,7 @@ | |||
777 | 9 | <item> | 9 | <item> |
778 | 10 | <reservationId>r-cf24b1a6</reservationId> | 10 | <reservationId>r-cf24b1a6</reservationId> |
779 | 11 | <ownerId>123456789012</ownerId> | 11 | <ownerId>123456789012</ownerId> |
785 | 12 | <groupSet> | 12 | <groupSet/> |
781 | 13 | <item> | ||
782 | 14 | <groupId>default</groupId> | ||
783 | 15 | </item> | ||
784 | 16 | </groupSet> | ||
786 | 17 | <instancesSet> | 13 | <instancesSet> |
787 | 18 | <item> | 14 | <item> |
788 | 19 | <instanceId>i-abcdef01</instanceId> | 15 | <instanceId>i-abcdef01</instanceId> |
789 | @@ -22,6 +18,12 @@ | |||
790 | 22 | <code>16</code> | 18 | <code>16</code> |
791 | 23 | <name>running</name> | 19 | <name>running</name> |
792 | 24 | </instanceState> | 20 | </instanceState> |
793 | 21 | <groupSet> | ||
794 | 22 | <item> | ||
795 | 23 | <groupId>sg-64f9eb08</groupId> | ||
796 | 24 | <groupName>default</groupName> | ||
797 | 25 | </item> | ||
798 | 26 | </groupSet> | ||
799 | 25 | <privateDnsName>domU-12-31-39-03-15-11.compute-1.internal\ | 27 | <privateDnsName>domU-12-31-39-03-15-11.compute-1.internal\ |
800 | 26 | </privateDnsName> | 28 | </privateDnsName> |
801 | 27 | <dnsName>ec2-75-101-245-65.compute-1.amazonaws.com</dnsName> | 29 | <dnsName>ec2-75-101-245-65.compute-1.amazonaws.com</dnsName> |
802 | @@ -48,11 +50,7 @@ | |||
803 | 48 | <item> | 50 | <item> |
804 | 49 | <reservationId>r-cf24b1a6</reservationId> | 51 | <reservationId>r-cf24b1a6</reservationId> |
805 | 50 | <ownerId>123456789012</ownerId> | 52 | <ownerId>123456789012</ownerId> |
811 | 51 | <groupSet> | 53 | <groupSet/> |
807 | 52 | <item> | ||
808 | 53 | <groupId>default</groupId> | ||
809 | 54 | </item> | ||
810 | 55 | </groupSet> | ||
812 | 56 | <instancesSet> | 54 | <instancesSet> |
813 | 57 | <item> | 55 | <item> |
814 | 58 | <instanceId>i-abcdef01</instanceId> | 56 | <instanceId>i-abcdef01</instanceId> |
815 | @@ -67,6 +65,12 @@ | |||
816 | 67 | <privateIpAddress>10.0.0.1</privateIpAddress> | 65 | <privateIpAddress>10.0.0.1</privateIpAddress> |
817 | 68 | <ipAddress>75.101.245.65</ipAddress> | 66 | <ipAddress>75.101.245.65</ipAddress> |
818 | 69 | <reason/> | 67 | <reason/> |
819 | 68 | <groupSet> | ||
820 | 69 | <item> | ||
821 | 70 | <groupId>sg-64f9eb08</groupId> | ||
822 | 71 | <groupName>default</groupName> | ||
823 | 72 | </item> | ||
824 | 73 | </groupSet> | ||
825 | 70 | <keyName>keyname</keyName> | 74 | <keyName>keyname</keyName> |
826 | 71 | <amiLaunchIndex>0</amiLaunchIndex> | 75 | <amiLaunchIndex>0</amiLaunchIndex> |
827 | 72 | <productCodes> | 76 | <productCodes> |
828 | @@ -92,18 +96,14 @@ | |||
829 | 92 | <RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc/%s/"> | 96 | <RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc/%s/"> |
830 | 93 | <reservationId>r-47a5402e</reservationId> | 97 | <reservationId>r-47a5402e</reservationId> |
831 | 94 | <ownerId>495219933132</ownerId> | 98 | <ownerId>495219933132</ownerId> |
837 | 95 | <groupSet> | 99 | <groupSet/> |
833 | 96 | <item> | ||
834 | 97 | <groupId>default</groupId> | ||
835 | 98 | </item> | ||
836 | 99 | </groupSet> | ||
838 | 100 | <instancesSet> | 100 | <instancesSet> |
839 | 101 | <item> | 101 | <item> |
840 | 102 | <instanceId>i-2ba64342</instanceId> | 102 | <instanceId>i-2ba64342</instanceId> |
841 | 103 | <imageId>ami-60a54009</imageId> | 103 | <imageId>ami-60a54009</imageId> |
842 | 104 | <instanceState> | 104 | <instanceState> |
843 | 105 | <code>0</code> | 105 | <code>0</code> |
845 | 106 | <name>pending</name> | 106 | <name>pending</name> |
846 | 107 | </instanceState> | 107 | </instanceState> |
847 | 108 | <privateDnsName></privateDnsName> | 108 | <privateDnsName></privateDnsName> |
848 | 109 | <dnsName></dnsName> | 109 | <dnsName></dnsName> |
849 | @@ -111,6 +111,12 @@ | |||
850 | 111 | <amiLaunchIndex>0</amiLaunchIndex> | 111 | <amiLaunchIndex>0</amiLaunchIndex> |
851 | 112 | <instanceType>m1.small</instanceType> | 112 | <instanceType>m1.small</instanceType> |
852 | 113 | <launchTime>2007-08-07T11:51:50.000Z</launchTime> | 113 | <launchTime>2007-08-07T11:51:50.000Z</launchTime> |
853 | 114 | <groupSet> | ||
854 | 115 | <item> | ||
855 | 116 | <groupId>sg-64f9eb08</groupId> | ||
856 | 117 | <groupName>default</groupName> | ||
857 | 118 | </item> | ||
858 | 119 | </groupSet> | ||
859 | 114 | <placement> | 120 | <placement> |
860 | 115 | <availabilityZone>us-east-1b</availabilityZone> | 121 | <availabilityZone>us-east-1b</availabilityZone> |
861 | 116 | </placement> | 122 | </placement> |
862 | @@ -120,7 +126,7 @@ | |||
863 | 120 | <imageId>ami-60a54009</imageId> | 126 | <imageId>ami-60a54009</imageId> |
864 | 121 | <instanceState> | 127 | <instanceState> |
865 | 122 | <code>0</code> | 128 | <code>0</code> |
867 | 123 | <name>pending</name> | 129 | <name>pending</name> |
868 | 124 | </instanceState> | 130 | </instanceState> |
869 | 125 | <privateDnsName></privateDnsName> | 131 | <privateDnsName></privateDnsName> |
870 | 126 | <dnsName></dnsName> | 132 | <dnsName></dnsName> |
871 | @@ -128,6 +134,12 @@ | |||
872 | 128 | <amiLaunchIndex>1</amiLaunchIndex> | 134 | <amiLaunchIndex>1</amiLaunchIndex> |
873 | 129 | <instanceType>m1.small</instanceType> | 135 | <instanceType>m1.small</instanceType> |
874 | 130 | <launchTime>2007-08-07T11:51:50.000Z</launchTime> | 136 | <launchTime>2007-08-07T11:51:50.000Z</launchTime> |
875 | 137 | <groupSet> | ||
876 | 138 | <item> | ||
877 | 139 | <groupId>sg-64f9eb08</groupId> | ||
878 | 140 | <groupName>default</groupName> | ||
879 | 141 | </item> | ||
880 | 142 | </groupSet> | ||
881 | 131 | <placement> | 143 | <placement> |
882 | 132 | <availabilityZone>us-east-1b</availabilityZone> | 144 | <availabilityZone>us-east-1b</availabilityZone> |
883 | 133 | </placement> | 145 | </placement> |
884 | @@ -145,6 +157,12 @@ | |||
885 | 145 | <amiLaunchIndex>2</amiLaunchIndex> | 157 | <amiLaunchIndex>2</amiLaunchIndex> |
886 | 146 | <instanceType>m1.small</instanceType> | 158 | <instanceType>m1.small</instanceType> |
887 | 147 | <launchTime>2007-08-07T11:51:50.000Z</launchTime> | 159 | <launchTime>2007-08-07T11:51:50.000Z</launchTime> |
888 | 160 | <groupSet> | ||
889 | 161 | <item> | ||
890 | 162 | <groupId>sg-64f9eb08</groupId> | ||
891 | 163 | <groupName>default</groupName> | ||
892 | 164 | </item> | ||
893 | 165 | </groupSet> | ||
894 | 148 | <placement> | 166 | <placement> |
895 | 149 | <availabilityZone>us-east-1b</availabilityZone> | 167 | <availabilityZone>us-east-1b</availabilityZone> |
896 | 150 | </placement> | 168 | </placement> |
897 | @@ -213,6 +231,7 @@ | |||
898 | 213 | <fromPort/> | 231 | <fromPort/> |
899 | 214 | </item> | 232 | </item> |
900 | 215 | </ipPermissions> | 233 | </ipPermissions> |
901 | 234 | <groupId>sg-a1a1a1</groupId> | ||
902 | 216 | <groupName>WebServers</groupName> | 235 | <groupName>WebServers</groupName> |
903 | 217 | <groupDescription>Web servers</groupDescription> | 236 | <groupDescription>Web servers</groupDescription> |
904 | 218 | <ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId> | 237 | <ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId> |
905 | @@ -228,6 +247,7 @@ | |||
906 | 228 | <securityGroupInfo> | 247 | <securityGroupInfo> |
907 | 229 | <item> | 248 | <item> |
908 | 230 | <ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId> | 249 | <ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId> |
909 | 250 | <groupId>sg-a1a1a1</groupId> | ||
910 | 231 | <groupName>WebServers</groupName> | 251 | <groupName>WebServers</groupName> |
911 | 232 | <groupDescription>Web Servers</groupDescription> | 252 | <groupDescription>Web Servers</groupDescription> |
912 | 233 | <ipPermissions> | 253 | <ipPermissions> |
913 | @@ -256,6 +276,7 @@ | |||
914 | 256 | <securityGroupInfo> | 276 | <securityGroupInfo> |
915 | 257 | <item> | 277 | <item> |
916 | 258 | <ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId> | 278 | <ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId> |
917 | 279 | <groupId>sg-a1a1a1</groupId> | ||
918 | 259 | <groupName>MessageServers</groupName> | 280 | <groupName>MessageServers</groupName> |
919 | 260 | <groupDescription>Message Servers</groupDescription> | 281 | <groupDescription>Message Servers</groupDescription> |
920 | 261 | <ipPermissions> | 282 | <ipPermissions> |
921 | @@ -274,6 +295,7 @@ | |||
922 | 274 | </item> | 295 | </item> |
923 | 275 | <item> | 296 | <item> |
924 | 276 | <ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId> | 297 | <ownerId>UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM</ownerId> |
925 | 298 | <groupId>sg-c3c3c3</groupId> | ||
926 | 277 | <groupName>WebServers</groupName> | 299 | <groupName>WebServers</groupName> |
927 | 278 | <groupDescription>Web Servers</groupDescription> | 300 | <groupDescription>Web Servers</groupDescription> |
928 | 279 | <ipPermissions> | 301 | <ipPermissions> |
929 | @@ -457,6 +479,7 @@ | |||
930 | 457 | sample_create_security_group = """\ | 479 | sample_create_security_group = """\ |
931 | 458 | <CreateSecurityGroupResponse xmlns="http://ec2.amazonaws.com/doc/%s/"> | 480 | <CreateSecurityGroupResponse xmlns="http://ec2.amazonaws.com/doc/%s/"> |
932 | 459 | <return>true</return> | 481 | <return>true</return> |
933 | 482 | <groupId>sg-1a2b3c4d</groupId> | ||
934 | 460 | </CreateSecurityGroupResponse> | 483 | </CreateSecurityGroupResponse> |
935 | 461 | """ % (version.ec2_api,) | 484 | """ % (version.ec2_api,) |
936 | 462 | 485 | ||
937 | 463 | 486 | ||
938 | === modified file 'txaws/version.py' | |||
939 | --- txaws/version.py 2012-01-24 23:18:36 +0000 | |||
940 | +++ txaws/version.py 2012-11-21 12:35:25 +0000 | |||
941 | @@ -1,3 +1,3 @@ | |||
942 | 1 | txaws = "0.2.3" | 1 | txaws = "0.2.3" |
944 | 2 | ec2_api = "2009-11-30" | 2 | ec2_api = "2012-08-15" |
945 | 3 | s3_api = "2006-03-01" | 3 | s3_api = "2006-03-01" |
Reviewers: mp+135397_ code.launchpad. net,
Message:
Please take a look.
Description:
client, ec2: bundling changes needed for VPC
I use this CL for patching only, original CL's are:
https:/ /codereview. appspot. com/6852064/ /codereview. appspot. com/6826065/ /codereview. appspot. com/6814123/ /codereview. appspot. com/6822097/
https:/
https:/
https:/
This one also includes a change in parsing of instance sets.
https:/ /code.launchpad .net/~francisco souza/txaws/ txaws-bundled- vpc/+merge/ 135397
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/6851093/
Affected files: base.py discover/ tests/test_ command. py tests/test_ client. py tests/test_ model.py tests/test_ call.py payload. py
A [revision details]
M txaws/client/
M txaws/client/
M txaws/ec2/client.py
M txaws/ec2/model.py
M txaws/ec2/
M txaws/ec2/
M txaws/server/
M txaws/testing/
M txaws/version.py