vagrant-vultr_pro 0.2.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,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