vagrant-vultr_pro 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,76 @@
1
+ module VagrantPlugins
2
+ module Vultr
3
+ class Config < Vagrant.plugin(2, :config)
4
+ attr_accessor :token
5
+ attr_accessor :region
6
+ attr_accessor :os
7
+ attr_accessor :snapshot
8
+ attr_accessor :plan
9
+ attr_accessor :enable_ipv6
10
+ attr_accessor :enable_private_network
11
+ attr_accessor :label
12
+ attr_accessor :tag
13
+ attr_accessor :hostname
14
+ attr_accessor :timeout
15
+ attr_accessor :ssh_key
16
+ attr_accessor :startup_script
17
+
18
+ def initialize
19
+ @token = UNSET_VALUE
20
+ @region = UNSET_VALUE
21
+ @os = UNSET_VALUE
22
+ @snapshot = UNSET_VALUE
23
+ @plan = UNSET_VALUE
24
+ @enable_ipv6 = UNSET_VALUE
25
+ @enable_private_network = UNSET_VALUE
26
+ @label = UNSET_VALUE
27
+ @tag = UNSET_VALUE
28
+ @hostname = UNSET_VALUE
29
+ @timeout = UNSET_VALUE
30
+ @ssh_key = UNSET_VALUE
31
+ @startup_script = UNSET_VALUE
32
+ end
33
+
34
+ def finalize!
35
+ @token = ENV['VULTR_TOKEN'] if @token == UNSET_VALUE
36
+ @region = 'Seattle' if @region == UNSET_VALUE
37
+ @os = 'Ubuntu 14.04 x64' if @os == UNSET_VALUE && @snapshot == UNSET_VALUE
38
+ @plan = '768 MB RAM,15 GB SSD,1.00 TB BW' if @plan == UNSET_VALUE
39
+ @snapshot = nil if @snapshot == UNSET_VALUE
40
+ @enable_ipv6 = 'no' if @enable_ipv6 == UNSET_VALUE
41
+ @enable_private_network = 'no' if @enable_private_network == UNSET_VALUE
42
+ @label = '' if @label == UNSET_VALUE
43
+ @tag = '' if @tag == UNSET_VALUE
44
+ @hostname = '' if @hostname == UNSET_VALUE
45
+ @script = '' if @script == UNSET_VALUE
46
+ @timeout = 300 if @timeout == UNSET_VALUE
47
+ @ssh_key = 'vagrant' if @ssh_key == UNSET_VALUE
48
+ @startup_script = '' if @startup_script == UNSET_VALUE
49
+ end
50
+
51
+ def validate(machine)
52
+ errors = []
53
+
54
+ key = machine.config.ssh.private_key_path
55
+ key = key.first if key.is_a?(Array)
56
+ if !key
57
+ errors << 'You have to specify config.ssh.private_key_path.'
58
+ elsif !File.file?(File.expand_path("#{key}.pub", machine.env.root_path))
59
+ errors << "Cannot find SSH public key: #{key}.pub."
60
+ end
61
+
62
+ if both_os_and_snapshot_provided?
63
+ errors << 'You have to specify one of provider.os or provider.snapshot.'
64
+ end
65
+
66
+ {'vultr' => errors}
67
+ end
68
+
69
+ private
70
+
71
+ def both_os_and_snapshot_provided?
72
+ @os != UNSET_VALUE && @snapshot
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,156 @@
1
+ require 'vultr/vultr'
2
+ require 'vagrant/util/retryable'
3
+
4
+ module VagrantPlugins
5
+ module Vultr
6
+ module Helpers
7
+ module Client
8
+ def client
9
+ @client ||= ApiClient.new(@machine.provider_config.token, @machine.provider_config.timeout)
10
+ end
11
+ end
12
+
13
+
14
+ class ApiClient
15
+ include Vagrant::Util::Retryable
16
+
17
+ TimeoutError = Class.new(StandardError)
18
+
19
+ def initialize(token, timeout)
20
+ ::Vultr.api_key = token
21
+ @timeout = timeout || 300
22
+ end
23
+
24
+ def servers
25
+ servers = request { ::Vultr::Server.list }
26
+ servers = servers.values if servers.any?
27
+
28
+ servers
29
+ end
30
+
31
+ def server(sub_id)
32
+ servers.find { |server| server['SUBID'] == sub_id }
33
+ end
34
+
35
+ def create_server(attributes)
36
+ params = {
37
+ DCID: region_id(attributes[:region]),
38
+ VPSPLANID: vps_plan_id(attributes[:plan]),
39
+ SSHKEYID: ssh_key_id(attributes[:ssh_key_name]),
40
+ SCRIPTID: startup_script_id(attributes[:startup_script_name]),
41
+ enable_ipv6: attributes[:enable_ipv6],
42
+ enable_private_network: attributes[:enable_private_network],
43
+ label: attributes[:label],
44
+ tag: attributes[:tag],
45
+ hostname: attributes[:hostname]
46
+ }
47
+
48
+ if attributes[:snapshot]
49
+ params.merge!(OSID: os_id('Snapshot'), SNAPSHOTID: attributes[:snapshot])
50
+ else
51
+ params.merge!(OSID: os_id(attributes[:os]))
52
+ end
53
+
54
+ request { ::Vultr::Server.create(params) }['SUBID']
55
+ end
56
+
57
+ def start_server(sub_id)
58
+ request { ::Vultr::Server.start(SUBID: sub_id) }
59
+ end
60
+
61
+ def reboot_server(sub_id)
62
+ request { ::Vultr::Server.reboot(SUBID: sub_id) }
63
+ end
64
+
65
+ def stop_server(sub_id)
66
+ request { ::Vultr::Server.halt(SUBID: sub_id) }
67
+ end
68
+
69
+ def destroy_server(sub_id)
70
+ request { ::Vultr::Server.destroy(SUBID: sub_id) }
71
+ end
72
+
73
+ def os_id(os)
74
+ oses = request { ::Vultr::OS.list }
75
+ oses.values.find { |o| o['name'] == os }['OSID']
76
+ end
77
+
78
+ def region_id(region)
79
+ regions = request { ::Vultr::Regions.list }
80
+ regions.values.find { |r| r['name'] == region }['DCID']
81
+ end
82
+
83
+ def vps_plan_id(plan)
84
+ plans = request { ::Vultr::Plans.list }
85
+ plans.values.find { |p| p['name'] == plan }['VPSPLANID']
86
+ end
87
+
88
+ def startup_script_id(startup_script_name)
89
+ scripts = request { ::Vultr::StartupScript.list }
90
+ script = scripts.values.find { |s| s['name'] == startup_script_name }
91
+ script['SCRIPTID'] if script
92
+ end
93
+
94
+ def ssh_key_id(ssh_key_name)
95
+ ssh_keys = request { ::Vultr::SSHKey.list }
96
+ ssh_key = ssh_keys.values.find { |s| s['name'] == ssh_key_name }
97
+ ssh_key['SSHKEYID'] if ssh_key
98
+ end
99
+
100
+ def create_ssh_key(name, key)
101
+ request { ::Vultr::SSHKey.create(name: name, ssh_key: key) }['SSHKEYID']
102
+ end
103
+
104
+ def wait_to_activate(sub_id)
105
+ wait_until do
106
+ # it might be not shown in API for some reason
107
+ server = server(sub_id)
108
+ server && server['status'] == 'active'
109
+ end
110
+ end
111
+
112
+ def wait_to_power_on(sub_id)
113
+ wait_until do
114
+ # it might be not shown in API for some reason
115
+ server = server(sub_id)
116
+ server && server['status'] == 'active' && server['power_status'] == 'running' && server['server_state'] == 'ok'
117
+ end
118
+ end
119
+
120
+ def wait_to_destroy(sub_id)
121
+ wait_until { !server(sub_id) }
122
+ end
123
+
124
+ # @todo Fix the case when SSH key is not ready so it asks for password
125
+ # @todo Extract away from client?
126
+ def wait_for_ssh(machine)
127
+ # SSH may be unreachable after server is started
128
+ wait_until(Errno::ENETUNREACH) do
129
+ machine.communicate.wait_for_ready(@timeout)
130
+ end
131
+ end
132
+
133
+ private
134
+
135
+ def request
136
+ if interval = ENV['VULTR_RATE_LIMIT_INTERVAL_MS']
137
+ sleep interval.to_f / 1000
138
+ end
139
+
140
+ response = yield
141
+ if response[:status] != 200
142
+ raise "API request failed: #{response[:result]}."
143
+ else
144
+ response[:result]
145
+ end
146
+ end
147
+
148
+ def wait_until(exception = TimeoutError)
149
+ retryable(tries: @timeout, sleep: 1, on: exception) do
150
+ yield or raise exception
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,18 @@
1
+ module VagrantPlugins
2
+ module Vultr
3
+ class Plugin < Vagrant.plugin(2)
4
+ name 'vagrant-vultr_pro'
5
+ description 'Plugin allows to use Vultr as provider'
6
+
7
+ config(:vultr, :provider) do
8
+ require_relative 'config'
9
+ Config
10
+ end
11
+
12
+ provider(:vultr) do
13
+ require_relative 'provider'
14
+ Provider
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,48 @@
1
+ require 'vagrant-vultr/helpers/client'
2
+
3
+ module VagrantPlugins
4
+ module Vultr
5
+ class Provider < Vagrant.plugin(2, :provider)
6
+ include Helpers::Client
7
+
8
+ def initialize(machine)
9
+ @machine = machine
10
+ @client = client
11
+ end
12
+
13
+ def action(name)
14
+ return unless Action.respond_to?(name)
15
+ Action.__send__(name)
16
+ end
17
+
18
+ def state
19
+ server = @client.server(@machine.id)
20
+
21
+ if server
22
+ if server['status'] == 'active' && server['power_status'] == 'running'
23
+ state = :active
24
+ else
25
+ state = :off
26
+ end
27
+ else
28
+ state = :not_created
29
+ end
30
+
31
+ long = short = state.to_s
32
+ Vagrant::MachineState.new(state, short, long)
33
+ end
34
+
35
+ def ssh_info
36
+ server = @client.server(@machine.id)
37
+ return if server['status'] != 'active' && server['power_status'] != 'running'
38
+
39
+ {
40
+ host: server['main_ip'],
41
+ port: '22',
42
+ username: 'root',
43
+ PasswordAuthentication: 'no'
44
+ }
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,12 @@
1
+ require 'vagrant'
2
+
3
+ require 'vagrant-vultr/action'
4
+ require 'vagrant-vultr/plugin'
5
+
6
+ module VagrantPlugins
7
+ module Vultr
8
+ def self.source_root
9
+ @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ module Vultr
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 4
5
+ TINY = 3
6
+ PRE = nil
7
+
8
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
+ end
10
+ end