Browse code

* S3/CloudFront.py: Added Cmd.info() that handles both cflist and cfinfo commands (in fact they're aliases). Made DistributionConfig() class consistent with other Distribution*() classes. Use S3Uri and CFUri in outputs. * s3cmd: Enabled cfinfo command.

git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/branches/s3cmd-airlock@344 830e0280-6d2a-0410-9c65-932aecc39d9d

Michal Ludvig authored on 2009/01/17 21:34:12
Showing 3 changed files
... ...
@@ -1,5 +1,14 @@
1 1
 2009-01-18  Michal Ludvig  <michal@logix.cz>
2 2
 
3
+	* S3/CloudFront.py: Added Cmd.info() that handles both 
4
+	  cflist and cfinfo commands (in fact they're aliases).
5
+	  Made DistributionConfig() class consistent with other
6
+	  Distribution*() classes.
7
+	  Use S3Uri and CFUri in outputs.
8
+	* s3cmd: Enabled cfinfo command.
9
+
10
+2009-01-18  Michal Ludvig  <michal@logix.cz>
11
+
3 12
 	* S3/S3Uri.py: Added S3UriCloudFront.
4 13
 	  Added S3UriS3.httpurl_to_s3uri() static method.
5 14
 
... ...
@@ -24,7 +24,7 @@ except ImportError:
24 24
 from Config import Config
25 25
 from Exceptions import *
26 26
 from Utils import getTreeFromXml, appendXmlTextNode, getDictFromTree, dateS3toPython
27
-from S3Uri import S3Uri
27
+from S3Uri import S3Uri, S3UriS3
28 28
 
29 29
 def output(message):
30 30
 	sys.stdout.write(message + "\n")
... ...
@@ -45,7 +45,7 @@ class DistributionSummary(object):
45 45
 	##	<Origin>example.bucket.s3.amazonaws.com</Origin>
46 46
 	##	<Enabled>true</Enabled>
47 47
 	## </DistributionSummary>
48
-	
48
+
49 49
 	def __init__(self, tree):
50 50
 		if tree.tag != "DistributionSummary":
51 51
 			raise ValueError("Expected <DistributionSummary /> xml, got: <%s />" % tree.tag)
... ...
@@ -55,6 +55,9 @@ class DistributionSummary(object):
55 55
 		self.info = getDictFromTree(tree)
56 56
 		self.info['Enabled'] = (self.info['Enabled'].lower() == "true")
57 57
 
58
+	def uri(self):
59
+		return S3Uri("cf://%s" % self.info['Id'])
60
+
58 61
 class DistributionList(object):
59 62
 	## Example:
60 63
 	## 
... ...
@@ -107,6 +110,9 @@ class Distribution(object):
107 107
 		self.info['LastModifiedTime'] = dateS3toPython(self.info['LastModifiedTime'])
108 108
 
109 109
 		self.info['DistributionConfig'] = DistributionConfig(tree = tree.find(".//DistributionConfig"))
110
+	
111
+	def uri(self):
112
+		return S3Uri("cf://%s" % self.info['Id'])
110 113
 
111 114
 class DistributionConfig(object):
112 115
 	## Example:
... ...
@@ -132,27 +138,22 @@ class DistributionConfig(object):
132 132
 		self.parse(tree)
133 133
 
134 134
 	def parse(self, tree):
135
-		self.Origin = tree.findtext(".//Origin") or ""
136
-		self.CallerReference = tree.findtext(".//CallerReference") or ""
137
-		self.Comment = tree.findtext(".//Comment") or ""
138
-		self.Cnames = []
139
-		for cname in tree.findall(".//CNAME"):
140
-			self.Cnames.append(cname.text.lower())
141
-		enabled = tree.findtext(".//Enabled") or ""
142
-		self.Enabled = (enabled.lower() == "true")
135
+		self.info = getDictFromTree(tree)
136
+		self.info['Enabled'] = (self.info['Enabled'].lower() == "true")
137
+		self.info['CNAME'] = [cname.lower() for cname in self.info['CNAME']]
143 138
 
144 139
 	def __str__(self):
145 140
 		tree = getTreeFromXml(DistributionConfig.EMPTY_CONFIG)
146 141
 		tree.attrib['xmlns'] = DistributionConfig.xmlns
147 142
 
148 143
 		## Retain the order of the following calls!
149
-		appendXmlTextNode("Origin", self.Origin, tree)
150
-		appendXmlTextNode("CallerReference", self.CallerReference, tree)
144
+		appendXmlTextNode("Origin", self.info['Origin'], tree)
145
+		appendXmlTextNode("CallerReference", self.info['CallerReference'], tree)
151 146
 		if self.Comment:
152
-			appendXmlTextNode("Comment", self.Comment, tree)
153
-		for cname in self.Cnames:
147
+			appendXmlTextNode("Comment", self.info['Comment'], tree)
148
+		for cname in self.info['CNAME']:
154 149
 			appendXmlTextNode("CNAME", cname.lower(), tree)
155
-		appendXmlTextNode("Enabled", str(self.Enabled).lower(), tree)
150
+		appendXmlTextNode("Enabled", str(self.info['Enabled']).lower(), tree)
156 151
 
157 152
 		return ET.tostring(tree)
158 153
 
... ...
@@ -186,17 +187,31 @@ class CloudFront(object):
186 186
 	
187 187
 	def CreateDistribution(self, uri, cnames = []):
188 188
 		dist_conf = DistributionConfig()
189
-		dist_conf.Enabled = True
190
-		dist_conf.Origin = uri.host_name()
191
-		dist_conf.CallerReference = str(uri)
192
-		dist_conf.Comment = uri.public_url()
189
+		dist_conf.info['Enabled'] = True
190
+		dist_conf.info['Origin'] = uri.host_name()
191
+		dist_conf.info['CallerReference'] = str(uri)
192
+		dist_conf.info['Comment'] = uri.public_url()
193 193
 		if cnames:
194
-			dist_conf.Cnames = cnames
194
+			dist_conf.info['Cnames'] = cnames
195 195
 		request_body = str(dist_conf)
196 196
 		debug("CreateDistribution(): request_body: %s" % request_body)
197 197
 		response = self.send_request("CreateDist", body = request_body)
198 198
 		response['distribution'] = Distribution(response['data'])
199 199
 		return response
200
+	
201
+	def DeleteDistribution(self, cfuri):
202
+		if cfuri.type != "cf":
203
+			raise ValueError("Expected CFUri instead of: %s" % cfuri)
204
+		raise NotImplementedError()
205
+		# DisableDistribution
206
+		# response = self.send_request("DeleteDist", dist_id = cfuri.dist_id())
207
+	
208
+	def GetDistInfo(self, cfuri):
209
+		if cfuri.type != "cf":
210
+			raise ValueError("Expected CFUri instead of: %s" % cfuri)
211
+		response = self.send_request("GetDistInfo", dist_id = cfuri.dist_id())
212
+		response['distribution'] = Distribution(response['data'])
213
+		return response
200 214
 
201 215
 	## --------------------------------------------------
202 216
 	## Low-level methods for handling CloudFront requests
... ...
@@ -283,17 +298,34 @@ class Cmd(object):
283 283
 	"""
284 284
 	
285 285
 	@staticmethod
286
-	def list(args):
286
+	def info(args):
287 287
 		cf = CloudFront(Config())
288
-		response = cf.GetList()
289
-		for d in response['dist_list'].dist_summs:
290
-			pretty_output("Origin", d.info['Origin'])
291
-			pretty_output("DomainName", d.info['DomainName'])
292
-			pretty_output("Id", d.info['Id'])
293
-			pretty_output("Status", d.info['Status'])
294
-			pretty_output("Enabled", d.info['Enabled'])
295
-			output("")
296
-	
288
+		if not args:
289
+			response = cf.GetList()
290
+			for d in response['dist_list'].dist_summs:
291
+				pretty_output("Origin", S3UriS3.httpurl_to_s3uri(d.info['Origin']))
292
+				pretty_output("DistId", d.uri())
293
+				pretty_output("DomainName", d.info['DomainName'])
294
+				pretty_output("Status", d.info['Status'])
295
+				pretty_output("Enabled", d.info['Enabled'])
296
+				output("")
297
+		else:
298
+			cfuris = []
299
+			for arg in args:
300
+				cfuris.append(S3Uri(arg))
301
+				if cfuris[-1].type != 'cf':
302
+					raise ParameterError("CloudFront URI required instead of: %s" % arg)
303
+			for cfuri in cfuris:
304
+				response = cf.GetDistInfo(cfuri)
305
+				d = response['distribution']
306
+				dc = d.info['DistributionConfig']
307
+				pretty_output("Origin", S3UriS3.httpurl_to_s3uri(dc.info['Origin']))
308
+				pretty_output("DistId", d.uri())
309
+				pretty_output("DomainName", d.info['DomainName'])
310
+				pretty_output("Status", d.info['Status'])
311
+				pretty_output("Enabled", dc.info['Enabled'])
312
+				pretty_output("Etag", response['headers']['etag'])
313
+
297 314
 	@staticmethod
298 315
 	def create(args):
299 316
 		cf = CloudFront(Config())
... ...
@@ -315,9 +347,8 @@ class Cmd(object):
315 315
 			d = response['distribution']
316 316
 			dc = d.info['DistributionConfig']
317 317
 			output("Distribution created:")
318
-			#pretty_output("Origin", dc.info['Origin'])
319
-			pretty_output("Origin", dc.Origin)
318
+			pretty_output("Origin", S3UriS3.httpurl_to_s3uri(dc.info['Origin']))
319
+			pretty_output("DistId", d.uri())
320 320
 			pretty_output("DomainName", d.info['DomainName'])
321
-			pretty_output("Id", d.info['Id'])
322 321
 			pretty_output("Status", d.info['Status'])
323
-			pretty_output("Enabled", dc.Enabled)
322
+			pretty_output("Enabled", dc.info['Enabled'])
... ...
@@ -1118,10 +1118,10 @@ def get_commands_list():
1118 1118
 	{"cmd":"mv", "label":"Move object", "param":"s3://BUCKET1/OBJECT1 s3://BUCKET2[/OBJECT2]", "func":cmd_mv, "argc":2},
1119 1119
 	{"cmd":"setacl", "label":"Modify Access control list for Bucket or Object", "param":"s3://BUCKET[/OBJECT]", "func":cmd_setacl, "argc":1},
1120 1120
 	## CloudFront commands
1121
-	{"cmd":"cflist", "label":"List CloudFront distribution points", "param":"", "func":CfCmd.list, "argc":0},
1121
+	{"cmd":"cflist", "label":"List CloudFront distribution points", "param":"", "func":CfCmd.info, "argc":0},
1122
+	{"cmd":"cfinfo", "label":"Display CloudFront distribution point parameters", "param":"[cf://DIST_ID]", "func":CfCmd.info, "argc":0},
1122 1123
 	{"cmd":"cfcreate", "label":"Create CloudFront distribution point", "param":"s3://BUCKET", "func":CfCmd.create, "argc":1},
1123
-	#{"cmd":"cfdelete", "label":"Delete CloudFront distribution point", "param":"cf://DIST_ID", "func":cmd_cf_delete, "argc":1},
1124
-	#{"cmd":"cfinfo", "label":"Display CloudFront distribution point parameters", "param":"cf://DIST_ID", "func":cmd_cf_info, "argc":1},
1124
+	#{"cmd":"cfdelete", "label":"Delete CloudFront distribution point", "param":"cf://DIST_ID", "func":CfCmd.delete, "argc":1},
1125 1125
 	#{"cmd":"cfmodify", "label":"Change CloudFront distribution point parameters", "param":"cf://DIST_ID", "func":cmd_cf_modify, "argc":1},
1126 1126
 	]
1127 1127