vagrant-simple_cloud 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +10 -0
- data/LICENSE +373 -0
- data/Rakefile +22 -0
- data/lib/vagrant-simple_cloud/actions/check_state.rb +19 -0
- data/lib/vagrant-simple_cloud/actions/create.rb +94 -0
- data/lib/vagrant-simple_cloud/actions/destroy.rb +30 -0
- data/lib/vagrant-simple_cloud/actions/modify_provision_path.rb +38 -0
- data/lib/vagrant-simple_cloud/actions/power_off.rb +35 -0
- data/lib/vagrant-simple_cloud/actions/power_on.rb +36 -0
- data/lib/vagrant-simple_cloud/actions/rebuild.rb +49 -0
- data/lib/vagrant-simple_cloud/actions/reload.rb +33 -0
- data/lib/vagrant-simple_cloud/actions/setup_key.rb +58 -0
- data/lib/vagrant-simple_cloud/actions/setup_sudo.rb +48 -0
- data/lib/vagrant-simple_cloud/actions/setup_user.rb +66 -0
- data/lib/vagrant-simple_cloud/actions/shut_down.rb +35 -0
- data/lib/vagrant-simple_cloud/actions.rb +164 -0
- data/lib/vagrant-simple_cloud/commands/list.rb +93 -0
- data/lib/vagrant-simple_cloud/commands/rebuild.rb +29 -0
- data/lib/vagrant-simple_cloud/config.rb +69 -0
- data/lib/vagrant-simple_cloud/errors.rb +37 -0
- data/lib/vagrant-simple_cloud/helpers/client.rb +106 -0
- data/lib/vagrant-simple_cloud/helpers/client_service.rb +81 -0
- data/lib/vagrant-simple_cloud/helpers/result.rb +40 -0
- data/lib/vagrant-simple_cloud/plugin.rb +31 -0
- data/lib/vagrant-simple_cloud/provider.rb +102 -0
- data/lib/vagrant-simple_cloud/version.rb +5 -0
- data/lib/vagrant-simple_cloud.rb +20 -0
- data/locales/en.yml +92 -0
- data/test/Vagrantfile +24 -0
- data/test/scripts/provision.sh +3 -0
- data/test/test.sh +10 -0
- data/test/test_id_rsa +27 -0
- data/test/test_id_rsa.pub +1 -0
- data/vagrant-simple_cloud.gemspec +21 -0
- metadata +127 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'vagrant-simple_cloud/helpers/client'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SimpleCloud
|
5
|
+
module Actions
|
6
|
+
class ShutDown
|
7
|
+
include Helpers::Client
|
8
|
+
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@machine = env[:machine]
|
12
|
+
@client = client
|
13
|
+
@logger = Log4r::Logger.new('vagrant::simple_cloud::shut_down')
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
# submit shutdown droplet request
|
18
|
+
result = @client.post("/v2/vps/#{@machine.id}/actions", {
|
19
|
+
:type => 'shutdown'
|
20
|
+
})
|
21
|
+
|
22
|
+
# wait for request to complete
|
23
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.shutting_down')
|
24
|
+
@client.wait_for_event(env, result['action']['id'])
|
25
|
+
|
26
|
+
# refresh droplet state with provider
|
27
|
+
Provider.droplet(@machine, :refresh => true)
|
28
|
+
|
29
|
+
@app.call(env)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'vagrant-simple_cloud/actions/check_state'
|
2
|
+
require 'vagrant-simple_cloud/actions/create'
|
3
|
+
require 'vagrant-simple_cloud/actions/destroy'
|
4
|
+
require 'vagrant-simple_cloud/actions/shut_down'
|
5
|
+
require 'vagrant-simple_cloud/actions/power_off'
|
6
|
+
require 'vagrant-simple_cloud/actions/power_on'
|
7
|
+
require 'vagrant-simple_cloud/actions/rebuild'
|
8
|
+
require 'vagrant-simple_cloud/actions/reload'
|
9
|
+
require 'vagrant-simple_cloud/actions/setup_user'
|
10
|
+
require 'vagrant-simple_cloud/actions/setup_sudo'
|
11
|
+
require 'vagrant-simple_cloud/actions/setup_key'
|
12
|
+
require 'vagrant-simple_cloud/actions/modify_provision_path'
|
13
|
+
|
14
|
+
module VagrantPlugins
|
15
|
+
module SimpleCloud
|
16
|
+
module Actions
|
17
|
+
include Vagrant::Action::Builtin
|
18
|
+
|
19
|
+
def self.destroy
|
20
|
+
return Vagrant::Action::Builder.new.tap do |builder|
|
21
|
+
builder.use ConfigValidate
|
22
|
+
builder.use Call, CheckState do |env, b|
|
23
|
+
case env[:machine_state]
|
24
|
+
when :not_created
|
25
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.not_created')
|
26
|
+
else
|
27
|
+
b.use Call, DestroyConfirm do |env2, b2|
|
28
|
+
if env2[:result]
|
29
|
+
b2.use Destroy
|
30
|
+
b2.use ProvisionerCleanup if defined?(ProvisionerCleanup)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.ssh
|
39
|
+
return Vagrant::Action::Builder.new.tap do |builder|
|
40
|
+
builder.use ConfigValidate
|
41
|
+
builder.use Call, CheckState do |env, b|
|
42
|
+
case env[:machine_state]
|
43
|
+
when :active
|
44
|
+
b.use SSHExec
|
45
|
+
when :off
|
46
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.off')
|
47
|
+
when :not_created
|
48
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.not_created')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.ssh_run
|
55
|
+
return Vagrant::Action::Builder.new.tap do |builder|
|
56
|
+
builder.use ConfigValidate
|
57
|
+
builder.use Call, CheckState do |env, b|
|
58
|
+
case env[:machine_state]
|
59
|
+
when :active
|
60
|
+
b.use SSHRun
|
61
|
+
when :off
|
62
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.off')
|
63
|
+
when :not_created
|
64
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.not_created')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.provision
|
71
|
+
return Vagrant::Action::Builder.new.tap do |builder|
|
72
|
+
builder.use ConfigValidate
|
73
|
+
builder.use Call, CheckState do |env, b|
|
74
|
+
case env[:machine_state]
|
75
|
+
when :active
|
76
|
+
b.use Provision
|
77
|
+
b.use ModifyProvisionPath
|
78
|
+
b.use SyncedFolders
|
79
|
+
when :off
|
80
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.off')
|
81
|
+
when :not_created
|
82
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.not_created')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.up
|
89
|
+
return Vagrant::Action::Builder.new.tap do |builder|
|
90
|
+
builder.use ConfigValidate
|
91
|
+
builder.use Call, CheckState do |env, b|
|
92
|
+
case env[:machine_state]
|
93
|
+
when :active
|
94
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.already_active')
|
95
|
+
when :off
|
96
|
+
b.use PowerOn
|
97
|
+
b.use provision
|
98
|
+
when :not_created
|
99
|
+
b.use SetupKey
|
100
|
+
b.use Create
|
101
|
+
b.use SetupSudo
|
102
|
+
b.use SetupUser
|
103
|
+
b.use provision
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.halt
|
110
|
+
return Vagrant::Action::Builder.new.tap do |builder|
|
111
|
+
builder.use ConfigValidate
|
112
|
+
builder.use Call, CheckState do |env, b|
|
113
|
+
case env[:machine_state]
|
114
|
+
when :active
|
115
|
+
if env[:force_halt]
|
116
|
+
b.use PowerOff
|
117
|
+
else
|
118
|
+
b.use ShutDown
|
119
|
+
end
|
120
|
+
when :off
|
121
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.already_off')
|
122
|
+
when :not_created
|
123
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.not_created')
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.reload
|
130
|
+
return Vagrant::Action::Builder.new.tap do |builder|
|
131
|
+
builder.use ConfigValidate
|
132
|
+
builder.use Call, CheckState do |env, b|
|
133
|
+
case env[:machine_state]
|
134
|
+
when :active
|
135
|
+
b.use Reload
|
136
|
+
b.use provision
|
137
|
+
when :off
|
138
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.off')
|
139
|
+
when :not_created
|
140
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.not_created')
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.rebuild
|
147
|
+
return Vagrant::Action::Builder.new.tap do |builder|
|
148
|
+
builder.use ConfigValidate
|
149
|
+
builder.use Call, CheckState do |env, b|
|
150
|
+
case env[:machine_state]
|
151
|
+
when :active, :off
|
152
|
+
b.use Rebuild
|
153
|
+
b.use SetupSudo
|
154
|
+
b.use SetupUser
|
155
|
+
b.use provision
|
156
|
+
when :not_created
|
157
|
+
env[:ui].info I18n.t('vagrant_simple_cloud.info.not_created')
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'vagrant-simple_cloud/helpers/client'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module SimpleCloud
|
6
|
+
module Commands
|
7
|
+
class List < Vagrant.plugin('2', :command)
|
8
|
+
def self.synopsis
|
9
|
+
"list available images and regions from SimpleCloud"
|
10
|
+
end
|
11
|
+
|
12
|
+
def execute
|
13
|
+
@token = nil
|
14
|
+
|
15
|
+
@opts = OptionParser.new do |o|
|
16
|
+
o.banner = 'Usage: vagrant simplecloud-list [options] <images|regions|sizes> <token>'
|
17
|
+
|
18
|
+
o.on("-r", "--[no-]regions", "show the regions when listing images") do |r|
|
19
|
+
@regions = r
|
20
|
+
end
|
21
|
+
o.on("-h", "--help", "Displays help") do
|
22
|
+
puts o
|
23
|
+
return 0
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
argv = parse_options(@opts)
|
28
|
+
@token = argv[1]
|
29
|
+
|
30
|
+
if @token.nil?
|
31
|
+
usage
|
32
|
+
return 1
|
33
|
+
end
|
34
|
+
|
35
|
+
case argv[0]
|
36
|
+
when "images"
|
37
|
+
result = query('/v2/images')
|
38
|
+
images = Array(result["images"])
|
39
|
+
if @regions
|
40
|
+
images_table = images.map do |image|
|
41
|
+
'%-50s %-20s %-20s %-50s' % ["#{image['distribution']} #{image['name']}", image['slug'], image['id'], image['regions'].join(', ')]
|
42
|
+
end
|
43
|
+
@env.ui.info I18n.t('vagrant_simple_cloud.info.images_with_regions', images: images_table.sort.join("\r\n"))
|
44
|
+
else
|
45
|
+
images_table = images.map do |image|
|
46
|
+
'%-50s %-30s %-30s' % ["#{image['distribution']} #{image['name']}", image['slug'], image['id']]
|
47
|
+
end
|
48
|
+
@env.ui.info I18n.t('vagrant_simple_cloud.info.images', images: images_table.sort.join("\r\n"))
|
49
|
+
end
|
50
|
+
when "regions"
|
51
|
+
result = query('/v2/regions')
|
52
|
+
regions = Array(result["regions"])
|
53
|
+
regions_table = regions.map { |region| '%-30s %-12s' % [region['name'], region['slug']] }
|
54
|
+
@env.ui.info I18n.t('vagrant_simple_cloud.info.regions', regions: regions_table.sort.join("\r\n"))
|
55
|
+
when "sizes"
|
56
|
+
result = query('/v2/sizes')
|
57
|
+
sizes = Array(result["sizes"])
|
58
|
+
sizes_table = sizes.map { |size| '%-15s %-15s %-12s' % ["#{size['memory']}", size['vcpus'], size['slug']] }
|
59
|
+
@env.ui.info I18n.t('vagrant_simple_cloud.info.sizes', sizes: sizes_table.sort_by{|s| s['memory']}.join("\r\n"))
|
60
|
+
else
|
61
|
+
usage
|
62
|
+
return 1
|
63
|
+
end
|
64
|
+
|
65
|
+
0
|
66
|
+
rescue Faraday::Error::ConnectionFailed, RuntimeError => e
|
67
|
+
@env.ui.error I18n.t('vagrant_simple_cloud.info.list_error', message: e.message)
|
68
|
+
1
|
69
|
+
end
|
70
|
+
|
71
|
+
def query(path)
|
72
|
+
connection = Faraday.new({
|
73
|
+
:url => "https://api.simplecloud.ru/"
|
74
|
+
})
|
75
|
+
|
76
|
+
result = connection.get(path, per_page: 100) do |req|
|
77
|
+
req.headers['Authorization'] = "Bearer #{@token}"
|
78
|
+
end
|
79
|
+
|
80
|
+
case result.status
|
81
|
+
when 200 then JSON.parse(result.body)
|
82
|
+
when 401 then raise("unauthorized access — is the token correct?")
|
83
|
+
else raise("call returned with status #{result.status}")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def usage
|
88
|
+
@env.ui.info(@opts)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module SimpleCloud
|
5
|
+
module Commands
|
6
|
+
class Rebuild < Vagrant.plugin('2', :command)
|
7
|
+
|
8
|
+
# Show description when `vagrant list-commands` is triggered
|
9
|
+
def self.synopsis
|
10
|
+
"plugin: vagrant-simple_cloud: destroys and ups the vm with the same ip address"
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
opts = OptionParser.new do |o|
|
15
|
+
o.banner = 'Usage: vagrant rebuild [vm-name]'
|
16
|
+
end
|
17
|
+
|
18
|
+
argv = parse_options(opts)
|
19
|
+
|
20
|
+
with_target_vms(argv) do |machine|
|
21
|
+
machine.action(:rebuild)
|
22
|
+
end
|
23
|
+
|
24
|
+
0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SimpleCloud
|
3
|
+
class Config < Vagrant.plugin('2', :config)
|
4
|
+
attr_accessor :token
|
5
|
+
attr_accessor :image
|
6
|
+
attr_accessor :region
|
7
|
+
attr_accessor :size
|
8
|
+
attr_accessor :private_networking
|
9
|
+
attr_accessor :ipv6
|
10
|
+
attr_accessor :backups_enabled
|
11
|
+
attr_accessor :ca_path
|
12
|
+
attr_accessor :serviceaddr
|
13
|
+
attr_accessor :ssh_key_name
|
14
|
+
attr_accessor :setup
|
15
|
+
attr_accessor :user_data
|
16
|
+
|
17
|
+
alias_method :setup?, :setup
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@token = UNSET_VALUE
|
21
|
+
@image = UNSET_VALUE
|
22
|
+
@region = UNSET_VALUE
|
23
|
+
@size = UNSET_VALUE
|
24
|
+
@private_networking = UNSET_VALUE
|
25
|
+
@ipv6 = UNSET_VALUE
|
26
|
+
@backups_enable = UNSET_VALUE
|
27
|
+
@ca_path = UNSET_VALUE
|
28
|
+
@serviceaddr = UNSET_VALUE
|
29
|
+
@ssh_key_name = UNSET_VALUE
|
30
|
+
@setup = UNSET_VALUE
|
31
|
+
@user_data = UNSET_VALUE
|
32
|
+
end
|
33
|
+
|
34
|
+
def finalize!
|
35
|
+
@token = ENV['DO_TOKEN'] if @token == UNSET_VALUE
|
36
|
+
@image = '26' if @image == UNSET_VALUE
|
37
|
+
@region = 'miran' if @region == UNSET_VALUE
|
38
|
+
@size = '1' if @size == UNSET_VALUE
|
39
|
+
@private_networking = false if @private_networking == UNSET_VALUE
|
40
|
+
@ipv6 = false if @ipv6 == UNSET_VALUE
|
41
|
+
@backups_enabled = false if @backups_enabled == UNSET_VALUE
|
42
|
+
@ca_path = nil if @ca_path == UNSET_VALUE
|
43
|
+
@serviceaddr = nil if @serviceaddr == UNSET_VALUE
|
44
|
+
@ssh_key_name = 'Vagrant' if @ssh_key_name == UNSET_VALUE
|
45
|
+
@setup = true if @setup == UNSET_VALUE
|
46
|
+
@user_data = nil if @user_data == UNSET_VALUE
|
47
|
+
end
|
48
|
+
|
49
|
+
def validate(machine)
|
50
|
+
errors = []
|
51
|
+
errors << I18n.t('vagrant_simple_cloud.config.token') if !@token
|
52
|
+
|
53
|
+
errors << I18n.t('vagrant_simple_cloud.config.serviceaddr') if !@serviceaddr
|
54
|
+
|
55
|
+
key = machine.config.ssh.private_key_path
|
56
|
+
key = key[0] if key.is_a?(Array)
|
57
|
+
if !key
|
58
|
+
errors << I18n.t('vagrant_simple_cloud.config.private_key')
|
59
|
+
elsif !File.file?(File.expand_path("#{key}.pub", machine.env.root_path))
|
60
|
+
errors << I18n.t('vagrant_simple_cloud.config.public_key', {
|
61
|
+
:key => "#{key}.pub"
|
62
|
+
})
|
63
|
+
end
|
64
|
+
|
65
|
+
{ 'SimpleCloud Provider' => errors }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SimpleCloud
|
3
|
+
module Errors
|
4
|
+
class SimpleCloudError < Vagrant::Errors::VagrantError
|
5
|
+
error_namespace("vagrant_simple_cloud.errors")
|
6
|
+
end
|
7
|
+
|
8
|
+
class APIStatusError < SimpleCloudError
|
9
|
+
error_key(:api_status)
|
10
|
+
end
|
11
|
+
|
12
|
+
class JSONError < SimpleCloudError
|
13
|
+
error_key(:json)
|
14
|
+
end
|
15
|
+
|
16
|
+
class ResultMatchError < SimpleCloudError
|
17
|
+
error_key(:result_match)
|
18
|
+
end
|
19
|
+
|
20
|
+
class CertificateError < SimpleCloudError
|
21
|
+
error_key(:certificate)
|
22
|
+
end
|
23
|
+
|
24
|
+
class LocalIPError < SimpleCloudError
|
25
|
+
error_key(:local_ip)
|
26
|
+
end
|
27
|
+
|
28
|
+
class PublicKeyError < SimpleCloudError
|
29
|
+
error_key(:public_key)
|
30
|
+
end
|
31
|
+
|
32
|
+
class RsyncError < SimpleCloudError
|
33
|
+
error_key(:rsync)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'vagrant-simple_cloud/helpers/result'
|
2
|
+
require 'faraday'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module SimpleCloud
|
7
|
+
module Helpers
|
8
|
+
module Client
|
9
|
+
def client
|
10
|
+
@client ||= ApiClient.new(@machine)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ApiClient
|
15
|
+
include Vagrant::Util::Retryable
|
16
|
+
|
17
|
+
def initialize(machine)
|
18
|
+
@logger = Log4r::Logger.new('vagrant::simple_cloud::apiclient')
|
19
|
+
@config = machine.provider_config
|
20
|
+
@client = Faraday.new({
|
21
|
+
:url => 'https://api.simplecloud.ru/',
|
22
|
+
:ssl => {
|
23
|
+
:ca_file => @config.ca_path
|
24
|
+
}
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
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)
|
39
|
+
begin
|
40
|
+
@logger.info "Request: #{path}"
|
41
|
+
result = @client.send(method) do |req|
|
42
|
+
req.url path
|
43
|
+
req.headers['Authorization'] = "Bearer #{@config.token}"
|
44
|
+
req.body = params.to_json
|
45
|
+
end
|
46
|
+
rescue Faraday::Error::ConnectionFailed => e
|
47
|
+
# TODO this is suspect but because farady wraps the exception
|
48
|
+
# in something generic there doesn't appear to be another
|
49
|
+
# way to distinguish different connection errors :(
|
50
|
+
if e.message =~ /certificate verify failed/
|
51
|
+
raise Errors::CertificateError
|
52
|
+
end
|
53
|
+
|
54
|
+
raise e
|
55
|
+
end
|
56
|
+
|
57
|
+
unless method == :delete
|
58
|
+
begin
|
59
|
+
body = JSON.parse(result.body)
|
60
|
+
@logger.info "Response: #{body}"
|
61
|
+
next_page = body["links"]["pages"]["next"] rescue nil
|
62
|
+
unless next_page.nil?
|
63
|
+
uri = URI.parse(next_page)
|
64
|
+
new_path = path.split("?")[0]
|
65
|
+
next_result = self.request("#{new_path}?#{uri.query}")
|
66
|
+
req_target = new_path.split("/")[-1]
|
67
|
+
body["#{req_target}"].concat(next_result["#{req_target}"])
|
68
|
+
end
|
69
|
+
rescue JSON::ParserError => e
|
70
|
+
raise(Errors::JSONError, {
|
71
|
+
:message => e.message,
|
72
|
+
:path => path,
|
73
|
+
:params => params,
|
74
|
+
:response => result.body
|
75
|
+
})
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
unless /^2\d\d$/ =~ result.status.to_s
|
80
|
+
raise(Errors::APIStatusError, {
|
81
|
+
:path => path,
|
82
|
+
:params => params,
|
83
|
+
:status => result.status,
|
84
|
+
:response => body.inspect
|
85
|
+
})
|
86
|
+
end
|
87
|
+
|
88
|
+
Result.new(body)
|
89
|
+
end
|
90
|
+
|
91
|
+
def wait_for_event(env, id)
|
92
|
+
retryable(:tries => 120, :sleep => 10) do
|
93
|
+
# stop waiting if interrupted
|
94
|
+
next if env[:interrupted]
|
95
|
+
|
96
|
+
# check action status
|
97
|
+
result = self.request("/v2/actions/#{id}")
|
98
|
+
|
99
|
+
yield result if block_given?
|
100
|
+
raise 'not ready' if result['action']['status'] != 'completed'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|