vagrant-s3auth 0.1.0 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -3
- data/.rubocop.yml +18 -6
- data/.ruby-version +1 -0
- data/.travis.yml +43 -0
- data/CHANGELOG.md +14 -0
- data/CONTRIBUTING.md +40 -0
- data/Gemfile +6 -6
- data/Gemfile.lock +51 -23
- data/README.md +60 -53
- data/Rakefile +5 -1
- data/TESTING.md +70 -0
- data/lib/vagrant-s3auth.rb +3 -4
- data/lib/vagrant-s3auth/errors.rb +8 -0
- data/lib/vagrant-s3auth/extensions.rb +0 -1
- data/lib/vagrant-s3auth/extensions/downloader.rb +14 -12
- data/lib/vagrant-s3auth/plugin.rb +0 -5
- data/lib/vagrant-s3auth/util.rb +52 -0
- data/lib/vagrant-s3auth/version.rb +1 -1
- data/locales/en.yml +14 -1
- data/test/box/minimal +13 -0
- data/test/box/minimal.box +0 -0
- data/test/cleanup.rb +15 -0
- data/test/run.bats +93 -0
- data/test/setup.rb +33 -0
- data/test/support.rb +81 -0
- data/vagrant-s3auth.gemspec +5 -1
- metadata +61 -10
- data/lib/vagrant-s3auth/extensions/box_add.rb +0 -41
- data/lib/vagrant-s3auth/util/authenticator.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7eca0ac3297ce700dc01ce1324d0749881a3e734
|
4
|
+
data.tar.gz: 5356d66628358d58497b437fdf5b1757a6f7279e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 235f0f650c517820d65990d5e76c226849198c8b65d405e5314ad9569ed9d32fbc63725eb616ccc753d2c8849f7f66219c50b9cab9f740ab0a96b9a82b75bb37
|
7
|
+
data.tar.gz: c64a7083938c0c32e07b80949f76a2c7f4ab837220cfd460b757ef1454aeda0e5323816a5c6b6a8e5e5d47607d81f4629d3f25f37fb07381386dffced83ecacd
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
Lint/AssignmentInCondition:
|
2
2
|
Enabled: false
|
3
3
|
|
4
|
+
Metrics/AbcSize:
|
5
|
+
Max: 30
|
6
|
+
|
7
|
+
Metrics/CyclomaticComplexity:
|
8
|
+
Max: 10
|
9
|
+
|
10
|
+
Metrics/LineLength:
|
11
|
+
Max: 100
|
12
|
+
|
13
|
+
Metrics/MethodLength:
|
14
|
+
CountComments: false
|
15
|
+
Max: 20
|
16
|
+
|
17
|
+
Metrics/PerceivedComplexity:
|
18
|
+
Max: 12
|
19
|
+
|
4
20
|
Style/AlignParameters:
|
5
21
|
EnforcedStyle: with_fixed_indentation
|
6
22
|
|
@@ -10,12 +26,8 @@ Style/Documentation:
|
|
10
26
|
Style/FileName:
|
11
27
|
Enabled: false
|
12
28
|
|
13
|
-
Style/
|
14
|
-
|
15
|
-
|
16
|
-
Style/MethodLength:
|
17
|
-
CountComments: false # count full line comments?
|
18
|
-
Max: 20
|
29
|
+
Style/RescueModifier:
|
30
|
+
Enabled: false
|
19
31
|
|
20
32
|
Style/SignalException:
|
21
33
|
EnforcedStyle: only_raise
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.1.1
|
data/.travis.yml
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.1
|
4
|
+
|
5
|
+
before_install:
|
6
|
+
# Install Bats, the Bash testing framework
|
7
|
+
- git clone https://github.com/sstephenson/bats.git
|
8
|
+
- (cd bats; sudo ./install.sh /usr/local)
|
9
|
+
|
10
|
+
# Vagrant from source doesn't ship with `bsdtar`
|
11
|
+
- sudo apt-get install -qy bsdtar
|
12
|
+
|
13
|
+
# Speed up Nokogiri installation substantially by using precompiled libxslt
|
14
|
+
- sudo apt-get install -qy libxslt1.1
|
15
|
+
- bundle config build.nokogiri --use-system-libraries
|
16
|
+
|
17
|
+
# Older versions of Vagrant can't handle the current version of Bundler, which
|
18
|
+
# ships with Travis.
|
19
|
+
- rvm @default,@global do gem uninstall bundler --all --executables
|
20
|
+
- gem install bundler -v '~> 1.5.2'
|
21
|
+
- bundle --version
|
22
|
+
|
23
|
+
# Allow dynamically changing the bundled Vagrant version via environment
|
24
|
+
# variables.
|
25
|
+
- rm Gemfile.lock
|
26
|
+
|
27
|
+
before_script:
|
28
|
+
- test/setup.rb
|
29
|
+
|
30
|
+
after_script:
|
31
|
+
- test/cleanup.rb
|
32
|
+
|
33
|
+
env:
|
34
|
+
global:
|
35
|
+
- VAGRANT_S3AUTH_ATLAS_BOX_NAME="travis-$TRAVIS_JOB_NUMBER"
|
36
|
+
- VAGRANT_S3AUTH_BUCKET="travis-$TRAVIS_JOB_NUMBER.vagrant-s3auth.com"
|
37
|
+
- VAGRANT_S3AUTH_REGION_NONSTANDARD=eu-west-1
|
38
|
+
- VAGRANT_S3AUTH_BOX_BASE=minimal
|
39
|
+
matrix:
|
40
|
+
- VAGRANT_VERSION=master
|
41
|
+
- VAGRANT_VERSION=v1.7.1
|
42
|
+
- VAGRANT_VERSION=v1.6.5
|
43
|
+
- VAGRANT_VERSION=v1.5.0
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## 1.0.0
|
2
|
+
|
3
|
+
**Unreleased**
|
4
|
+
|
5
|
+
Enhancements:
|
6
|
+
|
7
|
+
* passes a complete acceptance test suite
|
8
|
+
* detects full and shorthand S3 URLs at all download stages
|
9
|
+
|
10
|
+
Fixes:
|
11
|
+
|
12
|
+
* automatically determines region for shorthand S3 URLs ([#1], [#7])
|
13
|
+
|
1
14
|
## 0.1.0
|
2
15
|
|
3
16
|
**13 June 2014**
|
@@ -23,3 +36,4 @@ Enhancements:
|
|
23
36
|
* initial release
|
24
37
|
|
25
38
|
[#1]: https://github.com/WhoopInc/vagrant-s3auth/issues/1
|
39
|
+
[#7]: https://github.com/WhoopInc/vagrant-s3auth/issues/7
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
We love contributions! Pull request away.
|
4
|
+
|
5
|
+
## Hacking
|
6
|
+
|
7
|
+
You'll need Ruby and Bundler, of course. Then, check out the code and install
|
8
|
+
the gems:
|
9
|
+
|
10
|
+
```bash
|
11
|
+
$ git clone git@github.com:WhoopInc/vagrant-s3auth.git
|
12
|
+
$ cd vagrant-s3auth
|
13
|
+
$ bundle
|
14
|
+
```
|
15
|
+
|
16
|
+
Hack away! When you're ready to test, either [run the test suite](TESTING.md) or
|
17
|
+
run Vagrant manually *using the configured Bundler environment*:
|
18
|
+
|
19
|
+
```bash
|
20
|
+
$ VAGRANT_LOG=debug bundle exec vagrant box add S3_URL
|
21
|
+
```
|
22
|
+
|
23
|
+
If you forget the `bundle exec`, you'll use system Vagrant—not the Vagrant that
|
24
|
+
has your plugin changes installed!
|
25
|
+
|
26
|
+
## Guidelines
|
27
|
+
|
28
|
+
We do ask that all contributions pass the linter and test suite. Travis will
|
29
|
+
automatically run these against your contribution once you submit the pull
|
30
|
+
request, but you can also run them locally as you go!
|
31
|
+
|
32
|
+
### Linting
|
33
|
+
|
34
|
+
```bash
|
35
|
+
$ rake lint
|
36
|
+
```
|
37
|
+
|
38
|
+
### Testing
|
39
|
+
|
40
|
+
See [TESTING](TESTING.md).
|
data/Gemfile
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
gem 'vagrant-s3auth', path: '.'
|
5
|
-
end
|
3
|
+
VAGRANT_REF = ENV['VAGRANT_VERSION'] || 'master'
|
6
4
|
|
7
5
|
group :development do
|
8
|
-
gem '
|
9
|
-
|
10
|
-
|
6
|
+
gem 'vagrant', git: 'git://github.com/mitchellh/vagrant.git', ref: VAGRANT_REF
|
7
|
+
end
|
8
|
+
|
9
|
+
group :plugins do
|
10
|
+
gemspec
|
11
11
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,24 +1,30 @@
|
|
1
1
|
GIT
|
2
2
|
remote: git://github.com/mitchellh/vagrant.git
|
3
|
-
revision:
|
3
|
+
revision: 686e940a8474a8733be40b32e5d9107d557c627b
|
4
|
+
ref: master
|
4
5
|
specs:
|
5
|
-
vagrant (1.
|
6
|
-
bundler (>= 1.5.2, < 1.
|
6
|
+
vagrant (1.7.2.dev)
|
7
|
+
bundler (>= 1.5.2, < 1.8.0)
|
7
8
|
childprocess (~> 0.5.0)
|
8
9
|
erubis (~> 2.7.0)
|
10
|
+
hashicorp-checkpoint (~> 0.1.1)
|
9
11
|
i18n (~> 0.6.0)
|
10
|
-
listen (~> 2.7.
|
12
|
+
listen (~> 2.7.11)
|
11
13
|
log4r (~> 1.1.9, < 1.1.11)
|
12
14
|
net-scp (~> 1.1.0)
|
15
|
+
net-sftp (~> 2.1)
|
13
16
|
net-ssh (>= 2.6.6, < 2.10.0)
|
17
|
+
nokogiri (= 1.6.3.1)
|
14
18
|
rb-kqueue (~> 0.2.0)
|
19
|
+
rest-client (>= 1.6.0, < 2.0)
|
15
20
|
wdm (~> 0.1.0)
|
16
21
|
winrm (~> 1.1.3)
|
17
22
|
|
18
23
|
PATH
|
19
24
|
remote: .
|
20
25
|
specs:
|
21
|
-
vagrant-s3auth (0.
|
26
|
+
vagrant-s3auth (1.0.0.rc1)
|
27
|
+
aws-sdk (~> 1.59.1)
|
22
28
|
|
23
29
|
GEM
|
24
30
|
remote: https://rubygems.org/
|
@@ -27,23 +33,35 @@ GEM
|
|
27
33
|
gyoku (>= 0.4.0)
|
28
34
|
nokogiri
|
29
35
|
ast (2.0.0)
|
36
|
+
astrolabe (1.3.0)
|
37
|
+
parser (>= 2.2.0.pre.3, < 3.0)
|
38
|
+
aws-sdk (1.59.1)
|
39
|
+
aws-sdk-v1 (= 1.59.1)
|
40
|
+
aws-sdk-v1 (1.59.1)
|
41
|
+
json (~> 1.4)
|
42
|
+
nokogiri (>= 1.4.4)
|
30
43
|
builder (3.2.2)
|
31
|
-
celluloid (0.
|
32
|
-
timers (~>
|
33
|
-
childprocess (0.5.
|
44
|
+
celluloid (0.16.0)
|
45
|
+
timers (~> 4.0.0)
|
46
|
+
childprocess (0.5.5)
|
34
47
|
ffi (~> 1.0, >= 1.0.11)
|
35
48
|
erubis (2.7.0)
|
36
|
-
ffi (1.9.
|
49
|
+
ffi (1.9.6)
|
37
50
|
gssapi (1.0.3)
|
38
51
|
ffi (>= 1.0.1)
|
39
|
-
gyoku (1.
|
52
|
+
gyoku (1.2.2)
|
40
53
|
builder (>= 2.1.2)
|
41
|
-
|
54
|
+
hashicorp-checkpoint (0.1.4)
|
55
|
+
hitimes (1.2.2)
|
56
|
+
http (0.6.3)
|
57
|
+
http_parser.rb (~> 0.6.0)
|
58
|
+
http_parser.rb (0.6.0)
|
59
|
+
httpclient (2.5.3.3)
|
42
60
|
httpi (0.9.7)
|
43
61
|
rack
|
44
|
-
i18n (0.6.
|
62
|
+
i18n (0.6.11)
|
45
63
|
json (1.8.1)
|
46
|
-
listen (2.7.
|
64
|
+
listen (2.7.12)
|
47
65
|
celluloid (>= 0.15.2)
|
48
66
|
rb-fsevent (>= 0.9.3)
|
49
67
|
rb-inotify (>= 0.9)
|
@@ -52,15 +70,19 @@ GEM
|
|
52
70
|
logging (1.8.2)
|
53
71
|
little-plugger (>= 1.1.3)
|
54
72
|
multi_json (>= 1.8.4)
|
73
|
+
mime-types (2.4.3)
|
55
74
|
mini_portile (0.6.0)
|
56
75
|
multi_json (1.10.1)
|
57
76
|
net-scp (1.1.2)
|
58
77
|
net-ssh (>= 2.6.5)
|
78
|
+
net-sftp (2.1.2)
|
79
|
+
net-ssh (>= 2.6.5)
|
59
80
|
net-ssh (2.9.1)
|
60
|
-
|
81
|
+
netrc (0.10.1)
|
82
|
+
nokogiri (1.6.3.1)
|
61
83
|
mini_portile (= 0.6.0)
|
62
84
|
nori (1.1.5)
|
63
|
-
parser (2.
|
85
|
+
parser (2.2.0.pre.8)
|
64
86
|
ast (>= 1.1, < 3.0)
|
65
87
|
slop (~> 3.4, >= 3.4.5)
|
66
88
|
powerpack (0.0.9)
|
@@ -72,13 +94,16 @@ GEM
|
|
72
94
|
ffi (>= 0.5.0)
|
73
95
|
rb-kqueue (0.2.3)
|
74
96
|
ffi (>= 0.5.0)
|
75
|
-
|
76
|
-
|
77
|
-
|
97
|
+
rest-client (1.7.2)
|
98
|
+
mime-types (>= 1.16, < 3.0)
|
99
|
+
netrc (~> 0.7)
|
100
|
+
rubocop (0.28.0)
|
101
|
+
astrolabe (~> 1.3)
|
102
|
+
parser (>= 2.2.0.pre.7, < 3.0)
|
78
103
|
powerpack (~> 0.0.6)
|
79
104
|
rainbow (>= 1.99.1, < 3.0)
|
80
105
|
ruby-progressbar (~> 1.4)
|
81
|
-
ruby-progressbar (1.
|
106
|
+
ruby-progressbar (1.7.0)
|
82
107
|
rubyntlm (0.1.1)
|
83
108
|
savon (0.9.5)
|
84
109
|
akami (~> 1.0)
|
@@ -88,9 +113,10 @@ GEM
|
|
88
113
|
nokogiri (>= 1.4.0)
|
89
114
|
nori (~> 1.0)
|
90
115
|
wasabi (~> 1.0)
|
91
|
-
slop (3.
|
92
|
-
timers (
|
93
|
-
|
116
|
+
slop (3.6.0)
|
117
|
+
timers (4.0.1)
|
118
|
+
hitimes
|
119
|
+
uuidtools (2.1.5)
|
94
120
|
wasabi (1.0.0)
|
95
121
|
nokogiri (>= 1.4.0)
|
96
122
|
wdm (0.1.0)
|
@@ -107,7 +133,9 @@ PLATFORMS
|
|
107
133
|
ruby
|
108
134
|
|
109
135
|
DEPENDENCIES
|
136
|
+
bundler (~> 1.5)
|
137
|
+
http (~> 0.6.3)
|
110
138
|
rake (~> 10.3.2)
|
111
|
-
rubocop (~> 0.
|
139
|
+
rubocop (~> 0.28.0)
|
112
140
|
vagrant!
|
113
141
|
vagrant-s3auth!
|
data/README.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# vagrant-s3auth
|
2
2
|
|
3
|
+
<a href="https://travis-ci.org/WhoopInc/vagrant-s3auth">
|
4
|
+
<img src="https://travis-ci.org/WhoopInc/vagrant-s3auth.svg?branch=1.0-cleanup"
|
5
|
+
align="right">
|
6
|
+
</a>
|
7
|
+
|
3
8
|
Private, versioned Vagrant boxes hosted on Amazon S3.
|
4
9
|
|
5
10
|
## Installation
|
@@ -16,23 +21,18 @@ $ vagrant plugin install vagrant-s3auth
|
|
16
21
|
|
17
22
|
## Usage
|
18
23
|
|
19
|
-
vagrant-s3auth will automatically
|
24
|
+
vagrant-s3auth will automatically sign requests for S3 URLs
|
20
25
|
|
21
26
|
```
|
22
27
|
s3://bucket.example.com/path/to/metadata
|
23
28
|
```
|
24
29
|
|
25
|
-
|
26
|
-
|
27
|
-
```
|
28
|
-
https://s3.amazonaws.com/bucket.example.com/path/to/metadata?AWSAccessKeyId=
|
29
|
-
AKIAIOSFODNN7EXAMPLE&Expires=1141889120&Signature=vjbyPxybdZaNmGa%2ByT272YEAiv4%3D
|
30
|
-
```
|
30
|
+
with your AWS access key.
|
31
31
|
|
32
32
|
This means you can host your team's sensitive, private boxes on S3, and use your
|
33
33
|
developers' existing AWS credentials to securely grant access.
|
34
34
|
|
35
|
-
If you've already got your credentials stored in the
|
35
|
+
If you've already got your credentials stored in the standard environment
|
36
36
|
variables:
|
37
37
|
|
38
38
|
```ruby
|
@@ -56,59 +56,80 @@ following at the top of your Vagrantfile:
|
|
56
56
|
|
57
57
|
```ruby
|
58
58
|
creds = File.read(File.expand_path('~/.company-aws-creds')).lines
|
59
|
-
ENV['AWS_ACCESS_KEY_ID'] = creds[0]
|
60
|
-
ENV['AWS_SECRET_ACCESS_KEY'] = creds[1]
|
59
|
+
ENV['AWS_ACCESS_KEY_ID'] = creds[0].chomp
|
60
|
+
ENV['AWS_SECRET_ACCESS_KEY'] = creds[1].chomp
|
61
61
|
```
|
62
62
|
|
63
|
+
#### S3 URLs
|
63
64
|
|
64
|
-
|
65
|
+
Note that your URL must use the path style of specifying the bucket:
|
65
66
|
|
66
|
-
|
67
|
+
```
|
68
|
+
http://s3.amazonaws.com/bucket/resource
|
69
|
+
https://s3.amazonaws.com/bucket/resource
|
70
|
+
```
|
67
71
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
end
|
72
|
+
Or the S3 protocol shorthand
|
73
|
+
|
74
|
+
```
|
75
|
+
s3://bucket/resource
|
73
76
|
```
|
74
77
|
|
75
|
-
|
78
|
+
which expands to the path-style HTTPS URL.
|
79
|
+
|
80
|
+
Virtual host-style S3 URLs, where the bucket is specified in the hostname, are
|
81
|
+
**not detected**!
|
76
82
|
|
77
83
|
```
|
78
|
-
https://s3.amazonaws.com/
|
84
|
+
https://bucket.s3-region.amazonaws.com/resource # ignored
|
79
85
|
```
|
80
86
|
|
81
|
-
|
82
|
-
not be detected by vagrant-s3auth.
|
87
|
+
##### Non-standard regions
|
83
88
|
|
84
|
-
|
85
|
-
|
89
|
+
If your bucket is not hosted in the US Standard region, you'll need to specify
|
90
|
+
the correct region endpoint as part of the URL:
|
91
|
+
|
92
|
+
```
|
93
|
+
https://s3-us-west-2.amazonaws.com/bucket/resource
|
94
|
+
```
|
95
|
+
|
96
|
+
Or just use the S3 protocol shorthand, which will automatically determine the
|
97
|
+
correct region at the cost of an extra API call:
|
98
|
+
|
99
|
+
```
|
100
|
+
s3://bucket/resource
|
101
|
+
```
|
102
|
+
|
103
|
+
For additional details on specifying S3 URLs, refer to the [S3 Developer Guide:
|
104
|
+
Virtual hosting of buckets][bucket-vhost].
|
105
|
+
|
106
|
+
#### Simple boxes
|
107
|
+
|
108
|
+
Simply point your `box_url` at a [supported S3 URL](#s3-url):
|
86
109
|
|
87
110
|
```ruby
|
88
111
|
Vagrant.configure('2') do |config|
|
89
112
|
config.vm.box = 'simple-secrets'
|
90
|
-
config.vm.box_url = 's3
|
113
|
+
config.vm.box_url = 'https://s3.amazonaws.com/bucket.example.com/secret.box'
|
91
114
|
end
|
92
115
|
```
|
93
116
|
|
94
|
-
**Note:** Simple box URLs must end in `.box`, or they'll be interpreted as
|
95
|
-
[metadata boxes](#metadata-boxes).
|
96
|
-
|
97
117
|
#### Vagrant Cloud
|
98
118
|
|
99
|
-
|
100
|
-
|
101
|
-
Cloud.
|
119
|
+
If you've got a box version on [Vagrant Cloud][vagrant-cloud], just point it at
|
120
|
+
a [supported S3 URL](#s3-urls):
|
102
121
|
|
103
|
-
|
122
|
+
![Adding a S3 box to Vagrant Cloud](https://cloud.githubusercontent.com/assets/882976/3273399/d5d70966-f323-11e3-8393-22195050aeac.png)
|
123
|
+
|
124
|
+
Then configure your Vagrantfile like normal:
|
104
125
|
|
105
126
|
```ruby
|
106
127
|
Vagrant.configure('2') do |config|
|
107
|
-
config.vm.box = '
|
128
|
+
config.vm.box = 'benesch/test-box'
|
108
129
|
end
|
109
130
|
```
|
110
131
|
|
111
|
-
#### Metadata boxes
|
132
|
+
#### Metadata (versioned) boxes
|
112
133
|
|
113
134
|
[Metadata boxes][metadata-boxes] were added to Vagrant in 1.5 and power Vagrant
|
114
135
|
Cloud. You can host your own metadata and bypass Vagrant Cloud entirely.
|
@@ -143,27 +164,12 @@ end
|
|
143
164
|
}
|
144
165
|
```
|
145
166
|
|
146
|
-
|
147
|
-
`s3.amazonaws.com/bucket.example.com/resource.box` URL form, or it won't get
|
148
|
-
auto-signed.
|
149
|
-
|
150
|
-
### Rules
|
151
|
-
|
152
|
-
To sum up:
|
153
|
-
|
154
|
-
* Only the `box_url` setting can use the `s3://` shorthand. URLs entered on the
|
155
|
-
Vagrant Cloud management interface and in JSON metadata must use the full
|
156
|
-
HTTPS URL.
|
157
|
-
|
158
|
-
* The full HTTPS URL must be of the form
|
159
|
-
`https://s3.amazonaws.com/bucket.example.com/resource.box`, or it won't be
|
160
|
-
signed properly.
|
161
|
-
|
162
|
-
* Metadata box files must *not* end in `.box`.
|
167
|
+
Within your metadata JSON, be sure to use [supported S3 URLs](#s3-urls).
|
163
168
|
|
164
|
-
|
169
|
+
Note that the metadata itself doesn't need to be hosted on S3. Any metadata that
|
170
|
+
points to a supported S3 URL will result in an authenticated request.
|
165
171
|
|
166
|
-
|
172
|
+
## Auto-install
|
167
173
|
|
168
174
|
The beauty of Vagrant is the magic of "`vagrant up` and done." Making your users
|
169
175
|
install a plugin is lame.
|
@@ -182,7 +188,8 @@ end
|
|
182
188
|
```
|
183
189
|
|
184
190
|
|
185
|
-
[aws-signed]: http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#
|
191
|
+
[aws-signed]: http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#ConstructingTheAuthenticationHeader
|
192
|
+
[bucket-vhost]: http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html#VirtualHostingExamples
|
186
193
|
[metadata-boxes]: http://docs.vagrantup.com/v2/boxes/format.html
|
187
194
|
[vagrant]: http://vagrantup.com
|
188
195
|
[vagrant-cloud]: http://vagrantcloud.com
|
data/Rakefile
CHANGED
data/TESTING.md
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Testing
|
2
|
+
|
3
|
+
No unit testing, since the project is so small. But a full suite of acceptance
|
4
|
+
tests that run using [Bats: Bash Automated Testing System][bats]! Basically, the
|
5
|
+
acceptance tests run `vagrant box add S3_URL` with a bunch of S3 URLs and box
|
6
|
+
types, and assert that everything works!
|
7
|
+
|
8
|
+
See [the .travis.yml CI configuration](.travis.yml) for a working example.
|
9
|
+
|
10
|
+
## Environment variables
|
11
|
+
|
12
|
+
You'll need to export the below. Recommended values included when not sensitive.
|
13
|
+
|
14
|
+
```bash
|
15
|
+
# AWS credentials with permissions to create S3 buckets
|
16
|
+
export AWS_ACCESS_KEY_ID=
|
17
|
+
export AWS_SECRET_ACCESS_KEY=
|
18
|
+
|
19
|
+
# Atlas (Vagrant Cloud) API credentials
|
20
|
+
export ATLAS_USERNAME="vagrant-s3auth"
|
21
|
+
export ATLAS_TOKEN
|
22
|
+
|
23
|
+
# Base name of bucket. Must be unique.
|
24
|
+
export VAGRANT_S3AUTH_BUCKET="testing.vagrant-s3auth.com"
|
25
|
+
|
26
|
+
# If specified as 'metadata', will upload 'box/metadata' and 'box/metadata.box'
|
27
|
+
# to each S3 bucket
|
28
|
+
export VAGRANT_S3AUTH_BOX_BASE="minimal"
|
29
|
+
|
30
|
+
# Base name of Atlas (Vagrant Cloud) box. Atlas boxes can never re-use a once
|
31
|
+
# existing name, so include a timestamp or random string in the name.
|
32
|
+
export VAGRANT_S3AUTH_ATLAS_BOX_NAME="vagrant-s3auth-192458"
|
33
|
+
|
34
|
+
# Additional S3 region to use in testing. US Standard is always used.
|
35
|
+
export VAGRANT_S3AUTH_REGION_NONSTANDARD="eu-west-1"
|
36
|
+
```
|
37
|
+
|
38
|
+
[bats]: https://github.com/sstephenson/bats
|
39
|
+
|
40
|
+
## Running tests
|
41
|
+
|
42
|
+
You'll need [Bats][bats] installed! Then:
|
43
|
+
|
44
|
+
```bash
|
45
|
+
# export env vars as described
|
46
|
+
$ test/setup.rb
|
47
|
+
$ rake test
|
48
|
+
# hack hack hack
|
49
|
+
$ rake test
|
50
|
+
$ test/cleanup.rb
|
51
|
+
```
|
52
|
+
|
53
|
+
## Scripts
|
54
|
+
|
55
|
+
### test/setup.rb
|
56
|
+
|
57
|
+
Creates two S3 buckets—one in US Standard (`us-east-1`) and one in
|
58
|
+
`$VAGRANT_S3AUTH_REGION_NONSTANDARD`, both with the contents of the box
|
59
|
+
directory.
|
60
|
+
|
61
|
+
Then creates an Atlas (Vagrant Cloud) box with one version with one VirtualBox
|
62
|
+
provider that points to one of the S3 boxes at random.
|
63
|
+
|
64
|
+
### test/cleanup.rb
|
65
|
+
|
66
|
+
Destroys S3 buckets and Atlas box.
|
67
|
+
|
68
|
+
## run.bats
|
69
|
+
|
70
|
+
Attempts to `vagrant box add` the boxes on S3 in every way possible.
|
data/lib/vagrant-s3auth.rb
CHANGED
@@ -4,12 +4,11 @@ require 'vagrant-s3auth/plugin'
|
|
4
4
|
|
5
5
|
module VagrantPlugins
|
6
6
|
module S3Auth
|
7
|
-
S3_HOST = 's3.amazonaws.com'
|
8
|
-
S3_HOST_MATCHER = /^s3([[:alnum:]\-\.]+)?\.amazonaws\.com$/
|
9
|
-
BOX_URL_MATCHER = %r{^s3://(?<bucket>[[:alnum:]\-\.]+)(?<resource>.*)/?}
|
10
|
-
|
11
7
|
def self.source_root
|
12
8
|
@source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
13
9
|
end
|
10
|
+
|
11
|
+
I18n.load_path << File.expand_path('locales/en.yml', source_root)
|
12
|
+
I18n.reload!
|
14
13
|
end
|
15
14
|
end
|
@@ -10,6 +10,14 @@ module VagrantPlugins
|
|
10
10
|
class MissingCredentialsError < VagrantS3AuthError
|
11
11
|
error_key(:missing_credentials)
|
12
12
|
end
|
13
|
+
|
14
|
+
class MalformedShorthandURLError < VagrantS3AuthError
|
15
|
+
error_key(:malformed_shorthand_url)
|
16
|
+
end
|
17
|
+
|
18
|
+
class S3APIError < VagrantS3AuthError
|
19
|
+
error_key(:s3_api_error)
|
20
|
+
end
|
13
21
|
end
|
14
22
|
end
|
15
23
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'uri'
|
2
2
|
|
3
3
|
require 'vagrant/util/downloader'
|
4
|
-
require 'vagrant-s3auth/util
|
4
|
+
require 'vagrant-s3auth/util'
|
5
5
|
|
6
6
|
module Vagrant
|
7
7
|
module Util
|
@@ -13,22 +13,24 @@ module Vagrant
|
|
13
13
|
@logger.info("s3auth: Ignoring unparsable URL: #{url}")
|
14
14
|
end
|
15
15
|
|
16
|
-
if url &&
|
17
|
-
@logger.info("s3auth:
|
16
|
+
if url && (s3_object = VagrantPlugins::S3Auth::Util.s3_object_for(url))
|
17
|
+
@logger.info("s3auth: Discovered S3 URL: #{url}")
|
18
|
+
@logger.debug("s3auth: Bucket: #{s3_object.bucket.name.inspect}")
|
19
|
+
@logger.debug("s3auth: Key: #{s3_object.key.inspect}")
|
18
20
|
|
19
|
-
method = options.any? { |o| o == '-I' } ?
|
20
|
-
headers = VagrantPlugins::S3Auth::Util::Authenticator.sign(url, method)
|
21
|
+
method = options.any? { |o| o == '-I' } ? :head : :get
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
@logger.info("s3auth: Generating signed URL for #{method.upcase}")
|
24
|
+
|
25
|
+
options.pop
|
26
|
+
options << VagrantPlugins::S3Auth::Util.s3_url_for(method, s3_object).to_s
|
25
27
|
end
|
26
28
|
|
27
29
|
execute_curl_without_s3(options, subprocess_options, &data_proc)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
rescue AWS::Errors::MissingCredentialsError
|
31
|
+
raise VagrantPlugins::S3Auth::Errors::MissingCredentialsError
|
32
|
+
rescue AWS::Errors::Base => e
|
33
|
+
raise VagrantPlugins::S3Auth::Errors::S3APIError, error: e
|
32
34
|
end
|
33
35
|
|
34
36
|
alias_method :execute_curl_without_s3, :execute_curl
|
@@ -19,11 +19,6 @@ module VagrantPlugins
|
|
19
19
|
description <<-DESC
|
20
20
|
Use versioned Vagrant boxes with S3 authentication.
|
21
21
|
DESC
|
22
|
-
|
23
|
-
def self.setup_i18n
|
24
|
-
I18n.load_path << File.expand_path('locales/en.yml', VagrantPlugins::S3Auth.source_root)
|
25
|
-
I18n.reload!
|
26
|
-
end
|
27
22
|
end
|
28
23
|
end
|
29
24
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'aws'
|
2
|
+
require 'log4r'
|
3
|
+
require 'net/http'
|
4
|
+
require 'uri'
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module S3Auth
|
8
|
+
module Util
|
9
|
+
S3_HOST_MATCHER = /^s3([[:alnum:]\-\.]+)?\.amazonaws\.com$/
|
10
|
+
|
11
|
+
LOCATION_TO_REGION = Hash.new { |_, key| key }.merge(
|
12
|
+
nil => 'us-east-1',
|
13
|
+
'EU' => 'eu-west-1'
|
14
|
+
)
|
15
|
+
|
16
|
+
def self.s3_object_for(url, follow_redirect = true)
|
17
|
+
url = URI(url)
|
18
|
+
|
19
|
+
if url.scheme == 's3'
|
20
|
+
bucket = url.host
|
21
|
+
key = url.path[1..-1]
|
22
|
+
raise Errors::MalformedShorthandURLError, url: url unless bucket && key
|
23
|
+
elsif url.host =~ S3_HOST_MATCHER
|
24
|
+
components = url.path.split('/').delete_if(&:empty?)
|
25
|
+
bucket = components.shift
|
26
|
+
key = components.join('/')
|
27
|
+
end
|
28
|
+
|
29
|
+
if bucket && key
|
30
|
+
AWS::S3.new(region: get_bucket_region(bucket))
|
31
|
+
.buckets[bucket].objects[key]
|
32
|
+
elsif follow_redirect
|
33
|
+
response = Net::HTTP.get_response(url) rescue nil
|
34
|
+
if response.is_a?(Net::HTTPRedirection)
|
35
|
+
s3_object_for(response['location'], false)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.s3_url_for(method, s3_object)
|
41
|
+
s3_object.url_for(method,
|
42
|
+
expires: 10,
|
43
|
+
signature_version: :v4,
|
44
|
+
force_path_style: true)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.get_bucket_region(bucket)
|
48
|
+
LOCATION_TO_REGION[AWS::S3.new.buckets[bucket].location_constraint]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/locales/en.yml
CHANGED
@@ -7,4 +7,17 @@ en:
|
|
7
7
|
Ensure the following variables are set in your environment, or set
|
8
8
|
them at the top of your Vagrantfile:
|
9
9
|
|
10
|
-
|
10
|
+
AWS_ACCESS_KEY_ID
|
11
|
+
AWS_SECRET_ACCESS_KEY
|
12
|
+
|
13
|
+
malformed_shorthand_url: |-
|
14
|
+
Malformed shorthand S3 box URL:
|
15
|
+
|
16
|
+
%{url}
|
17
|
+
|
18
|
+
Check your `box_url` setting.
|
19
|
+
|
20
|
+
s3_api_error: |-
|
21
|
+
Unable to communicate with Amazon S3 to download box. The S3 API reports:
|
22
|
+
|
23
|
+
%{error}
|
data/test/box/minimal
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
{
|
2
|
+
"name": "vagrant-s3auth/minimal",
|
3
|
+
"description": "This box contains company secrets.",
|
4
|
+
"versions": [{
|
5
|
+
"version": "1.0.1",
|
6
|
+
"providers": [{
|
7
|
+
"name": "virtualbox",
|
8
|
+
"url": "%{box_url}",
|
9
|
+
"checksum_type": "sha1",
|
10
|
+
"checksum": "8ea536dd3092cf159f02405edd44ded5b62ba4e6"
|
11
|
+
}]
|
12
|
+
}]
|
13
|
+
}
|
Binary file
|
data/test/cleanup.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'aws'
|
5
|
+
|
6
|
+
require_relative 'support'
|
7
|
+
|
8
|
+
[REGION_STANDARD, REGION_NONSTANDARD].each do |region|
|
9
|
+
s3 = AWS::S3.new(region: region)
|
10
|
+
bucket = s3.buckets["#{region}.#{BUCKET}"]
|
11
|
+
bucket.delete! if bucket.exists?
|
12
|
+
end
|
13
|
+
|
14
|
+
atlas = Atlas.new(ATLAS_TOKEN, ATLAS_USERNAME)
|
15
|
+
atlas.delete_box(ATLAS_BOX_NAME)
|
data/test/run.bats
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
#!/usr/bin/env bats
|
2
|
+
|
3
|
+
missing_vars=()
|
4
|
+
|
5
|
+
require_var() {
|
6
|
+
[[ "${!1}" ]] || missing_vars+=("$1")
|
7
|
+
}
|
8
|
+
|
9
|
+
require_var AWS_ACCESS_KEY_ID
|
10
|
+
require_var AWS_SECRET_ACCESS_KEY
|
11
|
+
require_var ATLAS_TOKEN
|
12
|
+
require_var ATLAS_USERNAME
|
13
|
+
require_var VAGRANT_S3AUTH_BUCKET
|
14
|
+
require_var VAGRANT_S3AUTH_BOX_BASE
|
15
|
+
require_var VAGRANT_S3AUTH_ATLAS_BOX_NAME
|
16
|
+
require_var VAGRANT_S3AUTH_REGION_NONSTANDARD
|
17
|
+
|
18
|
+
if [[ ${#missing_vars[*]} -gt 0 ]]; then
|
19
|
+
echo "Missing required environment variables:"
|
20
|
+
printf ' %s\n' "${missing_vars[@]}"
|
21
|
+
exit 1
|
22
|
+
fi
|
23
|
+
|
24
|
+
teardown() {
|
25
|
+
bundle exec vagrant box remove "$VAGRANT_S3AUTH_BOX_BASE" > /dev/null 2>&1 || true
|
26
|
+
bundle exec vagrant box remove "vagrant-s3auth/$VAGRANT_S3AUTH_BOX_BASE" > /dev/null 2>&1 || true
|
27
|
+
bundle exec vagrant box remove "$ATLAS_USERNAME/$VAGRANT_S3AUTH_ATLAS_BOX_NAME" > /dev/null 2>&1 || true
|
28
|
+
}
|
29
|
+
|
30
|
+
@test "vagrant cloud" {
|
31
|
+
bundle exec vagrant box add "$ATLAS_USERNAME/$VAGRANT_S3AUTH_ATLAS_BOX_NAME"
|
32
|
+
}
|
33
|
+
|
34
|
+
@test "simple box with full standard url" {
|
35
|
+
bundle exec vagrant box add \
|
36
|
+
--name "$VAGRANT_S3AUTH_BOX_BASE" \
|
37
|
+
"https://s3.amazonaws.com/us-east-1.$VAGRANT_S3AUTH_BUCKET/$VAGRANT_S3AUTH_BOX_BASE.box"
|
38
|
+
}
|
39
|
+
|
40
|
+
@test "simple box with shorthand standard url" {
|
41
|
+
bundle exec vagrant box add \
|
42
|
+
--name "$VAGRANT_S3AUTH_BOX_BASE" \
|
43
|
+
"s3://us-east-1.$VAGRANT_S3AUTH_BUCKET/$VAGRANT_S3AUTH_BOX_BASE.box"
|
44
|
+
}
|
45
|
+
|
46
|
+
@test "simple box with full nonstandard url" {
|
47
|
+
bundle exec vagrant box add \
|
48
|
+
--name "$VAGRANT_S3AUTH_BOX_BASE" \
|
49
|
+
"https://s3-$VAGRANT_S3AUTH_REGION_NONSTANDARD.amazonaws.com/$VAGRANT_S3AUTH_REGION_NONSTANDARD.$VAGRANT_S3AUTH_BUCKET/$VAGRANT_S3AUTH_BOX_BASE.box"
|
50
|
+
}
|
51
|
+
|
52
|
+
@test "simple box with shorthand nonstandard url" {
|
53
|
+
bundle exec vagrant box add \
|
54
|
+
--name "$VAGRANT_S3AUTH_BOX_BASE" \
|
55
|
+
"s3://$VAGRANT_S3AUTH_REGION_NONSTANDARD.$VAGRANT_S3AUTH_BUCKET/$VAGRANT_S3AUTH_BOX_BASE.box"
|
56
|
+
}
|
57
|
+
|
58
|
+
@test "metadata box with full standard url" {
|
59
|
+
bundle exec vagrant box add \
|
60
|
+
--name "vagrant-s3auth/$VAGRANT_S3AUTH_BOX_BASE" \
|
61
|
+
"https://s3.amazonaws.com/us-east-1.$VAGRANT_S3AUTH_BUCKET/$VAGRANT_S3AUTH_BOX_BASE"
|
62
|
+
}
|
63
|
+
|
64
|
+
@test "metadata box with shorthand standard url" {
|
65
|
+
bundle exec vagrant box add \
|
66
|
+
--name "vagrant-s3auth/$VAGRANT_S3AUTH_BOX_BASE" \
|
67
|
+
"s3://us-east-1.$VAGRANT_S3AUTH_BUCKET/$VAGRANT_S3AUTH_BOX_BASE"
|
68
|
+
}
|
69
|
+
|
70
|
+
@test "metadata box with full nonstandard url" {
|
71
|
+
bundle exec vagrant box add \
|
72
|
+
--name "vagrant-s3auth/$VAGRANT_S3AUTH_BOX_BASE" \
|
73
|
+
"https://s3-$VAGRANT_S3AUTH_REGION_NONSTANDARD.amazonaws.com/$VAGRANT_S3AUTH_REGION_NONSTANDARD.$VAGRANT_S3AUTH_BUCKET/$VAGRANT_S3AUTH_BOX_BASE"
|
74
|
+
}
|
75
|
+
|
76
|
+
@test "metadata box with shorthand nonstandard url" {
|
77
|
+
bundle exec vagrant box add \
|
78
|
+
--name "vagrant-s3auth/$VAGRANT_S3AUTH_BOX_BASE" \
|
79
|
+
"s3://$VAGRANT_S3AUTH_REGION_NONSTANDARD.$VAGRANT_S3AUTH_BUCKET/$VAGRANT_S3AUTH_BOX_BASE"
|
80
|
+
}
|
81
|
+
|
82
|
+
@test "garbage shorthand url" {
|
83
|
+
run bundle exec vagrant box add --name "$VAGRANT_S3AUTH_BOX_BASE" s3://smoogedydoop
|
84
|
+
[[ "$status" -eq 1 ]]
|
85
|
+
[[ "$output" == *"Malformed shorthand S3 box URL"* ]]
|
86
|
+
}
|
87
|
+
|
88
|
+
@test "garbage full url" {
|
89
|
+
run bundle exec vagrant box add --name "$VAGRANT_S3AUTH_BOX_BASE" https://smoogedydoop
|
90
|
+
[[ "$status" -eq 1 ]]
|
91
|
+
echo "$output"
|
92
|
+
[[ "$output" == *"error occurred while downloading the remote file"* ]]
|
93
|
+
}
|
data/test/setup.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'aws'
|
5
|
+
|
6
|
+
require_relative 'support'
|
7
|
+
|
8
|
+
ROOT = Pathname.new(File.dirname(__FILE__))
|
9
|
+
|
10
|
+
box_urls = [REGION_STANDARD, REGION_NONSTANDARD].map do |region|
|
11
|
+
s3 = AWS::S3.new(region: region)
|
12
|
+
bucket = s3.buckets.create("#{region}.#{BUCKET}")
|
13
|
+
|
14
|
+
box = bucket.objects["#{BOX_BASE}.box"]
|
15
|
+
box.write(ROOT + Pathname.new("box/#{BOX_BASE}.box"))
|
16
|
+
box.public_url
|
17
|
+
|
18
|
+
metadata_string = File.read(ROOT + Pathname.new("box/#{BOX_BASE}")) % {
|
19
|
+
box_url: box.public_url
|
20
|
+
}
|
21
|
+
|
22
|
+
metadata = bucket.objects[BOX_BASE]
|
23
|
+
metadata.write(metadata_string, content_type: 'application/json')
|
24
|
+
metadata.acl = :public_read
|
25
|
+
|
26
|
+
box.public_url
|
27
|
+
end
|
28
|
+
|
29
|
+
atlas = Atlas.new(ATLAS_TOKEN, ATLAS_USERNAME)
|
30
|
+
atlas.create_box(ATLAS_BOX_NAME)
|
31
|
+
atlas.create_version(ATLAS_BOX_NAME, '1.0.1')
|
32
|
+
atlas.create_provider(ATLAS_BOX_NAME, '1.0.1', box_urls.sample)
|
33
|
+
atlas.release_version(ATLAS_BOX_NAME, '1.0.1')
|
data/test/support.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'http'
|
2
|
+
|
3
|
+
BOX_BASE = ENV['VAGRANT_S3AUTH_BOX_BASE']
|
4
|
+
BUCKET = ENV['VAGRANT_S3AUTH_BUCKET']
|
5
|
+
REGION_STANDARD = 'us-east-1'
|
6
|
+
REGION_NONSTANDARD = ENV['VAGRANT_S3AUTH_REGION_NONSTANDARD']
|
7
|
+
|
8
|
+
ATLAS_TOKEN = ENV['ATLAS_TOKEN']
|
9
|
+
ATLAS_USERNAME = ENV['ATLAS_USERNAME']
|
10
|
+
ATLAS_BOX_NAME = ENV['VAGRANT_S3AUTH_ATLAS_BOX_NAME']
|
11
|
+
|
12
|
+
class Atlas
|
13
|
+
BASE_URL = 'https://atlas.hashicorp.com/api/v1'
|
14
|
+
|
15
|
+
BOX_CREATE_URL = "#{BASE_URL}/boxes"
|
16
|
+
BOX_RESOURCE_URL = "#{BASE_URL}/box/%{username}/%{box_name}"
|
17
|
+
|
18
|
+
VERSION_CREATE_URL = "#{BOX_RESOURCE_URL}/versions"
|
19
|
+
VERSION_RESOURCE_URL = "#{BOX_RESOURCE_URL}/version/%{version}"
|
20
|
+
VERSION_RELEASE_URL = "#{VERSION_RESOURCE_URL}/release"
|
21
|
+
|
22
|
+
PROVIDER_CREATE_URL = "#{VERSION_RESOURCE_URL}/providers"
|
23
|
+
PROVIDER_RESOURCE_URL = "#{VERSION_RESOURCE_URL}/provider/%{provider_name}"
|
24
|
+
|
25
|
+
attr_accessor :provider
|
26
|
+
|
27
|
+
def initialize(token, username)
|
28
|
+
raise if !token || token.empty?
|
29
|
+
raise if !username || username.empty?
|
30
|
+
|
31
|
+
@token = token
|
32
|
+
@username = username
|
33
|
+
@provider = 'virtualbox'
|
34
|
+
end
|
35
|
+
|
36
|
+
def create_box(box_name)
|
37
|
+
post(BOX_CREATE_URL, data: { box: { name: box_name, is_private: false } })
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete_box(box_name)
|
41
|
+
url_params = { box_name: box_name }
|
42
|
+
delete(BOX_RESOURCE_URL, url_params: url_params)
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_version(box_name, version)
|
46
|
+
post(VERSION_CREATE_URL,
|
47
|
+
data: { version: { version: version } },
|
48
|
+
url_params: { box_name: box_name })
|
49
|
+
end
|
50
|
+
|
51
|
+
def release_version(box_name, version)
|
52
|
+
put(VERSION_RELEASE_URL,
|
53
|
+
url_params: { box_name: box_name, version: version })
|
54
|
+
end
|
55
|
+
|
56
|
+
def create_provider(box_name, version, url)
|
57
|
+
post(PROVIDER_CREATE_URL,
|
58
|
+
data: { provider: { name: @provider, url: url } },
|
59
|
+
url_params: { box_name: box_name, version: version })
|
60
|
+
end
|
61
|
+
|
62
|
+
def request(method, url, options)
|
63
|
+
url_params = (options[:url_params] || {}).merge(username: @username)
|
64
|
+
data = (options[:data] || {}).merge(access_token: @token)
|
65
|
+
|
66
|
+
response = HTTP.request(method, url % url_params, json: data)
|
67
|
+
raise response unless response.code >= 200 && response.code < 400
|
68
|
+
end
|
69
|
+
|
70
|
+
def post(url, options)
|
71
|
+
request(:post, url, options)
|
72
|
+
end
|
73
|
+
|
74
|
+
def put(url, options)
|
75
|
+
request(:put, url, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
def delete(url, options)
|
79
|
+
request(:delete, url, options)
|
80
|
+
end
|
81
|
+
end
|
data/vagrant-s3auth.gemspec
CHANGED
@@ -15,6 +15,10 @@ Gem::Specification.new do |spec|
|
|
15
15
|
spec.test_files = spec.files.grep(/spec/)
|
16
16
|
spec.require_paths = ['lib']
|
17
17
|
|
18
|
+
spec.add_dependency 'aws-sdk', '~> 1.59.1'
|
19
|
+
|
18
20
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
19
|
-
spec.add_development_dependency '
|
21
|
+
spec.add_development_dependency 'http', '~> 0.6.3'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.3.2'
|
23
|
+
spec.add_development_dependency 'rubocop', '~> 0.28.0'
|
20
24
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-s3auth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikhil Benesch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: aws-sdk
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.59.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.59.1
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,20 +38,48 @@ dependencies:
|
|
24
38
|
- - ~>
|
25
39
|
- !ruby/object:Gem::Version
|
26
40
|
version: '1.5'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: http
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.6.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.6.3
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: rake
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
|
-
- -
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 10.3.2
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 10.3.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
32
74
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
75
|
+
version: 0.28.0
|
34
76
|
type: :development
|
35
77
|
prerelease: false
|
36
78
|
version_requirements: !ruby/object:Gem::Requirement
|
37
79
|
requirements:
|
38
|
-
- -
|
80
|
+
- - ~>
|
39
81
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
82
|
+
version: 0.28.0
|
41
83
|
description:
|
42
84
|
email:
|
43
85
|
- benesch@whoop.com
|
@@ -47,21 +89,30 @@ extra_rdoc_files: []
|
|
47
89
|
files:
|
48
90
|
- .gitignore
|
49
91
|
- .rubocop.yml
|
92
|
+
- .ruby-version
|
93
|
+
- .travis.yml
|
50
94
|
- CHANGELOG.md
|
95
|
+
- CONTRIBUTING.md
|
51
96
|
- Gemfile
|
52
97
|
- Gemfile.lock
|
53
98
|
- LICENSE
|
54
99
|
- README.md
|
55
100
|
- Rakefile
|
101
|
+
- TESTING.md
|
56
102
|
- lib/vagrant-s3auth.rb
|
57
103
|
- lib/vagrant-s3auth/errors.rb
|
58
104
|
- lib/vagrant-s3auth/extensions.rb
|
59
|
-
- lib/vagrant-s3auth/extensions/box_add.rb
|
60
105
|
- lib/vagrant-s3auth/extensions/downloader.rb
|
61
106
|
- lib/vagrant-s3auth/plugin.rb
|
62
|
-
- lib/vagrant-s3auth/util
|
107
|
+
- lib/vagrant-s3auth/util.rb
|
63
108
|
- lib/vagrant-s3auth/version.rb
|
64
109
|
- locales/en.yml
|
110
|
+
- test/box/minimal
|
111
|
+
- test/box/minimal.box
|
112
|
+
- test/cleanup.rb
|
113
|
+
- test/run.bats
|
114
|
+
- test/setup.rb
|
115
|
+
- test/support.rb
|
65
116
|
- vagrant-s3auth.gemspec
|
66
117
|
homepage: https://github.com/WhoopInc/vagrant-s3auth
|
67
118
|
licenses:
|
@@ -78,9 +129,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
129
|
version: '0'
|
79
130
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
131
|
requirements:
|
81
|
-
- - '
|
132
|
+
- - '>'
|
82
133
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
134
|
+
version: 1.3.1
|
84
135
|
requirements: []
|
85
136
|
rubyforge_project:
|
86
137
|
rubygems_version: 2.0.14
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'uri'
|
2
|
-
|
3
|
-
module Vagrant
|
4
|
-
module Action
|
5
|
-
module Builtin
|
6
|
-
class BoxAdd
|
7
|
-
def call_with_s3(env)
|
8
|
-
box_url = env[:box_url]
|
9
|
-
|
10
|
-
# Non-iterable box_urls are Vagrant Cloud boxes, which we don't need
|
11
|
-
# to handle.
|
12
|
-
if box_url.respond_to?(:map!)
|
13
|
-
box_url.map! do |url|
|
14
|
-
if matched = VagrantPlugins::S3Auth::BOX_URL_MATCHER.match(url)
|
15
|
-
@logger.info('Transforming S3 box URL: #{url}')
|
16
|
-
s3_url(matched[:bucket], matched[:resource])
|
17
|
-
else
|
18
|
-
@logger.info("Not transforming non-S3 box: #{url}")
|
19
|
-
url
|
20
|
-
end
|
21
|
-
end
|
22
|
-
else
|
23
|
-
@logger.debug('Box URL #{box_url.inspect} looks like a Vagrant "
|
24
|
-
Cloud box, skipping S3 transformation...')
|
25
|
-
end
|
26
|
-
|
27
|
-
call_without_s3(env)
|
28
|
-
end
|
29
|
-
|
30
|
-
def s3_url(bucket, resource)
|
31
|
-
URI::HTTPS.build(
|
32
|
-
host: VagrantPlugins::S3Auth::S3_HOST,
|
33
|
-
path: File.join('/', bucket, resource)).to_s
|
34
|
-
end
|
35
|
-
|
36
|
-
alias_method :call_without_s3, :call
|
37
|
-
alias_method :call, :call_with_s3
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'base64'
|
2
|
-
require 'cgi'
|
3
|
-
require 'log4r'
|
4
|
-
require 'openssl'
|
5
|
-
require 'uri'
|
6
|
-
|
7
|
-
require 'vagrant/util/downloader'
|
8
|
-
|
9
|
-
module VagrantPlugins
|
10
|
-
module S3Auth
|
11
|
-
module Util
|
12
|
-
class Authenticator
|
13
|
-
def self.sign(url, method)
|
14
|
-
new.sign(url, method)
|
15
|
-
end
|
16
|
-
|
17
|
-
def initialize
|
18
|
-
@access_key = ENV['AWS_ACCESS_KEY_ID']
|
19
|
-
@secret_key = ENV['AWS_SECRET_ACCESS_KEY']
|
20
|
-
|
21
|
-
ensure_credentials
|
22
|
-
end
|
23
|
-
|
24
|
-
def sign(url, method)
|
25
|
-
now = CGI.rfc1123_date(Time.now)
|
26
|
-
message = "#{method}\n\n\n#{now}\n#{url.path}"
|
27
|
-
signature = Base64.strict_encode64(
|
28
|
-
OpenSSL::HMAC.digest('sha1', @secret_key, message))
|
29
|
-
|
30
|
-
{
|
31
|
-
date: now,
|
32
|
-
authorization: "AWS #{@access_key}:#{signature}"
|
33
|
-
}
|
34
|
-
end
|
35
|
-
|
36
|
-
protected
|
37
|
-
|
38
|
-
def ensure_credentials
|
39
|
-
missing_variables = []
|
40
|
-
missing_variables << 'AWS_ACCESS_KEY_ID' unless @access_key
|
41
|
-
missing_variables << 'AWS_SECRET_ACCESS_KEY' unless @secret_key
|
42
|
-
|
43
|
-
# rubocop:disable Style/GuardClause
|
44
|
-
unless missing_variables.empty?
|
45
|
-
raise Errors::MissingCredentialsError,
|
46
|
-
missing_variables: missing_variables.join(', ')
|
47
|
-
end
|
48
|
-
# rubocop:enable Style/GuardClause
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|