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.
@@ -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