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,54 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'cloudfront/helpers/download_distribution'
4
+ require_relative 'distribution'
5
+
6
+ class Cloudfront
7
+ module Distribution
8
+ module DownloadDistribution
9
+ include Distribution
10
+
11
+ ::DOWNLOAD_DISTRIBUTION_URL = "/#{Cloudfront::Utils::Api.version}/distribution"
12
+
13
+ def download_distribution_create(distribution)
14
+ distribution_create(DOWNLOAD_DISTRIBUTION_URL, distribution)
15
+ end
16
+
17
+ def download_distribution_list(max_items = 0, marker = "")
18
+ distribution_list(DOWNLOAD_DISTRIBUTION_URL, max_items, marker)
19
+ end
20
+
21
+ def download_distribution_get(distribution_id)
22
+ distribution_get(DOWNLOAD_DISTRIBUTION_URL, distribution_id)
23
+ end
24
+
25
+ def download_distribution_get_config(distribution_id)
26
+ distribution_get_config(DOWNLOAD_DISTRIBUTION_URL, distribution_id)
27
+ end
28
+
29
+ def download_distribution_put_config(distribution_id, distribution, etag)
30
+ distribution_put_config(DOWNLOAD_DISTRIBUTION_URL, distribution_id, distribution, etag)
31
+ end
32
+
33
+ def download_distribution_enable(distribution_id)
34
+ distribution_enable(DOWNLOAD_DISTRIBUTION_URL, distribution_id)
35
+ end
36
+
37
+ def download_distribution_disable(distribution_id)
38
+ distribution_disable(DOWNLOAD_DISTRIBUTION_URL, distribution_id)
39
+ end
40
+
41
+ def download_distribution_delete(distribution_id)
42
+ distribution_delete(DOWNLOAD_DISTRIBUTION_URL, distribution_id)
43
+ end
44
+
45
+ private
46
+ def get_download_distribution_wrapper(hash)
47
+ Cloudfront::Helpers::DownloadDistribution.from_hash hash
48
+ end
49
+
50
+ end
51
+ end
52
+ end
53
+
54
+
@@ -0,0 +1,53 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'cloudfront/helpers/streaming_distribution'
4
+ require_relative 'distribution'
5
+
6
+ class Cloudfront
7
+ module Distribution
8
+ module StreamingDistribution
9
+ include Distribution
10
+
11
+ ::STREAMING_DISTRIBUTION_URL = "/#{Cloudfront::Utils::Api.version}/streaming-distribution"
12
+
13
+ def streaming_distribution_create(distribution)
14
+ distribution_create(STREAMING_DISTRIBUTION_URL, distribution)
15
+ end
16
+
17
+ def streaming_distribution_list(max_items = 0, marker = "")
18
+ distribution_list(STREAMING_DISTRIBUTION_URL, max_items, marker)
19
+ end
20
+
21
+ def streaming_distribution_get(distribution_id)
22
+ distribution_get(STREAMING_DISTRIBUTION_URL, distribution_id)
23
+ end
24
+
25
+ def streaming_distribution_get_config(distribution_id)
26
+ distribution_get_config(STREAMING_DISTRIBUTION_URL, distribution_id)
27
+ end
28
+
29
+ def streaming_distribution_put_config(distribution_id, distribution, etag)
30
+ distribution_put_config(STREAMING_DISTRIBUTION_URL, distribution_id, distribution, etag)
31
+ end
32
+
33
+ def streaming_distribution_enable(distribution_id)
34
+ distribution_enable(STREAMING_DISTRIBUTION_URL, distribution_id)
35
+ end
36
+
37
+ def streaming_distribution_disable(distribution_id)
38
+ distribution_disable(STREAMING_DISTRIBUTION_URL, distribution_id)
39
+ end
40
+
41
+ def streaming_distribution_delete(distribution_id)
42
+ distribution_delete(STREAMING_DISTRIBUTION_URL, distribution_id)
43
+ end
44
+
45
+ private
46
+ def get_streaming_distribution_wrapper(hash)
47
+ Cloudfront::Helpers::StreamingDistribution.from_hash hash
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class CloudfrontError < StandardError
6
+ attr_reader :response
7
+ def initialize(message, response = nil)
8
+ super(message)
9
+ @response = response
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class CNAMEAlreadyExistsError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class DistributionAlreadyExistsError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class IllegalUpdateError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class InvalidOriginAccessIdentityError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class InvalidOriginError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class InvalidRequiredProtocolError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class MissingBodyError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class PreconditionFailedError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class TooManyDistributionCNAMEsError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class TooManyDistributionsError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class TooManyTrustedSignersError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Errors
5
+ class TrustedSignerDoesNotExistError < CloudfrontError; end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Exceptions
5
+ class DeleteEnabledDistributionException < StandardError;end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Exceptions
5
+ class DistributionAlreadyDisabledException < StandardError;end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Exceptions
5
+ class DistributionAlreadyEnabledException < StandardError;end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Exceptions
5
+ class DistributionConfigurationException < StandardError;end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Exceptions
5
+ class MissingEtagException < StandardError;end
6
+ end
7
+ end
@@ -0,0 +1,71 @@
1
+ # encoding: UTF-8
2
+
3
+ class Cloudfront
4
+ module Helpers
5
+ class Aliases
6
+ include Cloudfront::Utils::ConfigurationChecker
7
+ include Cloudfront::Utils::XmlSerializer
8
+
9
+ attr_accessor :cnames
10
+
11
+ def initialize(&block)
12
+ #set default values
13
+ @cnames = []
14
+
15
+ #set values from block
16
+ instance_eval &block if block_given?
17
+ end
18
+
19
+ def validate
20
+ # some wrapping
21
+ @cnames = Array.wrap @cnames # wraps single elements into an array and removes nil parasites
22
+
23
+
24
+ # Some additional checking should be done on cnames.
25
+ for cname in cnames
26
+ error_messages.push("#{cname} isn't a valid url") unless cname =~ Cloudfront::Utils::Util::URL_REGEXP
27
+ end
28
+ end
29
+
30
+ # A factory method that creates a Aliases instance from a hash
31
+ # Input example
32
+ # hash = {
33
+ # "Aliases" => {
34
+ # "Quantity" => "number of CNAME cnames",
35
+ # "Items" => {
36
+ # "CNAME" => "CNAME alias"
37
+ # }
38
+ # }
39
+ # }
40
+ #
41
+ def self.from_hash(hash)
42
+ hash = hash["Aliases"] || hash
43
+ self.new do
44
+ self.cnames = Array.wrap((hash["Items"] || {})["CNAME"])
45
+ end
46
+ end
47
+
48
+ # Output example
49
+ # <Aliases>
50
+ # <Quantity>number of CNAME cnames</Quantity>
51
+ # <Items>
52
+ # <CNAME>CNAME alias</CNAME>
53
+ # </Items>
54
+ # </Aliases>
55
+ def build_xml(xml)
56
+ check_configuration
57
+ xml.Aliases {
58
+ xml.Quantity @cnames.size
59
+ if @cnames.size > 0
60
+ xml.Items {
61
+ for cname in Array.wrap @cnames
62
+ xml.CNAME cname
63
+ end
64
+ }
65
+ end
66
+ }
67
+ end
68
+
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,166 @@
1
+ # encoding: UTF-8
2
+
3
+ require_relative 'trusted_signers'
4
+
5
+ class Cloudfront
6
+ module Helpers
7
+ class CacheBehavior
8
+ include Cloudfront::Utils::ConfigurationChecker
9
+ include Cloudfront::Utils::XmlSerializer
10
+
11
+ attr_accessor :is_default,
12
+ :path_pattern,
13
+ :target_origin_id,
14
+ :query_string_forward,
15
+ :cookies_forward_policy,
16
+ :cookies_to_forward,
17
+ :trusted_signers,
18
+ :viewer_protocol_policy,
19
+ :min_ttl
20
+
21
+ def initialize(&block)
22
+ #set default values
23
+ @is_default = false
24
+ @query_string_forward = true
25
+ @cookies_forward_policy = "all"
26
+ @trusted_signers = TrustedSigners.new
27
+ @viewer_protocol_policy = "allow-all"
28
+ @min_ttl = 86400 # one day as the default minimum ttl
29
+
30
+ #set values from block
31
+ instance_eval &block if block_given?
32
+ end
33
+
34
+ def validate
35
+ # some wrapping
36
+ @cookies_to_forward = Array.wrap @cookies_to_forward
37
+
38
+ # Error checking
39
+ error_messages.push "target_origin_id shouldn't be nil" if @target_origin_id.nil?
40
+ error_messages.push "query_string_forward must be a boolean" unless !!@query_string_forward == @query_string_forward
41
+ error_messages.push "cookies_forward_policy should be one of #{Cloudfront::Utils::Util::FORWARD_POLICY_VALUES.join(', ')}" unless Cloudfront::Utils::Util::FORWARD_POLICY_VALUES.include?(@cookies_forward_policy)
42
+ # trusted signers validation
43
+ if @trusted_signers.is_a?(TrustedSigners)
44
+ @trusted_signers.check_configuration
45
+ else
46
+ error_messages.push "trusted_signer field should be a TrustedSigners"
47
+ end
48
+
49
+ error_messages.push "viewer_protocol_policy should be one of #{Cloudfront::Utils::Util::VIEWER_PROTOCOL_VALUES.join(', ')}" unless Cloudfront::Utils::Util::VIEWER_PROTOCOL_VALUES.include?(@viewer_protocol_policy)
50
+ error_messages.push "min_ttl should be a number" unless @min_ttl.is_a? Fixnum
51
+ end
52
+
53
+ def cache_behavior_body(xml)
54
+ unless @is_default
55
+ xml.PathPattern @path_pattern
56
+ end
57
+ xml.TargetOriginId @target_origin_id
58
+ xml.ForwardedValues {
59
+ xml.QueryString @query_string_forward
60
+ xml.Cookies {
61
+ xml.Forward @cookies_forward_policy
62
+ if (@cookies_forward_policy == "whitelist")
63
+ xml.WhitelistedNames {
64
+ xml.Quantity @cookies_to_forward.size
65
+ if (@cookies_to_forward.size > 0)
66
+ xml.Items {
67
+ for cookie in @cookies_to_forward
68
+ xml.Name cookie
69
+ end
70
+ }
71
+ end
72
+ }
73
+ end
74
+ }
75
+ }
76
+ @trusted_signers.build_xml(xml)
77
+ xml.ViewerProtocolPolicy @viewer_protocol_policy
78
+ xml.MinTTL @min_ttl
79
+ end
80
+
81
+ # Creates a CacheBehavior instance from a hash
82
+ # {
83
+ # "CacheBehavior" => {
84
+ # "PathPattern" => "*",
85
+ # "TargetOriginId" => "id",
86
+ # "ForwardedValues" => {
87
+ # "QueryString" => "true",
88
+ # "Cookies" => {
89
+ # "Forward" => "all | whitelist | none",
90
+ # "WhitelistedNames" => {
91
+ # "Quantity" => "0",
92
+ # "Items" =>
93
+ # {
94
+ # "Name" => ["name of a cookie to forward to the origin"]
95
+ # }
96
+ # }
97
+ # }
98
+ # },
99
+ # "TrustedSigners" => {},
100
+ # "ViewerProtocolPolicy" => "allow-all",
101
+ # "MinTTL" => "86400"
102
+ # }
103
+ # }
104
+ def self.from_hash(hash)
105
+ hash = hash["DefaultCacheBehavior"] || hash["CacheBehavior"] || hash
106
+ self.new do
107
+ self.is_default = !hash.has_key?("PathPattern")
108
+ self.path_pattern = hash["PathPattern"]
109
+ self.target_origin_id = hash["TargetOriginId"]
110
+ forwarded_values = hash["ForwardedValues"]
111
+ if forwarded_values
112
+ self.query_string_forward = (forwarded_values["QueryString"] || "true").to_bool
113
+ cookies = forwarded_values["Cookies"]
114
+ if cookies
115
+ self.cookies_forward_policy = cookies["Forward"] || "all"
116
+ white_listed_names = cookies["WhitelistedNames"]
117
+ if (white_listed_names && white_listed_names["Items"]||{})["Name"]
118
+ self.cookies_to_forward = Array.wrap white_listed_names["Items"]["Name"]
119
+ end
120
+ end
121
+ end
122
+ self.trusted_signers = TrustedSigners.from_hash(hash["TrustedSigners"])
123
+ self.viewer_protocol_policy = hash["ViewerProtocolPolicy"] || "allow-all"
124
+ self.min_ttl = (hash["MinTTL"] || "86400").to_i
125
+ end
126
+ end
127
+
128
+ # The cache behavior class container
129
+ # <CacheBehavior>
130
+ # <PathPattern>pattern that specifies files that this cache behavior applies to</PathPattern>
131
+ # <TargetOriginId>ID of the origin that this cache behavior applies to</TargetOriginId>
132
+ # <ForwardedValues>
133
+ # <QueryString>true | false</QueryString>
134
+ # <Cookies>
135
+ # <Forward>all | whitelist | none</Forward>
136
+ # <!-- Required when Forward = whitelist, omitted otherwise. -->
137
+ # <WhitelistedNames>
138
+ # <Quantity>number of cookie names to forward to origin</Quantity>
139
+ # <Items>
140
+ # <Name>name of a cookie to forward to the origin</Name>
141
+ # </Items>
142
+ # </WhitelistedNames>
143
+ # </Cookies>
144
+ # </ForwardedValues>
145
+ # <TrustedSigners>
146
+ # ... see TrustedSigners class
147
+ # </TrustedSigners>
148
+ # <ViewerProtocolPolicy>allow-all | https-only</ViewerProtocolPolicy>
149
+ # <MinTTL>minimum TTL in seconds for files specified by PathPattern</MinTTL>
150
+ # </CacheBehavior>
151
+ def build_xml(xml)
152
+ check_configuration
153
+ if @is_default
154
+ xml.DefaultCacheBehavior {
155
+ cache_behavior_body(xml)
156
+ }
157
+ else
158
+ xml.CacheBehavior {
159
+ cache_behavior_body(xml)
160
+ }
161
+ end
162
+ end
163
+
164
+ end
165
+ end
166
+ end