vagrant-softlayer 0.1.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.
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