comparison env/lib/python3.9/site-packages/boto/cloudfront/distribution.py @ 0:4f3585e2f14b draft default tip

"planemo upload commit 60cee0fc7c0cda8592644e1aad72851dec82c959"
author shellac
date Mon, 22 Mar 2021 18:12:50 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4f3585e2f14b
1 # Copyright (c) 2006-2009 Mitch Garnaat http://garnaat.org/
2 #
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-
9 # lowing conditions:
10 #
11 # The above copyright notice and this permission notice shall be included
12 # in all copies or substantial portions of the Software.
13 #
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
20 # IN THE SOFTWARE.
21
22 import uuid
23 import base64
24 import time
25 from boto.compat import six, json
26 from boto.cloudfront.identity import OriginAccessIdentity
27 from boto.cloudfront.object import Object, StreamingObject
28 from boto.cloudfront.signers import ActiveTrustedSigners, TrustedSigners
29 from boto.cloudfront.logging import LoggingInfo
30 from boto.cloudfront.origin import S3Origin, CustomOrigin
31 from boto.s3.acl import ACL
32
33 class DistributionConfig(object):
34
35 def __init__(self, connection=None, origin=None, enabled=False,
36 caller_reference='', cnames=None, comment='',
37 trusted_signers=None, default_root_object=None,
38 logging=None):
39 """
40 :param origin: Origin information to associate with the
41 distribution. If your distribution will use
42 an Amazon S3 origin, then this should be an
43 S3Origin object. If your distribution will use
44 a custom origin (non Amazon S3), then this
45 should be a CustomOrigin object.
46 :type origin: :class:`boto.cloudfront.origin.S3Origin` or
47 :class:`boto.cloudfront.origin.CustomOrigin`
48
49 :param enabled: Whether the distribution is enabled to accept
50 end user requests for content.
51 :type enabled: bool
52
53 :param caller_reference: A unique number that ensures the
54 request can't be replayed. If no
55 caller_reference is provided, boto
56 will generate a type 4 UUID for use
57 as the caller reference.
58 :type enabled: str
59
60 :param cnames: A CNAME alias you want to associate with this
61 distribution. You can have up to 10 CNAME aliases
62 per distribution.
63 :type enabled: array of str
64
65 :param comment: Any comments you want to include about the
66 distribution.
67 :type comment: str
68
69 :param trusted_signers: Specifies any AWS accounts you want to
70 permit to create signed URLs for private
71 content. If you want the distribution to
72 use signed URLs, this should contain a
73 TrustedSigners object; if you want the
74 distribution to use basic URLs, leave
75 this None.
76 :type trusted_signers: :class`boto.cloudfront.signers.TrustedSigners`
77
78 :param default_root_object: Designates a default root object.
79 Only include a DefaultRootObject value
80 if you are going to assign a default
81 root object for the distribution.
82 :type comment: str
83
84 :param logging: Controls whether access logs are written for the
85 distribution. If you want to turn on access logs,
86 this should contain a LoggingInfo object; otherwise
87 it should contain None.
88 :type logging: :class`boto.cloudfront.logging.LoggingInfo`
89
90 """
91 self.connection = connection
92 self.origin = origin
93 self.enabled = enabled
94 if caller_reference:
95 self.caller_reference = caller_reference
96 else:
97 self.caller_reference = str(uuid.uuid4())
98 self.cnames = []
99 if cnames:
100 self.cnames = cnames
101 self.comment = comment
102 self.trusted_signers = trusted_signers
103 self.logging = logging
104 self.default_root_object = default_root_object
105
106 def __repr__(self):
107 return "DistributionConfig:%s" % self.origin
108
109 def to_xml(self):
110 s = '<?xml version="1.0" encoding="UTF-8"?>\n'
111 s += '<DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-07-15/">\n'
112 if self.origin:
113 s += self.origin.to_xml()
114 s += ' <CallerReference>%s</CallerReference>\n' % self.caller_reference
115 for cname in self.cnames:
116 s += ' <CNAME>%s</CNAME>\n' % cname
117 if self.comment:
118 s += ' <Comment>%s</Comment>\n' % self.comment
119 s += ' <Enabled>'
120 if self.enabled:
121 s += 'true'
122 else:
123 s += 'false'
124 s += '</Enabled>\n'
125 if self.trusted_signers:
126 s += '<TrustedSigners>\n'
127 for signer in self.trusted_signers:
128 if signer == 'Self':
129 s += ' <Self></Self>\n'
130 else:
131 s += ' <AwsAccountNumber>%s</AwsAccountNumber>\n' % signer
132 s += '</TrustedSigners>\n'
133 if self.logging:
134 s += '<Logging>\n'
135 s += ' <Bucket>%s</Bucket>\n' % self.logging.bucket
136 s += ' <Prefix>%s</Prefix>\n' % self.logging.prefix
137 s += '</Logging>\n'
138 if self.default_root_object:
139 dro = self.default_root_object
140 s += '<DefaultRootObject>%s</DefaultRootObject>\n' % dro
141 s += '</DistributionConfig>\n'
142 return s
143
144 def startElement(self, name, attrs, connection):
145 if name == 'TrustedSigners':
146 self.trusted_signers = TrustedSigners()
147 return self.trusted_signers
148 elif name == 'Logging':
149 self.logging = LoggingInfo()
150 return self.logging
151 elif name == 'S3Origin':
152 self.origin = S3Origin()
153 return self.origin
154 elif name == 'CustomOrigin':
155 self.origin = CustomOrigin()
156 return self.origin
157 else:
158 return None
159
160 def endElement(self, name, value, connection):
161 if name == 'CNAME':
162 self.cnames.append(value)
163 elif name == 'Comment':
164 self.comment = value
165 elif name == 'Enabled':
166 if value.lower() == 'true':
167 self.enabled = True
168 else:
169 self.enabled = False
170 elif name == 'CallerReference':
171 self.caller_reference = value
172 elif name == 'DefaultRootObject':
173 self.default_root_object = value
174 else:
175 setattr(self, name, value)
176
177 class StreamingDistributionConfig(DistributionConfig):
178
179 def __init__(self, connection=None, origin='', enabled=False,
180 caller_reference='', cnames=None, comment='',
181 trusted_signers=None, logging=None):
182 super(StreamingDistributionConfig, self).__init__(connection=connection,
183 origin=origin, enabled=enabled,
184 caller_reference=caller_reference,
185 cnames=cnames, comment=comment,
186 trusted_signers=trusted_signers,
187 logging=logging)
188 def to_xml(self):
189 s = '<?xml version="1.0" encoding="UTF-8"?>\n'
190 s += '<StreamingDistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2010-07-15/">\n'
191 if self.origin:
192 s += self.origin.to_xml()
193 s += ' <CallerReference>%s</CallerReference>\n' % self.caller_reference
194 for cname in self.cnames:
195 s += ' <CNAME>%s</CNAME>\n' % cname
196 if self.comment:
197 s += ' <Comment>%s</Comment>\n' % self.comment
198 s += ' <Enabled>'
199 if self.enabled:
200 s += 'true'
201 else:
202 s += 'false'
203 s += '</Enabled>\n'
204 if self.trusted_signers:
205 s += '<TrustedSigners>\n'
206 for signer in self.trusted_signers:
207 if signer == 'Self':
208 s += ' <Self/>\n'
209 else:
210 s += ' <AwsAccountNumber>%s</AwsAccountNumber>\n' % signer
211 s += '</TrustedSigners>\n'
212 if self.logging:
213 s += '<Logging>\n'
214 s += ' <Bucket>%s</Bucket>\n' % self.logging.bucket
215 s += ' <Prefix>%s</Prefix>\n' % self.logging.prefix
216 s += '</Logging>\n'
217 s += '</StreamingDistributionConfig>\n'
218 return s
219
220 class DistributionSummary(object):
221
222 def __init__(self, connection=None, domain_name='', id='',
223 last_modified_time=None, status='', origin=None,
224 cname='', comment='', enabled=False):
225 self.connection = connection
226 self.domain_name = domain_name
227 self.id = id
228 self.last_modified_time = last_modified_time
229 self.status = status
230 self.origin = origin
231 self.enabled = enabled
232 self.cnames = []
233 if cname:
234 self.cnames.append(cname)
235 self.comment = comment
236 self.trusted_signers = None
237 self.etag = None
238 self.streaming = False
239
240 def __repr__(self):
241 return "DistributionSummary:%s" % self.domain_name
242
243 def startElement(self, name, attrs, connection):
244 if name == 'TrustedSigners':
245 self.trusted_signers = TrustedSigners()
246 return self.trusted_signers
247 elif name == 'S3Origin':
248 self.origin = S3Origin()
249 return self.origin
250 elif name == 'CustomOrigin':
251 self.origin = CustomOrigin()
252 return self.origin
253 return None
254
255 def endElement(self, name, value, connection):
256 if name == 'Id':
257 self.id = value
258 elif name == 'Status':
259 self.status = value
260 elif name == 'LastModifiedTime':
261 self.last_modified_time = value
262 elif name == 'DomainName':
263 self.domain_name = value
264 elif name == 'Origin':
265 self.origin = value
266 elif name == 'CNAME':
267 self.cnames.append(value)
268 elif name == 'Comment':
269 self.comment = value
270 elif name == 'Enabled':
271 if value.lower() == 'true':
272 self.enabled = True
273 else:
274 self.enabled = False
275 elif name == 'StreamingDistributionSummary':
276 self.streaming = True
277 else:
278 setattr(self, name, value)
279
280 def get_distribution(self):
281 return self.connection.get_distribution_info(self.id)
282
283 class StreamingDistributionSummary(DistributionSummary):
284
285 def get_distribution(self):
286 return self.connection.get_streaming_distribution_info(self.id)
287
288 class Distribution(object):
289
290 def __init__(self, connection=None, config=None, domain_name='',
291 id='', last_modified_time=None, status=''):
292 self.connection = connection
293 self.config = config
294 self.domain_name = domain_name
295 self.id = id
296 self.last_modified_time = last_modified_time
297 self.status = status
298 self.in_progress_invalidation_batches = 0
299 self.active_signers = None
300 self.etag = None
301 self._bucket = None
302 self._object_class = Object
303
304 def __repr__(self):
305 return "Distribution:%s" % self.domain_name
306
307 def startElement(self, name, attrs, connection):
308 if name == 'DistributionConfig':
309 self.config = DistributionConfig()
310 return self.config
311 elif name == 'ActiveTrustedSigners':
312 self.active_signers = ActiveTrustedSigners()
313 return self.active_signers
314 else:
315 return None
316
317 def endElement(self, name, value, connection):
318 if name == 'Id':
319 self.id = value
320 elif name == 'LastModifiedTime':
321 self.last_modified_time = value
322 elif name == 'Status':
323 self.status = value
324 elif name == 'InProgressInvalidationBatches':
325 self.in_progress_invalidation_batches = int(value)
326 elif name == 'DomainName':
327 self.domain_name = value
328 else:
329 setattr(self, name, value)
330
331 def update(self, enabled=None, cnames=None, comment=None):
332 """
333 Update the configuration of the Distribution. The only values
334 of the DistributionConfig that can be directly updated are:
335
336 * CNAMES
337 * Comment
338 * Whether the Distribution is enabled or not
339
340 Any changes to the ``trusted_signers`` or ``origin`` properties of
341 this distribution's current config object will also be included in
342 the update. Therefore, to set the origin access identity for this
343 distribution, set ``Distribution.config.origin.origin_access_identity``
344 before calling this update method.
345
346 :type enabled: bool
347 :param enabled: Whether the Distribution is active or not.
348
349 :type cnames: list of str
350 :param cnames: The DNS CNAME's associated with this
351 Distribution. Maximum of 10 values.
352
353 :type comment: str or unicode
354 :param comment: The comment associated with the Distribution.
355
356 """
357 new_config = DistributionConfig(self.connection, self.config.origin,
358 self.config.enabled, self.config.caller_reference,
359 self.config.cnames, self.config.comment,
360 self.config.trusted_signers,
361 self.config.default_root_object)
362 if enabled is not None:
363 new_config.enabled = enabled
364 if cnames is not None:
365 new_config.cnames = cnames
366 if comment is not None:
367 new_config.comment = comment
368 self.etag = self.connection.set_distribution_config(self.id, self.etag, new_config)
369 self.config = new_config
370 self._object_class = Object
371
372 def enable(self):
373 """
374 Activate the Distribution. A convenience wrapper around
375 the update method.
376 """
377 self.update(enabled=True)
378
379 def disable(self):
380 """
381 Deactivate the Distribution. A convenience wrapper around
382 the update method.
383 """
384 self.update(enabled=False)
385
386 def delete(self):
387 """
388 Delete this CloudFront Distribution. The content
389 associated with the Distribution is not deleted from
390 the underlying Origin bucket in S3.
391 """
392 self.connection.delete_distribution(self.id, self.etag)
393
394 def _get_bucket(self):
395 if isinstance(self.config.origin, S3Origin):
396 if not self._bucket:
397 bucket_dns_name = self.config.origin.dns_name
398 bucket_name = bucket_dns_name.replace('.s3.amazonaws.com', '')
399 from boto.s3.connection import S3Connection
400 s3 = S3Connection(self.connection.aws_access_key_id,
401 self.connection.aws_secret_access_key,
402 proxy=self.connection.proxy,
403 proxy_port=self.connection.proxy_port,
404 proxy_user=self.connection.proxy_user,
405 proxy_pass=self.connection.proxy_pass)
406 self._bucket = s3.get_bucket(bucket_name)
407 self._bucket.distribution = self
408 self._bucket.set_key_class(self._object_class)
409 return self._bucket
410 else:
411 raise NotImplementedError('Unable to get_objects on CustomOrigin')
412
413 def get_objects(self):
414 """
415 Return a list of all content objects in this distribution.
416
417 :rtype: list of :class:`boto.cloudfront.object.Object`
418 :return: The content objects
419 """
420 bucket = self._get_bucket()
421 objs = []
422 for key in bucket:
423 objs.append(key)
424 return objs
425
426 def set_permissions(self, object, replace=False):
427 """
428 Sets the S3 ACL grants for the given object to the appropriate
429 value based on the type of Distribution. If the Distribution
430 is serving private content the ACL will be set to include the
431 Origin Access Identity associated with the Distribution. If
432 the Distribution is serving public content the content will
433 be set up with "public-read".
434
435 :type object: :class:`boto.cloudfront.object.Object`
436 :param enabled: The Object whose ACL is being set
437
438 :type replace: bool
439 :param replace: If False, the Origin Access Identity will be
440 appended to the existing ACL for the object.
441 If True, the ACL for the object will be
442 completely replaced with one that grants
443 READ permission to the Origin Access Identity.
444
445 """
446 if isinstance(self.config.origin, S3Origin):
447 if self.config.origin.origin_access_identity:
448 id = self.config.origin.origin_access_identity.split('/')[-1]
449 oai = self.connection.get_origin_access_identity_info(id)
450 policy = object.get_acl()
451 if replace:
452 policy.acl = ACL()
453 policy.acl.add_user_grant('READ', oai.s3_user_id)
454 object.set_acl(policy)
455 else:
456 object.set_canned_acl('public-read')
457
458 def set_permissions_all(self, replace=False):
459 """
460 Sets the S3 ACL grants for all objects in the Distribution
461 to the appropriate value based on the type of Distribution.
462
463 :type replace: bool
464 :param replace: If False, the Origin Access Identity will be
465 appended to the existing ACL for the object.
466 If True, the ACL for the object will be
467 completely replaced with one that grants
468 READ permission to the Origin Access Identity.
469
470 """
471 bucket = self._get_bucket()
472 for key in bucket:
473 self.set_permissions(key, replace)
474
475 def add_object(self, name, content, headers=None, replace=True):
476 """
477 Adds a new content object to the Distribution. The content
478 for the object will be copied to a new Key in the S3 Bucket
479 and the permissions will be set appropriately for the type
480 of Distribution.
481
482 :type name: str or unicode
483 :param name: The name or key of the new object.
484
485 :type content: file-like object
486 :param content: A file-like object that contains the content
487 for the new object.
488
489 :type headers: dict
490 :param headers: A dictionary containing additional headers
491 you would like associated with the new
492 object in S3.
493
494 :rtype: :class:`boto.cloudfront.object.Object`
495 :return: The newly created object.
496 """
497 if self.config.origin.origin_access_identity:
498 policy = 'private'
499 else:
500 policy = 'public-read'
501 bucket = self._get_bucket()
502 object = bucket.new_key(name)
503 object.set_contents_from_file(content, headers=headers, policy=policy)
504 if self.config.origin.origin_access_identity:
505 self.set_permissions(object, replace)
506 return object
507
508 def create_signed_url(self, url, keypair_id,
509 expire_time=None, valid_after_time=None,
510 ip_address=None, policy_url=None,
511 private_key_file=None, private_key_string=None):
512 """
513 Creates a signed CloudFront URL that is only valid within the specified
514 parameters.
515
516 :type url: str
517 :param url: The URL of the protected object.
518
519 :type keypair_id: str
520 :param keypair_id: The keypair ID of the Amazon KeyPair used to sign
521 theURL. This ID MUST correspond to the private key
522 specified with private_key_file or private_key_string.
523
524 :type expire_time: int
525 :param expire_time: The expiry time of the URL. If provided, the URL
526 will expire after the time has passed. If not provided the URL will
527 never expire. Format is a unix epoch.
528 Use int(time.time() + duration_in_sec).
529
530 :type valid_after_time: int
531 :param valid_after_time: If provided, the URL will not be valid until
532 after valid_after_time. Format is a unix epoch.
533 Use int(time.time() + secs_until_valid).
534
535 :type ip_address: str
536 :param ip_address: If provided, only allows access from the specified
537 IP address. Use '192.168.0.10' for a single IP or
538 use '192.168.0.0/24' CIDR notation for a subnet.
539
540 :type policy_url: str
541 :param policy_url: If provided, allows the signature to contain
542 wildcard globs in the URL. For example, you could
543 provide: 'http://example.com/media/\*' and the policy
544 and signature would allow access to all contents of
545 the media subdirectory. If not specified, only
546 allow access to the exact url provided in 'url'.
547
548 :type private_key_file: str or file object.
549 :param private_key_file: If provided, contains the filename of the
550 private key file used for signing or an open
551 file object containing the private key
552 contents. Only one of private_key_file or
553 private_key_string can be provided.
554
555 :type private_key_string: str
556 :param private_key_string: If provided, contains the private key string
557 used for signing. Only one of private_key_file or
558 private_key_string can be provided.
559
560 :rtype: str
561 :return: The signed URL.
562 """
563 # Get the required parameters
564 params = self._create_signing_params(
565 url=url, keypair_id=keypair_id, expire_time=expire_time,
566 valid_after_time=valid_after_time, ip_address=ip_address,
567 policy_url=policy_url, private_key_file=private_key_file,
568 private_key_string=private_key_string)
569
570 #combine these into a full url
571 if "?" in url:
572 sep = "&"
573 else:
574 sep = "?"
575 signed_url_params = []
576 for key in ["Expires", "Policy", "Signature", "Key-Pair-Id"]:
577 if key in params:
578 param = "%s=%s" % (key, params[key])
579 signed_url_params.append(param)
580 signed_url = url + sep + "&".join(signed_url_params)
581 return signed_url
582
583 def _create_signing_params(self, url, keypair_id,
584 expire_time=None, valid_after_time=None,
585 ip_address=None, policy_url=None,
586 private_key_file=None, private_key_string=None):
587 """
588 Creates the required URL parameters for a signed URL.
589 """
590 params = {}
591 # Check if we can use a canned policy
592 if expire_time and not valid_after_time and not ip_address and not policy_url:
593 # we manually construct this policy string to ensure formatting
594 # matches signature
595 policy = self._canned_policy(url, expire_time)
596 params["Expires"] = str(expire_time)
597 else:
598 # If no policy_url is specified, default to the full url.
599 if policy_url is None:
600 policy_url = url
601 # Can't use canned policy
602 policy = self._custom_policy(policy_url, expires=expire_time,
603 valid_after=valid_after_time,
604 ip_address=ip_address)
605
606 encoded_policy = self._url_base64_encode(policy)
607 params["Policy"] = encoded_policy
608 #sign the policy
609 signature = self._sign_string(policy, private_key_file, private_key_string)
610 #now base64 encode the signature (URL safe as well)
611 encoded_signature = self._url_base64_encode(signature)
612 params["Signature"] = encoded_signature
613 params["Key-Pair-Id"] = keypair_id
614 return params
615
616 @staticmethod
617 def _canned_policy(resource, expires):
618 """
619 Creates a canned policy string.
620 """
621 policy = ('{"Statement":[{"Resource":"%(resource)s",'
622 '"Condition":{"DateLessThan":{"AWS:EpochTime":'
623 '%(expires)s}}}]}' % locals())
624 return policy
625
626 @staticmethod
627 def _custom_policy(resource, expires=None, valid_after=None, ip_address=None):
628 """
629 Creates a custom policy string based on the supplied parameters.
630 """
631 condition = {}
632 # SEE: http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/RestrictingAccessPrivateContent.html#CustomPolicy
633 # The 'DateLessThan' property is required.
634 if not expires:
635 # Defaults to ONE day
636 expires = int(time.time()) + 86400
637 condition["DateLessThan"] = {"AWS:EpochTime": expires}
638 if valid_after:
639 condition["DateGreaterThan"] = {"AWS:EpochTime": valid_after}
640 if ip_address:
641 if '/' not in ip_address:
642 ip_address += "/32"
643 condition["IpAddress"] = {"AWS:SourceIp": ip_address}
644 policy = {"Statement": [{
645 "Resource": resource,
646 "Condition": condition}]}
647 return json.dumps(policy, separators=(",", ":"))
648
649 @staticmethod
650 def _sign_string(message, private_key_file=None, private_key_string=None):
651 """
652 Signs a string for use with Amazon CloudFront.
653 Requires the rsa library be installed.
654 """
655 try:
656 import rsa
657 except ImportError:
658 raise NotImplementedError("Boto depends on the python rsa "
659 "library to generate signed URLs for "
660 "CloudFront")
661 # Make sure only one of private_key_file and private_key_string is set
662 if private_key_file and private_key_string:
663 raise ValueError("Only specify the private_key_file or the private_key_string not both")
664 if not private_key_file and not private_key_string:
665 raise ValueError("You must specify one of private_key_file or private_key_string")
666 # If private_key_file is a file name, open it and read it
667 if private_key_string is None:
668 if isinstance(private_key_file, six.string_types):
669 with open(private_key_file, 'r') as file_handle:
670 private_key_string = file_handle.read()
671 # Otherwise, treat it like a file
672 else:
673 private_key_string = private_key_file.read()
674
675 # Sign it!
676 private_key = rsa.PrivateKey.load_pkcs1(private_key_string)
677 signature = rsa.sign(str(message), private_key, 'SHA-1')
678 return signature
679
680 @staticmethod
681 def _url_base64_encode(msg):
682 """
683 Base64 encodes a string using the URL-safe characters specified by
684 Amazon.
685 """
686 msg_base64 = base64.b64encode(msg)
687 msg_base64 = msg_base64.replace('+', '-')
688 msg_base64 = msg_base64.replace('=', '_')
689 msg_base64 = msg_base64.replace('/', '~')
690 return msg_base64
691
692 class StreamingDistribution(Distribution):
693
694 def __init__(self, connection=None, config=None, domain_name='',
695 id='', last_modified_time=None, status=''):
696 super(StreamingDistribution, self).__init__(connection, config,
697 domain_name, id, last_modified_time, status)
698 self._object_class = StreamingObject
699
700 def startElement(self, name, attrs, connection):
701 if name == 'StreamingDistributionConfig':
702 self.config = StreamingDistributionConfig()
703 return self.config
704 else:
705 return super(StreamingDistribution, self).startElement(name, attrs,
706 connection)
707
708 def update(self, enabled=None, cnames=None, comment=None):
709 """
710 Update the configuration of the StreamingDistribution. The only values
711 of the StreamingDistributionConfig that can be directly updated are:
712
713 * CNAMES
714 * Comment
715 * Whether the Distribution is enabled or not
716
717 Any changes to the ``trusted_signers`` or ``origin`` properties of
718 this distribution's current config object will also be included in
719 the update. Therefore, to set the origin access identity for this
720 distribution, set
721 ``StreamingDistribution.config.origin.origin_access_identity``
722 before calling this update method.
723
724 :type enabled: bool
725 :param enabled: Whether the StreamingDistribution is active or not.
726
727 :type cnames: list of str
728 :param cnames: The DNS CNAME's associated with this
729 Distribution. Maximum of 10 values.
730
731 :type comment: str or unicode
732 :param comment: The comment associated with the Distribution.
733
734 """
735 new_config = StreamingDistributionConfig(self.connection,
736 self.config.origin,
737 self.config.enabled,
738 self.config.caller_reference,
739 self.config.cnames,
740 self.config.comment,
741 self.config.trusted_signers)
742 if enabled is not None:
743 new_config.enabled = enabled
744 if cnames is not None:
745 new_config.cnames = cnames
746 if comment is not None:
747 new_config.comment = comment
748 self.etag = self.connection.set_streaming_distribution_config(self.id,
749 self.etag,
750 new_config)
751 self.config = new_config
752 self._object_class = StreamingObject
753
754 def delete(self):
755 self.connection.delete_streaming_distribution(self.id, self.etag)
756
757