vagrant-linode 0.1.3 → 0.2.0
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 +4 -4
- data/.gitignore +3 -0
- data/.rspec +4 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +164 -0
- data/Gemfile +9 -6
- data/README.md +21 -9
- data/Rakefile +21 -1
- data/Vagrantfile.multi +18 -0
- data/box/linode-debian-7.5.box +0 -0
- data/box/linode.box +0 -0
- data/box/metadata-debian-7.5.json +12 -0
- data/box/metadata.json +2 -2
- data/features/provision.feature +34 -0
- data/features/steps/sdk_steps.rb +13 -0
- data/features/steps/server_steps.rb +25 -0
- data/features/support/env.rb +34 -0
- data/features/support/fog_mock.rb +16 -0
- data/features/vagrant-linode.feature +68 -0
- data/lib/vagrant-linode.rb +44 -5
- data/lib/vagrant-linode/actions.rb +201 -87
- data/lib/vagrant-linode/actions/connect_linode.rb +36 -0
- data/lib/vagrant-linode/actions/create.rb +9 -9
- data/lib/vagrant-linode/actions/create_image.rb +23 -0
- data/lib/vagrant-linode/actions/destroy.rb +1 -3
- data/lib/vagrant-linode/actions/halt.rb +29 -0
- data/lib/vagrant-linode/actions/is_created.rb +16 -0
- data/lib/vagrant-linode/actions/is_stopped.rb +17 -0
- data/lib/vagrant-linode/actions/list_datacenters.rb +20 -0
- data/lib/vagrant-linode/actions/list_distributions.rb +20 -0
- data/lib/vagrant-linode/actions/list_images.rb +20 -0
- data/lib/vagrant-linode/actions/list_plans.rb +20 -0
- data/lib/vagrant-linode/actions/list_servers.rb +20 -0
- data/lib/vagrant-linode/actions/message_already_active.rb +16 -0
- data/lib/vagrant-linode/actions/message_already_off.rb +16 -0
- data/lib/vagrant-linode/actions/message_not_created.rb +16 -0
- data/lib/vagrant-linode/actions/message_off.rb +16 -0
- data/lib/vagrant-linode/actions/power_off.rb +4 -3
- data/lib/vagrant-linode/actions/power_on.rb +3 -2
- data/lib/vagrant-linode/actions/read_ssh_info.rb +48 -0
- data/lib/vagrant-linode/actions/read_state.rb +38 -0
- data/lib/vagrant-linode/actions/rebuild.rb +3 -2
- data/lib/vagrant-linode/actions/reload.rb +3 -2
- data/lib/vagrant-linode/commands/create_image.rb +21 -0
- data/lib/vagrant-linode/commands/datacenters.rb +21 -0
- data/lib/vagrant-linode/commands/distributions.rb +21 -0
- data/lib/vagrant-linode/commands/images.rb +59 -0
- data/lib/vagrant-linode/commands/list_images.rb +21 -0
- data/lib/vagrant-linode/commands/networks.rb +21 -0
- data/lib/vagrant-linode/commands/plans.rb +21 -0
- data/lib/vagrant-linode/commands/root.rb +81 -0
- data/lib/vagrant-linode/commands/servers.rb +21 -0
- data/lib/vagrant-linode/config.rb +11 -3
- data/lib/vagrant-linode/helpers/client.rb +21 -79
- data/lib/vagrant-linode/helpers/waiter.rb +21 -0
- data/lib/vagrant-linode/plugin.rb +20 -0
- data/lib/vagrant-linode/provider.rb +27 -32
- data/lib/vagrant-linode/version.rb +1 -1
- data/locales/en.yml +17 -1
- data/spec/spec_helper.rb +20 -0
- data/spec/vagrant-linode/actions/list_distributions_spec.rb +47 -0
- data/spec/vagrant-linode/actions/list_plans_spec.rb +47 -0
- data/spec/vagrant-linode/config_spec.rb +189 -0
- data/test/Vagrantfile +4 -9
- data/vagrant-linode.gemspec +1 -1
- metadata +70 -20
- data/lib/vagrant-linode/actions/check_state.rb +0 -19
- data/lib/vagrant-linode/actions/setup_key.rb +0 -52
@@ -8,26 +8,26 @@ include Vagrant::Util::Retryable
|
|
8
8
|
module VagrantPlugins
|
9
9
|
module Linode
|
10
10
|
module Helpers
|
11
|
-
module Client
|
12
|
-
def client
|
13
|
-
def wait_for_event(env, id)
|
14
|
-
retryable(tries: 120, sleep: 10) do
|
15
|
-
# stop waiting if interrupted
|
16
|
-
next if env[:interrupted]
|
17
|
-
# check action status
|
18
|
-
result = @client.linode.job.list(jobid: id, linodeid: env[:machine].id)
|
19
|
-
result = result[0] if result.is_a?(Array)
|
20
|
-
|
21
|
-
yield result if block_given?
|
22
|
-
fail 'not ready' if result['host_finish_dt'] > ''
|
23
|
-
end
|
24
|
-
end
|
25
|
-
linodeapi = ::LinodeAPI::Raw.new(apikey: @machine.provider_config.
|
26
|
-
|
27
|
-
# linodeapi.wait_for_event = wait_for_event
|
28
|
-
# linodeapi.extend wait_for_event
|
29
|
-
end
|
30
|
-
end
|
11
|
+
# module Client
|
12
|
+
# def client
|
13
|
+
# def wait_for_event(env, id)
|
14
|
+
# retryable(tries: 120, sleep: 10) do
|
15
|
+
# # stop waiting if interrupted
|
16
|
+
# next if env[:interrupted]
|
17
|
+
# # check action status
|
18
|
+
# result = @client.linode.job.list(jobid: id, linodeid: env[:machine].id)
|
19
|
+
# result = result[0] if result.is_a?(Array)
|
20
|
+
#
|
21
|
+
# yield result if block_given?
|
22
|
+
# fail 'not ready' if result['host_finish_dt'] > ''
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
# linodeapi = ::LinodeAPI::Raw.new(apikey: @machine.provider_config.api_key,
|
26
|
+
# endpoint: @machine.provider_config.api_url || nil)
|
27
|
+
# # linodeapi.wait_for_event = wait_for_event
|
28
|
+
# # linodeapi.extend wait_for_event
|
29
|
+
# end
|
30
|
+
# end
|
31
31
|
|
32
32
|
class ApiClient
|
33
33
|
include Vagrant::Util::Retryable
|
@@ -35,69 +35,11 @@ module VagrantPlugins
|
|
35
35
|
def initialize(machine)
|
36
36
|
@logger = Log4r::Logger.new('vagrant::linode::apiclient')
|
37
37
|
@config = machine.provider_config
|
38
|
-
|
38
|
+
@client = ::LinodeAPI::Raw.new(apikey: @config.api_key, endpoint: @config.api_url || nil)
|
39
39
|
end
|
40
40
|
|
41
41
|
attr_reader :client
|
42
42
|
|
43
|
-
def delete(path, params = {}, _method = :delete)
|
44
|
-
@client.request :url_encoded
|
45
|
-
request(path, params, :delete)
|
46
|
-
end
|
47
|
-
|
48
|
-
def post(path, params = {}, _method = :post)
|
49
|
-
@client.headers['Content-Type'] = 'application/json'
|
50
|
-
request(path, params, :post)
|
51
|
-
end
|
52
|
-
|
53
|
-
def request(path, params = {}, method = :get)
|
54
|
-
begin
|
55
|
-
@logger.info "Request: #{path}"
|
56
|
-
result = @client.send(method) do |req|
|
57
|
-
req.url path, params
|
58
|
-
req.headers['Authorization'] = "Bearer #{@config.token}"
|
59
|
-
end
|
60
|
-
rescue Faraday::Error::ConnectionFailed => e
|
61
|
-
# TODO this is suspect but because farady wraps the exception
|
62
|
-
# in something generic there doesn't appear to be another
|
63
|
-
# way to distinguish different connection errors :(
|
64
|
-
if e.message =~ /certificate verify failed/
|
65
|
-
raise Errors::CertificateError
|
66
|
-
end
|
67
|
-
|
68
|
-
raise e
|
69
|
-
end
|
70
|
-
|
71
|
-
unless method == :delete
|
72
|
-
begin
|
73
|
-
body = JSON.parse(result.body)
|
74
|
-
@logger.info "Response: #{body}"
|
75
|
-
next_page = body['links']['pages']['next'] rescue nil
|
76
|
-
unless next_page.nil?
|
77
|
-
uri = URI.parse(next_page)
|
78
|
-
new_path = path.split('?')[0]
|
79
|
-
next_result = request("#{new_path}?#{uri.query}")
|
80
|
-
req_target = new_path.split('/')[-1]
|
81
|
-
body["#{req_target}"].concat(next_result["#{req_target}"])
|
82
|
-
end
|
83
|
-
rescue JSON::ParserError => e
|
84
|
-
raise(Errors::JSONError, message: e.message,
|
85
|
-
path: path,
|
86
|
-
params: params,
|
87
|
-
response: result.body)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
unless /^2\d\d$/ =~ result.status.to_s
|
92
|
-
fail(Errors::APIStatusError, path: path,
|
93
|
-
params: params,
|
94
|
-
status: result.status,
|
95
|
-
response: body.inspect)
|
96
|
-
end
|
97
|
-
|
98
|
-
Result.new(body)
|
99
|
-
end
|
100
|
-
|
101
43
|
def wait_for_event(env, id)
|
102
44
|
retryable(tries: 120, sleep: 10) do
|
103
45
|
# stop waiting if interrupted
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Linode
|
3
|
+
module Helpers
|
4
|
+
module Waiter
|
5
|
+
include Vagrant::Util::Retryable
|
6
|
+
def wait_for_event(env, id)
|
7
|
+
retryable(tries: 120, sleep: 10) do
|
8
|
+
# stop waiting if interrupted
|
9
|
+
next if env[:interrupted]
|
10
|
+
# check action status
|
11
|
+
result = env[:linode_api].linode.job.list(jobid: id, linodeid: env[:machine].id)
|
12
|
+
result = result[0] if result.is_a?(Array)
|
13
|
+
|
14
|
+
yield result if block_given?
|
15
|
+
fail 'not ready' if result['host_finish_dt'] > ''
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,3 +1,15 @@
|
|
1
|
+
begin
|
2
|
+
require 'vagrant'
|
3
|
+
rescue LoadError
|
4
|
+
raise 'The Linode provider must be run within Vagrant.'
|
5
|
+
end
|
6
|
+
|
7
|
+
# This is a sanity check to make sure no one is attempting to install
|
8
|
+
# this into an early Vagrant version.
|
9
|
+
if Vagrant::VERSION < '1.1.0'
|
10
|
+
fail 'Linode provider is only compatible with Vagrant 1.1+'
|
11
|
+
end
|
12
|
+
|
1
13
|
module VagrantPlugins
|
2
14
|
module Linode
|
3
15
|
class Plugin < Vagrant.plugin('2')
|
@@ -13,10 +25,18 @@ module VagrantPlugins
|
|
13
25
|
end
|
14
26
|
|
15
27
|
provider(:linode, parallel: true) do
|
28
|
+
Linode.init_i18n
|
29
|
+
Linode.init_logging
|
30
|
+
|
16
31
|
require_relative 'provider'
|
17
32
|
Provider
|
18
33
|
end
|
19
34
|
|
35
|
+
command(:linode) do
|
36
|
+
require_relative 'commands/root'
|
37
|
+
Commands::Root
|
38
|
+
end
|
39
|
+
|
20
40
|
command(:rebuild) do
|
21
41
|
require_relative 'commands/rebuild'
|
22
42
|
Commands::Rebuild
|
@@ -1,13 +1,22 @@
|
|
1
|
+
require 'vagrant-linode/helpers/client'
|
1
2
|
require 'vagrant-linode/actions'
|
2
3
|
|
3
4
|
module VagrantPlugins
|
4
5
|
module Linode
|
5
6
|
class Provider < Vagrant.plugin('2', :provider)
|
7
|
+
def initialize(machine)
|
8
|
+
@machine = machine
|
9
|
+
end
|
10
|
+
|
6
11
|
# This class method caches status for all linodes within
|
7
12
|
# the Linode account. A specific linode's status
|
8
13
|
# may be refreshed by passing :refresh => true as an option.
|
9
14
|
def self.linode(machine, opts = {})
|
10
|
-
|
15
|
+
client = Helpers::ApiClient.new(machine).client
|
16
|
+
|
17
|
+
# @todo how do I reuse VagrantPlugins::Linode::Actions::ConnectLinode ?
|
18
|
+
# ..and nuke the helper
|
19
|
+
# client = env[:linode_api]
|
11
20
|
|
12
21
|
# load status of linodes if it has not been done before
|
13
22
|
unless @linodes
|
@@ -20,7 +29,7 @@ module VagrantPlugins
|
|
20
29
|
linode = client.linode.list(linodeid: machine.id).first
|
21
30
|
linode.network = client.linode.ip.list linodeid: linode['linodeid']
|
22
31
|
@linodes << linode
|
23
|
-
|
32
|
+
elsif machine.id
|
24
33
|
# lookup linode status for the given machine
|
25
34
|
linode = @linodes.find { |d| d['linodeid'].to_s == machine.id }
|
26
35
|
end
|
@@ -37,15 +46,12 @@ module VagrantPlugins
|
|
37
46
|
linode ||= { status: :not_created }
|
38
47
|
end
|
39
48
|
|
40
|
-
def initialize(machine)
|
41
|
-
@machine = machine
|
42
|
-
end
|
43
|
-
|
44
49
|
# Attempt to get the action method from the Action class if it
|
45
50
|
# exists, otherwise return nil to show that we don't support the
|
46
51
|
# given action.
|
47
52
|
def action(name)
|
48
|
-
|
53
|
+
action_method = "action_#{name}"
|
54
|
+
return Actions.send(action_method) if Actions.respond_to?(action_method)
|
49
55
|
nil
|
50
56
|
end
|
51
57
|
|
@@ -56,6 +62,9 @@ module VagrantPlugins
|
|
56
62
|
# is simply the machine instance given to this object. And no
|
57
63
|
# return value is necessary.
|
58
64
|
def machine_id_changed
|
65
|
+
if @machine.id
|
66
|
+
Provider.linode(@machine, refresh: true)
|
67
|
+
end
|
59
68
|
end
|
60
69
|
|
61
70
|
# This should return a hash of information that explains how to
|
@@ -77,40 +86,26 @@ module VagrantPlugins
|
|
77
86
|
# `ssh` prompt with a password, whereas we can pass a private key
|
78
87
|
# via commandline.
|
79
88
|
def ssh_info
|
80
|
-
|
81
|
-
|
82
|
-
return nil if self.state.id != :active
|
83
|
-
|
84
|
-
public_network = linode.network.find { |network| network['ispublic'] == 1 }
|
85
|
-
|
86
|
-
{
|
87
|
-
host: public_network['ipaddress'],
|
88
|
-
port: '22',
|
89
|
-
username: 'root',
|
90
|
-
private_key_path: @machine.config.ssh.private_key_path
|
91
|
-
}
|
89
|
+
env = @machine.action('read_ssh_info')
|
90
|
+
env[:machine_ssh_info]
|
92
91
|
end
|
93
92
|
|
94
93
|
# This should return the state of the machine within this provider.
|
95
94
|
# The state must be an instance of {MachineState}. Please read the
|
96
95
|
# documentation of that class for more information.
|
97
96
|
def state
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
'2' => :off, # powered off
|
106
|
-
'3' => :shutting_down
|
107
|
-
}
|
108
|
-
id = long = short = states[status.to_s]
|
109
|
-
Vagrant::MachineState.new(id, short, long)
|
97
|
+
env = @machine.action('read_state')
|
98
|
+
state_id = env[:machine_state]
|
99
|
+
|
100
|
+
short = I18n.t("vagrant_linode.states.short_#{state_id}")
|
101
|
+
long = I18n.t("vagrant_linode.states.long_#{state_id}")
|
102
|
+
|
103
|
+
Vagrant::MachineState.new(state_id, short, long)
|
110
104
|
end
|
111
105
|
|
112
106
|
def to_s
|
113
|
-
|
107
|
+
id = @machine.id.nil? ? 'new' : @machine.id
|
108
|
+
"Linode (#{id})"
|
114
109
|
end
|
115
110
|
end
|
116
111
|
end
|
data/locales/en.yml
CHANGED
@@ -23,8 +23,24 @@ en:
|
|
23
23
|
trying_rsync_install: "Rsync not found, attempting to install with yum..."
|
24
24
|
rsyncing: "Rsyncing folder: %{hostpath} => %{guestpath}..."
|
25
25
|
rsync_missing: "The rsync executable was not found in the current path."
|
26
|
+
states:
|
27
|
+
short_not_created: "Not Created"
|
28
|
+
short_boot_failed: "Boot Failed"
|
29
|
+
short_being_created: "Being Created"
|
30
|
+
short_brand_new: "Brand New"
|
31
|
+
short_active: "Active"
|
32
|
+
short_off: "Powered Off"
|
33
|
+
short_shutting_down: "Shutting Down"
|
34
|
+
long_not_created: "Linode has not been created"
|
35
|
+
long_boot_failed: "Linode boot failed"
|
36
|
+
long_being_created: "Linode is created"
|
37
|
+
long_brand_new: "Linode is brand new"
|
38
|
+
long_active: "Linode is active"
|
39
|
+
long_off: "Linode is powered off"
|
40
|
+
long_shutting_down: "Linode is shutting down"
|
26
41
|
config:
|
27
|
-
|
42
|
+
api_key: "API Key is required"
|
43
|
+
token: "Config option token is deprecated. Use api_key."
|
28
44
|
private_key: "SSH private key path is required"
|
29
45
|
public_key: "SSH public key not found: %{key}"
|
30
46
|
disk_too_large: "Disk Images use more drive space than plan allocates"
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
if ENV['COVERAGE'] != 'false'
|
2
|
+
require 'simplecov'
|
3
|
+
require 'coveralls'
|
4
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
5
|
+
SimpleCov::Formatter::HTMLFormatter,
|
6
|
+
Coveralls::SimpleCov::Formatter
|
7
|
+
]
|
8
|
+
SimpleCov.start
|
9
|
+
|
10
|
+
# Normally classes are lazily loaded, so any class without a test
|
11
|
+
# is missing from the report. This ensures they show up so we can
|
12
|
+
# see uncovered methods.
|
13
|
+
require 'vagrant'
|
14
|
+
Dir['lib/**/*.rb'].each do|file|
|
15
|
+
require_string = file.match(/lib\/(.*)\.rb/)[1]
|
16
|
+
require require_string
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'linode'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'vagrant-linode/actions/list_distributions'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Linode::Actions::ListImages do
|
5
|
+
let(:app) { lambda { |_env| } }
|
6
|
+
let(:ui) { Vagrant::UI::Silent.new }
|
7
|
+
let(:distributions) do
|
8
|
+
Fog.mock!
|
9
|
+
Fog::Compute.new(provider: :linode,
|
10
|
+
linode_region: :dfw,
|
11
|
+
linode_api_key: 'anything',
|
12
|
+
linode_username: 'anything').distributions
|
13
|
+
end
|
14
|
+
let(:compute_connection) { double('fog connection') }
|
15
|
+
let(:env) do
|
16
|
+
{
|
17
|
+
linode_compute: compute_connection,
|
18
|
+
ui: ui
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
subject(:action) { described_class.new(app, env) }
|
23
|
+
|
24
|
+
before do
|
25
|
+
allow(compute_connection).to receive(:distributions).and_return distributions
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'get distributions from Fog' do
|
29
|
+
expect(compute_connection).to receive(:distributions).and_return distributions
|
30
|
+
action.call(env)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'writes a sorted, formatted image table to Vagrant::UI' do
|
34
|
+
header_line = '%-36s %s' % ['Image ID', 'Image Name']
|
35
|
+
expect(ui).to receive(:info).with(header_line)
|
36
|
+
distributions.sort_by(&:name).each do |image|
|
37
|
+
formatted_line = '%-36s %s' % [image.id.to_s, image.name]
|
38
|
+
expect(ui).to receive(:info).with formatted_line
|
39
|
+
end
|
40
|
+
action.call(env)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'continues the middleware chain' do
|
44
|
+
expect(app).to receive(:call).with(env)
|
45
|
+
action.call(env)
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'vagrant-linode/actions/list_plans'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Linode::Actions::ListPlans do
|
5
|
+
let(:app) { lambda { |_env| } }
|
6
|
+
let(:ui) { Vagrant::UI::Silent.new }
|
7
|
+
let(:plans) do
|
8
|
+
Fog.mock!
|
9
|
+
Fog::Compute.new(provider: :linode,
|
10
|
+
linode_datacenter: :dallas,
|
11
|
+
linode_api_key: 'anything',
|
12
|
+
linode_username: 'anything').plans
|
13
|
+
end
|
14
|
+
let(:compute_connection) { double('fog connection') }
|
15
|
+
let(:env) do
|
16
|
+
{
|
17
|
+
linode_compute: compute_connection,
|
18
|
+
ui: ui
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
subject(:action) { described_class.new(app, env) }
|
23
|
+
|
24
|
+
before do
|
25
|
+
allow(compute_connection).to receive(:plans).and_return plans
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'get plans from Fog' do
|
29
|
+
expect(compute_connection).to receive(:plans).and_return plans
|
30
|
+
action.call(env)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'writes a sorted, formatted plan table to Vagrant::UI' do
|
34
|
+
header_line = '%-36s %s' % ['Plan ID', 'Plan Name']
|
35
|
+
expect(ui).to receive(:info).with(header_line)
|
36
|
+
plans.sort_by(&:id).each do |plan|
|
37
|
+
formatted_line = '%-36s %s' % [plan.id, plan.name]
|
38
|
+
expect(ui).to receive(:info).with formatted_line
|
39
|
+
end
|
40
|
+
action.call(env)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'continues the middleware chain' do
|
44
|
+
expect(app).to receive(:call).with(env)
|
45
|
+
action.call(env)
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'vagrant-linode/config'
|
3
|
+
|
4
|
+
describe VagrantPlugins::Linode::Config do
|
5
|
+
describe 'defaults' do
|
6
|
+
let(:vagrant_public_key) { Vagrant.source_root.join('keys/vagrant.pub') }
|
7
|
+
|
8
|
+
subject do
|
9
|
+
super().tap(&:finalize!)
|
10
|
+
end
|
11
|
+
|
12
|
+
its(:api_key) { should be_nil }
|
13
|
+
its(:api_url) { should be_nil }
|
14
|
+
its(:distribution) { should eq(/Ubuntu/) }
|
15
|
+
its(:datacenter) { should eq(/dallas/) }
|
16
|
+
its(:plan) { should eq(/1024/) }
|
17
|
+
its(:paymentterm) { should eq(/1/) }
|
18
|
+
its(:private_networking) { should eq(/Ubuntu/) }
|
19
|
+
its(:ca_path) { should eql(vagrant_public_key) }
|
20
|
+
its(:ssh_key_name) { should eq(/Vagrant/) }
|
21
|
+
its(:setup) { should eq(true) }
|
22
|
+
its(:xvda_size) { should eq(true) }
|
23
|
+
its(:swap_size) { should eq(256) }
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'overriding defaults' do
|
27
|
+
[:api_key,
|
28
|
+
:api_url,
|
29
|
+
:distribution,
|
30
|
+
:plan,
|
31
|
+
:paymentterm,
|
32
|
+
:private_networking,
|
33
|
+
:ca_path,
|
34
|
+
:ssh_key_name,
|
35
|
+
:setup,
|
36
|
+
:xvda_size,
|
37
|
+
:swap_size].each do |attribute|
|
38
|
+
it "should not default #{attribute} if overridden" do
|
39
|
+
subject.send("#{attribute}=".to_sym, 'foo')
|
40
|
+
subject.finalize!
|
41
|
+
subject.send(attribute).should == 'foo'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should not default plan if overridden' do
|
46
|
+
plan = 'Linode 2048'
|
47
|
+
subject.send(:plan, plan)
|
48
|
+
subject.finalize!
|
49
|
+
subject.send(:plan).should include(plan)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'validation' do
|
55
|
+
let(:machine) { double('machine') }
|
56
|
+
let(:validation_errors) { subject.validate(machine)['Linode Provider'] }
|
57
|
+
let(:error_message) { double('error message') }
|
58
|
+
|
59
|
+
before(:each) do
|
60
|
+
machine.stub_chain(:env, :root_path).and_return '/'
|
61
|
+
subject.api_key = 'bar'
|
62
|
+
end
|
63
|
+
|
64
|
+
subject do
|
65
|
+
super().tap(&:finalize!)
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'with invalid key' do
|
69
|
+
it 'should raise an error' do
|
70
|
+
subject.nonsense1 = true
|
71
|
+
subject.nonsense2 = false
|
72
|
+
I18n.should_receive(:t).with('vagrant.config.common.bad_field',
|
73
|
+
fields: 'nonsense1, nonsense2')
|
74
|
+
.and_return error_message
|
75
|
+
validation_errors.first.should == error_message
|
76
|
+
end
|
77
|
+
end
|
78
|
+
context 'with good values' do
|
79
|
+
it 'should validate' do
|
80
|
+
validation_errors.should be_empty
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'the API key' do
|
85
|
+
it 'should error if not given' do
|
86
|
+
subject.api_key = nil
|
87
|
+
I18n.should_receive(:t).with('vagrant_linode.config.api_key').and_return error_message
|
88
|
+
validation_errors.first.should == error_message
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'the public key path' do
|
93
|
+
it "should have errors if the key doesn't exist" do
|
94
|
+
subject.public_key_path = 'missing'
|
95
|
+
I18n.should_receive(:t).with('vagrant_linode.config.public_key_not_found').and_return error_message
|
96
|
+
validation_errors.first.should == error_message
|
97
|
+
end
|
98
|
+
it 'should not have errors if the key exists with an absolute path' do
|
99
|
+
subject.public_key_path = File.expand_path 'locales/en.yml', Dir.pwd
|
100
|
+
validation_errors.should be_empty
|
101
|
+
end
|
102
|
+
it 'should not have errors if the key exists with a relative path' do
|
103
|
+
machine.stub_chain(:env, :root_path).and_return '.'
|
104
|
+
subject.public_key_path = 'locales/en.yml'
|
105
|
+
validation_errors.should be_empty
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'the username' do
|
110
|
+
it 'should error if not given' do
|
111
|
+
subject.username = nil
|
112
|
+
I18n.should_receive(:t).with('vagrant_linode.config.username_required').and_return error_message
|
113
|
+
validation_errors.first.should == error_message
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
[:linode_compute_url, :linode_auth_url].each do |url|
|
118
|
+
context "the #{url}" do
|
119
|
+
it 'should not validate if the URL is invalid' do
|
120
|
+
subject.send "#{url}=", 'baz'
|
121
|
+
I18n.should_receive(:t).with('vagrant_linode.config.invalid_uri', key: url, uri: 'baz').and_return error_message
|
122
|
+
validation_errors.first.should == error_message
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe 'linode_auth_url' do
|
129
|
+
it 'should return UNSET_VALUE if linode_auth_url and linode_region are UNSET' do
|
130
|
+
subject.linode_auth_url.should == VagrantPlugins::Linode::Config::UNSET_VALUE
|
131
|
+
end
|
132
|
+
it 'should return UNSET_VALUE if linode_auth_url is UNSET and linode_region is :ord' do
|
133
|
+
subject.linode_region = :ord
|
134
|
+
subject.linode_auth_url.should == VagrantPlugins::Linode::Config::UNSET_VALUE
|
135
|
+
end
|
136
|
+
it 'should return UK Authentication endpoint if linode_auth_url is UNSET and linode_region is :lon' do
|
137
|
+
subject.linode_region = :lon
|
138
|
+
subject.linode_auth_url.should == Fog::Linode::UK_AUTH_ENDPOINT
|
139
|
+
end
|
140
|
+
it 'should return custom endpoint if supplied and linode_region is :lon' do
|
141
|
+
my_endpoint = 'http://custom-endpoint.com'
|
142
|
+
subject.linode_region = :lon
|
143
|
+
subject.linode_auth_url = my_endpoint
|
144
|
+
subject.linode_auth_url.should == my_endpoint
|
145
|
+
end
|
146
|
+
it 'should return custom endpoint if supplied and linode_region is UNSET' do
|
147
|
+
my_endpoint = 'http://custom-endpoint.com'
|
148
|
+
subject.linode_auth_url = my_endpoint
|
149
|
+
subject.linode_auth_url.should == my_endpoint
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe 'lon_region?' do
|
154
|
+
it 'should return false if linode_region is UNSET_VALUE' do
|
155
|
+
subject.linode_region = VagrantPlugins::Linode::Config::UNSET_VALUE
|
156
|
+
subject.send(:lon_region?).should be_false
|
157
|
+
end
|
158
|
+
it 'should return false if linode_region is nil' do
|
159
|
+
subject.linode_region = nil
|
160
|
+
subject.send(:lon_region?).should be_false
|
161
|
+
end
|
162
|
+
it 'should return false if linode_region is :ord' do
|
163
|
+
subject.linode_region = :ord
|
164
|
+
subject.send(:lon_region?).should be_false
|
165
|
+
end
|
166
|
+
it "should return true if linode_region is 'lon'" do
|
167
|
+
subject.linode_region = 'lon'
|
168
|
+
subject.send(:lon_region?).should be_true
|
169
|
+
end
|
170
|
+
it 'should return true if linode_Region is :lon' do
|
171
|
+
subject.linode_region = :lon
|
172
|
+
subject.send(:lon_region?).should be_true
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'network' do
|
177
|
+
it 'should remove SERVICE_NET_ID if :service_net is detached' do
|
178
|
+
subject.send(:network, :service_net, attached: false)
|
179
|
+
subject.send(:networks).should_not include(VagrantPlugins::Linode::Config::SERVICE_NET_ID)
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should not allow duplicate networks' do
|
183
|
+
net_id = 'deadbeef-0000-0000-0000-000000000000'
|
184
|
+
subject.send(:network, net_id)
|
185
|
+
subject.send(:network, net_id)
|
186
|
+
subject.send(:networks).count(net_id).should == 1
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|