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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rspec +4 -0
  4. data/.rubocop.yml +1 -0
  5. data/.rubocop_todo.yml +164 -0
  6. data/Gemfile +9 -6
  7. data/README.md +21 -9
  8. data/Rakefile +21 -1
  9. data/Vagrantfile.multi +18 -0
  10. data/box/linode-debian-7.5.box +0 -0
  11. data/box/linode.box +0 -0
  12. data/box/metadata-debian-7.5.json +12 -0
  13. data/box/metadata.json +2 -2
  14. data/features/provision.feature +34 -0
  15. data/features/steps/sdk_steps.rb +13 -0
  16. data/features/steps/server_steps.rb +25 -0
  17. data/features/support/env.rb +34 -0
  18. data/features/support/fog_mock.rb +16 -0
  19. data/features/vagrant-linode.feature +68 -0
  20. data/lib/vagrant-linode.rb +44 -5
  21. data/lib/vagrant-linode/actions.rb +201 -87
  22. data/lib/vagrant-linode/actions/connect_linode.rb +36 -0
  23. data/lib/vagrant-linode/actions/create.rb +9 -9
  24. data/lib/vagrant-linode/actions/create_image.rb +23 -0
  25. data/lib/vagrant-linode/actions/destroy.rb +1 -3
  26. data/lib/vagrant-linode/actions/halt.rb +29 -0
  27. data/lib/vagrant-linode/actions/is_created.rb +16 -0
  28. data/lib/vagrant-linode/actions/is_stopped.rb +17 -0
  29. data/lib/vagrant-linode/actions/list_datacenters.rb +20 -0
  30. data/lib/vagrant-linode/actions/list_distributions.rb +20 -0
  31. data/lib/vagrant-linode/actions/list_images.rb +20 -0
  32. data/lib/vagrant-linode/actions/list_plans.rb +20 -0
  33. data/lib/vagrant-linode/actions/list_servers.rb +20 -0
  34. data/lib/vagrant-linode/actions/message_already_active.rb +16 -0
  35. data/lib/vagrant-linode/actions/message_already_off.rb +16 -0
  36. data/lib/vagrant-linode/actions/message_not_created.rb +16 -0
  37. data/lib/vagrant-linode/actions/message_off.rb +16 -0
  38. data/lib/vagrant-linode/actions/power_off.rb +4 -3
  39. data/lib/vagrant-linode/actions/power_on.rb +3 -2
  40. data/lib/vagrant-linode/actions/read_ssh_info.rb +48 -0
  41. data/lib/vagrant-linode/actions/read_state.rb +38 -0
  42. data/lib/vagrant-linode/actions/rebuild.rb +3 -2
  43. data/lib/vagrant-linode/actions/reload.rb +3 -2
  44. data/lib/vagrant-linode/commands/create_image.rb +21 -0
  45. data/lib/vagrant-linode/commands/datacenters.rb +21 -0
  46. data/lib/vagrant-linode/commands/distributions.rb +21 -0
  47. data/lib/vagrant-linode/commands/images.rb +59 -0
  48. data/lib/vagrant-linode/commands/list_images.rb +21 -0
  49. data/lib/vagrant-linode/commands/networks.rb +21 -0
  50. data/lib/vagrant-linode/commands/plans.rb +21 -0
  51. data/lib/vagrant-linode/commands/root.rb +81 -0
  52. data/lib/vagrant-linode/commands/servers.rb +21 -0
  53. data/lib/vagrant-linode/config.rb +11 -3
  54. data/lib/vagrant-linode/helpers/client.rb +21 -79
  55. data/lib/vagrant-linode/helpers/waiter.rb +21 -0
  56. data/lib/vagrant-linode/plugin.rb +20 -0
  57. data/lib/vagrant-linode/provider.rb +27 -32
  58. data/lib/vagrant-linode/version.rb +1 -1
  59. data/locales/en.yml +17 -1
  60. data/spec/spec_helper.rb +20 -0
  61. data/spec/vagrant-linode/actions/list_distributions_spec.rb +47 -0
  62. data/spec/vagrant-linode/actions/list_plans_spec.rb +47 -0
  63. data/spec/vagrant-linode/config_spec.rb +189 -0
  64. data/test/Vagrantfile +4 -9
  65. data/vagrant-linode.gemspec +1 -1
  66. metadata +70 -20
  67. data/lib/vagrant-linode/actions/check_state.rb +0 -19
  68. 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.token,
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
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
- @client = ::LinodeAPI::Raw.new(apikey: @config.token, endpoint: @config.api_url || nil)
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
- client = Helpers::ApiClient.new(machine).client
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
- else
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
- return Actions.send(name) if Actions.respond_to?(name)
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
- linode = Provider.linode(@machine, refresh: true)
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
- status = Provider.linode(@machine)['status']
99
- states = {
100
- "" => :not_created,
101
- '-2' => :boot_failed,
102
- '-1' => :being_created,
103
- '0' => :brand_new, # brand new
104
- '1' => :active, # running
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
- "Linode"
107
+ id = @machine.id.nil? ? 'new' : @machine.id
108
+ "Linode (#{id})"
114
109
  end
115
110
  end
116
111
  end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Linode
3
- VERSION = '0.1.3'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  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
- token: "Token is required"
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"
@@ -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