vagrant-softlayer 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. data/.gitignore +15 -0
  2. data/Gemfile +7 -0
  3. data/LICENSE +20 -0
  4. data/README.md +233 -0
  5. data/Rakefile +6 -0
  6. data/dummy.box +0 -0
  7. data/example_box/README.md +13 -0
  8. data/example_box/metadata.json +3 -0
  9. data/lib/vagrant-softlayer/action/create_instance.rb +54 -0
  10. data/lib/vagrant-softlayer/action/destroy_instance.rb +23 -0
  11. data/lib/vagrant-softlayer/action/is.rb +21 -0
  12. data/lib/vagrant-softlayer/action/message.rb +22 -0
  13. data/lib/vagrant-softlayer/action/read_ssh_info.rb +28 -0
  14. data/lib/vagrant-softlayer/action/read_state.rb +42 -0
  15. data/lib/vagrant-softlayer/action/rebuild_instance.rb +35 -0
  16. data/lib/vagrant-softlayer/action/setup_softlayer.rb +37 -0
  17. data/lib/vagrant-softlayer/action/start_instance.rb +21 -0
  18. data/lib/vagrant-softlayer/action/stop_instance.rb +30 -0
  19. data/lib/vagrant-softlayer/action/sync_folders.rb +99 -0
  20. data/lib/vagrant-softlayer/action/update_dns.rb +96 -0
  21. data/lib/vagrant-softlayer/action/wait_for_provision.rb +40 -0
  22. data/lib/vagrant-softlayer/action/wait_for_rebuild.rb +36 -0
  23. data/lib/vagrant-softlayer/action.rb +200 -0
  24. data/lib/vagrant-softlayer/command/rebuild.rb +34 -0
  25. data/lib/vagrant-softlayer/config.rb +178 -0
  26. data/lib/vagrant-softlayer/errors.rb +25 -0
  27. data/lib/vagrant-softlayer/plugin.rb +77 -0
  28. data/lib/vagrant-softlayer/provider.rb +47 -0
  29. data/lib/vagrant-softlayer/util/network.rb +42 -0
  30. data/lib/vagrant-softlayer/util/warden.rb +38 -0
  31. data/lib/vagrant-softlayer/version.rb +5 -0
  32. data/lib/vagrant-softlayer.rb +22 -0
  33. data/locales/en.yml +146 -0
  34. data/spec/spec_helper.rb +1 -0
  35. data/spec/vagrant-softlayer/config_spec.rb +156 -0
  36. data/vagrant-softlayer.gemspec +53 -0
  37. metadata +152 -0
@@ -0,0 +1,99 @@
1
+ require "log4r"
2
+
3
+ require "vagrant/util/scoped_hash_override"
4
+ require "vagrant/util/subprocess"
5
+ require "vagrant/util/which"
6
+
7
+ module VagrantPlugins
8
+ module SoftLayer
9
+ module Action
10
+ # This middleware uses `rsync` to sync the folders over to the
11
+ # SoftLayer instance.
12
+ class SyncFolders
13
+ include Vagrant::Util::ScopedHashOverride
14
+
15
+ def initialize(app, env)
16
+ @app = app
17
+ @logger = Log4r::Logger.new("vagrant_softlayer::action::sync_folders")
18
+ end
19
+
20
+ def call(env)
21
+ @app.call(env)
22
+
23
+ ssh_info = env[:machine].ssh_info
24
+
25
+ unless Vagrant::Util::Which.which("rsync")
26
+ env[:ui].warn(I18n.t("vagrant_softlayer.sync_folders.rsync_not_found", :side => "host"))
27
+ return
28
+ end
29
+
30
+ if env[:machine].communicate.execute("which rsync", :error_check => false) != 0
31
+ env[:ui].warn(I18n.t("vagrant_softlayer.sync_folders.rsync_not_found", :side => "guest"))
32
+ return
33
+ end
34
+
35
+ env[:machine].config.vm.synced_folders.each do |id, data|
36
+ data = scoped_hash_override(data, :softlayer)
37
+
38
+ # Ignore disabled shared folders
39
+ next if data[:disabled]
40
+
41
+ hostpath = File.expand_path(data[:hostpath], env[:root_path])
42
+ guestpath = data[:guestpath]
43
+
44
+ # Make sure there is a trailing slash on the host path to
45
+ # avoid creating an additional directory with rsync
46
+ hostpath = "#{hostpath}/" if hostpath !~ /\/$/
47
+
48
+ # on windows rsync.exe requires cygdrive-style paths
49
+ if Vagrant::Util::Platform.windows?
50
+ hostpath = hostpath.gsub(/^(\w):/) { "/cygdrive/#{$1}" }
51
+ end
52
+
53
+ env[:ui].info(I18n.t("vagrant_softlayer.sync_folders.rsync_folder",
54
+ :hostpath => hostpath,
55
+ :guestpath => guestpath))
56
+
57
+ # Create the host path if it doesn't exist and option flag is set
58
+ if data[:create]
59
+ begin
60
+ FileUtils::mkdir_p(hostpath)
61
+ rescue => err
62
+ raise Errors::MkdirError,
63
+ :hostpath => hostpath,
64
+ :err => err
65
+ end
66
+ end
67
+
68
+ # Create the guest path
69
+ env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
70
+ env[:machine].communicate.sudo(
71
+ "chown #{ssh_info[:username]} '#{guestpath}'")
72
+
73
+ # Rsync over to the guest path using the SSH info
74
+ command = [
75
+ "rsync", "--verbose", "--archive", "-z",
76
+ "--exclude", ".vagrant/", "--exclude", "Vagrantfile",
77
+ "-e", "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no -i '#{ssh_info[:private_key_path]}'",
78
+ hostpath,
79
+ "#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
80
+
81
+ # we need to fix permissions when using rsync.exe on windows, see
82
+ # http://stackoverflow.com/questions/5798807/rsync-permission-denied-created-directories-have-no-permissions
83
+ if Vagrant::Util::Platform.windows?
84
+ command.insert(1, "--chmod", "ugo=rwX")
85
+ end
86
+
87
+ r = Vagrant::Util::Subprocess.execute(*command)
88
+ if r.exit_code != 0
89
+ raise Errors::RsyncError,
90
+ :guestpath => guestpath,
91
+ :hostpath => hostpath,
92
+ :stderr => r.stderr
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,96 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Action
4
+ # Look for the DNS zone relative to the configured domain and,
5
+ # on return path, perform an API call to add or remove the A
6
+ # resource record for the host.
7
+ class UpdateDNS
8
+ include Util::Network
9
+ include Util::Warden
10
+
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new("vagrant_softlayer::action::update_dns")
14
+ end
15
+
16
+ def call(env)
17
+ @env = env
18
+
19
+ @env[:dns_zone] = setup_dns
20
+
21
+ @app.call(@env)
22
+
23
+ update_dns
24
+ end
25
+
26
+ def dns_id
27
+ id = nil
28
+ id_file = @env[:machine].data_dir.join("dns_id")
29
+ id = id_file.read.chomp.to_i if id_file.file?
30
+ return id
31
+ end
32
+
33
+ def dns_id=(value)
34
+ @logger.info("New machine DNS ID: #{value.inspect}")
35
+
36
+ # The file that will store the id if we have one. This allows the
37
+ # ID to persist across Vagrant runs.
38
+ id_file = @env[:machine].data_dir.join("dns_id")
39
+
40
+ if value
41
+ # Write the "id" file with the id given.
42
+ id_file.open("w+") do |f|
43
+ f.write(value)
44
+ end
45
+ end
46
+ end
47
+
48
+ def setup_dns
49
+ unless @env[:machine].provider_config.manage_dns
50
+ @logger.debug("Not managing DNS. Going ahead.")
51
+ return
52
+ end
53
+
54
+ dns_zone = ::SoftLayer::Service.new("SoftLayer_Dns_Domain", @env[:sl_credentials])
55
+
56
+ domain = @env[:machine].provider_config.domain
57
+ @logger.debug("Looking for #{domain} zone into the SoftLayer zone list.")
58
+ dns_zone_obj = sl_warden { dns_zone.getByDomainName(domain).first }
59
+ raise Errors::SLDNSZoneNotFound, :zone => domain unless dns_zone_obj
60
+ @logger.debug("Found DNS zone: #{dns_zone_obj.inspect}")
61
+ return dns_zone_obj
62
+ end
63
+
64
+ def update_dns
65
+ unless @env[:machine].provider_config.manage_dns
66
+ @logger.debug("Not managing DNS. Going ahead.")
67
+ return
68
+ end
69
+
70
+ dns_resource = ::SoftLayer::Service.new("SoftLayer_Dns_Domain_ResourceRecord", @env[:sl_credentials])
71
+
72
+ case @env[:action_name]
73
+ when :machine_action_up
74
+ hostname = @env[:machine].provider_config.hostname || @env[:machine].config.vm.hostname
75
+ @env[:sl_machine] = @env[:sl_connection].object_with_id(@env[:machine].id.to_i)
76
+ res_template = {
77
+ "data" => ip_address(@env),
78
+ "domainId" => @env[:dns_zone]["id"],
79
+ "host" => hostname,
80
+ "ttl" => 86400,
81
+ "type" => "a"
82
+ }
83
+ @env[:ui].info I18n.t("vagrant_softlayer.vm.creating_dns_record")
84
+ @logger.debug("Creating DNS A record for #{hostname}.#{@env[:dns_zone][:name]} (IP address #{res_template['data']}).")
85
+ new_rr = sl_warden { dns_resource.createObject(res_template) }
86
+ self.dns_id = new_rr["id"]
87
+ when :machine_action_destroy
88
+ @env[:ui].info I18n.t("vagrant_softlayer.vm.deleting_dns_record")
89
+ @logger.debug("Deleting stored DNS A record (ID #{self.dns_id}).")
90
+ sl_warden { dns_resource.object_with_id(self.dns_id).deleteObject }
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,40 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module SoftLayer
5
+ module Action
6
+ # Waits until the new machine has been provisioned.
7
+ class WaitForProvision
8
+ include Util::Warden
9
+
10
+ def initialize(app, env)
11
+ @app = app
12
+ @logger = Log4r::Logger.new("vagrant_softlayer::action::wait_for_provision")
13
+ end
14
+
15
+ def call(env)
16
+ env[:ui].info I18n.t("vagrant_softlayer.vm.wait_for_provision")
17
+
18
+ env[:sl_machine] = env[:sl_connection].object_with_id(env[:machine].id.to_i)
19
+
20
+ retry_msg = lambda { @logger.debug("Object not found, retrying in 10 seconds.") }
21
+
22
+ # 20 minutes timeout
23
+ Timeout::timeout(1200) do
24
+ @logger.debug("Checking if the newly ordered machine has been provisioned.")
25
+ sl_warden(retry_msg, 10) do
26
+ while env[:sl_machine].getPowerState["name"] != "Running" || env[:sl_machine].object_mask( { "provisionDate" => "" } ).getObject == {}
27
+ @logger.debug("The machine is still provisioning. Retrying in 10 seconds.")
28
+ sleep 10
29
+ end
30
+ end
31
+ end
32
+
33
+ env[:ui].info I18n.t("vagrant_softlayer.vm.provisioned")
34
+
35
+ @app.call(env)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,36 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module SoftLayer
5
+ module Action
6
+ # Waits until the new machine has been rebuilt.
7
+ class WaitForRebuild
8
+ include Util::Warden
9
+
10
+ def initialize(app, env)
11
+ @app = app
12
+ @logger = Log4r::Logger.new("vagrant_softlayer::action::wait_for_rebuild")
13
+ end
14
+
15
+ def call(env)
16
+ env[:ui].info I18n.t("vagrant_softlayer.vm.wait_for_rebuild")
17
+
18
+ # 20 minutes timeout
19
+ Timeout::timeout(1200) do
20
+ @logger.debug("Checking if the instance has been rebuilt.")
21
+ sl_warden do
22
+ while env[:sl_machine].object_mask("activeTransactionCount").getObject["activeTransactionCount"] > 0
23
+ @logger.debug("The machine is still being rebuilt. Retrying in 10 seconds.")
24
+ sleep 10
25
+ end
26
+ end
27
+ end
28
+
29
+ env[:ui].info I18n.t("vagrant_softlayer.vm.rebuilt")
30
+
31
+ @app.call(env)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,200 @@
1
+ require "pathname"
2
+ require "vagrant-softlayer/util/network"
3
+ require "vagrant-softlayer/util/warden"
4
+
5
+ module VagrantPlugins
6
+ module SoftLayer
7
+ module Action
8
+ # Include the built-in modules so we can use them as top-level things.
9
+ include Vagrant::Action::Builtin
10
+
11
+ # This action is called to terminate the remote machine.
12
+ def self.action_destroy
13
+ Vagrant::Action::Builder.new.tap do |b|
14
+ b.use Call, DestroyConfirm do |env, b2|
15
+ if env[:result]
16
+ b2.use ConfigValidate
17
+ b.use Call, Is, :not_created do |env2, b3|
18
+ if env2[:result]
19
+ b3.use Message, :error, "vagrant_softlayer.vm.not_created"
20
+ next
21
+ end
22
+ end
23
+ b2.use SetupSoftLayer
24
+ b2.use DestroyInstance
25
+ b2.use UpdateDNS
26
+ else
27
+ b2.use Message, :warn, "vagrant_softlayer.vm.not_destroying"
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ # This action is called to halt the remote machine.
34
+ def self.action_halt
35
+ Vagrant::Action::Builder.new.tap do |b|
36
+ b.use ConfigValidate
37
+ b.use Call, Is, :running do |env, b2|
38
+ if !env[:result]
39
+ b2.use Message, :error, "vagrant_softlayer.vm.not_running"
40
+ next
41
+ end
42
+
43
+ b2.use SetupSoftLayer
44
+ b2.use StopInstance
45
+ end
46
+ end
47
+ end
48
+
49
+ # This action is called to run provisioners on the machine.
50
+ def self.action_provision
51
+ Vagrant::Action::Builder.new.tap do |b|
52
+ b.use ConfigValidate
53
+ b.use Call, Is, :running do |env, b2|
54
+ if !env[:result]
55
+ b2.use Message, :error, "vagrant_softlayer.vm.not_running"
56
+ next
57
+ end
58
+
59
+ b2.use Provision
60
+ b2.use SyncFolders
61
+ end
62
+ end
63
+ end
64
+
65
+ # This action is called to read the SSH info of the machine. The
66
+ # resulting state is expected to be put into the `:machine_ssh_info`
67
+ # key.
68
+ def self.action_read_ssh_info
69
+ Vagrant::Action::Builder.new.tap do |b|
70
+ b.use ConfigValidate
71
+ b.use SetupSoftLayer
72
+ b.use ReadSSHInfo
73
+ end
74
+ end
75
+
76
+ # This action is called to read the state of the machine. The
77
+ # resulting state is expected to be put into the `:machine_state_id`
78
+ # key.
79
+ def self.action_read_state
80
+ Vagrant::Action::Builder.new.tap do |b|
81
+ b.use ConfigValidate
82
+ b.use SetupSoftLayer
83
+ b.use ReadState
84
+ end
85
+ end
86
+
87
+ # This action is called to rebuild the machine OS from scratch.
88
+ def self.action_rebuild
89
+ Vagrant::Action::Builder.new.tap do |b|
90
+ b.use Call, Confirm, I18n.t("vagrant_softlayer.vm.rebuild_confirmation"), :force_rebuild do |env, b2|
91
+ if env[:result]
92
+ b2.use ConfigValidate
93
+ b.use Call, Is, :not_created do |env2, b3|
94
+ if env2[:result]
95
+ b3.use Message, :error, "vagrant_softlayer.vm.not_created"
96
+ next
97
+ end
98
+ end
99
+ b2.use SetupSoftLayer
100
+ b2.use RebuildInstance
101
+ b2.use Provision
102
+ b2.use SyncFolders
103
+ b2.use WaitForRebuild
104
+ b2.use WaitForCommunicator
105
+ else
106
+ b2.use Message, :warn, "vagrant_softlayer.vm.not_rebuilding"
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ # This action is called to reload the machine.
113
+ def self.action_reload
114
+ Vagrant::Action::Builder.new.tap do |b|
115
+ b.use action_halt
116
+ b.use action_up
117
+ end
118
+ end
119
+
120
+ # This action is called to SSH into the machine.
121
+ def self.action_ssh
122
+ Vagrant::Action::Builder.new.tap do |b|
123
+ b.use ConfigValidate
124
+ b.use Call, Is, :running do |env, b2|
125
+ if !env[:result]
126
+ b2.use Message, :error, "vagrant_softlayer.vm.not_running"
127
+ next
128
+ end
129
+
130
+ b2.use SSHExec
131
+ end
132
+ end
133
+ end
134
+
135
+ def self.action_ssh_run
136
+ Vagrant::Action::Builder.new.tap do |b|
137
+ b.use ConfigValidate
138
+ b.use Call, Is, :running do |env, b2|
139
+ if !env[:result]
140
+ b2.use Message, :error, "vagrant_softlayer.vm.not_running"
141
+ next
142
+ end
143
+
144
+ b2.use SSHRun
145
+ end
146
+ end
147
+ end
148
+
149
+ # This action is called to bring the box up from nothing.
150
+ def self.action_up
151
+ Vagrant::Action::Builder.new.tap do |b|
152
+ b.use HandleBoxUrl
153
+ b.use ConfigValidate
154
+ b.use SetupSoftLayer
155
+ b.use Call, Is, :not_created do |env1, b1|
156
+ if env1[:result]
157
+ b1.use SetupSoftLayer
158
+ b1.use Provision
159
+ b1.use SyncFolders
160
+ b1.use UpdateDNS
161
+ b1.use CreateInstance
162
+ b1.use WaitForProvision
163
+ b1.use WaitForCommunicator
164
+ else
165
+ b1.use Call, Is, :halted do |env2, b2|
166
+ if env2[:result]
167
+ b2.use SetupSoftLayer
168
+ b2.use Provision
169
+ b2.use SyncFolders
170
+ b2.use StartInstance
171
+ b2.use WaitForCommunicator
172
+ else
173
+ b2.use Message, :warn, "vagrant_softlayer.vm.already_running"
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ # The autoload farm
182
+ action_root = Pathname.new(File.expand_path("../action", __FILE__))
183
+
184
+ autoload :CreateInstance, action_root.join("create_instance")
185
+ autoload :DestroyInstance, action_root.join("destroy_instance")
186
+ autoload :Is, action_root.join("is")
187
+ autoload :Message, action_root.join("message")
188
+ autoload :ReadSSHInfo, action_root.join("read_ssh_info")
189
+ autoload :ReadState, action_root.join("read_state")
190
+ autoload :RebuildInstance, action_root.join("rebuild_instance")
191
+ autoload :SetupSoftLayer, action_root.join("setup_softlayer")
192
+ autoload :StartInstance, action_root.join("start_instance")
193
+ autoload :StopInstance, action_root.join("stop_instance")
194
+ autoload :SyncFolders, action_root.join("sync_folders")
195
+ autoload :UpdateDNS, action_root.join("update_dns")
196
+ autoload :WaitForProvision, action_root.join("wait_for_provision")
197
+ autoload :WaitForRebuild, action_root.join("wait_for_rebuild")
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,34 @@
1
+ require 'optparse'
2
+
3
+ module VagrantPlugins
4
+ module SoftLayer
5
+ module Command
6
+ class Rebuild < Vagrant.plugin('2', :command)
7
+ def execute
8
+ options = {}
9
+ options[:force] = false
10
+
11
+ opts = OptionParser.new do |o|
12
+ o.banner = "Usage: vagrant rebuild [vm-name]"
13
+ o.separator ""
14
+
15
+ o.on("-f", "--force", "Rebuild without confirmation.") do |f|
16
+ options[:force] = f
17
+ end
18
+ end
19
+
20
+ argv = parse_options(opts)
21
+ return if !argv
22
+
23
+ declined = false
24
+ with_target_vms(argv) do |vm|
25
+ action_env = vm.action(:rebuild, :force_rebuild => options[:force], :provision_ignore_sentinel => false)
26
+ declined = true if action_env.has_key?(:force_rebuild_result) && action_env[:force_rebuild_result] == false
27
+ end
28
+
29
+ declined ? 1 : 0
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,178 @@
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ class Config < Vagrant.plugin("2", :config)
4
+ # The API key to access SoftLayer.
5
+ attr_accessor :api_key
6
+
7
+ # The endpoint SoftLayer API url.
8
+ attr_accessor :endpoint_url
9
+
10
+ # The username to access SoftLayer.
11
+ attr_accessor :username
12
+
13
+ # The datacenter shortname.
14
+ attr_accessor :datacenter
15
+
16
+ # Whether to allocate a dedicated instance.
17
+ attr_accessor :dedicated
18
+
19
+ # The domain of the instance.
20
+ attr_accessor :domain
21
+
22
+ # The hostname of the instance.
23
+ attr_accessor :hostname
24
+
25
+ # The billing type of the instance (true for hourly, false for monthly).
26
+ attr_accessor :hourly_billing
27
+
28
+ # The disk type of the instance (true for local, false for SAN).
29
+ attr_accessor :local_disk
30
+
31
+ # The amount of RAM of the instance.
32
+ attr_accessor :max_memory
33
+
34
+ # Network port speed in Mbps.
35
+ attr_accessor :network_speed
36
+
37
+ # The instance operating system identifier.
38
+ attr_accessor :operating_system
39
+
40
+ # URI of post-install script to download.
41
+ attr_accessor :post_install
42
+
43
+ # Whether or not the instance only has access to the private network.
44
+ attr_accessor :private_only
45
+
46
+ # The id or name of the ssh key to be provisioned.
47
+ attr_accessor :ssh_key
48
+
49
+ # The number of processors of the instance.
50
+ attr_accessor :start_cpus
51
+
52
+ # User defined metadata string.
53
+ attr_accessor :user_data
54
+
55
+ # The ID of the private VLAN.
56
+ attr_accessor :vlan_private
57
+
58
+ # The ID of the public VLAN.
59
+ attr_accessor :vlan_public
60
+
61
+ # Automatically update DNS on create and destroy.
62
+ attr_accessor :manage_dns
63
+
64
+ def initialize
65
+ @api_key = UNSET_VALUE
66
+ @endpoint_url = UNSET_VALUE
67
+ @username = UNSET_VALUE
68
+
69
+ @datacenter = UNSET_VALUE
70
+ @dedicated = UNSET_VALUE
71
+ @domain = UNSET_VALUE
72
+ @hostname = UNSET_VALUE
73
+ @hourly_billing = UNSET_VALUE
74
+ @local_disk = UNSET_VALUE
75
+ @max_memory = UNSET_VALUE
76
+ @network_speed = UNSET_VALUE
77
+ @operating_system = UNSET_VALUE
78
+ @post_install = UNSET_VALUE
79
+ @private_only = UNSET_VALUE
80
+ @ssh_key = UNSET_VALUE
81
+ @start_cpus = UNSET_VALUE
82
+ @user_data = UNSET_VALUE
83
+ @vlan_private = UNSET_VALUE
84
+ @vlan_public = UNSET_VALUE
85
+
86
+ @manage_dns = UNSET_VALUE
87
+ end
88
+
89
+ def finalize!
90
+ # Try to get username and api key from environment variables.
91
+ # They will default to nil if the environment variables are not present.
92
+ @api_key = ENV["SL_API_KEY"] if @api_key == UNSET_VALUE
93
+ @username = ENV["SL_USERNAME"] if @username == UNSET_VALUE
94
+
95
+ # Endpoint url defaults to public SoftLayer API url.
96
+ @endpoint_url = API_PUBLIC_ENDPOINT if @endpoint_url == UNSET_VALUE
97
+
98
+ # No default datacenter.
99
+ @datacenter = nil if @datacenter == UNSET_VALUE
100
+
101
+ # Shared instance by default.
102
+ @dedicated = false if @dedicated == UNSET_VALUE
103
+
104
+ # Domain should be specified in Vagrantfile, so we set default to nil.
105
+ @domain = nil if @domain == UNSET_VALUE
106
+
107
+ # Hostname should be specified in Vagrantfile, either using `config.vm.hostname`
108
+ # or the provider specific configuration entry.
109
+ @hostname = nil if @hostname == UNSET_VALUE
110
+
111
+ # Bill hourly by default.
112
+ @hourly_billing = true if @hourly_billing == UNSET_VALUE
113
+
114
+ # Use local disk by default.
115
+ @local_disk = true if @local_disk == UNSET_VALUE
116
+
117
+ # 1Gb of RAM by default.
118
+ @max_memory = 1024 if @max_memory == UNSET_VALUE
119
+
120
+ # 10Mbps by default.
121
+ @network_speed = 10 if @network_speed == UNSET_VALUE
122
+
123
+ # Provision with the latest Ubuntu by default.
124
+ @operating_system = "UBUNTU_LATEST" if @operating_system == UNSET_VALUE
125
+
126
+ # No post install script by default.
127
+ @post_install = nil if @post_install == UNSET_VALUE
128
+
129
+ # Private-network only is false by default.
130
+ @private_only = false if @private_only == UNSET_VALUE
131
+
132
+ # SSH key should be specified in Vagrantfile, so we set default to nil.
133
+ @ssh_key = nil if @ssh_key == UNSET_VALUE
134
+
135
+ # One processor by default.
136
+ @start_cpus = 1 if @start_cpus == UNSET_VALUE
137
+
138
+ # No user metadata by default.
139
+ @user_data = nil if @user_data == UNSET_VALUE
140
+
141
+ # No specific private VLAN by default.
142
+ @vlan_private = nil if @vlan_private == UNSET_VALUE
143
+
144
+ # No specific public VLAN by default.
145
+ @vlan_public = nil if @vlan_public == UNSET_VALUE
146
+
147
+ # DNS management off by default
148
+ @manage_dns = false if @manage_dns == UNSET_VALUE
149
+ end
150
+
151
+ # Aliases for ssh_key for beautiful semantic
152
+ def ssh_keys=(value)
153
+ @ssh_key = value
154
+ end
155
+ alias_method :ssh_key_id=, :ssh_keys=
156
+ alias_method :ssh_key_ids=, :ssh_keys=
157
+ alias_method :ssh_key_name=, :ssh_keys=
158
+ alias_method :ssh_key_names=, :ssh_keys=
159
+
160
+ def validate(machine)
161
+ errors = []
162
+
163
+ errors << I18n.t("vagrant_softlayer.config.api_key_required") if !@api_key
164
+ errors << I18n.t("vagrant_softlayer.config.username_required") if !@username
165
+
166
+ errors << I18n.t("vagrant_softlayer.config.domain_required") if !@domain
167
+ errors << I18n.t("vagrant_softlayer.config.ssh_key_required") if !@ssh_key
168
+
169
+ # Fail if both `vm.hostname` and `provider.hostname` are nil.
170
+ if !@hostname && !machine.config.vm.hostname
171
+ errors << I18n.t("vagrant_softlayer.config.hostname_required")
172
+ end
173
+
174
+ { "SoftLayer" => errors }
175
+ end
176
+ end
177
+ end
178
+ end