1
# Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
3
# Permission is hereby granted, free of charge, to any person obtaining a
4
# copy of this software and associated documentation files (the
5
# "Software"), to deal in the Software without restriction, including
6
# without limitation the rights to use, copy, modify, merge, publish, dis-
7
# tribute, sublicense, and/or sell copies of the Software, and to permit
8
# persons to whom the Software is furnished to do so, subject to the fol-
11
# The above copyright notice and this permission notice shall be included
12
# in all copies or substantial portions of the Software.
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26
from boto.connection import AWSAuthConnection
27
from boto import handler
28
from boto.cloudfront.distribution import Distribution, DistributionSummary, DistributionConfig
29
from boto.cloudfront.distribution import StreamingDistribution, StreamingDistributionSummary, StreamingDistributionConfig
30
from boto.cloudfront.identity import OriginAccessIdentity
31
from boto.cloudfront.identity import OriginAccessIdentitySummary
32
from boto.cloudfront.identity import OriginAccessIdentityConfig
33
from boto.resultset import ResultSet
34
from boto.cloudfront.exception import CloudFrontServerError
36
class CloudFrontConnection(AWSAuthConnection):
38
DefaultHost = 'cloudfront.amazonaws.com'
39
Version = '2009-12-01'
41
def __init__(self, aws_access_key_id=None, aws_secret_access_key=None,
42
port=None, proxy=None, proxy_port=None,
43
host=DefaultHost, debug=0):
44
AWSAuthConnection.__init__(self, host,
45
aws_access_key_id, aws_secret_access_key,
46
True, port, proxy, proxy_port, debug=debug)
48
def get_etag(self, response):
49
response_headers = response.msg
50
for key in response_headers.keys():
51
if key.lower() == 'etag':
52
return response_headers[key]
55
def add_aws_auth_header(self, headers, method, path):
56
if not headers.has_key('Date'):
57
headers['Date'] = time.strftime("%a, %d %b %Y %H:%M:%S GMT",
60
hmac = self.hmac.copy()
61
hmac.update(headers['Date'])
62
b64_hmac = base64.encodestring(hmac.digest()).strip()
63
headers['Authorization'] = "AWS %s:%s" % (self.aws_access_key_id, b64_hmac)
67
def _get_all_objects(self, resource, tags):
69
tags=[('DistributionSummary', DistributionSummary)]
70
response = self.make_request('GET', '/%s/%s' % (self.Version, resource))
71
body = response.read()
72
if response.status >= 300:
73
raise CloudFrontServerError(response.status, response.reason, body)
75
h = handler.XmlHandler(rs, self)
76
xml.sax.parseString(body, h)
79
def _get_info(self, id, resource, dist_class):
80
uri = '/%s/%s/%s' % (self.Version, resource, id)
81
response = self.make_request('GET', uri)
82
body = response.read()
83
if response.status >= 300:
84
raise CloudFrontServerError(response.status, response.reason, body)
85
d = dist_class(connection=self)
86
response_headers = response.msg
87
for key in response_headers.keys():
88
if key.lower() == 'etag':
89
d.etag = response_headers[key]
90
h = handler.XmlHandler(d, self)
91
xml.sax.parseString(body, h)
94
def _get_config(self, id, resource, config_class):
95
uri = '/%s/%s/%s/config' % (self.Version, resource, id)
96
response = self.make_request('GET', uri)
97
body = response.read()
98
if response.status >= 300:
99
raise CloudFrontServerError(response.status, response.reason, body)
100
d = config_class(connection=self)
101
d.etag = self.get_etag(response)
102
h = handler.XmlHandler(d, self)
103
xml.sax.parseString(body, h)
106
def _set_config(self, distribution_id, etag, config):
107
if isinstance(config, StreamingDistributionConfig):
108
resource = 'streaming-distribution'
110
resource = 'distribution'
111
uri = '/%s/%s/%s/config' % (self.Version, resource, distribution_id)
112
headers = {'If-Match' : etag, 'Content-Type' : 'text/xml'}
113
response = self.make_request('PUT', uri, headers, config.to_xml())
114
body = response.read()
115
return self.get_etag(response)
116
if response.status != 200:
117
raise CloudFrontServerError(response.status, response.reason, body)
119
def _create_object(self, config, resource, dist_class):
120
response = self.make_request('POST', '/%s/%s' % (self.Version, resource),
121
{'Content-Type' : 'text/xml'}, data=config.to_xml())
122
body = response.read()
123
if response.status == 201:
124
d = dist_class(connection=self)
125
h = handler.XmlHandler(d, self)
126
xml.sax.parseString(body, h)
129
raise CloudFrontServerError(response.status, response.reason, body)
131
def _delete_object(self, id, etag, resource):
132
uri = '/%s/%s/%s' % (self.Version, resource, id)
133
response = self.make_request('DELETE', uri, {'If-Match' : etag})
134
body = response.read()
135
if response.status != 204:
136
raise CloudFrontServerError(response.status, response.reason, body)
140
def get_all_distributions(self):
141
tags=[('DistributionSummary', DistributionSummary)]
142
return self._get_all_objects('distribution', tags)
144
def get_distribution_info(self, distribution_id):
145
return self._get_info(distribution_id, 'distribution', Distribution)
147
def get_distribution_config(self, distribution_id):
148
return self._get_config(distribution_id, 'distribution',
151
def set_distribution_config(self, distribution_id, etag, config):
152
return self._set_config(distribution_id, etag, config)
154
def create_distribution(self, origin, enabled, caller_reference='',
155
cnames=None, comment=''):
156
config = DistributionConfig(origin=origin, enabled=enabled,
157
caller_reference=caller_reference,
158
cnames=cnames, comment=comment)
159
return self._create_object(config, 'distribution', Distribution)
161
def delete_distribution(self, distribution_id, etag):
162
return self._delete_object(distribution_id, etag, 'distribution')
164
# Streaming Distributions
166
def get_all_streaming_distributions(self):
167
tags=[('StreamingDistributionSummary', StreamingDistributionSummary)]
168
return self._get_all_objects('streaming-distribution', tags)
170
def get_streaming_distribution_info(self, distribution_id):
171
return self._get_info(distribution_id, 'streaming-distribution',
172
StreamingDistribution)
174
def get_streaming_distribution_config(self, distribution_id):
175
return self._get_config(distribution_id, 'streaming-distribution',
176
StreamingDistributionConfig)
178
def set_streaming_distribution_config(self, distribution_id, etag, config):
179
return self._set_config(distribution_id, etag, config)
181
def create_streaming_distribution(self, origin, enabled,
183
cnames=None, comment=''):
184
config = StreamingDistributionConfig(origin=origin, enabled=enabled,
185
caller_reference=caller_reference,
186
cnames=cnames, comment=comment)
187
return self._create_object(config, 'streaming-distribution',
188
StreamingDistribution)
190
def delete_streaming_distribution(self, distribution_id, etag):
191
return self._delete_object(distribution_id, etag, 'streaming-distribution')
193
# Origin Access Identity
195
def get_all_origin_access_identity(self):
196
tags=[('CloudFrontOriginAccessIdentitySummary',
197
OriginAccessIdentitySummary)]
198
return self._get_all_objects('origin-access-identity/cloudfront', tags)
200
def get_origin_access_identity_info(self, access_id):
201
return self._get_info(access_id, 'origin-access-identity/cloudfront',
202
OriginAccessIdentity)
204
def get_origin_access_identity_config(self, access_id):
205
return self._get_config(access_id,
206
'origin-access-identity/cloudfront',
207
OriginAccessIdentityConfig)
209
def set_origin_access_identity_config(self, access_id,
211
return self._set_config(access_id, etag, config)
213
def create_origin_access_identity(self, caller_reference='', comment=''):
214
config = OriginAccessIdentityConfig(caller_reference=caller_reference,
216
return self._create_object(config, 'origin-access-identity/cloudfront',
217
OriginAccessIdentity)
219
def delete_origin_access_identity(self, access_id, etag):
220
return self._delete_object(access_id, etag,
221
'origin-access-identity/cloudfront')