vagrant-1cloud 0.0.1
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 +7 -0
- data/.gitignore +11 -0
- data/Gemfile +10 -0
- data/LICENSE +373 -0
- data/Rakefile +22 -0
- data/lib/vagrant-1cloud.rb +14 -0
- data/lib/vagrant-1cloud/actions.rb +138 -0
- data/lib/vagrant-1cloud/actions/check_state.rb +19 -0
- data/lib/vagrant-1cloud/actions/create.rb +70 -0
- data/lib/vagrant-1cloud/actions/destroy.rb +30 -0
- data/lib/vagrant-1cloud/actions/power_off.rb +35 -0
- data/lib/vagrant-1cloud/actions/power_on.rb +36 -0
- data/lib/vagrant-1cloud/actions/reload.rb +33 -0
- data/lib/vagrant-1cloud/actions/shut_down.rb +35 -0
- data/lib/vagrant-1cloud/config.rb +46 -0
- data/lib/vagrant-1cloud/errors.rb +33 -0
- data/lib/vagrant-1cloud/helpers/client.rb +83 -0
- data/lib/vagrant-1cloud/helpers/result.rb +40 -0
- data/lib/vagrant-1cloud/plugin.rb +21 -0
- data/lib/vagrant-1cloud/provider.rb +67 -0
- data/lib/vagrant-1cloud/version.rb +5 -0
- data/locales/en.yml +67 -0
- data/test/Vagrantfile +16 -0
- data/test/scripts/provision.sh +3 -0
- data/test/test.sh +9 -0
- data/vagrant-1cloud.gemspec +21 -0
- metadata +113 -0
@@ -0,0 +1,19 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module OneCloud
|
3
|
+
module Actions
|
4
|
+
class CheckState
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@machine = env[:machine]
|
8
|
+
@logger = Log4r::Logger.new('vagrant::1cloud::check_state')
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env[:machine_state] = @machine.state.id
|
13
|
+
@logger.info "Machine state is '#{@machine.state.id}'"
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'vagrant-1cloud/helpers/client'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OneCloud
|
5
|
+
module Actions
|
6
|
+
class Create
|
7
|
+
include Helpers::Client
|
8
|
+
include Vagrant::Util::Retryable
|
9
|
+
|
10
|
+
def initialize(app, env)
|
11
|
+
@app = app
|
12
|
+
@machine = env[:machine]
|
13
|
+
@client = client
|
14
|
+
@logger = Log4r::Logger.new('vagrant::1cloud::create')
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
# submit new droplet request
|
19
|
+
result = @clientservice.post('/server', {
|
20
|
+
:HDD => @machine.provider_config.hdd,
|
21
|
+
:HDDType => @machine.provider_config.hdd_type,
|
22
|
+
:CPU => @machine.provider_config.cpu,
|
23
|
+
:RAM => @machine.provider_config.ram,
|
24
|
+
:DCLocation => @machine.provider_config.region,
|
25
|
+
:ImageID => @machine.provider_config.image,
|
26
|
+
:Name => @machine.config.vm.hostname || @machine.name,
|
27
|
+
:isHighPerformance => @machine.provider_config.hi_perf
|
28
|
+
})
|
29
|
+
|
30
|
+
# assign the machine id for reference in other commands
|
31
|
+
@machine.id = result['id'].to_s
|
32
|
+
|
33
|
+
# wait for request to complete
|
34
|
+
result = @client.request("/server/#{@machine.id}/action")
|
35
|
+
env[:ui].info I18n.t('vagrant_1cloud.info.creating')
|
36
|
+
@client.wait_for_event(env, @machine.id, result.first['ID'])
|
37
|
+
|
38
|
+
# refresh droplet state with provider
|
39
|
+
droplet = Provider.droplet(@machine, :refresh => true)
|
40
|
+
|
41
|
+
# wait for ssh to be ready
|
42
|
+
retryable(:tries => 120, :sleep => 10) do
|
43
|
+
next if env[:interrupted]
|
44
|
+
raise 'not ready' if !@machine.communicate.ready?
|
45
|
+
end
|
46
|
+
|
47
|
+
@app.call(env)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Both the recover and terminate are stolen almost verbatim from
|
51
|
+
# the Vagrant AWS provider up action
|
52
|
+
# def recover(env)
|
53
|
+
# return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
|
54
|
+
|
55
|
+
# if @machine.state.id != :not_created
|
56
|
+
# terminate(env)
|
57
|
+
# end
|
58
|
+
# end
|
59
|
+
|
60
|
+
# def terminate(env)
|
61
|
+
# destroy_env = env.dup
|
62
|
+
# destroy_env.delete(:interrupted)
|
63
|
+
# destroy_env[:config_validate] = false
|
64
|
+
# destroy_env[:force_confirm_destroy] = true
|
65
|
+
# env[:action_runner].run(Actions.destroy, destroy_env)
|
66
|
+
# end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'vagrant-1cloud/helpers/client'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OneCloud
|
5
|
+
module Actions
|
6
|
+
class Destroy
|
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::1cloud::destroy')
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
# submit destroy droplet request
|
18
|
+
@client.delete("/server/#{@machine.id}")
|
19
|
+
|
20
|
+
env[:ui].info I18n.t('vagrant_1cloud.info.destroying')
|
21
|
+
|
22
|
+
# set the machine id to nil to cleanup local vagrant state
|
23
|
+
@machine.id = nil
|
24
|
+
|
25
|
+
@app.call(env)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'vagrant-1cloud/helpers/client'
|
2
|
+
#TODO: --force
|
3
|
+
module VagrantPlugins
|
4
|
+
module OneCloud
|
5
|
+
module Actions
|
6
|
+
class PowerOff
|
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::1cloud::power_off')
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
# submit power off droplet request
|
18
|
+
result = @client.post("/server/#{@machine.id}/action", {
|
19
|
+
:Type => 'PowerOff'
|
20
|
+
})
|
21
|
+
|
22
|
+
# wait for request to complete
|
23
|
+
env[:ui].info I18n.t('vagrant_1cloud.info.powering_off')
|
24
|
+
@client.wait_for_event(env, @machine.id, result['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,36 @@
|
|
1
|
+
require 'vagrant-1cloud/helpers/client'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OneCloud
|
5
|
+
module Actions
|
6
|
+
class PowerOn
|
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::1cloud::power_on')
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
# submit power on droplet request
|
18
|
+
result = @client.post("/server/#{@machine.id}/action", {
|
19
|
+
:Type => 'PowerOn'
|
20
|
+
})
|
21
|
+
|
22
|
+
# wait for request to complete
|
23
|
+
env[:ui].info I18n.t('vagrant_1cloud.info.powering_on')
|
24
|
+
@client.wait_for_event(env, @machine.id, result['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
|
+
|
36
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'vagrant-1cloud/helpers/client'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OneCloud
|
5
|
+
module Actions
|
6
|
+
class Reload
|
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::1cloud::reload')
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
# submit reboot droplet request
|
18
|
+
result = @client.post("/server/#{@machine.id}/action", {
|
19
|
+
:Type => 'PowerReboot'
|
20
|
+
})
|
21
|
+
|
22
|
+
# wait for request to complete
|
23
|
+
env[:ui].info I18n.t('vagrant_1cloud.info.reloading')
|
24
|
+
@client.wait_for_event(env, @machine.id, result['ID'])
|
25
|
+
|
26
|
+
@app.call(env)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'vagrant-1cloud/helpers/client'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module OneCloud
|
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::1cloud::shut_down')
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
# submit shutdown droplet request
|
18
|
+
result = @client.post("/server/#{@machine.id}/action", {
|
19
|
+
:Type => 'ShutDownGuestOS'
|
20
|
+
})
|
21
|
+
|
22
|
+
# wait for request to complete
|
23
|
+
env[:ui].info I18n.t('vagrant_1cloud.info.shutting_down')
|
24
|
+
@client.wait_for_event(env, @machine.id, result['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,46 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module OneCloud
|
3
|
+
class Config < Vagrant.plugin('2', :config)
|
4
|
+
attr_accessor :token
|
5
|
+
attr_accessor :image
|
6
|
+
attr_accessor :region
|
7
|
+
attr_accessor :hdd
|
8
|
+
attr_accessor :hdd_type
|
9
|
+
attr_accessor :cpu
|
10
|
+
attr_accessor :ram
|
11
|
+
attr_accessor :hi_perf
|
12
|
+
attr_accessor :ca_path
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@token = UNSET_VALUE
|
16
|
+
@image = UNSET_VALUE
|
17
|
+
@region = UNSET_VALUE
|
18
|
+
@hdd = UNSET_VALUE
|
19
|
+
@hdd_type = UNSET_VALUE
|
20
|
+
@cpu = UNSET_VALUE
|
21
|
+
@ram = UNSET_VALUE
|
22
|
+
@hi_perf = UNSET_VALUE
|
23
|
+
@ca_path = UNSET_VALUE
|
24
|
+
end
|
25
|
+
|
26
|
+
def finalize!
|
27
|
+
@token = ENV['DO_TOKEN'] if @token == UNSET_VALUE
|
28
|
+
@image = '7' if @image == UNSET_VALUE
|
29
|
+
@region = 'SDN_SPb' if @region == UNSET_VALUE
|
30
|
+
@hdd = '1' if @hdd == UNSET_VALUE
|
31
|
+
@hdd_type = 'SAS' if @hdd_type == UNSET_VALUE
|
32
|
+
@cpu = '1' if @cpu == UNSET_VALUE
|
33
|
+
@ram = '512' if @ram == UNSET_VALUE
|
34
|
+
@hi_perf = false if @hi_perf == UNSET_VALUE
|
35
|
+
@ca_path = nil if @ca_path == UNSET_VALUE
|
36
|
+
end
|
37
|
+
|
38
|
+
def validate(machine)
|
39
|
+
errors = []
|
40
|
+
errors << I18n.t('vagrant_1cloud.config.token') if !@token
|
41
|
+
|
42
|
+
{ '1cloud Provider' => errors }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module OneCloud
|
3
|
+
module Errors
|
4
|
+
class OneCloudError < Vagrant::Errors::VagrantError
|
5
|
+
error_namespace("vagrant_1cloud.errors")
|
6
|
+
end
|
7
|
+
|
8
|
+
class APIStatusError < OneCloudError
|
9
|
+
error_key(:api_status)
|
10
|
+
end
|
11
|
+
|
12
|
+
class JSONError < OneCloudError
|
13
|
+
error_key(:json)
|
14
|
+
end
|
15
|
+
|
16
|
+
class ResultMatchError < OneCloudError
|
17
|
+
error_key(:result_match)
|
18
|
+
end
|
19
|
+
|
20
|
+
class CertificateError < OneCloudError
|
21
|
+
error_key(:certificate)
|
22
|
+
end
|
23
|
+
|
24
|
+
class LocalIPError < OneCloudError
|
25
|
+
error_key(:local_ip)
|
26
|
+
end
|
27
|
+
|
28
|
+
class RsyncError < OneCloudError
|
29
|
+
error_key(:rsync)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'vagrant-1cloud/helpers/result'
|
2
|
+
require 'faraday'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module OneCloud
|
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::1cloud::apiclient')
|
19
|
+
@config = machine.provider_config
|
20
|
+
@client = Faraday.new({
|
21
|
+
:url => 'https://api.1cloud.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 faraday 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
|
+
raise e
|
54
|
+
end
|
55
|
+
|
56
|
+
unless /^2\d\d$/ =~ result.status.to_s
|
57
|
+
raise(Errors::APIStatusError, {
|
58
|
+
:path => path,
|
59
|
+
:params => params,
|
60
|
+
:status => result.status,
|
61
|
+
:response => body.inspect
|
62
|
+
})
|
63
|
+
end
|
64
|
+
|
65
|
+
Result.new(result)
|
66
|
+
end
|
67
|
+
|
68
|
+
def wait_for_event(env, m_id, id)
|
69
|
+
retryable(:tries => 120, :sleep => 10) do
|
70
|
+
# stop waiting if interrupted
|
71
|
+
next if env[:interrupted]
|
72
|
+
|
73
|
+
# check action status
|
74
|
+
result = self.request("/server/#{m_id}/action/#{id}")
|
75
|
+
|
76
|
+
yield result if block_given?
|
77
|
+
raise 'not ready' if result['State'] != 'Completed'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module OneCloud
|
3
|
+
module Helpers
|
4
|
+
class Result
|
5
|
+
def initialize(body)
|
6
|
+
@result = body
|
7
|
+
end
|
8
|
+
|
9
|
+
def [](key)
|
10
|
+
@result[key.to_s]
|
11
|
+
end
|
12
|
+
|
13
|
+
def find_id(sub_obj, search)
|
14
|
+
find(sub_obj, search)["id"]
|
15
|
+
end
|
16
|
+
|
17
|
+
def find(sub_obj, search)
|
18
|
+
key = search.keys.first
|
19
|
+
value = search[key].to_s
|
20
|
+
key = key.to_s
|
21
|
+
|
22
|
+
result = @result[sub_obj.to_s].inject(nil) do |result, obj|
|
23
|
+
obj[key] == value ? obj : result
|
24
|
+
end
|
25
|
+
|
26
|
+
result || error(sub_obj, key, value)
|
27
|
+
end
|
28
|
+
|
29
|
+
def error(sub_obj, key, value)
|
30
|
+
raise(Errors::ResultMatchError, {
|
31
|
+
:key => key,
|
32
|
+
:value => value,
|
33
|
+
:collection_name => sub_obj.to_s,
|
34
|
+
:sub_obj => @result[sub_obj.to_s]
|
35
|
+
})
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|