From: <lu...@us...> - 2009-01-18 13:10:33
|
Revision: 346 http://s3tools.svn.sourceforge.net/s3tools/?rev=346&view=rev Author: ludvigm Date: 2009-01-18 13:10:23 +0000 (Sun, 18 Jan 2009) Log Message: ----------- * S3/CloudFront.py: Implemented ModifyDistribution(), added support for CNAMEs, Comments and Enable/Disable. * s3cmd: Enabled cfmodify, added --enable/--disable, --cf-add-cname/--cf-remove-cname, --cf-comment options. Added updating from 'options' to CfCmd.options. Modified Paths: -------------- s3cmd/branches/s3cmd-airlock/ChangeLog s3cmd/branches/s3cmd-airlock/S3/CloudFront.py s3cmd/branches/s3cmd-airlock/s3cmd Modified: s3cmd/branches/s3cmd-airlock/ChangeLog =================================================================== --- s3cmd/branches/s3cmd-airlock/ChangeLog 2009-01-17 13:24:07 UTC (rev 345) +++ s3cmd/branches/s3cmd-airlock/ChangeLog 2009-01-18 13:10:23 UTC (rev 346) @@ -1,3 +1,11 @@ +2009-01-19 Michal Ludvig <mi...@lo...> + + * S3/CloudFront.py: Implemented ModifyDistribution(), + added support for CNAMEs, Comments and Enable/Disable. + * s3cmd: Enabled cfmodify, added --enable/--disable, + --cf-add-cname/--cf-remove-cname, --cf-comment options. + Added updating from 'options' to CfCmd.options. + 2009-01-18 Michal Ludvig <mi...@lo...> * S3/CloudFront.py: Implemented DeleteDistribution(), Modified: s3cmd/branches/s3cmd-airlock/S3/CloudFront.py =================================================================== --- s3cmd/branches/s3cmd-airlock/S3/CloudFront.py 2009-01-17 13:24:07 UTC (rev 345) +++ s3cmd/branches/s3cmd-airlock/S3/CloudFront.py 2009-01-18 13:10:23 UTC (rev 346) @@ -155,10 +155,10 @@ ## Retain the order of the following calls! appendXmlTextNode("Origin", self.info['Origin'], tree) appendXmlTextNode("CallerReference", self.info['CallerReference'], tree) + for cname in self.info['CNAME']: + appendXmlTextNode("CNAME", cname.lower(), tree) if self.info['Comment']: appendXmlTextNode("Comment", self.info['Comment'], tree) - for cname in self.info['CNAME']: - appendXmlTextNode("CNAME", cname.lower(), tree) appendXmlTextNode("Enabled", str(self.info['Enabled']).lower(), tree) return ET.tostring(tree) @@ -191,20 +191,45 @@ ## TODO: handle Truncated return response - def CreateDistribution(self, uri, cnames = []): + def CreateDistribution(self, uri, cnames_add = [], comment = None): dist_config = DistributionConfig() dist_config.info['Enabled'] = True dist_config.info['Origin'] = uri.host_name() dist_config.info['CallerReference'] = str(uri) - dist_config.info['Comment'] = uri.public_url() - if cnames: - dist_config.info['Cnames'] = cnames + if comment == None: + dist_config.info['Comment'] = uri.public_url() + else: + dist_config.info['Comment'] = comment + for cname in cnames_add: + if dist_config.info['CNAME'].count(cname) == 0: + dist_config.info['CNAME'].append(cname) request_body = str(dist_config) debug("CreateDistribution(): request_body: %s" % request_body) response = self.send_request("CreateDist", body = request_body) response['distribution'] = Distribution(response['data']) return response + def ModifyDistribution(self, cfuri, cnames_add = [], cnames_remove = [], + comment = None, enabled = None): + if cfuri.type != "cf": + raise ValueError("Expected CFUri instead of: %s" % cfuri) + # Get current dist status (enabled/disabled) and Etag + info("Checking current status of %s" % cfuri) + response = self.GetDistConfig(cfuri) + dc = response['dist_config'] + if enabled != None: + dc.info['Enabled'] = enabled + if comment != None: + dc.info['Comment'] = comment + for cname in cnames_add: + if dc.info['CNAME'].count(cname) == 0: + dc.info['CNAME'].append(cname) + for cname in cnames_remove: + while dc.info['CNAME'].count(cname) > 0: + dc.info['CNAME'].remove(cname) + response = self.SetDistConfig(cfuri, dc, response['headers']['etag']) + return response + def DeleteDistribution(self, cfuri): if cfuri.type != "cf": raise ValueError("Expected CFUri instead of: %s" % cfuri) @@ -342,6 +367,20 @@ Class that implements CloudFront commands """ + class Options(object): + cf_cnames_add = [] + cf_cnames_remove = [] + cf_comment = None + cf_enable = None + + def option_list(self): + return [opt for opt in dir(self) if opt.startswith("cf_")] + + def update_option(self, option, value): + setattr(Cmd.options, option, value) + + options = Options() + @staticmethod def info(args): cf = CloudFront(Config()) @@ -368,6 +407,8 @@ pretty_output("DistId", d.uri()) pretty_output("DomainName", d.info['DomainName']) pretty_output("Status", d.info['Status']) + pretty_output("CNAMEs", ", ".join(dc.info['CNAME'])) + pretty_output("Comment", dc.info['Comment']) pretty_output("Enabled", dc.info['Enabled']) pretty_output("Etag", response['headers']['etag']) @@ -388,16 +429,20 @@ raise ParameterError("No valid bucket names found") for uri in buckets: info("Creating distribution from: %s" % uri) - response = cf.CreateDistribution(uri) + response = cf.CreateDistribution(uri, cnames_add = Cmd.options.cf_cnames_add, + comment = Cmd.options.cf_comment) d = response['distribution'] dc = d.info['DistributionConfig'] output("Distribution created:") pretty_output("Origin", S3UriS3.httpurl_to_s3uri(dc.info['Origin'])) pretty_output("DistId", d.uri()) pretty_output("DomainName", d.info['DomainName']) + pretty_output("CNAMEs", ", ".join(dc.info['CNAME'])) + pretty_output("Comment", dc.info['Comment']) pretty_output("Status", d.info['Status']) pretty_output("Enabled", dc.info['Enabled']) - + pretty_output("Etag", response['headers']['etag']) + @staticmethod def delete(args): cf = CloudFront(Config()) @@ -409,6 +454,34 @@ for cfuri in cfuris: response = cf.DeleteDistribution(cfuri) if response['status'] >= 400: - output("Distribution %s deleted" % cfuri) - else: error("Distribution %s could not be deleted: %s" % (cfuri, response['reason'])) + output("Distribution %s deleted" % cfuri) + + @staticmethod + def modify(args): + cf = CloudFront(Config()) + cfuri = S3Uri(args.pop(0)) + if cfuri.type != 'cf': + raise ParameterError("CloudFront URI required instead of: %s" % arg) + if len(args): + raise ParameterError("Too many parameters. Modify one Distribution at a time.") + + response = cf.ModifyDistribution(cfuri, + cnames_add = Cmd.options.cf_cnames_add, + cnames_remove = Cmd.options.cf_cnames_remove, + comment = Cmd.options.cf_comment, + enabled = Cmd.options.cf_enable) + if response['status'] >= 400: + error("Distribution %s could not be modified: %s" % (cfuri, response['reason'])) + output("Distribution modified: %s" % cfuri) + response = cf.GetDistInfo(cfuri) + d = response['distribution'] + dc = d.info['DistributionConfig'] + pretty_output("Origin", S3UriS3.httpurl_to_s3uri(dc.info['Origin'])) + pretty_output("DistId", d.uri()) + pretty_output("DomainName", d.info['DomainName']) + pretty_output("Status", d.info['Status']) + pretty_output("CNAMEs", ", ".join(dc.info['CNAME'])) + pretty_output("Comment", dc.info['Comment']) + pretty_output("Enabled", dc.info['Enabled']) + pretty_output("Etag", response['headers']['etag']) Modified: s3cmd/branches/s3cmd-airlock/s3cmd =================================================================== --- s3cmd/branches/s3cmd-airlock/s3cmd 2009-01-17 13:24:07 UTC (rev 345) +++ s3cmd/branches/s3cmd-airlock/s3cmd 2009-01-18 13:10:23 UTC (rev 346) @@ -1122,7 +1122,7 @@ {"cmd":"cfinfo", "label":"Display CloudFront distribution point parameters", "param":"[cf://DIST_ID]", "func":CfCmd.info, "argc":0}, {"cmd":"cfcreate", "label":"Create CloudFront distribution point", "param":"s3://BUCKET", "func":CfCmd.create, "argc":1}, {"cmd":"cfdelete", "label":"Delete CloudFront distribution point", "param":"cf://DIST_ID", "func":CfCmd.delete, "argc":1}, - #{"cmd":"cfmodify", "label":"Change CloudFront distribution point parameters", "param":"cf://DIST_ID", "func":cmd_cf_modify, "argc":1}, + {"cmd":"cfmodify", "label":"Change CloudFront distribution point parameters", "param":"cf://DIST_ID", "func":CfCmd.modify, "argc":1}, ] def format_commands(progname): @@ -1213,6 +1213,11 @@ optparser.add_option( "--progress", dest="progress_meter", action="store_true", help="Display progress meter (default on TTY).") optparser.add_option( "--no-progress", dest="progress_meter", action="store_false", help="Don't display progress meter (default on non-TTY).") + optparser.add_option( "--enable", dest="cf_enable", action="store_true", help="Enable given CloudFront distribution (only for [cfmodify] command)") + optparser.add_option( "--disable", dest="cf_enable", action="store_false", help="Enable given CloudFront distribution (only for [cfmodify] command)") + optparser.add_option( "--cf-add-cname", dest="cf_cnames_add", action="append", metavar="CNAME", help="Add given CNAME to a CloudFront distribution (only for [cfcreate] and [cfmodify] commands)") + optparser.add_option( "--cf-remove-cname", dest="cf_cnames_remove", action="append", metavar="CNAME", help="Remove given CNAME from a CloudFront distribution (only for [cfmodify] command)") + optparser.add_option( "--cf-comment", dest="cf_comment", action="store", metavar="COMMENT", help="Set COMMENT for a given CloudFront distribution (only for [cfcreate] and [cfmodify] commands)") optparser.add_option("-v", "--verbose", dest="verbosity", action="store_const", const=logging.INFO, help="Enable verbose output.") optparser.add_option("-d", "--debug", dest="verbosity", action="store_const", const=logging.DEBUG, help="Enable debug output.") optparser.add_option( "--version", dest="show_version", action="store_true", help="Show s3cmd version (%s) and exit." % (PkgInfo.version)) @@ -1276,11 +1281,21 @@ for option in cfg.option_list(): try: if getattr(options, option) != None: - debug(u"Updating %s -> %s" % (option, getattr(options, option))) + debug(u"Updating Config.Config %s -> %s" % (option, getattr(options, option))) cfg.update_option(option, getattr(options, option)) except AttributeError: ## Some Config() options are not settable from command line pass + + ## Update CloudFront options if some were set + for option in CfCmd.options.option_list(): + try: + if getattr(options, option) != None: + debug(u"Updating CloudFront.Cmd %s -> %s" % (option, getattr(options, option))) + CfCmd.options.update_option(option, getattr(options, option)) + except AttributeError: + ## Some CloudFront.Cmd.Options() options are not settable from command line + pass ## Set output and filesystem encoding for printing out filenames. sys.stdout = codecs.getwriter(cfg.encoding)(sys.stdout, "replace") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |