cloudfront 0.0.1 → 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/Gemfile +11 -8
  2. data/LICENSE.txt +1 -1
  3. data/README.rdoc +64 -7
  4. data/Rakefile +11 -14
  5. data/cloudfront.gemspec +85 -27
  6. data/lib/cloudfront.rb +39 -0
  7. data/lib/cloudfront/connection.rb +25 -0
  8. data/lib/cloudfront/distribution/distribution.rb +136 -0
  9. data/lib/cloudfront/distribution/download_distribution.rb +54 -0
  10. data/lib/cloudfront/distribution/streaming_distribution.rb +53 -0
  11. data/lib/cloudfront/errors/cloudfront_error.rb +13 -0
  12. data/lib/cloudfront/errors/cname_already_exists_error.rb +7 -0
  13. data/lib/cloudfront/errors/distribution_already_exists_error.rb +7 -0
  14. data/lib/cloudfront/errors/illegal_update_error.rb +7 -0
  15. data/lib/cloudfront/errors/invalid_origin_access_identity_error.rb +7 -0
  16. data/lib/cloudfront/errors/invalid_origin_error.rb +7 -0
  17. data/lib/cloudfront/errors/invalid_required_protocol_error.rb +7 -0
  18. data/lib/cloudfront/errors/missing_body_error.rb +7 -0
  19. data/lib/cloudfront/errors/precondition_failed_error.rb +7 -0
  20. data/lib/cloudfront/errors/too_many_distribution_cnames_error.rb +7 -0
  21. data/lib/cloudfront/errors/too_many_distributions_error.rb +7 -0
  22. data/lib/cloudfront/errors/too_many_trusted_signers_error.rb +7 -0
  23. data/lib/cloudfront/errors/trusted_signer_does_not_exist_error.rb +7 -0
  24. data/lib/cloudfront/exceptions/delete_enabled_distribution_exception.rb +7 -0
  25. data/lib/cloudfront/exceptions/distribution_already_disabled_exception.rb +7 -0
  26. data/lib/cloudfront/exceptions/distribution_already_enabled_exception.rb +7 -0
  27. data/lib/cloudfront/exceptions/distribution_configuration_exception.rb +7 -0
  28. data/lib/cloudfront/exceptions/missing_etag_exception.rb +7 -0
  29. data/lib/cloudfront/helpers/aliases.rb +71 -0
  30. data/lib/cloudfront/helpers/cache_behavior.rb +166 -0
  31. data/lib/cloudfront/helpers/cache_behaviors.rb +108 -0
  32. data/lib/cloudfront/helpers/download_distribution.rb +157 -0
  33. data/lib/cloudfront/helpers/invalidation.rb +83 -0
  34. data/lib/cloudfront/helpers/logging.rb +71 -0
  35. data/lib/cloudfront/helpers/origin.rb +101 -0
  36. data/lib/cloudfront/helpers/origin_access_identity.rb +58 -0
  37. data/lib/cloudfront/helpers/origins.rb +94 -0
  38. data/lib/cloudfront/helpers/s3_origin.rb +51 -0
  39. data/lib/cloudfront/helpers/streaming_distribution.rb +150 -0
  40. data/lib/cloudfront/helpers/trusted_signers.rb +73 -0
  41. data/lib/cloudfront/invalidation/invalidations.rb +57 -0
  42. data/lib/cloudfront/origin_access_identity/origin_access_identity.rb +60 -0
  43. data/lib/cloudfront/utils/api.rb +18 -0
  44. data/lib/cloudfront/utils/array.rb +5 -0
  45. data/lib/cloudfront/utils/configuration_checker.rb +19 -0
  46. data/lib/cloudfront/utils/string.rb +11 -0
  47. data/lib/cloudfront/utils/util.rb +20 -0
  48. data/lib/cloudfront/utils/xml_serializer.rb +18 -0
  49. data/lib/faraday/request/cloudfront_signer.rb +35 -0
  50. data/lib/faraday/request/xml_content_type.rb +18 -0
  51. metadata +198 -31
  52. data/.document +0 -5
  53. data/Gemfile.lock +0 -27
  54. data/test/helper.rb +0 -19
  55. data/test/test_cloudfront.rb +0 -7
@@ -0,0 +1,58 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Helpers
5
+ class OriginAccessIdentity
6
+ include Cloudfront::Utils::ConfigurationChecker
7
+ include Cloudfront::Utils::XmlSerializer
8
+
9
+ attr_accessor :caller_reference,
10
+ :comment
11
+
12
+ def initialize(&block)
13
+ #setting default values
14
+ @caller_reference = Cloudfront::Utils::Util.generate_caller_reference
15
+ @comment = "Created with cloudfront Gem, visit https://github.com/Belkacem/cloudfront"
16
+
17
+ #set value from block
18
+ instance_eval &block if block_given?
19
+ end
20
+
21
+ def validate
22
+ this = self
23
+
24
+ # Error checking
25
+ error_messages.push "The caller_reference shouldn't be empty" if @caller_reference.empty?
26
+ end
27
+
28
+ #{
29
+ # "CloudFrontOriginAccessIdentityConfig" => {
30
+ # "CallerReference" => "ref",
31
+ # "Comment" => "The comment."
32
+ # }
33
+ #}
34
+ def self.from_hash(hash)
35
+ hash = hash["CloudFrontOriginAccessIdentityConfig"] || hash
36
+ self.new do
37
+ self.caller_reference = hash["CallerReference"]
38
+ self.comment = hash["Comment"]
39
+ end
40
+ end
41
+
42
+ #<?xml version="1.0" encoding="UTF-8"?>
43
+ #<CloudFrontOriginAccessIdentityConfig xmlns="http://cloudfront.amazonaws.com/doc/2012-07-01/">
44
+ # <CallerReference>ref</CallerReference>
45
+ # <Comment>The comment.</Comment>
46
+ #</CloudFrontOriginAccessIdentityConfig>
47
+
48
+ def build_xml(xml)
49
+ check_configuration
50
+ xml.CloudFrontOriginAccessIdentityConfig('xmlns' => "http://cloudfront.amazonaws.com/doc/#{Cloudfront::Utils::Api.version}/") {
51
+ xml.CallerReference @caller_reference
52
+ xml.Comment @comment
53
+ }
54
+ end
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,94 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative 'origin'
4
+
5
+ class Cloudfront
6
+ module Helpers
7
+ class Origins
8
+ include Cloudfront::Utils::ConfigurationChecker
9
+ include Cloudfront::Utils::XmlSerializer
10
+
11
+ attr_accessor :origins
12
+
13
+ def initialize(&block)
14
+ #set default values
15
+ @origins = []
16
+
17
+ #set values from block
18
+ instance_eval &block if block_given?
19
+ end
20
+
21
+ def validate
22
+ # put origin in a list (this is done for single origin distributions)
23
+ @origins = [@origins] unless @origins.is_a? Array
24
+
25
+ for origin in @origins
26
+ if origin.is_a?(Origin)
27
+ origin.check_configuration
28
+ end
29
+ end
30
+ end
31
+
32
+ # {
33
+ # "Origins" => {
34
+ # "Quantity" => "2",
35
+ # "Items" => {
36
+ # "Origin" => [
37
+ # {
38
+ # "Id" => "example-Amazon S3-origin",
39
+ # "DomainName" => "myawsbucket.s3.amazonaws.com",
40
+ # "S3OriginConfig" => {
41
+ # "OriginAccessIdentity" => "origin-access-identity/cloudfront/E74FTE3AEXAMPLE"
42
+ # }
43
+ # },
44
+ # {
45
+ # "Id" => "example-custom-origin",
46
+ # "DomainName" => "example.com",
47
+ # "CustomOriginConfig" => {
48
+ # "HTTPPort" => "80",
49
+ # "HTTPSPort" => "443",
50
+ # "OriginProtocolPolicy" => "match-viewer"
51
+ # }
52
+ # }
53
+ # ]
54
+ # }
55
+ # }
56
+ # }
57
+ def self.from_hash(hash)
58
+ hash = hash["Origins"] || hash
59
+ self.new do
60
+ unless hash["Items"].nil?
61
+ origins_list = hash["Items"]["Origin"].is_a?(Hash) ? [hash["Items"]["Origin"]] : hash["Items"]["Origin"]
62
+ for origin_hash in origins_list
63
+ unless origin_hash.nil?
64
+ self.origins.push(Origin.from_hash(origin_hash))
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ # <Origins>
72
+ # <Quantity>number of origins</Quantity>
73
+ # <Items>
74
+ # ... see Origin class
75
+ # </Items>
76
+ # </Origins>
77
+ #
78
+ def build_xml(xml)
79
+ check_configuration
80
+ xml.Origins {
81
+ xml.Quantity @origins.size
82
+ if @origins.size > 0
83
+ xml.Items {
84
+ for origin in @origins
85
+ origin.build_xml(xml)
86
+ end
87
+ }
88
+ end
89
+ }
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Helpers
5
+ class S3Origin
6
+ include Cloudfront::Utils::ConfigurationChecker
7
+ include Cloudfront::Utils::XmlSerializer
8
+
9
+ attr_accessor :domain_name,
10
+ :origin_access_identity
11
+
12
+ def initialize(&block)
13
+ #set value from block
14
+ instance_eval &block if block_given?
15
+ end
16
+
17
+ def validate
18
+ error_messages.push "domain_name can't be null" if @domain_name.nil?
19
+ error_messages.push "origin_access_identity can't be null" if @origin_access_identity.nil?
20
+ end
21
+
22
+ # {
23
+ # "S3Origin" => {
24
+ # "DomainName" => "CloudFront domain name assigned to the distribution",
25
+ # "OriginAccessIdentity" => "origin-access-identity/cloudfront/ID"
26
+ # }
27
+ # }
28
+ def self.from_hash(hash)
29
+ hash = hash["S3Origin"] || hash
30
+ self.new do
31
+ self.domain_name = hash["DomainName"]
32
+ self.origin_access_identity = hash["OriginAccessIdentity"]
33
+ end
34
+ end
35
+
36
+ # The origin class container
37
+ # <S3Origin>
38
+ # <DomainName>CloudFront domain name assigned to the distribution</DNSName>
39
+ # <OriginAccessIdentity>origin-access-identity/cloudfront/ID</OriginAccessIdentity>
40
+ # </S3Origin>
41
+ def build_xml(xml)
42
+ check_configuration
43
+ xml.S3Origin {
44
+ xml.DomainName @domain_name unless @domain_name.nil?
45
+ xml.OriginAccessIdentity @origin_access_identity
46
+ }
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,150 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative 's3_origin'
4
+ require_relative 'aliases'
5
+ require_relative 'logging'
6
+ require_relative 'trusted_signers'
7
+
8
+ class Cloudfront
9
+ module Helpers
10
+ class StreamingDistribution
11
+ include Cloudfront::Utils::ConfigurationChecker
12
+ include Cloudfront::Utils::XmlSerializer
13
+
14
+ attr_accessor :caller_reference,
15
+ :domain_name,
16
+ :origin_access_identity,
17
+ :cnames,
18
+ :comment,
19
+ :logging,
20
+ :trusted_signers,
21
+ :price_class,
22
+ :enabled
23
+
24
+ def initialize(&block)
25
+ #setting default values
26
+ @caller_reference = Cloudfront::Utils::Util.generate_caller_reference
27
+ @s3_origin = S3Origin.new
28
+ @cnames = []
29
+ @comment = "Created with cloudfront Gem, visit https://github.com/Belkacem/cloudfront"
30
+ @logging = Logging.new
31
+ @trusted_signers = []
32
+ @price_class = "PriceClass_All"
33
+ @enabled = false
34
+
35
+ #set value from block
36
+ instance_eval &block if block_given?
37
+ end
38
+
39
+ def validate
40
+ this = self
41
+
42
+ # s3_origin, aliases and trusted_signers_container are internal structures.
43
+ @s3_origin = S3Origin.new do
44
+ self.domain_name = this.domain_name
45
+ self.origin_access_identity = this.origin_access_identity
46
+ end
47
+
48
+ @aliases = Aliases.new do
49
+ self.cnames = this.cnames
50
+ end
51
+
52
+ @trusted_signers_container = TrustedSigners.new do
53
+ #self.enabled = true
54
+ self.trusted_signers = this.trusted_signers
55
+ end
56
+
57
+ @logging.include_cookies = "undefined"
58
+
59
+ # Error checking
60
+ error_messages.push "The caller_reference shouldn't be empty" if @caller_reference.empty?
61
+ @s3_origin.check_configuration
62
+ @aliases.check_configuration
63
+ @logging.check_configuration
64
+ @trusted_signers_container.check_configuration
65
+
66
+ error_messages.push "price_class is invalid should be in #{Cloudfront::Utils::Util::PRICE_CLASS.join(', ')}" unless Cloudfront::Utils::Util::PRICE_CLASS.include?(@price_class)
67
+ error_messages.push "enabled should be a boolean" unless !!@enabled == @enabled
68
+ end
69
+
70
+ # Creates a distribution configuration wrapper from a hash
71
+ # {
72
+ # "StreamingDistributionConfig" => {
73
+ # "CallerReference" => "unique description for this distribution",
74
+ # "S3Origin" => {
75
+ # ... see s3Origin
76
+ # },
77
+ # "Aliases" => {
78
+ # "Quantity" => "number of CNAME aliases",
79
+ # "Items" => {
80
+ # "CNAME" => "CNAME alias"
81
+ # }
82
+ # },
83
+ # "Comment" => "comment about the distribution",
84
+ # "Logging" => {
85
+ # "Enabled" => "true | false",
86
+ # "Bucket" => "Amazon S3 bucket for logs",
87
+ # "Prefix" => "prefix for log file names"
88
+ # },
89
+ # "TrustedSigners" => {
90
+ # "Quantity" => "number of trusted signers",
91
+ # "Items" => {
92
+ # "AwsAccountNumber" => "self | AWS account that can create \n signed URLs"
93
+ # }
94
+ # },
95
+ # "PriceClass" => "maximum price class for the distribution",
96
+ # "Enabled" => "true | false"
97
+ # }
98
+ # }
99
+ def self.from_hash(hash)
100
+ hash = hash["StreamingDistributionConfig"] || hash
101
+ self.new do
102
+ self.caller_reference = hash["CallerReference"]
103
+ origin = S3Origin.from_hash(hash)
104
+ self.domain_name = origin.domain_name
105
+ self.origin_access_identity = origin.origin_access_identity
106
+ self.cnames = Aliases.from_hash(hash).cnames # Aliases class contains the code that extract cnames
107
+ self.comment = hash["Comment"]
108
+ self.logging = Logging.from_hash(hash)
109
+ self.trusted_signers = TrustedSigners.from_hash(hash).trusted_signers
110
+ self.price_class = hash["PriceClass"] || "PriceClass_All"
111
+ self.enabled = (hash["Enabled"] || "false").to_bool
112
+ end
113
+ end
114
+
115
+ #<StreamingDistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2012-07-01/">
116
+ # <CallerReference>unique description for this distribution</CallerReference>
117
+ # <S3Origin>
118
+ # <DNSName>CloudFront domain name assigned to the distribution</DNSName>
119
+ # <OriginAccessIdentity>origin-access-identity/cloudfront/ID</OriginAccessIdentity>
120
+ # </S3Origin>
121
+ # <Aliases>
122
+ # ... see Aliases class
123
+ # </Aliases>
124
+ # <Comment>comment about the distribution</Comment>
125
+ # <Logging>
126
+ # ... see Logging class.
127
+ # </Logging>
128
+ # <TrustedSigners>
129
+ # ... see TrustedSigners.
130
+ # </TrustedSigners>
131
+ # <PriceClass>maximum price class for the distribution</PriceClass>
132
+ # <Enabled>true | false</Enabled>
133
+ #</StreamingDistributionConfig>
134
+ def build_xml(xml)
135
+ check_configuration
136
+ xml.StreamingDistributionConfig('xmlns' => "http://cloudfront.amazonaws.com/doc/#{Cloudfront::Utils::Api.version}/") {
137
+ xml.CallerReference @caller_reference
138
+ @s3_origin.build_xml(xml)
139
+ @aliases.build_xml(xml)
140
+ xml.Comment @comment
141
+ @logging.build_xml(xml)
142
+ @trusted_signers_container.build_xml(xml)
143
+ xml.PriceClass @price_class
144
+ xml.Enabled @enabled
145
+ }
146
+ end
147
+
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Helpers
5
+ class TrustedSigners
6
+ include Cloudfront::Utils::ConfigurationChecker
7
+ include Cloudfront::Utils::XmlSerializer
8
+
9
+ attr_accessor :enabled,
10
+ :trusted_signers
11
+
12
+ def initialize(&block)
13
+ #set default values
14
+ @enabled = false
15
+ @trusted_signers = []
16
+
17
+ #set values from block
18
+ instance_eval &block if block_given?
19
+ end
20
+
21
+ def validate
22
+ @trusted_signers = Array.wrap @trusted_signers
23
+ @trusted_signers.push "self" unless @trusted_signers.include? "self"
24
+ end
25
+
26
+ # A factory method that creates a TrustedSigners instance from a hash
27
+ # Input example
28
+ # hash = {
29
+ # "TrustedSigners" => {
30
+ # "Enabled" => "true | false",
31
+ # "Quantity" => "number of trusted signers",
32
+ # "Items" => {
33
+ # "AwsAccountNumber" => "self | AWS account that can create signed URLs"
34
+ # }
35
+ # }
36
+ # }
37
+ #
38
+ def self.from_hash(hash)
39
+ hash = hash["TrustedSigners"] || hash
40
+ self.new do
41
+ self.enabled = hash["Enabled"].nil? ? nil : hash["Enabled"].to_bool
42
+ if (hash["Quantity"]|| "0").to_i > 0
43
+ self.trusted_signers = Array.wrap((hash["Items"]|| {})["AwsAccountNumber"])
44
+ end
45
+ end
46
+ end
47
+
48
+ # Output example
49
+ # <TrustedSigners>
50
+ # <Enabled>true</Enabled>
51
+ # <Quantity>number of trusted signers</Quantity>
52
+ # <Items>
53
+ # <AwsAccountNumber>self</AwsAccountNumber>
54
+ # </Items>
55
+ # </TrustedSigners>
56
+ def build_xml(xml)
57
+ check_configuration
58
+ xml.TrustedSigners {
59
+ xml.Enabled (@enabled || @trusted_signers.any?)
60
+ xml.Quantity @trusted_signers.size
61
+ if @trusted_signers.any?
62
+ xml.Items {
63
+ for signer in @trusted_signers
64
+ xml.AwsAccountNumber signer
65
+ end
66
+ }
67
+ end
68
+ }
69
+ end
70
+
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'cloudfront/helpers/invalidation'
4
+
5
+ class Cloudfront
6
+ module Invalidation
7
+ module Invalidations
8
+ INVALIDATION_URL = "/#{Cloudfront::Utils::Api.version}/distribution/%s/invalidation"
9
+
10
+ # Invalidates files
11
+ # @param distribution_id [String] The id of the distribution.
12
+ # @param files [Array] an array of files to be invalidated.
13
+ # @param caller_reference [String] The custom caller reference to be added to the request.
14
+ # @return [Faraday::Response] the response from cloudfront
15
+ def invalidation_send(distribution_id, files, caller_reference = nil)
16
+ connection.post do |request|
17
+ request.url INVALIDATION_URL % distribution_id
18
+ request.body = invalidation_body(files, caller_reference)
19
+ end
20
+ end
21
+
22
+ # Lists all the invalidations.
23
+ # @param distribution_id [String] The id of the distribution.
24
+ # @param max_items [int] the max items to be retrieved
25
+ # @param marker [String] The invalidation from which begins the list.
26
+ # @return [Faraday::Response] the response from cloudfront
27
+ def invalidation_list(distribution_id, max_items = 0, marker = "")
28
+ connection.get do |request|
29
+ request.url INVALIDATION_URL % distribution_id
30
+ request.params['Marker'] = marker unless marker.nil? || marker.strip.empty?
31
+ request.params['MaxItems'] = max_items if max_items > 0
32
+ end
33
+ end
34
+
35
+ # gets the invalidation information.
36
+ # @param distribution_id [String] The id of the distribution.
37
+ # @param invalidation_id [String] The id of the invalidation.
38
+ # @return [Faraday::Response] the response from cloudfront
39
+ def invalidation_get(distribution_id, invalidation_id)
40
+ connection.get INVALIDATION_URL % distribution_id + '/' + invalidation_id
41
+ end
42
+
43
+ private
44
+ # Method that builds the invalidation body.
45
+ # @param files [Array] an array containing the list of files to be invalidated.
46
+ # @return [String] the xml to be sent to cloudfront.
47
+ def invalidation_body(files, caller_reference)
48
+ invalidation = Helpers::Invalidation.new do
49
+ self.files = files
50
+ self.caller_reference = caller_reference unless caller_reference.nil?
51
+ end
52
+ invalidation.to_xml
53
+ end
54
+
55
+ end
56
+ end
57
+ end