configure-s3-website 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -44,6 +44,29 @@ configuration file a row like this:
44
44
  The valid *s3_endpoint* values consist of the [S3 location constraint
45
45
  values](http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region).
46
46
 
47
+ ### Configuring redirects
48
+
49
+ You can configure redirects on your S3 website by adding `routing_rules` into
50
+ the config file.
51
+
52
+ Here is an example:
53
+
54
+ ````yaml
55
+ routing_rules:
56
+ - condition:
57
+ key_prefix_equals: blog/some_path
58
+ redirect:
59
+ host_name: blog.example.com
60
+ replace_key_prefix_with: some_new_path/
61
+ http_redirect_code: 301
62
+ ````
63
+
64
+ You can use any routing rule property that the [REST
65
+ API](http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUTwebsite.html)
66
+ supports. All you have to do is to replace the uppercase letter in AWS XML with
67
+ an underscore and an undercase version of the same letter. For example,
68
+ `KeyPrefixEquals` becomes `key_prefix_equals` in the config file.
69
+
47
70
  ## How does `configure-s3-website` work?
48
71
 
49
72
  It calls the [PUT Bucket
@@ -79,10 +102,22 @@ API with the following JSON:
79
102
  }
80
103
  ```
81
104
 
105
+ If you define `routing_rules` in the config file, `configure-s3-website` will
106
+ make an additional call to the AWS API.
107
+
82
108
  ## Development
83
109
 
84
110
  * This project uses [Semantic Versioning](http://semver.org)
85
111
 
112
+ ## Credit
113
+
114
+ Created by Lauri Lehmijoki.
115
+
116
+ Big thanks to the following contributors (in alphabetical order):
117
+
118
+ * SlawD
119
+ * Steve Schwartz
120
+
86
121
  ## License
87
122
 
88
123
  See the file LICENSE.
@@ -2,6 +2,10 @@
2
2
 
3
3
  This project uses [Semantic Versioning](http://semver.org).
4
4
 
5
+ ## 1.2.0
6
+
7
+ * Support configuring redirects on the S3 website
8
+
5
9
  ## 1.1.2
6
10
 
7
11
  * Use UTC time when signing requests
@@ -0,0 +1,203 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: put
5
+ uri: https://s3.amazonaws.com/website-with-redirects/?website
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ! "\n <WebsiteConfiguration xmlns='http://s3.amazonaws.com/doc/2006-03-01/'>\n
9
+ \ <IndexDocument>\n <Suffix>index.html</Suffix>\n </IndexDocument>\n
10
+ \ <ErrorDocument>\n <Key>error.html</Key>\n </ErrorDocument>\n
11
+ \ </WebsiteConfiguration>\n "
12
+ headers:
13
+ Date:
14
+ - Sun, 05 May 2013 17:15:13 EEST
15
+ Content-Type:
16
+ - ''
17
+ Content-Length:
18
+ - '298'
19
+ Authorization:
20
+ - AWS
21
+ response:
22
+ status:
23
+ code: 404
24
+ message: Not Found
25
+ headers:
26
+ X-Amz-Request-Id:
27
+ - 2DFD9AF9459D6EBA
28
+ X-Amz-Id-2:
29
+ - xuu
30
+ Content-Type:
31
+ - application/xml
32
+ Transfer-Encoding:
33
+ - chunked
34
+ Date:
35
+ - Sun, 05 May 2013 14:15:16 GMT
36
+ Connection:
37
+ - close
38
+ Server:
39
+ - AmazonS3
40
+ body:
41
+ encoding: US-ASCII
42
+ string: ! '<?xml version="1.0" encoding="UTF-8"?>
43
+
44
+ <Error><Code>NoSuchBucket</Code><Message>The specified bucket does not exist</Message><BucketName>website-with-redirects</BucketName><RequestId>2DFD9AF9459D6EBA</RequestId><HostId>+mKBZUngt5PWBeABkXaUZFengM23XP683j5NXVkvIlDnfkfsYdU6jJuoRMJaQZF/</HostId></Error>'
45
+ http_version:
46
+ recorded_at: Sun, 05 May 2013 14:15:14 GMT
47
+ - request:
48
+ method: put
49
+ uri: https://s3.amazonaws.com/website-with-redirects
50
+ body:
51
+ encoding: US-ASCII
52
+ string: ''
53
+ headers:
54
+ Date:
55
+ - Sun, 05 May 2013 17:15:14 EEST
56
+ Content-Type:
57
+ - ''
58
+ Content-Length:
59
+ - '0'
60
+ Authorization:
61
+ - AWS
62
+ response:
63
+ status:
64
+ code: 200
65
+ message: OK
66
+ headers:
67
+ X-Amz-Id-2:
68
+ - Hn9luS/t3JpOkwnXRnyVOJ+HlYVS1PNZ//XVrAiZjP95xY4Aot5X0X8S+rQ8eDwp
69
+ X-Amz-Request-Id:
70
+ - 60B4854F860963D6
71
+ Date:
72
+ - Sun, 05 May 2013 14:15:18 GMT
73
+ Location:
74
+ - /website-with-redirects
75
+ Content-Length:
76
+ - '0'
77
+ Server:
78
+ - AmazonS3
79
+ body:
80
+ encoding: US-ASCII
81
+ string: ''
82
+ http_version:
83
+ recorded_at: Sun, 05 May 2013 14:15:15 GMT
84
+ - request:
85
+ method: put
86
+ uri: https://s3.amazonaws.com/website-with-redirects/?website
87
+ body:
88
+ encoding: US-ASCII
89
+ string: ! "\n <WebsiteConfiguration xmlns='http://s3.amazonaws.com/doc/2006-03-01/'>\n
90
+ \ <IndexDocument>\n <Suffix>index.html</Suffix>\n </IndexDocument>\n
91
+ \ <ErrorDocument>\n <Key>error.html</Key>\n </ErrorDocument>\n
92
+ \ </WebsiteConfiguration>\n "
93
+ headers:
94
+ Date:
95
+ - Sun, 05 May 2013 17:15:15 EEST
96
+ Content-Type:
97
+ - ''
98
+ Content-Length:
99
+ - '298'
100
+ Authorization:
101
+ - AWS
102
+ response:
103
+ status:
104
+ code: 200
105
+ message: OK
106
+ headers:
107
+ X-Amz-Id-2:
108
+ - bBCMImUYwikvIu5M1aFYsEyouPNM3xQoLsNpKeXjSVbe3ZJJZLUdR0OMF+3zFX+y
109
+ X-Amz-Request-Id:
110
+ - 2E4F04F9CB9F14F9
111
+ Date:
112
+ - Sun, 05 May 2013 14:15:19 GMT
113
+ Content-Length:
114
+ - '0'
115
+ Server:
116
+ - AmazonS3
117
+ body:
118
+ encoding: US-ASCII
119
+ string: ''
120
+ http_version:
121
+ recorded_at: Sun, 05 May 2013 14:15:16 GMT
122
+ - request:
123
+ method: put
124
+ uri: https://s3.amazonaws.com/website-with-redirects/?policy
125
+ body:
126
+ encoding: US-ASCII
127
+ string: ! "{\n \"Version\":\"2008-10-17\",\n \"Statement\":[{\n
128
+ \ \"Sid\":\"PublicReadForGetBucketObjects\",\n \"Effect\":\"Allow\",\n
129
+ \ \"Principal\": { \"AWS\": \"*\" },\n \"Action\":[\"s3:GetObject\"],\n
130
+ \ \"Resource\":[\"arn:aws:s3:::website-with-redirects/*\"]\n }]\n
131
+ \ }"
132
+ headers:
133
+ Date:
134
+ - Sun, 05 May 2013 17:15:16 EEST
135
+ Content-Type:
136
+ - ''
137
+ Content-Length:
138
+ - '291'
139
+ Authorization:
140
+ - AWS
141
+ response:
142
+ status:
143
+ code: 204
144
+ message: No Content
145
+ headers:
146
+ X-Amz-Id-2:
147
+ - ijsq/+jpLhfwLnUJF2xKj5x+1x9YhapYBVk38FDb7BYQ2vRsiFUydmrYD8PIfr0b
148
+ X-Amz-Request-Id:
149
+ - EA0FDFDE47845326
150
+ Date:
151
+ - Sun, 05 May 2013 14:15:19 GMT
152
+ Server:
153
+ - AmazonS3
154
+ body:
155
+ encoding: US-ASCII
156
+ string: ''
157
+ http_version:
158
+ recorded_at: Sun, 05 May 2013 14:15:17 GMT
159
+ - request:
160
+ method: put
161
+ uri: https://s3.amazonaws.com/website-with-redirects/?website
162
+ body:
163
+ encoding: US-ASCII
164
+ string: ! "\n <WebsiteConfiguration xmlns='http://s3.amazonaws.com/doc/2006-03-01/'>\n
165
+ \ <IndexDocument>\n <Suffix>index.html</Suffix>\n </IndexDocument>\n
166
+ \ <ErrorDocument>\n <Key>error.html</Key>\n </ErrorDocument>\n
167
+ \ <RoutingRules>\n \n <RoutingRule>\n \n
168
+ \ <Condition>\n <KeyPrefixEquals>blog/some_path</KeyPrefixEquals></Condition>\n
169
+ \ <Redirect>\n <HostName>blog.example.com</HostName>\n
170
+ \ <ReplaceKeyPrefixWith>some_new_path/</ReplaceKeyPrefixWith>\n
171
+ \ <HttpRedirectCode>301</HttpRedirectCode></Redirect>\n </RoutingRule>\n
172
+ \ \n </RoutingRules>\n </WebsiteConfiguration>\n
173
+ \ "
174
+ headers:
175
+ Date:
176
+ - Sun, 05 May 2013 17:15:17 EEST
177
+ Content-Type:
178
+ - ''
179
+ Content-Length:
180
+ - '786'
181
+ Authorization:
182
+ - AWS
183
+ response:
184
+ status:
185
+ code: 200
186
+ message: OK
187
+ headers:
188
+ X-Amz-Id-2:
189
+ - aAt1wLoQJwkJHLmF8wHSX8fbfyVVacGEv3PO/Cx6y4kDkEqzp2v33l99ZWBH4dVt
190
+ X-Amz-Request-Id:
191
+ - 1C1A5EB5ABB7198A
192
+ Date:
193
+ - Sun, 05 May 2013 14:15:20 GMT
194
+ Content-Length:
195
+ - '0'
196
+ Server:
197
+ - AmazonS3
198
+ body:
199
+ encoding: US-ASCII
200
+ string: ''
201
+ http_version:
202
+ recorded_at: Sun, 05 May 2013 14:15:18 GMT
203
+ recorded_with: VCR 2.3.0
@@ -9,6 +9,7 @@ Feature: configure an S3 bucket to function as a website
9
9
  Created bucket name-of-a-new-bucket in the US Standard Region
10
10
  Bucket name-of-a-new-bucket now functions as a website
11
11
  Bucket name-of-a-new-bucket is now readable to the whole world
12
+ No redirects to configure for name-of-a-new-bucket bucket
12
13
 
13
14
  """
14
15
 
@@ -38,5 +39,19 @@ Feature: configure an S3 bucket to function as a website
38
39
  """
39
40
  Bucket name-of-an-existing-bucket now functions as a website
40
41
  Bucket name-of-an-existing-bucket is now readable to the whole world
42
+ No redirects to configure for name-of-an-existing-bucket bucket
43
+
44
+ """
45
+
46
+ @redirects
47
+ Scenario: The user wants to configure redirects for the S3 website
48
+ Given my config file is in "features/support/sample_config_files/redirects.yml"
49
+ When I run the configure-s3-website command
50
+ Then the output should be
51
+ """
52
+ Created bucket website-with-redirects in the US Standard Region
53
+ Bucket website-with-redirects now functions as a website
54
+ Bucket website-with-redirects is now readable to the whole world
55
+ 1 redirects configured for website-with-redirects bucket
41
56
 
42
57
  """
@@ -0,0 +1,10 @@
1
+ s3_id: foo
2
+ s3_secret: xuu
3
+ s3_bucket: website-with-redirects
4
+ routing_rules:
5
+ - condition:
6
+ key_prefix_equals: blog/some_path
7
+ redirect:
8
+ host_name: blog.example.com
9
+ replace_key_prefix_with: some_new_path/
10
+ http_redirect_code: 301
@@ -9,4 +9,5 @@ VCR.cucumber_tags do |t|
9
9
  t.tag '@bucket-does-not-exist'
10
10
  t.tag '@bucket-does-not-exist-in-tokyo'
11
11
  t.tag '@bucket-exists'
12
+ t.tag '@redirects'
12
13
  end
@@ -11,5 +11,8 @@ module ConfigureS3Website
11
11
 
12
12
  def s3_endpoint
13
13
  end
14
+
15
+ def routing_rules
16
+ end
14
17
  end
15
18
  end
@@ -23,6 +23,10 @@ module ConfigureS3Website
23
23
  @config['s3_endpoint']
24
24
  end
25
25
 
26
+ def routing_rules
27
+ @config['routing_rules']
28
+ end
29
+
26
30
  private
27
31
 
28
32
  def parse_config(yaml_file_path)
@@ -10,6 +10,7 @@ module ConfigureS3Website
10
10
  begin
11
11
  enable_website_configuration(config_source)
12
12
  make_bucket_readable_to_everyone(config_source)
13
+ configure_bucket_redirects(config_source)
13
14
  rescue NoSuchBucketError
14
15
  create_bucket(config_source)
15
16
  retry
@@ -58,6 +59,45 @@ module ConfigureS3Website
58
59
  puts "Bucket #{config_source.s3_bucket_name} is now readable to the whole world"
59
60
  end
60
61
 
62
+ def self.configure_bucket_redirects(config_source)
63
+ routing_rules = config_source.routing_rules
64
+ if routing_rules.is_a?(Array) && routing_rules.any?
65
+ body = %|
66
+ <WebsiteConfiguration xmlns='http://s3.amazonaws.com/doc/2006-03-01/'>
67
+ <IndexDocument>
68
+ <Suffix>index.html</Suffix>
69
+ </IndexDocument>
70
+ <ErrorDocument>
71
+ <Key>error.html</Key>
72
+ </ErrorDocument>
73
+ <RoutingRules>
74
+ |
75
+ routing_rules.each do |routing_rule|
76
+ body << %|
77
+ <RoutingRule>
78
+ |
79
+ body << self.hash_to_api_xml(routing_rule, 7)
80
+ body << %|
81
+ </RoutingRule>
82
+ |
83
+ end
84
+ body << %|
85
+ </RoutingRules>
86
+ </WebsiteConfiguration>
87
+ |
88
+
89
+ call_s3_api(
90
+ path = "/#{config_source.s3_bucket_name}/?website",
91
+ method = Net::HTTP::Put,
92
+ body = body,
93
+ config_source = config_source
94
+ )
95
+ puts "#{routing_rules.size} redirects configured for #{config_source.s3_bucket_name} bucket"
96
+ else
97
+ puts "No redirects to configure for #{config_source.s3_bucket_name} bucket"
98
+ end
99
+ end
100
+
61
101
  def self.create_bucket(config_source)
62
102
  endpoint = Endpoint.new(config_source.s3_endpoint || '')
63
103
  body = if endpoint.region == 'US Standard'
@@ -115,6 +155,18 @@ module ConfigureS3Website
115
155
  hmac = OpenSSL::HMAC.digest(digest, config_source.s3_secret_access_key, can_string)
116
156
  signature = Base64.encode64(hmac).strip
117
157
  end
158
+
159
+ def self.hash_to_api_xml(hash={}, indent=0)
160
+ "".tap do |body|
161
+ hash.each do |key, value|
162
+ key_name = key.sub(/^[a-z\d]*/) { $&.capitalize }.gsub(/(?:_|(\/))([a-z\d]*)/) { $2.capitalize }
163
+ value = value.is_a?(Hash) ? self.hash_to_api_xml(value, indent+1) : value
164
+ body << "\n"
165
+ body << " " * indent * 2 # 2-space indentation formatting for xml
166
+ body << "<#{key_name}>#{value}</#{key_name}>"
167
+ end
168
+ end
169
+ end
118
170
  end
119
171
  end
120
172
 
@@ -1,3 +1,3 @@
1
1
  module ConfigureS3Website
2
- VERSION = '1.1.2'
2
+ VERSION = '1.2.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configure-s3-website
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -142,11 +142,13 @@ files:
142
142
  - features/cassettes/cucumber_tags/bucket-does-not-exist-in-tokyo.yml
143
143
  - features/cassettes/cucumber_tags/bucket-does-not-exist.yml
144
144
  - features/cassettes/cucumber_tags/bucket-exists.yml
145
+ - features/cassettes/cucumber_tags/redirects.yml
145
146
  - features/config_file.feature
146
147
  - features/configure_bucket.feature
147
148
  - features/step_definitions/steps.rb
148
149
  - features/support/env.rb
149
150
  - features/support/sample_config_files/endpoint_tokyo.yml
151
+ - features/support/sample_config_files/redirects.yml
150
152
  - features/support/sample_config_files/s3_config_with_existing_bucket.yml
151
153
  - features/support/sample_config_files/s3_config_with_non-existing_bucket.yml
152
154
  - features/support/vcr.rb
@@ -174,7 +176,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
174
176
  version: '0'
175
177
  segments:
176
178
  - 0
177
- hash: 925918613448529982
179
+ hash: -1020516680573187683
178
180
  required_rubygems_version: !ruby/object:Gem::Requirement
179
181
  none: false
180
182
  requirements:
@@ -183,7 +185,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
185
  version: '0'
184
186
  segments:
185
187
  - 0
186
- hash: 925918613448529982
188
+ hash: -1020516680573187683
187
189
  requirements: []
188
190
  rubyforge_project:
189
191
  rubygems_version: 1.8.25
@@ -194,11 +196,13 @@ test_files:
194
196
  - features/cassettes/cucumber_tags/bucket-does-not-exist-in-tokyo.yml
195
197
  - features/cassettes/cucumber_tags/bucket-does-not-exist.yml
196
198
  - features/cassettes/cucumber_tags/bucket-exists.yml
199
+ - features/cassettes/cucumber_tags/redirects.yml
197
200
  - features/config_file.feature
198
201
  - features/configure_bucket.feature
199
202
  - features/step_definitions/steps.rb
200
203
  - features/support/env.rb
201
204
  - features/support/sample_config_files/endpoint_tokyo.yml
205
+ - features/support/sample_config_files/redirects.yml
202
206
  - features/support/sample_config_files/s3_config_with_existing_bucket.yml
203
207
  - features/support/sample_config_files/s3_config_with_non-existing_bucket.yml
204
208
  - features/support/vcr.rb