vagrant-s3auth 0.1.0 → 1.0.0.rc1
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.
- 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
|
+

|
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
|