# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Parts of this code were copied or derived from sample code supplied by AWS.
# The following notice applies to that code.
#
# This software code is made available "AS IS" without warranties of any
# kind. You may copy, display, modify and redistribute the software
# code either by itself or as incorporated into your code; provided that
# you do not remove any proprietary notices. Your use of this software
# code is at your own risk and you waive any claim against Amazon
# Digital Services, Inc. or its affiliates with respect to your use of
# this software code. (c) 2006 Amazon Digital Services, Inc. or its
# affiliates.
"""
Some handy utility functions used by several classes.
"""
import base64
import hmac
import re
import sha
import urllib, urllib2
import imp
METADATA_PREFIX = 'x-amz-meta-'
AMAZON_HEADER_PREFIX = 'x-amz-'
# generates the aws canonical string for the given parameters
def canonical_string(method, path, headers, expires=None):
interesting_headers = {}
for key in headers:
lk = key.lower()
if lk in ['content-md5', 'content-type', 'date'] or lk.startswith(AMAZON_HEADER_PREFIX):
interesting_headers[lk] = headers[key].strip()
# these keys get empty strings if they don't exist
if not interesting_headers.has_key('content-type'):
interesting_headers['content-type'] = ''
if not interesting_headers.has_key('content-md5'):
interesting_headers['content-md5'] = ''
# just in case someone used this. it's not necessary in this lib.
if interesting_headers.has_key('x-amz-date'):
interesting_headers['date'] = ''
# if you're using expires for query string auth, then it trumps date
# (and x-amz-date)
if expires:
interesting_headers['date'] = str(expires)
sorted_header_keys = interesting_headers.keys()
sorted_header_keys.sort()
buf = "%s\n" % method
for key in sorted_header_keys:
if key.startswith(AMAZON_HEADER_PREFIX):
buf += "%s:%s\n" % (key, interesting_headers[key])
else:
buf += "%s\n" % interesting_headers[key]
# don't include anything after the first ? in the resource...
buf += "%s" % path.split('?')[0]
# ...unless there is an acl or torrent parameter
if re.search("[&?]acl($|=|&)", path):
buf += "?acl"
elif re.search("[&?]logging($|=|&)", path):
buf += "?logging"
elif re.search("[&?]torrent($|=|&)", path):
buf += "?torrent"
return buf
# computes the base64'ed hmac-sha hash of the canonical string and the secret
# access key, optionally urlencoding the result
def encode(aws_secret_access_key, str, urlencode=False):
b64_hmac = base64.encodestring(hmac.new(aws_secret_access_key, str, sha).digest()).strip()
if urlencode:
return urllib.quote_plus(b64_hmac)
else:
return b64_hmac
def merge_meta(headers, metadata):
final_headers = headers.copy()
for k in metadata.keys():
final_headers[METADATA_PREFIX + k] = metadata[k]
return final_headers
def get_aws_metadata(headers):
metadata = {}
for hkey in headers.keys():
if hkey.lower().startswith(METADATA_PREFIX):
metadata[hkey[len(METADATA_PREFIX):]] = headers[hkey]
del headers[hkey]
return metadata
def get_instance_metadata(version='latest'):
metadata = {}
try:
url = 'http://169.254.169.254/%s/meta-data/' % version
s = urllib.urlopen(url)
md_fields = s.read().split('\n')
for md in md_fields:
md_url = url + md
s = urllib.urlopen(md_url)
metadata[md] = s.read()
except:
print 'problem reading metadata'
return metadata
def get_instance_userdata(version='latest', sep=None):
user_data = None
try:
url = 'http://169.254.169.254/%s/user-data/' % version
s = urllib.urlopen(url)
user_data = s.read()
if sep:
l = user_data.split(sep)
user_data = {}
for nvpair in l:
t = nvpair.split('=')
user_data[t[0].strip()] = t[1].strip()
except:
print 'problem reading metadata'
return user_data
def find_class(module_name, class_name):
modules = module_name.split('.')
path = None
for module_name in modules:
fp, pathname, description = imp.find_module(module_name, path)
module = imp.load_module(module_name, fp, pathname, description)
if hasattr(module, '__path__'):
path = module.__path__
return getattr(module, class_name)
def update_dme(username, password, dme_id, ip_address):
"""
Update your Dynamic DNS record with DNSMadeEasy.com
"""
dme_url = 'https://www.dnsmadeeasy.com/servlet/updateip'
dme_url += '?username=%s&password=%s&id=%s&ip=%s'
s = urllib2.urlopen(dme_url % (username, password, dme_id, ip_address))
return s.read()
syntax highlighted by Code2HTML, v. 0.9.1