vagrant-chassis-digitalocean 1.0.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/Gemfile +6 -1
- data/README.md +95 -11
- data/lib/vagrant-chassis-digitalocean/actions/create.rb +16 -20
- data/lib/vagrant-chassis-digitalocean/actions/destroy.rb +1 -6
- data/lib/vagrant-chassis-digitalocean/actions/power_off.rb +6 -4
- data/lib/vagrant-chassis-digitalocean/actions/power_on.rb +4 -2
- data/lib/vagrant-chassis-digitalocean/actions/rebuild.rb +6 -5
- data/lib/vagrant-chassis-digitalocean/actions/reload.rb +4 -2
- data/lib/vagrant-chassis-digitalocean/actions/setup_key.rb +4 -4
- data/lib/vagrant-chassis-digitalocean/actions/setup_user.rb +1 -1
- data/lib/vagrant-chassis-digitalocean/actions/sync_folders.rb +12 -21
- data/lib/vagrant-chassis-digitalocean/config.rb +14 -12
- data/lib/vagrant-chassis-digitalocean/helpers/client.rb +42 -25
- data/lib/vagrant-chassis-digitalocean/helpers/result.rb +4 -4
- data/lib/vagrant-chassis-digitalocean/provider.rb +5 -3
- data/lib/vagrant-chassis-digitalocean/version.rb +1 -1
- data/locales/en.yml +2 -2
- data/test/Vagrantfile +4 -5
- data/test/test.sh +8 -8
- metadata +2 -2
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.
|
3
|
+
gem 'vagrant', :git => 'git://github.com/mitchellh/vagrant.git', :tag => 'v1.6.3'
|
4
4
|
gem 'vagrant-omnibus'
|
5
5
|
gem 'rake'
|
6
|
+
|
7
|
+
group :plugins do
|
8
|
+
gem 'vagrant-digitalocean', :path => '.'
|
9
|
+
end
|
10
|
+
|
6
11
|
gemspec
|
data/README.md
CHANGED
@@ -4,19 +4,19 @@ Digital Ocean Vagrant Provider For Chassis
|
|
4
4
|
management of [Digital Ocean](https://www.digitalocean.com/) droplets
|
5
5
|
(instances) that setup WordPress using [Chassis](https://github.com/Chassis/Chassis/).
|
6
6
|
|
7
|
-
**NOTE:**
|
8
|
-
|
7
|
+
**NOTE:** The Chef provisioner is no longer supported by default (as of 0.2.0).
|
8
|
+
Please use the `vagrant-omnibus` plugin to install Chef on Vagrant-managed
|
9
|
+
machines. This plugin provides control over the specific version of Chef
|
10
|
+
to install.
|
9
11
|
|
10
12
|
Current features include:
|
11
13
|
- create and destroy droplets
|
12
14
|
- power on and off droplets
|
13
15
|
- rebuild a droplet
|
16
|
+
- provision a droplet with the shell or Chef provisioners
|
14
17
|
- setup a SSH public key for authentication
|
15
18
|
- create a new user account during droplet creation
|
16
19
|
|
17
|
-
The provider has been tested with Vagrant 1.1.5+ using Ubuntu 12.04 and
|
18
|
-
CentOS 6.3 guest operating systems.
|
19
|
-
|
20
20
|
Install
|
21
21
|
-------
|
22
22
|
Installation of the provider requires two steps:
|
@@ -37,7 +37,7 @@ Once the bundle is installed, add the following environment variable to your
|
|
37
37
|
`.bash_profile` script and `source` it:
|
38
38
|
|
39
39
|
```bash
|
40
|
-
export SSL_CERT_FILE=/usr/local/
|
40
|
+
export SSL_CERT_FILE=/usr/local/etc/openssl/cert.pem
|
41
41
|
```
|
42
42
|
|
43
43
|
Configure
|
@@ -46,13 +46,97 @@ Once the provider has been installed, you will need to configure your [Chassis](
|
|
46
46
|
to use it. You can use your we recommend adding your Digital Ocean details in your projects `config.yaml` or `config.local.yaml` file:
|
47
47
|
```bash
|
48
48
|
digitalocean:
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
49
|
+
token: 'YOUR TOKEN'
|
50
|
+
region: 'sgp1'
|
51
|
+
size: '512mbB'
|
52
|
+
image: 'Ubuntu 14.04 x64'
|
53
|
+
```
|
54
|
+
|
55
|
+
You must also add the following to your project `VagrantFile`
|
56
|
+
```
|
57
|
+
config.vm.provider :chassis_digitalocean do |provider, override|
|
58
|
+
override.ssh.private_key_path = '~/.ssh/id_rsa'
|
59
|
+
override.vm.box_url = 'https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digitalocean.box'
|
60
|
+
|
61
|
+
provider.token = CONF['digitalocean']['token']
|
62
|
+
provider.image = CONF['digitalocean']['image']
|
63
|
+
provider.region = CONF['digitalocean']['region']
|
64
|
+
provider.size = CONF['digitalocean']['size']
|
65
|
+
|
66
|
+
end
|
54
67
|
```
|
55
68
|
|
69
|
+
**Optionally,** you can remove exclude your .git folder from the rsync by including the following line after you've specified your
|
70
|
+
`config.vm.synced_folder`
|
71
|
+
|
72
|
+
```
|
73
|
+
rsync__exclude: ".git/"
|
74
|
+
```
|
75
|
+
|
76
|
+
Please note the following:
|
77
|
+
- You *must* specify the `override.ssh.private_key_path` to enable authentication
|
78
|
+
with the droplet. The provider will create a new Digital Ocean SSH key using
|
79
|
+
your public key which is assumed to be the `private_key_path` with a *.pub*
|
80
|
+
extension.
|
81
|
+
- You *must* specify your Digital Ocean Personal Access Token. This may be
|
82
|
+
found on the control panel within the *Apps & API* section.
|
83
|
+
|
84
|
+
**Supported Configuration Attributes**
|
85
|
+
|
86
|
+
The following attributes are available to further configure the provider:
|
87
|
+
- `provider.image` - A string representing the image to use when creating a
|
88
|
+
new droplet (e.g. `Debian 6.0 x64`). The available options may
|
89
|
+
be found on Digital Ocean's new droplet [form](https://cloud.digitalocean.com/droplets/new).
|
90
|
+
It defaults to `Ubuntu 14.04 x64`.
|
91
|
+
- `provider.ipv6` - A boolean flag indicating whether to enable IPv6
|
92
|
+
- `provider.region` - A string representing the region to create the new
|
93
|
+
droplet in. It defaults to `nyc2`.
|
94
|
+
- `provider.size` - A string representing the size to use when creating a
|
95
|
+
new droplet (e.g. `1gb`). It defaults to `512mb`.
|
96
|
+
- `provider.private_networking` - A boolean flag indicating whether to enable
|
97
|
+
a private network interface (if the region supports private networking). It
|
98
|
+
defaults to `false`.
|
99
|
+
- `provider.backups_enabled` - A boolean flag indicating whether to enable backups for
|
100
|
+
the droplet. It defaults to `false`.
|
101
|
+
- `provider.ssh_key_name` - A string representing the name to use when creating
|
102
|
+
a Digital Ocean SSH key for droplet authentication. It defaults to `Vagrant`.
|
103
|
+
- `provider.setup` - A boolean flag indicating whether to setup a new user
|
104
|
+
account and modify sudo to disable tty requirement. It defaults to `true`.
|
105
|
+
If you are using a tool like [packer](https://packer.io) to create
|
106
|
+
reusable snapshots with user accounts already provisioned, set to `false`.
|
107
|
+
|
108
|
+
The provider will create a new user account with the specified SSH key for
|
109
|
+
authorization if `config.ssh.username` is set and the `provider.setup`
|
110
|
+
attribute is `true`.
|
111
|
+
|
112
|
+
### provider.region slug
|
113
|
+
|
114
|
+
Each region has been specify with slug name.
|
115
|
+
Current Region-slug table is:
|
116
|
+
|
117
|
+
| slug | Region Name |
|
118
|
+
|:---- |:----------------|
|
119
|
+
| nyc1 | New York 1 |
|
120
|
+
| ams1 | Amsterdam 1 |
|
121
|
+
| sfo1 | San Francisco 1 |
|
122
|
+
| nyc2 | New York 2 |
|
123
|
+
| ams2 | Amsterdam 2 |
|
124
|
+
| sgp1 | Singapore 1 |
|
125
|
+
| lon1 | London 1 |
|
126
|
+
| nyc3 | New York 3 |
|
127
|
+
|
128
|
+
You can find latest region slug name using DigitalOcean API V2 call.
|
129
|
+
|
130
|
+
- example call.
|
131
|
+
|
132
|
+
```
|
133
|
+
curl -X GET "https://api.digitalocean.com/v2/regions" \
|
134
|
+
-H "Authorization: Bearer $DIGITAL_OCEAN_TOKEN" \
|
135
|
+
2>/dev/null | jq '.regions [] | .slug,.name'
|
136
|
+
```
|
137
|
+
|
138
|
+
More detail: [DigitalOcean API - Regions](https://developers.digitalocean.com/#regions)
|
139
|
+
|
56
140
|
Run
|
57
141
|
---
|
58
142
|
After creating your project's `Vagrantfile` with the required configuration
|
@@ -15,46 +15,42 @@ module VagrantPlugins
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def call(env)
|
18
|
-
ssh_key_id = env[:ssh_key_id]
|
19
|
-
|
20
|
-
size_id = @client
|
21
|
-
.request('/sizes')
|
22
|
-
.find_id(:sizes, :name => @machine.provider_config.size)
|
18
|
+
ssh_key_id = [env[:ssh_key_id]]
|
23
19
|
|
24
20
|
image_id = @client
|
25
|
-
.request('/images')
|
21
|
+
.request('/v2/images')
|
26
22
|
.find_id(:images, :name => @machine.provider_config.image)
|
27
23
|
|
28
|
-
region_id = @client
|
29
|
-
.request('/regions')
|
30
|
-
.find_id(:regions, :name => @machine.provider_config.region)
|
31
|
-
|
32
24
|
# submit new droplet request
|
33
|
-
result = @client.
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
25
|
+
result = @client.post('/v2/droplets', {
|
26
|
+
:size => @machine.provider_config.size,
|
27
|
+
:region => @machine.provider_config.region,
|
28
|
+
:image => image_id,
|
37
29
|
:name => @machine.config.vm.hostname || @machine.name,
|
38
|
-
:
|
30
|
+
:ssh_keys => ssh_key_id,
|
39
31
|
:private_networking => @machine.provider_config.private_networking,
|
40
|
-
:
|
32
|
+
:backups => @machine.provider_config.backups_enabled,
|
33
|
+
:ipv6 => @machine.provider_config.ipv6,
|
34
|
+
:user_data => @machine.provider_config.user_data
|
41
35
|
})
|
42
36
|
|
43
37
|
# wait for request to complete
|
44
38
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.creating')
|
45
|
-
@client.wait_for_event(env, result['
|
39
|
+
@client.wait_for_event(env, result['links']['actions'].first['id'])
|
46
40
|
|
47
41
|
# assign the machine id for reference in other commands
|
48
42
|
@machine.id = result['droplet']['id'].to_s
|
49
43
|
|
50
44
|
# refresh droplet state with provider and output ip address
|
51
45
|
droplet = Provider.droplet(@machine, :refresh => true)
|
46
|
+
public_network = droplet['networks']['v4'].find { |network| network['type'] == 'public' }
|
47
|
+
private_network = droplet['networks']['v4'].find { |network| network['type'] == 'private' }
|
52
48
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.droplet_ip', {
|
53
|
-
:ip =>
|
49
|
+
:ip => public_network['ip_address']
|
54
50
|
})
|
55
|
-
if
|
51
|
+
if private_network
|
56
52
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.droplet_private_ip', {
|
57
|
-
:ip =>
|
53
|
+
:ip => private_network['ip_address']
|
58
54
|
})
|
59
55
|
end
|
60
56
|
|
@@ -15,15 +15,10 @@ module VagrantPlugins
|
|
15
15
|
|
16
16
|
def call(env)
|
17
17
|
# submit destroy droplet request
|
18
|
-
|
18
|
+
@client.delete("/v2/droplets/#{@machine.id}")
|
19
19
|
|
20
20
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.destroying')
|
21
21
|
|
22
|
-
# wait for the destroy progress to start
|
23
|
-
@client.wait_for_event(env, result['event_id']) do |response|
|
24
|
-
break if response['event']['percentage'] != nil
|
25
|
-
end
|
26
|
-
|
27
22
|
# set the machine id to nil to cleanup local vagrant state
|
28
23
|
@machine.id = nil
|
29
24
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require 'vagrant-
|
2
|
-
|
1
|
+
require 'vagrant-digitalocean/helpers/client'
|
2
|
+
#TODO: --force
|
3
3
|
module VagrantPlugins
|
4
4
|
module DigitalOcean
|
5
5
|
module Actions
|
@@ -15,11 +15,13 @@ module VagrantPlugins
|
|
15
15
|
|
16
16
|
def call(env)
|
17
17
|
# submit power off droplet request
|
18
|
-
result = @client.
|
18
|
+
result = @client.post("/v2/droplets/#{@machine.id}/actions", {
|
19
|
+
:type => 'power_off'
|
20
|
+
})
|
19
21
|
|
20
22
|
# wait for request to complete
|
21
23
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.powering_off')
|
22
|
-
@client.wait_for_event(env, result['
|
24
|
+
@client.wait_for_event(env, result['action']['id'])
|
23
25
|
|
24
26
|
# refresh droplet state with provider
|
25
27
|
Provider.droplet(@machine, :refresh => true)
|
@@ -15,11 +15,13 @@ module VagrantPlugins
|
|
15
15
|
|
16
16
|
def call(env)
|
17
17
|
# submit power on droplet request
|
18
|
-
result = @client.
|
18
|
+
result = @client.post("/v2/droplets/#{@machine.id}/actions", {
|
19
|
+
:type => 'power_on'
|
20
|
+
})
|
19
21
|
|
20
22
|
# wait for request to complete
|
21
23
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.powering_on')
|
22
|
-
@client.wait_for_event(env, result['
|
24
|
+
@client.wait_for_event(env, result['action']['id'])
|
23
25
|
|
24
26
|
# refresh droplet state with provider
|
25
27
|
Provider.droplet(@machine, :refresh => true)
|
@@ -5,7 +5,7 @@ module VagrantPlugins
|
|
5
5
|
module Actions
|
6
6
|
class Rebuild
|
7
7
|
include Helpers::Client
|
8
|
-
|
8
|
+
include Vagrant::Util::Retryable
|
9
9
|
|
10
10
|
def initialize(app, env)
|
11
11
|
@app = app
|
@@ -17,17 +17,18 @@ module VagrantPlugins
|
|
17
17
|
def call(env)
|
18
18
|
# look up image id
|
19
19
|
image_id = @client
|
20
|
-
.request('/images')
|
20
|
+
.request('/v2/images')
|
21
21
|
.find_id(:images, :name => @machine.provider_config.image)
|
22
22
|
|
23
23
|
# submit rebuild request
|
24
|
-
result = @client.
|
25
|
-
:
|
24
|
+
result = @client.post("/v2/droplets/#{@machine.id}/actions", {
|
25
|
+
:type => 'rebuild',
|
26
|
+
:image => image_id
|
26
27
|
})
|
27
28
|
|
28
29
|
# wait for request to complete
|
29
30
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.rebuilding')
|
30
|
-
@client.wait_for_event(env, result['
|
31
|
+
@client.wait_for_event(env, result['action']['id'])
|
31
32
|
|
32
33
|
# refresh droplet state with provider
|
33
34
|
Provider.droplet(@machine, :refresh => true)
|
@@ -15,11 +15,13 @@ module VagrantPlugins
|
|
15
15
|
|
16
16
|
def call(env)
|
17
17
|
# submit reboot droplet request
|
18
|
-
result = @client.
|
18
|
+
result = @client.post("/v2/droplets/#{@machine.id}/actions", {
|
19
|
+
:type => 'reboot'
|
20
|
+
})
|
19
21
|
|
20
22
|
# wait for request to complete
|
21
23
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.reloading')
|
22
|
-
@client.wait_for_event(env, result['
|
24
|
+
@client.wait_for_event(env, result['action']['id'])
|
23
25
|
|
24
26
|
@app.call(env)
|
25
27
|
end
|
@@ -20,7 +20,7 @@ module VagrantPlugins
|
|
20
20
|
begin
|
21
21
|
# assigns existing ssh key id to env for use by other commands
|
22
22
|
env[:ssh_key_id] = @client
|
23
|
-
.request('/
|
23
|
+
.request('/v2/account/keys')
|
24
24
|
.find_id(:ssh_keys, :name => ssh_key_name)
|
25
25
|
|
26
26
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.using_key', {
|
@@ -38,7 +38,7 @@ module VagrantPlugins
|
|
38
38
|
def create_ssh_key(name, env)
|
39
39
|
# assumes public key exists on the same path as private key with .pub ext
|
40
40
|
path = @machine.config.ssh.private_key_path
|
41
|
-
|
41
|
+
path = path[0] if path.is_a?(Array)
|
42
42
|
path = File.expand_path(path, @machine.env.root_path)
|
43
43
|
pub_key = DigitalOcean.public_key(path)
|
44
44
|
|
@@ -46,9 +46,9 @@ module VagrantPlugins
|
|
46
46
|
:name => name
|
47
47
|
})
|
48
48
|
|
49
|
-
result = @client.
|
49
|
+
result = @client.post('/v2/account/keys', {
|
50
50
|
:name => name,
|
51
|
-
:
|
51
|
+
:public_key => pub_key
|
52
52
|
})
|
53
53
|
result['ssh_key']['id']
|
54
54
|
end
|
@@ -44,7 +44,7 @@ module VagrantPlugins
|
|
44
44
|
|
45
45
|
# add the specified key to the authorized keys file
|
46
46
|
path = @machine.config.ssh.private_key_path
|
47
|
-
|
47
|
+
path = path[0] if path.is_a?(Array)
|
48
48
|
path = File.expand_path(path, @machine.env.root_path)
|
49
49
|
pub_key = DigitalOcean.public_key(path)
|
50
50
|
@machine.communicate.execute(<<-BASH)
|
@@ -17,9 +17,14 @@ module VagrantPlugins
|
|
17
17
|
@machine.config.vm.synced_folders.each do |id, data|
|
18
18
|
next if data[:disabled]
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
if @machine.guest.capability?(:rsync_installed)
|
21
|
+
installed = @machine.guest.capability(:rsync_installed)
|
22
|
+
if !installed
|
23
|
+
can_install = @machine.guest.capability?(:rsync_install)
|
24
|
+
raise Vagrant::Errors::RSyncNotInstalledInGuest if !can_install
|
25
|
+
@machine.ui.info I18n.t("vagrant.rsync_installing")
|
26
|
+
@machine.guest.capability(:rsync_install)
|
27
|
+
end
|
23
28
|
end
|
24
29
|
|
25
30
|
hostpath = File.expand_path(data[:hostpath], env[:root_path])
|
@@ -47,21 +52,12 @@ module VagrantPlugins
|
|
47
52
|
key = ssh_info[:private_key_path]
|
48
53
|
key = key[0] if key.is_a?(Array)
|
49
54
|
|
50
|
-
|
51
|
-
# build exclude rules
|
52
|
-
excludes = ['.vagrant/']
|
53
|
-
excludes += Array(data[:rsync__exclude]).map(&:to_s) if data[:rsync__exclude]
|
54
|
-
excludes.uniq!
|
55
|
-
|
56
|
-
|
57
|
-
|
58
55
|
# rsync over to the guest path using the ssh info
|
59
56
|
command = [
|
60
|
-
"rsync", "--verbose", "--
|
57
|
+
"rsync", "--verbose", "--archive", "-z", "--delete",
|
61
58
|
"-e", "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no -i '#{key}'",
|
62
59
|
hostpath,
|
63
|
-
"#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"
|
64
|
-
{ :notify => [:stdout, :stderr] } ].flatten
|
60
|
+
"#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
|
65
61
|
|
66
62
|
# we need to fix permissions when using rsync.exe on windows, see
|
67
63
|
# http://stackoverflow.com/questions/5798807/rsync-permission-denied-created-directories-have-no-permissions
|
@@ -69,12 +65,7 @@ module VagrantPlugins
|
|
69
65
|
command.insert(1, "--chmod", "ugo=rwX")
|
70
66
|
end
|
71
67
|
|
72
|
-
r = Vagrant::Util::Subprocess.execute(*command)
|
73
|
-
if type == :stdout || type == :stderr
|
74
|
-
@machine.env.ui.info(data, :new_line => false, :prefix => false)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
68
|
+
r = Vagrant::Util::Subprocess.execute(*command)
|
78
69
|
if r.exit_code != 0
|
79
70
|
raise Errors::RsyncError,
|
80
71
|
:guestpath => guestpath,
|
@@ -88,4 +79,4 @@ module VagrantPlugins
|
|
88
79
|
end
|
89
80
|
end
|
90
81
|
end
|
91
|
-
end
|
82
|
+
end
|
@@ -1,52 +1,54 @@
|
|
1
1
|
module VagrantPlugins
|
2
2
|
module DigitalOcean
|
3
3
|
class Config < Vagrant.plugin('2', :config)
|
4
|
-
attr_accessor :
|
5
|
-
attr_accessor :api_key
|
4
|
+
attr_accessor :token
|
6
5
|
attr_accessor :image
|
7
6
|
attr_accessor :region
|
8
7
|
attr_accessor :size
|
9
8
|
attr_accessor :private_networking
|
9
|
+
attr_accessor :ipv6
|
10
10
|
attr_accessor :backups_enabled
|
11
11
|
attr_accessor :ca_path
|
12
12
|
attr_accessor :ssh_key_name
|
13
13
|
attr_accessor :setup
|
14
|
+
attr_accessor :user_data
|
14
15
|
|
15
16
|
alias_method :setup?, :setup
|
16
17
|
|
17
18
|
def initialize
|
18
|
-
@
|
19
|
-
@api_key = UNSET_VALUE
|
19
|
+
@token = UNSET_VALUE
|
20
20
|
@image = UNSET_VALUE
|
21
21
|
@region = UNSET_VALUE
|
22
22
|
@size = UNSET_VALUE
|
23
23
|
@private_networking = UNSET_VALUE
|
24
|
+
@ipv6 = UNSET_VALUE
|
24
25
|
@backups_enable = UNSET_VALUE
|
25
26
|
@ca_path = UNSET_VALUE
|
26
27
|
@ssh_key_name = UNSET_VALUE
|
27
28
|
@setup = UNSET_VALUE
|
29
|
+
@user_data = UNSET_VALUE
|
28
30
|
end
|
29
31
|
|
30
32
|
def finalize!
|
31
|
-
@
|
32
|
-
@
|
33
|
-
@
|
34
|
-
@
|
35
|
-
@size = '512MB' if @size == UNSET_VALUE
|
33
|
+
@token = ENV['DO_TOKEN'] if @token == UNSET_VALUE
|
34
|
+
@image = 'Ubuntu 14.04 x64' if @image == UNSET_VALUE
|
35
|
+
@region = 'nyc2' if @region == UNSET_VALUE
|
36
|
+
@size = '512mb' if @size == UNSET_VALUE
|
36
37
|
@private_networking = false if @private_networking == UNSET_VALUE
|
38
|
+
@ipv6 = false if @ipv6 == UNSET_VALUE
|
37
39
|
@backups_enabled = false if @backups_enabled == UNSET_VALUE
|
38
40
|
@ca_path = nil if @ca_path == UNSET_VALUE
|
39
41
|
@ssh_key_name = 'Vagrant' if @ssh_key_name == UNSET_VALUE
|
40
42
|
@setup = true if @setup == UNSET_VALUE
|
43
|
+
@user_data = nil if @user_data == UNSET_VALUE
|
41
44
|
end
|
42
45
|
|
43
46
|
def validate(machine)
|
44
47
|
errors = []
|
45
|
-
errors << I18n.t('vagrant_digital_ocean.config.
|
46
|
-
errors << I18n.t('vagrant_digital_ocean.config.api_key') if !@api_key
|
48
|
+
errors << I18n.t('vagrant_digital_ocean.config.token') if !@token
|
47
49
|
|
48
50
|
key = machine.config.ssh.private_key_path
|
49
|
-
|
51
|
+
key = key[0] if key.is_a?(Array)
|
50
52
|
if !key
|
51
53
|
errors << I18n.t('vagrant_digital_ocean.config.private_key')
|
52
54
|
elsif !File.file?(File.expand_path("#{key}.pub", machine.env.root_path))
|
@@ -15,7 +15,7 @@ module VagrantPlugins
|
|
15
15
|
include Vagrant::Util::Retryable
|
16
16
|
|
17
17
|
def initialize(machine)
|
18
|
-
|
18
|
+
@logger = Log4r::Logger.new('vagrant::digitalocean::apiclient')
|
19
19
|
@config = machine.provider_config
|
20
20
|
@client = Faraday.new({
|
21
21
|
:url => 'https://api.digitalocean.com/',
|
@@ -25,13 +25,23 @@ module VagrantPlugins
|
|
25
25
|
})
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
28
|
+
def delete(path, params = {}, method = :delete)
|
29
|
+
@client.request :url_encoded
|
30
|
+
request(path, params, :delete)
|
31
|
+
end
|
32
|
+
|
33
|
+
def post(path, params = {}, method = :post)
|
34
|
+
@client.headers['Content-Type'] = 'application/json'
|
35
|
+
request(path, params, :post)
|
36
|
+
end
|
37
|
+
|
38
|
+
def request(path, params = {}, method = :get)
|
29
39
|
begin
|
30
|
-
|
31
|
-
result = @client.
|
32
|
-
|
33
|
-
|
34
|
-
|
40
|
+
@logger.info "Request: #{path}"
|
41
|
+
result = @client.send(method) do |req|
|
42
|
+
req.url path, params
|
43
|
+
req.headers['Authorization'] = "Bearer #{@config.token}"
|
44
|
+
end
|
35
45
|
rescue Faraday::Error::ConnectionFailed => e
|
36
46
|
# TODO this is suspect but because farady wraps the exception
|
37
47
|
# in something generic there doesn't appear to be another
|
@@ -43,26 +53,33 @@ module VagrantPlugins
|
|
43
53
|
raise e
|
44
54
|
end
|
45
55
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
unless method == :delete
|
57
|
+
begin
|
58
|
+
body = JSON.parse(result.body)
|
59
|
+
@logger.info "Response: #{body}"
|
60
|
+
next_page = body["links"]["pages"]["next"] rescue nil
|
61
|
+
unless next_page.nil?
|
62
|
+
uri = URI.parse(next_page)
|
63
|
+
new_path = path.split("?")[0]
|
64
|
+
next_result = self.request("#{new_path}?#{uri.query}")
|
65
|
+
req_target = new_path.split("/")[-1]
|
66
|
+
body["#{req_target}"].concat(next_result["#{req_target}"])
|
67
|
+
end
|
68
|
+
rescue JSON::ParserError => e
|
69
|
+
raise(Errors::JSONError, {
|
70
|
+
:message => e.message,
|
71
|
+
:path => path,
|
72
|
+
:params => params,
|
73
|
+
:response => result.body
|
74
|
+
})
|
75
|
+
end
|
59
76
|
end
|
60
77
|
|
61
|
-
|
78
|
+
unless /^2\d\d$/ =~ result.status.to_s
|
62
79
|
raise(Errors::APIStatusError, {
|
63
80
|
:path => path,
|
64
81
|
:params => params,
|
65
|
-
:status =>
|
82
|
+
:status => result.status,
|
66
83
|
:response => body.inspect
|
67
84
|
})
|
68
85
|
end
|
@@ -75,11 +92,11 @@ module VagrantPlugins
|
|
75
92
|
# stop waiting if interrupted
|
76
93
|
next if env[:interrupted]
|
77
94
|
|
78
|
-
# check
|
79
|
-
result = self.request("/
|
95
|
+
# check action status
|
96
|
+
result = self.request("/v2/actions/#{id}")
|
80
97
|
|
81
98
|
yield result if block_given?
|
82
|
-
raise 'not ready' if result['
|
99
|
+
raise 'not ready' if result['action']['status'] != 'completed'
|
83
100
|
end
|
84
101
|
end
|
85
102
|
end
|
@@ -10,14 +10,14 @@ module VagrantPlugins
|
|
10
10
|
@result[key.to_s]
|
11
11
|
end
|
12
12
|
|
13
|
-
def find_id(sub_obj, search)
|
13
|
+
def find_id(sub_obj, search) #:ssh_keys, {:name => 'ijin (vagrant)'}
|
14
14
|
find(sub_obj, search)["id"]
|
15
15
|
end
|
16
16
|
|
17
17
|
def find(sub_obj, search)
|
18
|
-
key = search.keys.first
|
19
|
-
value = search[key].to_s
|
20
|
-
key = key.to_s
|
18
|
+
key = search.keys.first #:slug
|
19
|
+
value = search[key].to_s #sfo1
|
20
|
+
key = key.to_s #slug
|
21
21
|
|
22
22
|
result = @result[sub_obj.to_s].inject(nil) do |result, obj|
|
23
23
|
obj[key] == value ? obj : result
|
@@ -12,14 +12,14 @@ module VagrantPlugins
|
|
12
12
|
|
13
13
|
# load status of droplets if it has not been done before
|
14
14
|
if !@droplets
|
15
|
-
result = client.request('/droplets')
|
15
|
+
result = client.request('/v2/droplets')
|
16
16
|
@droplets = result['droplets']
|
17
17
|
end
|
18
18
|
|
19
19
|
if opts[:refresh] && machine.id
|
20
20
|
# refresh the droplet status for the given machine
|
21
21
|
@droplets.delete_if { |d| d['id'].to_s == machine.id }
|
22
|
-
result = client.request("/droplets/#{machine.id}")
|
22
|
+
result = client.request("/v2/droplets/#{machine.id}")
|
23
23
|
@droplets << droplet = result['droplet']
|
24
24
|
else
|
25
25
|
# lookup droplet status for the given machine
|
@@ -79,8 +79,10 @@ module VagrantPlugins
|
|
79
79
|
|
80
80
|
return nil if droplet['status'].to_sym != :active
|
81
81
|
|
82
|
+
public_network = droplet['networks']['v4'].find { |network| network['type'] == 'public' }
|
83
|
+
|
82
84
|
return {
|
83
|
-
:host =>
|
85
|
+
:host => public_network['ip_address'],
|
84
86
|
:port => '22',
|
85
87
|
:username => 'root',
|
86
88
|
:private_key_path => nil
|
data/locales/en.yml
CHANGED
@@ -19,9 +19,9 @@ en:
|
|
19
19
|
creating_key: "Creating new SSH key: %{name}..."
|
20
20
|
trying_rsync_install: "Rsync not found, attempting to install with yum..."
|
21
21
|
rsyncing: "Rsyncing folder: %{hostpath} => %{guestpath}..."
|
22
|
+
rsync_missing: "The rsync executable was not found in the current path."
|
22
23
|
config:
|
23
|
-
|
24
|
-
api_key: "API key is required"
|
24
|
+
token: "Token is required"
|
25
25
|
private_key: "SSH private key path is required"
|
26
26
|
public_key: "SSH public key not found: %{key}"
|
27
27
|
errors:
|
data/test/Vagrantfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Vagrant.require_plugin('vagrant-
|
1
|
+
Vagrant.require_plugin('vagrant-digitalocean')
|
2
2
|
Vagrant.require_plugin('vagrant-omnibus')
|
3
3
|
|
4
4
|
Vagrant.configure('2') do |config|
|
@@ -12,8 +12,7 @@ Vagrant.configure('2') do |config|
|
|
12
12
|
config.vm.provider :chassis_digitalocean do |provider, override|
|
13
13
|
override.vm.box = 'chassis_digitalocean'
|
14
14
|
override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
|
15
|
-
provider.
|
16
|
-
provider.api_key = ENV['DO_API_KEY']
|
15
|
+
provider.token = ENV['DO_TOKEN']
|
17
16
|
provider.ssh_key_name = 'Test Key'
|
18
17
|
end
|
19
18
|
|
@@ -25,8 +24,8 @@ Vagrant.configure('2') do |config|
|
|
25
24
|
end
|
26
25
|
|
27
26
|
config.vm.define :ubuntu do |ubuntu|
|
28
|
-
ubuntu.vm.provider :
|
29
|
-
provider.image = 'Ubuntu
|
27
|
+
ubuntu.vm.provider :digital_ocean do |provider|
|
28
|
+
provider.image = 'Ubuntu 14.04 x64'
|
30
29
|
end
|
31
30
|
end
|
32
31
|
|
data/test/test.sh
CHANGED
@@ -1,14 +1,14 @@
|
|
1
|
-
# if ! vagrant box list | grep
|
2
|
-
# vagrant box add
|
1
|
+
# if ! bundle exec vagrant box list | grep digital_ocean 1>/dev/null; then
|
2
|
+
# bundle exec vagrant box add digital_ocean box/digital_ocean.box
|
3
3
|
# fi
|
4
4
|
|
5
5
|
cd test
|
6
6
|
|
7
|
-
vagrant up --provider=
|
8
|
-
vagrant up
|
9
|
-
vagrant provision
|
10
|
-
vagrant rebuild
|
11
|
-
vagrant halt
|
12
|
-
vagrant destroy
|
7
|
+
bundle exec vagrant up --provider=digital_ocean
|
8
|
+
bundle exec vagrant up
|
9
|
+
bundle exec vagrant provision
|
10
|
+
bundle exec vagrant rebuild
|
11
|
+
bundle exec vagrant halt
|
12
|
+
bundle exec vagrant destroy
|
13
13
|
|
14
14
|
cd ..
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-chassis-digitalocean
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.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: 2014-
|
12
|
+
date: 2014-09-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|