vagrant-digitalocean 0.5.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +1 -0
- data/Gemfile +6 -1
- data/README.md +8 -6
- data/lib/vagrant-digitalocean/actions/create.rb +8 -16
- data/lib/vagrant-digitalocean/actions/destroy.rb +1 -6
- data/lib/vagrant-digitalocean/actions/power_off.rb +5 -3
- data/lib/vagrant-digitalocean/actions/power_on.rb +4 -2
- data/lib/vagrant-digitalocean/actions/rebuild.rb +5 -4
- data/lib/vagrant-digitalocean/actions/reload.rb +4 -2
- data/lib/vagrant-digitalocean/actions/setup_key.rb +3 -3
- data/lib/vagrant-digitalocean/config.rb +6 -10
- data/lib/vagrant-digitalocean/helpers/client.rb +32 -23
- data/lib/vagrant-digitalocean/helpers/result.rb +4 -4
- data/lib/vagrant-digitalocean/provider.rb +3 -3
- data/lib/vagrant-digitalocean/version.rb +1 -1
- data/locales/en.yml +1 -2
- data/test/Vagrantfile +2 -3
- data/test/test.sh +8 -8
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MTM5ODYzZWQ3ODUwZDI1OWViOWFjOTE4MWRkZWVkODI4M2JkN2U3Zg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YTdhZTU1MzVhODUyNjVlNTc0NmJmOTI1YzJhYTkwMjllYTY0YjlkNQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDNkYmE1OTQ2NTkwYzhhYWI5MmM1N2U1ZGJhNTgyZjQ1NDc4YWE1YTIzMmMw
|
10
|
+
N2M1OGNmZjllZDQzMmY1NzE3MGIxZTE0OGQ5NGI2NTU3NTJkNTA2MzdhMTg3
|
11
|
+
MTIyMjg0MTAxZWI1MWQxNzFmYzM5YzIwNzU1MWE4ZjA5NjMyMjk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZWQwN2VkZjUwNmQ2OTA2ZDljNzk3YTRjNjM1Y2I5YjAxMzI2ZDc2MmM5YWMx
|
14
|
+
MTYzMGQ0M2FkZjVlNjJiOWViNmU5ZDk2YzRiNmUwOGVjNzJmZmJlMjg4YmI1
|
15
|
+
Njk4YTU1NWFlNzhkZmE2ZmU0YTA3MTUzMmVlZWFlMjk4NmJkMzM=
|
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
@@ -57,8 +57,10 @@ Vagrant.configure('2') do |config|
|
|
57
57
|
override.vm.box = 'digital_ocean'
|
58
58
|
override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
|
59
59
|
|
60
|
-
provider.
|
61
|
-
provider.
|
60
|
+
provider.token = 'YOUR TOKEN'
|
61
|
+
provider.image = 'Ubuntu 14.04 x64'
|
62
|
+
provider.region = 'nyc2'
|
63
|
+
provider.size = '512mb'
|
62
64
|
end
|
63
65
|
end
|
64
66
|
```
|
@@ -77,11 +79,11 @@ The following attributes are available to further configure the provider:
|
|
77
79
|
- `provider.image` - A string representing the image to use when creating a
|
78
80
|
new droplet (e.g. `Debian 6.0 x64`). The available options may
|
79
81
|
be found on Digital Ocean's new droplet [form](https://www.digitalocean.com/droplets/new).
|
80
|
-
It defaults to `Ubuntu 14.04
|
82
|
+
It defaults to `Ubuntu 14.04 x64`.
|
81
83
|
- `provider.region` - A string representing the region to create the new
|
82
|
-
droplet in. It defaults to `
|
84
|
+
droplet in. It defaults to `nyc2`.
|
83
85
|
- `provider.size` - A string representing the size to use when creating a
|
84
|
-
new droplet (e.g. `
|
86
|
+
new droplet (e.g. `1gb`). It defaults to `512mb`.
|
85
87
|
- `provider.private_networking` - A boolean flag indicating whether to enable
|
86
88
|
a private network interface (if the region supports private networking). It
|
87
89
|
defaults to `false`.
|
@@ -120,7 +122,7 @@ The provider supports the following Vagrant sub-commands:
|
|
120
122
|
specified `config.vm.synced_folder`.
|
121
123
|
- `vagrant reload` - Reboots the droplet instance.
|
122
124
|
- `vagrant rebuild` - Destroys the droplet instance and recreates it with the
|
123
|
-
same IP address
|
125
|
+
same IP address which was previously assigned.
|
124
126
|
- `vagrant status` - Outputs the status (active, off, not created) for the
|
125
127
|
droplet instance.
|
126
128
|
|
@@ -15,34 +15,26 @@ 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_enabled => @machine.provider_config.backups_enabled
|
41
33
|
})
|
42
34
|
|
43
35
|
# wait for request to complete
|
44
36
|
env[:ui].info I18n.t('vagrant_digital_ocean.info.creating')
|
45
|
-
@client.wait_for_event(env, result['droplet']['
|
37
|
+
@client.wait_for_event(env, result['droplet']['action_ids'].first)
|
46
38
|
|
47
39
|
# assign the machine id for reference in other commands
|
48
40
|
@machine.id = result['droplet']['id'].to_s
|
@@ -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
1
|
require 'vagrant-digitalocean/helpers/client'
|
2
|
-
|
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)
|
@@ -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', {
|
@@ -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
|
@@ -1,8 +1,7 @@
|
|
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
|
@@ -15,8 +14,7 @@ module VagrantPlugins
|
|
15
14
|
alias_method :setup?, :setup
|
16
15
|
|
17
16
|
def initialize
|
18
|
-
@
|
19
|
-
@api_key = UNSET_VALUE
|
17
|
+
@token = UNSET_VALUE
|
20
18
|
@image = UNSET_VALUE
|
21
19
|
@region = UNSET_VALUE
|
22
20
|
@size = UNSET_VALUE
|
@@ -28,11 +26,10 @@ module VagrantPlugins
|
|
28
26
|
end
|
29
27
|
|
30
28
|
def finalize!
|
31
|
-
@
|
32
|
-
@api_key = ENV['DO_API_KEY'] if @api_key == UNSET_VALUE
|
29
|
+
@token = ENV['DO_TOKEN'] if @token == UNSET_VALUE
|
33
30
|
@image = 'Ubuntu 14.04 x64' if @image == UNSET_VALUE
|
34
|
-
@region = '
|
35
|
-
@size = '
|
31
|
+
@region = 'nyc2' if @region == UNSET_VALUE
|
32
|
+
@size = '512mb' if @size == UNSET_VALUE
|
36
33
|
@private_networking = false if @private_networking == UNSET_VALUE
|
37
34
|
@backups_enabled = false if @backups_enabled == UNSET_VALUE
|
38
35
|
@ca_path = nil if @ca_path == UNSET_VALUE
|
@@ -42,8 +39,7 @@ module VagrantPlugins
|
|
42
39
|
|
43
40
|
def validate(machine)
|
44
41
|
errors = []
|
45
|
-
errors << I18n.t('vagrant_digital_ocean.config.
|
46
|
-
errors << I18n.t('vagrant_digital_ocean.config.api_key') if !@api_key
|
42
|
+
errors << I18n.t('vagrant_digital_ocean.config.token') if !@token
|
47
43
|
|
48
44
|
key = machine.config.ssh.private_key_path
|
49
45
|
key = key[0] if key.is_a?(Array)
|
@@ -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
40
|
@logger.info "Request: #{path}"
|
31
|
-
result = @client.
|
32
|
-
|
33
|
-
|
34
|
-
|
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,25 @@ 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
|
+
rescue JSON::ParserError => e
|
61
|
+
raise(Errors::JSONError, {
|
62
|
+
:message => e.message,
|
63
|
+
:path => path,
|
64
|
+
:params => params,
|
65
|
+
:response => result.body
|
66
|
+
})
|
67
|
+
end
|
59
68
|
end
|
60
69
|
|
61
|
-
|
70
|
+
unless /^2\d\d$/ =~ result.status.to_s
|
62
71
|
raise(Errors::APIStatusError, {
|
63
72
|
:path => path,
|
64
73
|
:params => params,
|
65
|
-
:status =>
|
74
|
+
:status => result.status,
|
66
75
|
:response => body.inspect
|
67
76
|
})
|
68
77
|
end
|
@@ -75,11 +84,11 @@ module VagrantPlugins
|
|
75
84
|
# stop waiting if interrupted
|
76
85
|
next if env[:interrupted]
|
77
86
|
|
78
|
-
# check
|
79
|
-
result = self.request("/
|
87
|
+
# check action status
|
88
|
+
result = self.request("/v2/actions/#{id}")
|
80
89
|
|
81
90
|
yield result if block_given?
|
82
|
-
raise 'not ready' if result['
|
91
|
+
raise 'not ready' if result['action']['status'] != 'completed'
|
83
92
|
end
|
84
93
|
end
|
85
94
|
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
|
@@ -80,7 +80,7 @@ module VagrantPlugins
|
|
80
80
|
return nil if droplet['status'].to_sym != :active
|
81
81
|
|
82
82
|
return {
|
83
|
-
:host => droplet['ip_address'],
|
83
|
+
:host => droplet['networks']['v4'].first['ip_address'],
|
84
84
|
:port => '22',
|
85
85
|
:username => 'root',
|
86
86
|
:private_key_path => nil
|
data/locales/en.yml
CHANGED
@@ -21,8 +21,7 @@ en:
|
|
21
21
|
rsyncing: "Rsyncing folder: %{hostpath} => %{guestpath}..."
|
22
22
|
rsync_missing: "The rsync executable was not found in the current path."
|
23
23
|
config:
|
24
|
-
|
25
|
-
api_key: "API key is required"
|
24
|
+
token: "Token is required"
|
26
25
|
private_key: "SSH private key path is required"
|
27
26
|
public_key: "SSH public key not found: %{key}"
|
28
27
|
errors:
|
data/test/Vagrantfile
CHANGED
@@ -12,8 +12,7 @@ Vagrant.configure('2') do |config|
|
|
12
12
|
config.vm.provider :digital_ocean do |provider, override|
|
13
13
|
override.vm.box = 'digital_ocean'
|
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
|
|
@@ -26,7 +25,7 @@ Vagrant.configure('2') do |config|
|
|
26
25
|
|
27
26
|
config.vm.define :ubuntu do |ubuntu|
|
28
27
|
ubuntu.vm.provider :digital_ocean do |provider|
|
29
|
-
provider.image = 'Ubuntu
|
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 digital_ocean 1>/dev/null; then
|
2
|
-
# vagrant box add digital_ocean box/digital_ocean.box
|
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=digital_ocean
|
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,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-digitalocean
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Bender
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|