vagrant-1cloud 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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