configure-s3-website 1.1.2 → 1.2.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.
- data/README.md +35 -0
- data/changelog.md +4 -0
- data/features/cassettes/cucumber_tags/redirects.yml +203 -0
- data/features/configure_bucket.feature +15 -0
- data/features/support/sample_config_files/redirects.yml +10 -0
- data/features/support/vcr.rb +1 -0
- data/lib/configure-s3-website/config_source/config_source.rb +3 -0
- data/lib/configure-s3-website/config_source/file_config_source.rb +4 -0
- data/lib/configure-s3-website/s3_client.rb +52 -0
- data/lib/configure-s3-website/version.rb +1 -1
- metadata +7 -3
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.
|
data/changelog.md
CHANGED
@@ -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
|
"""
|
data/features/support/vcr.rb
CHANGED
@@ -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
|
|
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.
|
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:
|
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:
|
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
|