vagrant-softlayer 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +15 -0
- data/Gemfile +7 -0
- data/LICENSE +20 -0
- data/README.md +233 -0
- data/Rakefile +6 -0
- data/dummy.box +0 -0
- data/example_box/README.md +13 -0
- data/example_box/metadata.json +3 -0
- data/lib/vagrant-softlayer/action/create_instance.rb +54 -0
- data/lib/vagrant-softlayer/action/destroy_instance.rb +23 -0
- data/lib/vagrant-softlayer/action/is.rb +21 -0
- data/lib/vagrant-softlayer/action/message.rb +22 -0
- data/lib/vagrant-softlayer/action/read_ssh_info.rb +28 -0
- data/lib/vagrant-softlayer/action/read_state.rb +42 -0
- data/lib/vagrant-softlayer/action/rebuild_instance.rb +35 -0
- data/lib/vagrant-softlayer/action/setup_softlayer.rb +37 -0
- data/lib/vagrant-softlayer/action/start_instance.rb +21 -0
- data/lib/vagrant-softlayer/action/stop_instance.rb +30 -0
- data/lib/vagrant-softlayer/action/sync_folders.rb +99 -0
- data/lib/vagrant-softlayer/action/update_dns.rb +96 -0
- data/lib/vagrant-softlayer/action/wait_for_provision.rb +40 -0
- data/lib/vagrant-softlayer/action/wait_for_rebuild.rb +36 -0
- data/lib/vagrant-softlayer/action.rb +200 -0
- data/lib/vagrant-softlayer/command/rebuild.rb +34 -0
- data/lib/vagrant-softlayer/config.rb +178 -0
- data/lib/vagrant-softlayer/errors.rb +25 -0
- data/lib/vagrant-softlayer/plugin.rb +77 -0
- data/lib/vagrant-softlayer/provider.rb +47 -0
- data/lib/vagrant-softlayer/util/network.rb +42 -0
- data/lib/vagrant-softlayer/util/warden.rb +38 -0
- data/lib/vagrant-softlayer/version.rb +5 -0
- data/lib/vagrant-softlayer.rb +22 -0
- data/locales/en.yml +146 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/vagrant-softlayer/config_spec.rb +156 -0
- data/vagrant-softlayer.gemspec +53 -0
- metadata +152 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SoftLayer
|
3
|
+
module Errors
|
4
|
+
class VagrantSoftLayerError < Vagrant::Errors::VagrantError
|
5
|
+
error_namespace("vagrant_softlayer.errors")
|
6
|
+
end
|
7
|
+
|
8
|
+
class SLApiError < VagrantSoftLayerError
|
9
|
+
error_key(:api_error)
|
10
|
+
end
|
11
|
+
|
12
|
+
class SLCertificateError < VagrantSoftLayerError
|
13
|
+
error_key(:certificate_error)
|
14
|
+
end
|
15
|
+
|
16
|
+
class SLDNSZoneNotFound < VagrantSoftLayerError
|
17
|
+
error_key(:dns_zone_not_found)
|
18
|
+
end
|
19
|
+
|
20
|
+
class SLSshKeyNotFound < VagrantSoftLayerError
|
21
|
+
error_key(:ssh_key_not_found)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
begin
|
2
|
+
require "vagrant"
|
3
|
+
rescue LoadError
|
4
|
+
raise "The Vagrant SoftLayer plugin 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.3.0"
|
10
|
+
raise "The Vagrant SoftLayer plugin is only compatible with Vagrant 1.3+"
|
11
|
+
end
|
12
|
+
|
13
|
+
module VagrantPlugins
|
14
|
+
module SoftLayer
|
15
|
+
class Plugin < Vagrant.plugin("2")
|
16
|
+
name "SoftLayer"
|
17
|
+
description <<-DESC
|
18
|
+
This plugin installs a provider that allows Vagrant to manage
|
19
|
+
SoftLayer CCI.
|
20
|
+
DESC
|
21
|
+
|
22
|
+
command(:rebuild) do
|
23
|
+
require_relative 'command/rebuild'
|
24
|
+
Command::Rebuild
|
25
|
+
end
|
26
|
+
|
27
|
+
config(:softlayer, :provider) do
|
28
|
+
require_relative "config"
|
29
|
+
Config
|
30
|
+
end
|
31
|
+
|
32
|
+
provider(:softlayer) do
|
33
|
+
init_logging
|
34
|
+
init_i18n
|
35
|
+
|
36
|
+
require_relative "provider"
|
37
|
+
Provider
|
38
|
+
end
|
39
|
+
|
40
|
+
# This initializes the I18n load path so that the plugin specific
|
41
|
+
# transations work.
|
42
|
+
def self.init_i18n
|
43
|
+
I18n.load_path << File.expand_path("locales/en.yml", SoftLayer.source_root)
|
44
|
+
I18n.reload!
|
45
|
+
end
|
46
|
+
|
47
|
+
# This sets up our log level to be whatever VAGRANT_LOG is.
|
48
|
+
def self.init_logging
|
49
|
+
require "log4r"
|
50
|
+
|
51
|
+
level = nil
|
52
|
+
begin
|
53
|
+
level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
|
54
|
+
rescue NameError
|
55
|
+
# This means that the logging constant wasn't found,
|
56
|
+
# which is fine. We just keep `level` as `nil`. But
|
57
|
+
# we tell the user.
|
58
|
+
level = nil
|
59
|
+
end
|
60
|
+
|
61
|
+
# Some constants, such as "true" resolve to booleans, so the
|
62
|
+
# above error checking doesn't catch it. This will check to make
|
63
|
+
# sure that the log level is an integer, as Log4r requires.
|
64
|
+
level = nil if !level.is_a?(Integer)
|
65
|
+
|
66
|
+
# Set the logging level on all "vagrant" namespaced
|
67
|
+
# logs as long as we have a valid level.
|
68
|
+
if level
|
69
|
+
logger = Log4r::Logger.new("vagrant_softlayer")
|
70
|
+
logger.outputters = Log4r::Outputter.stderr
|
71
|
+
logger.level = level
|
72
|
+
logger = nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SoftLayer
|
3
|
+
class Provider < Vagrant.plugin("2", :provider)
|
4
|
+
def initialize(machine)
|
5
|
+
@machine = machine
|
6
|
+
end
|
7
|
+
|
8
|
+
def action(name)
|
9
|
+
# Attempt to get the action method from the Action class if it
|
10
|
+
# exists, otherwise return nil to show that we don't support the
|
11
|
+
# given action.
|
12
|
+
action_method = "action_#{name}"
|
13
|
+
return Action.send(action_method) if Action.respond_to?(action_method)
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def ssh_info
|
18
|
+
# Run a custom action called "read_ssh_info" which does what it
|
19
|
+
# says and puts the resulting SSH info into the `:machine_ssh_info`
|
20
|
+
# key in the environment.
|
21
|
+
env = @machine.action("read_ssh_info")
|
22
|
+
env[:machine_ssh_info]
|
23
|
+
end
|
24
|
+
|
25
|
+
def state
|
26
|
+
# Run a custom action we define called "read_state" which does
|
27
|
+
# what it says. It puts the state in the `:machine_state_id`
|
28
|
+
# key in the environment.
|
29
|
+
env = @machine.action("read_state")
|
30
|
+
|
31
|
+
state_id = env[:machine_state_id]
|
32
|
+
|
33
|
+
# Get the short and long description
|
34
|
+
short = I18n.t("vagrant_softlayer.states.short_#{state_id}")
|
35
|
+
long = I18n.t("vagrant_softlayer.states.long_#{state_id}")
|
36
|
+
|
37
|
+
# Return the MachineState object
|
38
|
+
Vagrant::MachineState.new(state_id, short, long)
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
id = @machine.id || "new VM"
|
43
|
+
"SoftLayer (#{id})"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SoftLayer
|
3
|
+
module Util
|
4
|
+
module Network
|
5
|
+
# Gets instance's IP address.
|
6
|
+
#
|
7
|
+
# Returns the private IP address if the instance has been
|
8
|
+
# defined as private only, the public IP address otherwise.
|
9
|
+
def ip_address(env)
|
10
|
+
service = env[:machine].provider_config.private_only ? :getPrimaryBackendIpAddress : :getPrimaryIpAddress
|
11
|
+
return sl_warden { env[:sl_machine].send(service) }
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns SSH keys starting from the configuration parameter.
|
15
|
+
#
|
16
|
+
# In the configuration, each key could be passed either as an
|
17
|
+
# id or as a label. The routine will detect this and lookup
|
18
|
+
# the id if needed.
|
19
|
+
#
|
20
|
+
# The first parameter is the current environment.
|
21
|
+
#
|
22
|
+
# The second parameter is useful for returning: if it is set
|
23
|
+
# the routine will return just the array of ids (this is needed,
|
24
|
+
# as an example, for reloading OS), otherwise an hash is
|
25
|
+
# returned (this latter case is needed instead for creating
|
26
|
+
# an instance).
|
27
|
+
def ssh_keys(env, ids_only = false)
|
28
|
+
account = ::SoftLayer::Service.new("SoftLayer_Account", env[:sl_credentials])
|
29
|
+
acc_keys = sl_warden { account.object_mask("id", "label").getSshKeys }
|
30
|
+
key_ids = []
|
31
|
+
Array(env[:machine].provider_config.ssh_key).each do |key|
|
32
|
+
pattern = key.is_a?(String) ? "label" : "id"
|
33
|
+
key_hash = acc_keys.find { |acc_key| acc_key[pattern] == key }
|
34
|
+
raise Errors::SLSshKeyNotFound, :key => key unless key_hash
|
35
|
+
key_ids << key_hash["id"]
|
36
|
+
end
|
37
|
+
return (ids_only ? key_ids : key_ids.map { |key_id| { :id => key_id } })
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module SoftLayer
|
3
|
+
module Util
|
4
|
+
module Warden
|
5
|
+
# Handles gracefully SoftLayer API calls.
|
6
|
+
#
|
7
|
+
# The block code is executed, catching both common
|
8
|
+
# connection errors and API exceptions.
|
9
|
+
#
|
10
|
+
# Optionally, in the not-so-uncommon case when
|
11
|
+
# the object (e.g. the SoftLayer instance) is not
|
12
|
+
# found, executes a proc and/or retry the API call
|
13
|
+
# after some seconds.
|
14
|
+
#
|
15
|
+
# A future version of the method will add a retry timeout.
|
16
|
+
def sl_warden(rescue_proc = nil, retry_interval = 0, &block)
|
17
|
+
begin
|
18
|
+
yield
|
19
|
+
rescue ::OpenSSL::SSL::SSLError
|
20
|
+
raise Errors::SLCertificateError
|
21
|
+
rescue SocketError, ::SoftLayer::SoftLayerAPIException => e
|
22
|
+
if e.class == ::SoftLayer::SoftLayerAPIException && e.message.start_with?("Unable to find object with id")
|
23
|
+
out = rescue_proc.call if rescue_proc
|
24
|
+
if retry_interval > 0
|
25
|
+
sleep retry_interval
|
26
|
+
retry
|
27
|
+
else
|
28
|
+
return out
|
29
|
+
end
|
30
|
+
else
|
31
|
+
raise Errors::SLApiError, :class => e.class, :message => e.message
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "pathname"
|
2
|
+
require "softlayer_api"
|
3
|
+
require "vagrant-softlayer/plugin"
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module SoftLayer
|
7
|
+
API_PRIVATE_ENDPOINT = ::SoftLayer::API_PRIVATE_ENDPOINT
|
8
|
+
API_PUBLIC_ENDPOINT = ::SoftLayer::API_PUBLIC_ENDPOINT
|
9
|
+
|
10
|
+
lib_path = Pathname.new(File.expand_path("../vagrant-softlayer", __FILE__))
|
11
|
+
autoload :Action, lib_path.join("action")
|
12
|
+
autoload :Config, lib_path.join("config")
|
13
|
+
autoload :Errors, lib_path.join("errors")
|
14
|
+
|
15
|
+
# This returns the path to the source of this plugin.
|
16
|
+
#
|
17
|
+
# @return [Pathname]
|
18
|
+
def self.source_root
|
19
|
+
@source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/locales/en.yml
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
en:
|
2
|
+
vagrant_softlayer:
|
3
|
+
config:
|
4
|
+
api_key_required: |-
|
5
|
+
The SoftLayer API key is required. Please specify it
|
6
|
+
using the SL_API_KEY environment variable or in the provider
|
7
|
+
section of the Vagrantfile:
|
8
|
+
|
9
|
+
config.vm.provider :softlayer do |sl|
|
10
|
+
sl.api_key = "my_API_key"
|
11
|
+
end
|
12
|
+
domain_required: |-
|
13
|
+
The domain of the SoftLayer instance is required.
|
14
|
+
Please specify it in the provider section of the Vagrantfile:
|
15
|
+
|
16
|
+
config.vm.provider :softlayer do |sl|
|
17
|
+
sl.domain = "example.com"
|
18
|
+
end
|
19
|
+
hostname_required: |-
|
20
|
+
The hostname of the SoftLayer instance is required.
|
21
|
+
Please specify it either with `config.vm.hostname` or
|
22
|
+
in the provider section of the Vagrantfile:
|
23
|
+
|
24
|
+
config.vm.hostname = "vagrant"
|
25
|
+
|
26
|
+
config.vm.provider :softlayer do |sl|
|
27
|
+
sl.hostname = "vagrant"
|
28
|
+
end
|
29
|
+
ssh_key_required: |-
|
30
|
+
At least an SSH key for the instance is required.
|
31
|
+
Please specify it, either using name or id, in the
|
32
|
+
provider section of the Vagrantfile:
|
33
|
+
|
34
|
+
config.vm.provider :softlayer do |sl|
|
35
|
+
sl.ssh_key = 1
|
36
|
+
end
|
37
|
+
username_required: |-
|
38
|
+
The SoftLayer username is required. Please specify it
|
39
|
+
using the SL_USERNAME environment variable or in the provider
|
40
|
+
section of the Vagrantfile:
|
41
|
+
|
42
|
+
config.vm.provider :softlayer do |sl|
|
43
|
+
sl.username = "my_username"
|
44
|
+
end
|
45
|
+
errors:
|
46
|
+
api_error: |-
|
47
|
+
Vagrant returned an exception while calling the SoftLayer API.
|
48
|
+
|
49
|
+
Exception class: %{class}
|
50
|
+
Exception message: %{message}
|
51
|
+
certificate_error: |-
|
52
|
+
The secure connection to the SoftLayer API has failed. This is
|
53
|
+
generally caused by the OpenSSL configuration associated with
|
54
|
+
the Ruby install being unaware of the system specific CA certs.
|
55
|
+
|
56
|
+
Please ensure that the SSL_CERT_FILE environment variable is set
|
57
|
+
with a path to a certificate authority.
|
58
|
+
|
59
|
+
Linux example:
|
60
|
+
|
61
|
+
export SSL_CERT_FILE=/opt/vagrant/embedded/cacert.pem
|
62
|
+
|
63
|
+
Mac OS X example:
|
64
|
+
|
65
|
+
export SSL_CERT_FILE=/Applications/Vagrant/embedded/cacert.pem
|
66
|
+
|
67
|
+
Windows example:
|
68
|
+
|
69
|
+
set SSL_CERT_FILE=C:\HashiCorp\Vagrant\embedded\cacert.pem
|
70
|
+
dns_zone_not_found: |-
|
71
|
+
The DNS zone you're trying to manage (%{zone}) has not been
|
72
|
+
found in the zone list.
|
73
|
+
ssh_key_not_found: |-
|
74
|
+
The SSH key you're trying to set (%{key}) does not exists in the
|
75
|
+
SoftLayer account's keychain.
|
76
|
+
states:
|
77
|
+
short_not_created: |-
|
78
|
+
not created
|
79
|
+
long_not_created: |-
|
80
|
+
The SoftLayer instance is not created. Run `vagrant up` to create it.
|
81
|
+
short_halted: |-
|
82
|
+
stopped
|
83
|
+
long_halted: |-
|
84
|
+
The SoftLayer instance is stopped. Run `vagrant up` to start it.
|
85
|
+
short_paused: |-
|
86
|
+
paused
|
87
|
+
long_paused: |-
|
88
|
+
The SoftLayer instance is paused. You need to resume it using another
|
89
|
+
SoftLayer client tool (e.g. `sl` command line utility).
|
90
|
+
short_running: |-
|
91
|
+
running
|
92
|
+
long_running: |-
|
93
|
+
The SoftLayer instance is running. To stop this machine, you can run
|
94
|
+
`vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
|
95
|
+
short_unknown: |-
|
96
|
+
unknown
|
97
|
+
long_unknown: |-
|
98
|
+
The SoftLayer instance is in an unknown state. You need to check it
|
99
|
+
out using SoftLayer administrative interface.
|
100
|
+
sync_folders:
|
101
|
+
rsync_folder: |-
|
102
|
+
Rsyncing folder: %{hostpath} => %{guestpath}
|
103
|
+
rsync_not_found: |-
|
104
|
+
Warning! Folder sync disabled because the rsync binary is missing in the %{side}.
|
105
|
+
Make sure rsync is installed and the binary can be found in the PATH.
|
106
|
+
vm:
|
107
|
+
already_running: |-
|
108
|
+
The SoftLayer instance is already running.
|
109
|
+
already_stopped: |-
|
110
|
+
The SoftLayer instance is already stopped.
|
111
|
+
creating: |-
|
112
|
+
Creating a new SoftLayer instance...
|
113
|
+
creating_dns_record: |-
|
114
|
+
Creating DNS record for the instance...
|
115
|
+
deleting_dns_record: |-
|
116
|
+
Deleting DNS record for the instance...
|
117
|
+
destroying: |-
|
118
|
+
Destroying the SoftLayer instance...
|
119
|
+
not_destroying: |-
|
120
|
+
The SoftLayer instance will not be destroyed, since the confirmation
|
121
|
+
was declined.
|
122
|
+
not_created: |-
|
123
|
+
The SoftLayer instance does not exists.
|
124
|
+
not_rebuilding: |-
|
125
|
+
The SoftLayer instance will not be rebuilded, since the confirmation
|
126
|
+
was declined.
|
127
|
+
not_running: |-
|
128
|
+
The SoftLayer instance is not running. Please run `vagrant up` first.
|
129
|
+
provisioned: |-
|
130
|
+
SoftLayer instance successfully provisioned!
|
131
|
+
rebuilding: |-
|
132
|
+
Rebuilding the SoftLayer instance...
|
133
|
+
rebuild_confirmation: |-
|
134
|
+
Are you sure you want to rebuild the current VM? [y/N]
|
135
|
+
rebuilt: |-
|
136
|
+
SoftLayer instance successfully rebuilt!
|
137
|
+
starting: |-
|
138
|
+
Starting the SoftLayer instance...
|
139
|
+
stopping: |-
|
140
|
+
Stopping the SoftLayer instance gracefully...
|
141
|
+
stopping_force: |-
|
142
|
+
Stopping the SoftLayer instance forcibly...
|
143
|
+
wait_for_provision: |-
|
144
|
+
Waiting for instance provisioning. This may take a few minutes...
|
145
|
+
wait_for_rebuild: |-
|
146
|
+
Waiting for instance rebuilding. This may take a few minutes...
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require_relative "../lib/vagrant-softlayer"
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe VagrantPlugins::SoftLayer::Config do
|
4
|
+
let(:config) { described_class.new }
|
5
|
+
let(:machine) { double("machine") }
|
6
|
+
|
7
|
+
describe "defaults" do
|
8
|
+
subject do
|
9
|
+
config.tap do |o|
|
10
|
+
o.finalize!
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
its("api_key") { should be_nil }
|
15
|
+
its("endpoint_url") { should eq VagrantPlugins::SoftLayer::API_PUBLIC_ENDPOINT }
|
16
|
+
its("username") { should be_nil }
|
17
|
+
|
18
|
+
its("datacenter") { should be_nil }
|
19
|
+
its("dedicated") { should be_false }
|
20
|
+
its("domain") { should be_nil }
|
21
|
+
its("hostname") { should be_nil }
|
22
|
+
its("hourly_billing") { should be_true }
|
23
|
+
its("local_disk") { should be_true }
|
24
|
+
its("max_memory") { should eq 1024 }
|
25
|
+
its("network_speed") { should eq 10 }
|
26
|
+
its("operating_system") { should eq "UBUNTU_LATEST" }
|
27
|
+
its("post_install") { should be_nil }
|
28
|
+
its("private_only") { should be_false }
|
29
|
+
its("ssh_key") { should be_nil }
|
30
|
+
its("start_cpus") { should eq 1 }
|
31
|
+
its("user_data") { should be_nil }
|
32
|
+
its("vlan_private") { should be_nil }
|
33
|
+
its("vlan_public") { should be_nil }
|
34
|
+
|
35
|
+
its("manage_dns") { should be_false }
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "overriding defaults" do
|
39
|
+
context "booleans" do
|
40
|
+
[true, false].each do |bool|
|
41
|
+
[:dedicated, :hourly_billing, :local_disk, :manage_dns, :private_only].each do |attribute|
|
42
|
+
it "should accept both true and false for #{attribute}" do
|
43
|
+
config.send("#{attribute}=".to_sym, bool)
|
44
|
+
config.finalize!
|
45
|
+
expect(config.send(attribute)).to eq bool
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "integers" do
|
52
|
+
[:max_memory, :network_speed, :ssh_key, :start_cpus, :vlan_private, :vlan_public].each do |attribute|
|
53
|
+
it "should not default #{attribute} if overridden" do
|
54
|
+
config.send("#{attribute}=".to_sym, 999)
|
55
|
+
config.finalize!
|
56
|
+
expect(config.send(attribute)).to eq 999
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "strings" do
|
62
|
+
[:api_key, :datacenter, :endpoint_url, :username, :domain, :hostname, :operating_system, :post_install, :ssh_key, :user_data].each do |attribute|
|
63
|
+
it "should not default #{attribute} if overridden" do
|
64
|
+
config.send("#{attribute}=".to_sym, "foo")
|
65
|
+
config.finalize!
|
66
|
+
expect(config.send(attribute)).to eq "foo"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe "using SL_ environment variables" do
|
73
|
+
before :each do
|
74
|
+
ENV.stub(:[]).with("SL_API_KEY").and_return("env_api_key")
|
75
|
+
ENV.stub(:[]).with("SL_USERNAME").and_return("env_username")
|
76
|
+
end
|
77
|
+
|
78
|
+
subject do
|
79
|
+
config.tap do |o|
|
80
|
+
o.finalize!
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
its("api_key") { should eq "env_api_key" }
|
85
|
+
its("username") { should eq "env_username" }
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "validation" do
|
89
|
+
before :each do
|
90
|
+
# Setup some good configuration values
|
91
|
+
config.api_key = "An API key"
|
92
|
+
config.username = "An username"
|
93
|
+
|
94
|
+
config.datacenter = "ams01"
|
95
|
+
config.dedicated = false
|
96
|
+
config.domain = "example.com"
|
97
|
+
config.hostname = "vagrant"
|
98
|
+
config.hourly_billing = true
|
99
|
+
config.local_disk = true
|
100
|
+
config.max_memory = 1024
|
101
|
+
config.network_speed = 10
|
102
|
+
config.operating_system = "UBUNTU_LATEST"
|
103
|
+
config.post_install = "http://example.com/foo"
|
104
|
+
config.ssh_key = ["First key", "Second key"]
|
105
|
+
config.start_cpus = 1
|
106
|
+
config.user_data = "some metadata"
|
107
|
+
config.vlan_private = 111
|
108
|
+
config.vlan_public = 222
|
109
|
+
|
110
|
+
config.manage_dns = false
|
111
|
+
|
112
|
+
machine.stub_chain(:config, :vm, :hostname).and_return(nil)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should validate" do
|
116
|
+
config.finalize!
|
117
|
+
expect(config.validate(machine)["SoftLayer"]).to have(:no).item
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should fail if API key is not given" do
|
121
|
+
config.api_key = nil
|
122
|
+
config.finalize!
|
123
|
+
expect(config.validate(machine)["SoftLayer"]).to have(1).item
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should fail if username is not given" do
|
127
|
+
config.username = nil
|
128
|
+
config.finalize!
|
129
|
+
expect(config.validate(machine)["SoftLayer"]).to have(1).item
|
130
|
+
end
|
131
|
+
|
132
|
+
it "should fail if domain is not given" do
|
133
|
+
config.domain = nil
|
134
|
+
config.finalize!
|
135
|
+
expect(config.validate(machine)["SoftLayer"]).to have(1).item
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should fail if hostname is not given" do
|
139
|
+
config.hostname = nil
|
140
|
+
config.finalize!
|
141
|
+
expect(config.validate(machine)["SoftLayer"]).to have(1).item
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should validate if hostname is not given but config.vm.hostname is set" do
|
145
|
+
config.hostname = nil
|
146
|
+
machine.stub_chain(:config, :vm, :hostname).and_return("vagrant")
|
147
|
+
expect(config.validate(machine)["SoftLayer"]).to have(:no).item
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should fail if ssh key is not given" do
|
151
|
+
config.ssh_key = nil
|
152
|
+
config.finalize!
|
153
|
+
expect(config.validate(machine)["SoftLayer"]).to have(1).item
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
2
|
+
require "vagrant-softlayer/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "vagrant-softlayer"
|
6
|
+
spec.version = VagrantPlugins::SoftLayer::VERSION
|
7
|
+
spec.authors = "Audiolize GmbH"
|
8
|
+
spec.email = ""
|
9
|
+
spec.description = "Enables Vagrant to manages SoftLayer CCI."
|
10
|
+
spec.summary = "Enables Vagrant to manages SoftLayer CCI."
|
11
|
+
|
12
|
+
# The following block of code determines the files that should be included
|
13
|
+
# in the gem. It does this by reading all the files in the directory where
|
14
|
+
# this gemspec is, and parsing out the ignored files from the gitignore.
|
15
|
+
# Note that the entire gitignore(5) syntax is not supported, specifically
|
16
|
+
# the "!" syntax, but it should mostly work correctly.
|
17
|
+
root_path = File.dirname(__FILE__)
|
18
|
+
all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
|
19
|
+
all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
|
20
|
+
gitignore_path = File.join(root_path, ".gitignore")
|
21
|
+
gitignore = File.readlines(gitignore_path)
|
22
|
+
gitignore.map! { |line| line.chomp.strip }
|
23
|
+
gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
|
24
|
+
|
25
|
+
unignored_files = all_files.reject do |file|
|
26
|
+
# Ignore any directories, the gemspec only cares about files
|
27
|
+
next true if File.directory?(file)
|
28
|
+
|
29
|
+
# Ignore any paths that match anything in the gitignore. We do
|
30
|
+
# two tests here:
|
31
|
+
#
|
32
|
+
# - First, test to see if the entire path matches the gitignore.
|
33
|
+
# - Second, match if the basename does, this makes it so that things
|
34
|
+
# like '.DS_Store' will match sub-directories too (same behavior
|
35
|
+
# as git).
|
36
|
+
#
|
37
|
+
gitignore.any? do |ignore|
|
38
|
+
File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
|
39
|
+
File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
spec.files = unignored_files
|
44
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
45
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
46
|
+
spec.require_path = "lib"
|
47
|
+
|
48
|
+
spec.add_dependency "softlayer_api"
|
49
|
+
|
50
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
51
|
+
spec.add_development_dependency "rake"
|
52
|
+
spec.add_development_dependency "rspec"
|
53
|
+
end
|