vagrant-linode 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|