On Sun, Jan 9, 2011 at 17:59, Jim Popovitch <jim...@gmail.com> wrote:
> Attached is a short script I hacked together from details at
> http://tomatohater.com/2010/10/22/cloudfront-object-invalidation-python/
>
> I'd love to see that functionality in s3cmd, and I am working to learn
> more about s3cmd in hopes of providing a patch to do that. In the
> mean time if anyone is looking for a quick way to invalidate a file(s)
> you can use the attached.
Attached is an update to this script, it takes input via stdin (cat
list-of-files | ./s3invalidate.py) as well as files passed on the
cmdline (./s3invalidate.py file1.html file2.html ....). If you run
the script without any parameters it will report on current/recent
invalidations, listing the comment, status, and files. Further this
script now reads s3 access credentials from ~/.s3cfg. You still have
to define "aws_dist_id" in the script for now.
-Jim P.
#!/usr/bin/python
##
## 400 Bad Request probably means too many currently open requests
##
import urllib2
import base64
import datetime
import hmac
import hashlib
from xml.dom import minidom
import sys, os
import ConfigParser
## TODO: read the bucket name from the last cmdline param
## convert the bucketname into a distro ID
## until then it has to be hardcoded here:
aws_dist_id = ""
if not aws_dist_id:
print "You first need to define aws_dist_id in this script.\n"
sys.exit()
## parse ~/.s3cmd for access and secret keys
config = ConfigParser.RawConfigParser()
config.read(os.path.expanduser('~/.s3cfg'))
host = 'cloudfront.amazonaws.com'
path = '/2010-11-01/distribution/%s/invalidation' % aws_dist_id
def get_aws_auth():
date = datetime.datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
auth = 'AWS %s:%s' % (
config.get('default','access_key'),
base64.b64encode(
hmac.new(
config.get('default','secret_key').encode('utf-8'),
date.encode('utf-8'),
hashlib.sha1
).digest()
)
)
return date, auth
if sys.stdin.isatty() and len(sys.argv) < 2:
date, auth = get_aws_auth()
# define required http headers
headers = {
'Host': host,
'Authorization' : auth,
'Date': date,
}
# send REST request
request_url = 'https://%s%s' % (host, path)
req = urllib2.Request(request_url, headers=headers)
response = urllib2.urlopen(req)
invalidationDoc = minidom.parseString(response.read())
##print invalidationDoc.toprettyxml(indent='\t')
idValue = None
statValue = None
commentValue = None
fileValue = None
print "Current Invalidations:"
print "Id\t\tStatus\t\tComment"
for summary in invalidationDoc.getElementsByTagName('InvalidationSummary'):
for summaryChild in summary.childNodes:
for value in summaryChild.childNodes:
if value.nodeType == summaryChild.TEXT_NODE:
if summaryChild.nodeName == "Id":
idValue = value.nodeValue
elif summaryChild.nodeName == "Status":
statValue = value.nodeValue
if idValue:
fileValue = None
# lookup the comment on the invalidation ID
request_url = 'https://%s%s/%s/' % (host, path, idValue)
req = urllib2.Request(request_url, headers=headers)
response = urllib2.urlopen(req)
batchDoc = minidom.parseString(response.read())
for invalidation in batchDoc.getElementsByTagName('InvalidationBatch'):
for invalidationChild in invalidation.childNodes:
for value in invalidationChild.childNodes:
if value.nodeType == invalidationChild.TEXT_NODE:
if invalidationChild.nodeName == "Path":
if fileValue:
fileValue = str(fileValue) + ", " + value.nodeValue
else:
fileValue = value.nodeValue
elif invalidationChild.nodeName == "CallerReference":
commentValue = value.nodeValue
output = '%s\t%s\t%s\t' % (idValue, statValue, commentValue)
print output, fileValue, "\n"
sys.exit()
# create authentication signature
date, auth = get_aws_auth()
files = []
if sys.stdin.isatty():
files = sys.argv[1:]
else:
files = sys.stdin.read().split()
# create xml data to post
data = ['<?xml version="1.0" encoding="UTF-8"?>']
data.append('<InvalidationBatch>')
data.append('%s' % ''.join(['<Path>/%s</Path>' % urllib2.quote(f) for f in files]))
data.append('<CallerReference>%s</CallerReference>' % date)
data.append('</InvalidationBatch>')
data = ''.join(data)
# define required http headers
headers = {
'Host': host,
'Authorization' : auth,
'Date': date,
'Content-Type': 'text/xml',
'Content-Length': len(data),
}
# make REST request, capture 201 (success) response
request_url = 'https://%s%s' % (host, path)
req = urllib2.Request(request_url, data, headers=headers)
try:
response = urllib2.urlopen(req)
#print minidom.parseString(response.read()).toprettyxml(indent=' '*4)
except urllib2.HTTPError, e:
print e
if not e.code == 201:
print "---------------------------------"
print "URL:", request_url
print ""
print "Headers:"
print headers
print ""
print "Data:"
print minidom.parseString(str(data)).toprettyxml(indent=' '*4)
print "---------------------------------"
------------------------------------------------------------------------------
The modern datacenter depends on network connectivity to access resources
and provide services. The best practices for maximizing a physical server's
connectivity to a physical network are well understood - see how these
rules translate into the virtual world?
http://p.sf.net/sfu/oracle-sfdevnlfb
_______________________________________________
S3tools-general mailing list
S3tools-general@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/s3tools-general