cloudfront 0.0.1 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
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