Created
October 7, 2011 18:52
-
-
Save tc/1271074 to your computer and use it in GitHub Desktop.
Cloudfront invalidate script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'openssl' | |
require 'uri' | |
require 'net/http' | |
require 'net/https' | |
require 'base64' | |
require 'optparse' | |
class CloudfrontDistribution | |
def initialize(aws_account, aws_secret, distribution, verbose=false) | |
@aws_account = aws_account | |
@aws_secret = aws_secret | |
@distribution = distribution | |
@verbose = verbose | |
end | |
def invalidate_objects(paths) | |
date = Time.now.strftime("%a, %d %b %Y %H:%M:%S %Z") | |
digest = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), @aws_secret, date)).strip | |
uri = URI.parse("https://cloudfront.amazonaws.com/2010-08-01/distribution/#{@distribution}/invalidation") | |
req = Net::HTTP::Post.new(uri.path) | |
req.initialize_http_header({ | |
'x-amz-date' => date, | |
'Content-Type' => 'text/xml', | |
'Authorization' => "AWS %s:%s" % [@aws_account, digest] | |
}) | |
xml_paths = paths.map{|p| "<Path>#{p}</Path>"}.join("") | |
req.body = %|<InvalidationBatch>#{xml_paths}<CallerReference>#{date.to_s.gsub(/\s+/, '_')}</CallerReference></InvalidationBatch>| | |
http = Net::HTTP.new(uri.host, uri.port) | |
http.use_ssl = true | |
http.verify_mode = OpenSSL::SSL::VERIFY_NONE | |
res = http.request(req) | |
if @verbose | |
puts req.body | |
puts "------" | |
puts res.body | |
end | |
# it was successful if response code was a 201 | |
return res.code == '201' | |
end | |
end | |
class CloudfrontConfig | |
# Access Credentials | |
def self.aws_account; ""; end | |
def self.aws_secret; ""; end | |
# Distributions | |
@@distributions = { "BUCKETNAME" => "DIST_ID" } | |
def self.get_dist_id(bucket); @@distributions[bucket]; end | |
end | |
if __FILE__ == $0 | |
options = {} | |
OptionParser.new do |opts| | |
opts.banner = "Usage: #{$0} [options]" | |
opts.on("-v", "--verbose", "Run verbosely") { |o| options[:verbose] = o } | |
opts.on("-b", "--bucket BUCKET_NAME", String, "s3 bucket") { |o| options[:bucket] = o } | |
opts.on("-f", "--files a,b,c", Array, "list of s3 files, should start with /") { |o| options[:files] = o } | |
end.parse!(ARGV) | |
dist_id = CloudfrontConfig.get_dist_id(options[:bucket]) | |
raise "Could not find dist_id for #{options[:bucket]}" unless dist_id | |
files = options[:files] | |
raise "Empty file list" if files.nil? || files.empty? | |
distribution = CloudfrontDistribution.new(CloudfrontConfig.aws_account, | |
CloudfrontConfig.aws_secret, | |
dist_id, | |
options[:verbose]) | |
distribution.invalidate_objects(files) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment