configure-s3-website 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +15 -3
- data/changelog.md +5 -0
- data/configure-s3-website.gemspec +1 -1
- data/features/cassettes/cucumber_tags/bucket-does-not-exist-in-tokyo.yml +159 -0
- data/features/configure_bucket.feature +19 -1
- data/features/step_definitions/steps.rb +4 -0
- data/features/support/sample_config_files/endpoint_tokyo.yml +4 -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 +45 -3
- data/lib/configure-s3-website/version.rb +1 -1
- data/spec/s3_client_spec.rb +18 -0
- metadata +10 -3
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -6,8 +6,7 @@
|
|
6
6
|
Configure an AWS S3 bucket to function as a website. Easily from the
|
7
7
|
command-line interface.
|
8
8
|
|
9
|
-
The
|
10
|
-
website. The bucket may or may not exist. If the bucket does not exist,
|
9
|
+
The bucket may or may not exist. If the bucket does not exist,
|
11
10
|
`configure-s3-website` will create it.
|
12
11
|
|
13
12
|
## Install
|
@@ -32,6 +31,19 @@ following command:
|
|
32
31
|
Congratulations! You now have an S3 bucket that can act as a website server for
|
33
32
|
you.
|
34
33
|
|
34
|
+
### Specifying a non-standard S3 endpoint
|
35
|
+
|
36
|
+
By default, `configure-s3-website` creates the S3 website into the US Standard
|
37
|
+
region.
|
38
|
+
|
39
|
+
If you want to create the website into another region, add into the
|
40
|
+
configuration file a row like this:
|
41
|
+
|
42
|
+
s3_endpoint: EU
|
43
|
+
|
44
|
+
The valid *s3_endpoint* values consist of the [S3 location constraint
|
45
|
+
values](http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region).
|
46
|
+
|
35
47
|
## How does `configure-s3-website` work?
|
36
48
|
|
37
49
|
It calls the [PUT Bucket
|
@@ -69,4 +81,4 @@ API with the following JSON:
|
|
69
81
|
|
70
82
|
## License
|
71
83
|
|
72
|
-
See file LICENSE.
|
84
|
+
See the file LICENSE.
|
data/changelog.md
ADDED
@@ -6,7 +6,7 @@ spec = Gem::Specification.new do |s|
|
|
6
6
|
s.email = 'lauri.lehmijoki@iki.fi'
|
7
7
|
s.homepage = 'https://github.com/laurilehmijoki/configure-s3-website'
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
|
-
s.summary = 'Configure your S3 bucket to function as a web site'
|
9
|
+
s.summary = 'Configure your AWS S3 bucket to function as a web site'
|
10
10
|
s.bindir = 'bin'
|
11
11
|
|
12
12
|
s.add_development_dependency 'rspec', '~> 2.10.0'
|
@@ -0,0 +1,159 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: put
|
5
|
+
uri: https://s3-ap-northeast-1.amazonaws.com/name-of-a-new-bucket/?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, 30 Dec 2012 19:59:34 EET
|
15
|
+
Content-Type:
|
16
|
+
- ''
|
17
|
+
Content-Length:
|
18
|
+
- '298'
|
19
|
+
Authorization:
|
20
|
+
- AWS foo
|
21
|
+
response:
|
22
|
+
status:
|
23
|
+
code: 404
|
24
|
+
message: Not Found
|
25
|
+
headers:
|
26
|
+
X-Amz-Request-Id:
|
27
|
+
- CD16DF6FF66B5922
|
28
|
+
X-Amz-Id-2:
|
29
|
+
- Xu30q0VM0aaYY091koYh8FIUDPB2KWOQLRPqnLulIK3ScIrMWgOwF7M2XRYIi5Vs
|
30
|
+
Content-Type:
|
31
|
+
- application/xml
|
32
|
+
Transfer-Encoding:
|
33
|
+
- chunked
|
34
|
+
Date:
|
35
|
+
- Sun, 30 Dec 2012 17:59:34 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>name-of-a-new-bucket</BucketName><RequestId>CD16DF6FF66B5922</RequestId><HostId>Xu30q0VM0aaYY091koYh8FIUDPB2KWOQLRPqnLulIK3ScIrMWgOwF7M2XRYIi5Vs</HostId></Error>'
|
45
|
+
http_version:
|
46
|
+
recorded_at: Sun, 30 Dec 2012 17:59:37 GMT
|
47
|
+
- request:
|
48
|
+
method: put
|
49
|
+
uri: https://s3-ap-northeast-1.amazonaws.com/name-of-a-new-bucket
|
50
|
+
body:
|
51
|
+
encoding: US-ASCII
|
52
|
+
string: ''
|
53
|
+
headers:
|
54
|
+
Date:
|
55
|
+
- Sun, 30 Dec 2012 19:59:37 EET
|
56
|
+
Content-Type:
|
57
|
+
- ''
|
58
|
+
Content-Length:
|
59
|
+
- '0'
|
60
|
+
Authorization:
|
61
|
+
- AWS foo
|
62
|
+
response:
|
63
|
+
status:
|
64
|
+
code: 200
|
65
|
+
message: OK
|
66
|
+
headers:
|
67
|
+
X-Amz-Id-2:
|
68
|
+
- 7HuGyurBPI/HV8DVtjtRufaMaLRJLU+vCch+BPuBAysYAlE7XS4Eavz7srhB2dTx
|
69
|
+
X-Amz-Request-Id:
|
70
|
+
- 431755651DECBBC5
|
71
|
+
Date:
|
72
|
+
- Sun, 30 Dec 2012 17:59:39 GMT
|
73
|
+
Location:
|
74
|
+
- /name-of-a-new-bucket
|
75
|
+
Content-Length:
|
76
|
+
- '0'
|
77
|
+
Server:
|
78
|
+
- AmazonS3
|
79
|
+
body:
|
80
|
+
encoding: US-ASCII
|
81
|
+
string: ''
|
82
|
+
http_version:
|
83
|
+
recorded_at: Sun, 30 Dec 2012 17:59:39 GMT
|
84
|
+
- request:
|
85
|
+
method: put
|
86
|
+
uri: https://s3-ap-northeast-1.amazonaws.com/name-of-a-new-bucket/?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, 30 Dec 2012 19:59:39 EET
|
96
|
+
Content-Type:
|
97
|
+
- ''
|
98
|
+
Content-Length:
|
99
|
+
- '298'
|
100
|
+
Authorization:
|
101
|
+
- AWS foo
|
102
|
+
response:
|
103
|
+
status:
|
104
|
+
code: 200
|
105
|
+
message: OK
|
106
|
+
headers:
|
107
|
+
X-Amz-Id-2:
|
108
|
+
- XZE0T/tWFNuRi6/yu1O+O3A7fJ/j2oas8ZqK4p6rLbaRxevXe44K/pAOsrB381ei
|
109
|
+
X-Amz-Request-Id:
|
110
|
+
- 514396AE3C1BB2C1
|
111
|
+
Date:
|
112
|
+
- Sun, 30 Dec 2012 17:59:41 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, 30 Dec 2012 17:59:42 GMT
|
122
|
+
- request:
|
123
|
+
method: put
|
124
|
+
uri: https://s3-ap-northeast-1.amazonaws.com/name-of-a-new-bucket/?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:::name-of-a-new-bucket/*\"]\n }]\n
|
131
|
+
\ }"
|
132
|
+
headers:
|
133
|
+
Date:
|
134
|
+
- Sun, 30 Dec 2012 19:59:42 EET
|
135
|
+
Content-Type:
|
136
|
+
- ''
|
137
|
+
Content-Length:
|
138
|
+
- '289'
|
139
|
+
Authorization:
|
140
|
+
- AWS foo
|
141
|
+
response:
|
142
|
+
status:
|
143
|
+
code: 204
|
144
|
+
message: No Content
|
145
|
+
headers:
|
146
|
+
X-Amz-Id-2:
|
147
|
+
- z/XdtqiOW0ihAGadAXwCNCAuE0OLeFisy4TN5e/3OmEI72dQxQjfftyXFSNNwOQN
|
148
|
+
X-Amz-Request-Id:
|
149
|
+
- 82E8EBABB5D150C5
|
150
|
+
Date:
|
151
|
+
- Sun, 30 Dec 2012 17:59:44 GMT
|
152
|
+
Server:
|
153
|
+
- AmazonS3
|
154
|
+
body:
|
155
|
+
encoding: US-ASCII
|
156
|
+
string: ''
|
157
|
+
http_version:
|
158
|
+
recorded_at: Sun, 30 Dec 2012 17:59:44 GMT
|
159
|
+
recorded_with: VCR 2.3.0
|
@@ -6,12 +6,30 @@ Feature: configure an S3 bucket to function as a website
|
|
6
6
|
When I run the configure-s3-website command
|
7
7
|
Then the output should be
|
8
8
|
"""
|
9
|
-
Created bucket name-of-a-new-bucket
|
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
12
|
|
13
13
|
"""
|
14
14
|
|
15
|
+
@bucket-does-not-exist
|
16
|
+
Scenario: The configuration does not contain the 's3_endpoint' setting
|
17
|
+
Given my config file is in "features/support/sample_config_files/s3_config_with_non-existing_bucket.yml"
|
18
|
+
When I run the configure-s3-website command
|
19
|
+
Then the output should include
|
20
|
+
"""
|
21
|
+
Created bucket name-of-a-new-bucket in the US Standard Region
|
22
|
+
"""
|
23
|
+
|
24
|
+
@bucket-does-not-exist-in-tokyo
|
25
|
+
Scenario: Create bucket into the Tokyo region
|
26
|
+
Given my config file is in "features/support/sample_config_files/endpoint_tokyo.yml"
|
27
|
+
When I run the configure-s3-website command
|
28
|
+
Then the output should include
|
29
|
+
"""
|
30
|
+
Created bucket name-of-a-new-bucket in the Asia Pacific (Tokyo) Region
|
31
|
+
"""
|
32
|
+
|
15
33
|
@bucket-exists
|
16
34
|
Scenario: The bucket already exists
|
17
35
|
Given my config file is in "features/support/sample_config_files/s3_config_with_existing_bucket.yml"
|
@@ -15,6 +15,10 @@ Then /^the output should be$/ do |expected_console_output|
|
|
15
15
|
@console_output.should eq(expected_console_output)
|
16
16
|
end
|
17
17
|
|
18
|
+
Then /^the output should include$/ do |expected_console_output|
|
19
|
+
@console_output.should include(expected_console_output)
|
20
|
+
end
|
21
|
+
|
18
22
|
module Kernel
|
19
23
|
require 'stringio'
|
20
24
|
|
data/features/support/vcr.rb
CHANGED
@@ -59,19 +59,30 @@ module ConfigureS3Website
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def self.create_bucket(config_source)
|
62
|
+
endpoint = Endpoint.new(config_source.s3_endpoint || '')
|
63
|
+
body = %|
|
64
|
+
<CreateBucketConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
|
65
|
+
<LocationConstraint>#{endpoint.location_constraint}</LocationConstraint>
|
66
|
+
</CreateBucketConfiguration >
|
67
|
+
|
|
62
68
|
call_s3_api(
|
63
69
|
path = "/#{config_source.s3_bucket_name}",
|
64
70
|
method = Net::HTTP::Put,
|
65
|
-
body =
|
71
|
+
body = body,
|
66
72
|
config_source = config_source
|
67
73
|
)
|
68
|
-
puts "Created bucket
|
74
|
+
puts "Created bucket %s in the %s Region" %
|
75
|
+
[
|
76
|
+
config_source.s3_bucket_name,
|
77
|
+
endpoint.region
|
78
|
+
]
|
69
79
|
end
|
70
80
|
|
71
81
|
def self.call_s3_api(path, method, body, config_source)
|
82
|
+
endpoint = Endpoint.new(config_source.s3_endpoint || '')
|
72
83
|
date = Time.now.strftime("%a, %d %b %Y %H:%M:%S %Z")
|
73
84
|
digest = create_digest(path, method, config_source, date)
|
74
|
-
url = "https
|
85
|
+
url = "https://#{endpoint.hostname}#{path}"
|
75
86
|
uri = URI.parse(url)
|
76
87
|
req = method.new(uri.to_s)
|
77
88
|
req.initialize_http_header({
|
@@ -104,6 +115,34 @@ end
|
|
104
115
|
|
105
116
|
private
|
106
117
|
|
118
|
+
module ConfigureS3Website
|
119
|
+
class Endpoint
|
120
|
+
attr_reader :region, :location_constraint, :hostname
|
121
|
+
|
122
|
+
def initialize(location_constraint)
|
123
|
+
raise InvalidS3LocationConstraintError unless
|
124
|
+
location_constraints.has_key?location_constraint
|
125
|
+
@region = location_constraints.fetch(location_constraint)[:region]
|
126
|
+
@hostname = location_constraints.fetch(location_constraint)[:endpoint]
|
127
|
+
@location_constraint = location_constraint
|
128
|
+
end
|
129
|
+
|
130
|
+
# http://docs.amazonwebservices.com/general/latest/gr/rande.html#s3_region
|
131
|
+
def location_constraints
|
132
|
+
{
|
133
|
+
'' => { :region => 'US Standard', :endpoint => 's3.amazonaws.com' },
|
134
|
+
'us-west-2' => { :region => 'US West (Oregon)', :endpoint => 's3-us-west-2.amazonaws.com' },
|
135
|
+
'us-west-1' => { :region => 'US West (Northern California)', :endpoint => 's3-us-west-1.amazonaws.com' },
|
136
|
+
'EU' => { :region => 'EU (Ireland)', :endpoint => 's3-eu-west-1.amazonaws.com' },
|
137
|
+
'ap-southeast-1' => { :region => 'Asia Pacific (Singapore)', :endpoint => 's3-ap-southeast-1.amazonaws.com' },
|
138
|
+
'ap-southeast-2' => { :region => 'Asia Pacific (Sydney)', :endpoint => 's3-ap-southeast-2.amazonaws.com' },
|
139
|
+
'ap-northeast-1' => { :region => 'Asia Pacific (Tokyo)', :endpoint => 's3-ap-northeast-1.amazonaws.com' },
|
140
|
+
'sa-east-1' => { :region => 'South America (Sao Paulo)', :endpoint => 's3-sa-east-1.amazonaws.com' }
|
141
|
+
}
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
107
146
|
module ConfigureS3Website
|
108
147
|
class ErrorParser
|
109
148
|
def self.create_error(amazon_error_xml)
|
@@ -117,6 +156,9 @@ module ConfigureS3Website
|
|
117
156
|
end
|
118
157
|
end
|
119
158
|
|
159
|
+
class InvalidS3LocationConstraintError < StandardError
|
160
|
+
end
|
161
|
+
|
120
162
|
class NoSuchBucketError < StandardError
|
121
163
|
end
|
122
164
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'configure-s3-website'
|
3
|
+
|
4
|
+
describe ConfigureS3Website::S3Client do
|
5
|
+
context '#create_bucket' do
|
6
|
+
let(:config_source) {
|
7
|
+
mock = double('config_source')
|
8
|
+
mock.stub(:s3_endpoint).and_return('invalid-location-constraint')
|
9
|
+
mock
|
10
|
+
}
|
11
|
+
it 'throws an error if the config contains an invalid S3 location constraint' do
|
12
|
+
expect {
|
13
|
+
extractor = ConfigureS3Website::S3Client.
|
14
|
+
send(:create_bucket, config_source)
|
15
|
+
}.to raise_error(InvalidS3LocationConstraintError)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
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.
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -138,13 +138,16 @@ files:
|
|
138
138
|
- README.md
|
139
139
|
- Rakefile
|
140
140
|
- bin/configure-s3-website
|
141
|
+
- changelog.md
|
141
142
|
- configure-s3-website.gemspec
|
143
|
+
- features/cassettes/cucumber_tags/bucket-does-not-exist-in-tokyo.yml
|
142
144
|
- features/cassettes/cucumber_tags/bucket-does-not-exist.yml
|
143
145
|
- features/cassettes/cucumber_tags/bucket-exists.yml
|
144
146
|
- features/config_file.feature
|
145
147
|
- features/configure_bucket.feature
|
146
148
|
- features/step_definitions/steps.rb
|
147
149
|
- features/support/env.rb
|
150
|
+
- features/support/sample_config_files/endpoint_tokyo.yml
|
148
151
|
- features/support/sample_config_files/s3_config_with_existing_bucket.yml
|
149
152
|
- features/support/sample_config_files/s3_config_with_non-existing_bucket.yml
|
150
153
|
- features/support/vcr.rb
|
@@ -154,6 +157,7 @@ files:
|
|
154
157
|
- lib/configure-s3-website/s3_client.rb
|
155
158
|
- lib/configure-s3-website/version.rb
|
156
159
|
- spec/config_extractor/file_config_extractor_spec.rb
|
160
|
+
- spec/s3_client_spec.rb
|
157
161
|
- spec/sample_files/_config_file_with_eruby.yml
|
158
162
|
homepage: https://github.com/laurilehmijoki/configure-s3-website
|
159
163
|
licenses: []
|
@@ -178,16 +182,19 @@ rubyforge_project:
|
|
178
182
|
rubygems_version: 1.8.24
|
179
183
|
signing_key:
|
180
184
|
specification_version: 3
|
181
|
-
summary: Configure your S3 bucket to function as a web site
|
185
|
+
summary: Configure your AWS S3 bucket to function as a web site
|
182
186
|
test_files:
|
187
|
+
- features/cassettes/cucumber_tags/bucket-does-not-exist-in-tokyo.yml
|
183
188
|
- features/cassettes/cucumber_tags/bucket-does-not-exist.yml
|
184
189
|
- features/cassettes/cucumber_tags/bucket-exists.yml
|
185
190
|
- features/config_file.feature
|
186
191
|
- features/configure_bucket.feature
|
187
192
|
- features/step_definitions/steps.rb
|
188
193
|
- features/support/env.rb
|
194
|
+
- features/support/sample_config_files/endpoint_tokyo.yml
|
189
195
|
- features/support/sample_config_files/s3_config_with_existing_bucket.yml
|
190
196
|
- features/support/sample_config_files/s3_config_with_non-existing_bucket.yml
|
191
197
|
- features/support/vcr.rb
|
192
198
|
- spec/config_extractor/file_config_extractor_spec.rb
|
199
|
+
- spec/s3_client_spec.rb
|
193
200
|
- spec/sample_files/_config_file_with_eruby.yml
|