vagrant-softlayer 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,103 +1,96 @@
1
- module VagrantPlugins
2
- module SoftLayer
3
- module Util
4
- # This mixin contains utility methods for load balancer management.
5
- module LoadBalancer
6
- # Whether load balancer management is enabled or not.
7
- def enabled?
8
- if @env[:machine].provider_config.load_balancers.empty?
9
- @logger.debug("No load balancer has been defined. Going ahead.")
10
- return false
11
- end
12
-
13
- # Currently we don't do load balancing for private machines.
14
- if @env[:machine].provider_config.private_only
15
- @logger.info("Load balancing doesn't work for private machines. Going ahead.")
16
- return false
17
- end
18
- true
19
- end
20
-
21
- # Get existing stuff.
22
- def read_load_balancers
23
- mask = [
24
- "id",
25
- "ipAddress.ipAddress",
26
- "virtualServers.serviceGroups.services.groupReferences",
27
- "virtualServers.serviceGroups.services.healthChecks"
28
- ]
29
- @logger.debug("Looking for existing load balancers.")
30
- @load_balancers = sl_warden { @services["Account"].object_mask(mask).getAdcLoadBalancers }
31
- @logger.debug("Got load balancer configuration:")
32
- @logger.debug("-- #{@load_balancers}")
33
- end
34
-
35
- # For each load balancer, check if total connections
36
- # are less than 100% and, if so, rebalance the allocations.
37
- def rebalance!
38
- read_load_balancers
39
-
40
- @load_balancers.each do |load_balancer|
41
- next if load_balancer["virtualServers"].empty?
42
- next if 100 == load_balancer["virtualServers"].inject(0) { |sum, vs| sum += vs["allocation"] }
43
-
44
- # Create allocation slots.
45
- count = load_balancer["virtualServers"].count
46
- allocation = [100 / count] * count
47
- (100 % count).times { |i| allocation[i] += 1 }
48
-
49
- # Rebalance allocations.
50
- load_balancer["virtualServers"].each do |vs|
51
- vs["allocation"] = allocation.pop
52
- end
53
-
54
- # Update the VIP object.
55
- @logger.debug("Rebalancing VIP #{load_balancer['id']}")
56
- @logger.debug("-- #{load_balancer}")
57
- @services["VirtualIpAddress"].object_with_id(load_balancer["id"]).editObject("virtualServers" => load_balancer["virtualServers"])
58
- end
59
- end
60
-
61
- # Initial setup.
62
- def setup
63
- # A plethora of service objects is required for managing
64
- # load balancers. We instanciate'em all here.
65
- @services = {
66
- "Account" => ::SoftLayer::Service.new("SoftLayer_Account", @env[:sl_credentials])
67
- }
68
- [
69
- "Health_Check_Type",
70
- "Routing_Method",
71
- "Routing_Type",
72
- "Service",
73
- "Service_Group",
74
- "VirtualIpAddress",
75
- "VirtualServer"
76
- ].each do |service|
77
- @services[service] = ::SoftLayer::Service.new(
78
- "SoftLayer_Network_Application_Delivery_Controller_LoadBalancer_#{service}",
79
- @env[:sl_credentials]
80
- )
81
- end
82
-
83
- # We create enumerations for the various configurables.
84
- @enums = {}
85
- [
86
- "Health_Check_Type",
87
- "Routing_Method",
88
- "Routing_Type"
89
- ].each do |service|
90
- {}.tap do |enum|
91
- sl_warden { @services[service].getAllObjects }.each do |record|
92
- enum[record["name"].upcase] = record["id"]
93
- end
94
- @enums[service] = enum
95
- end
96
- end
97
-
98
- read_load_balancers
99
- end
100
- end
101
- end
102
- end
103
- end
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Util
4
+ # This mixin contains utility methods for load balancer management.
5
+ module LoadBalancer
6
+ # Whether load balancer management is enabled or not.
7
+ def enabled?
8
+ if @env[:machine].provider_config.load_balancers.empty?
9
+ @logger.debug("No load balancer has been defined. Going ahead.")
10
+ return false
11
+ end
12
+
13
+ # Currently we don't do load balancing for private machines.
14
+ if @env[:machine].provider_config.private_only
15
+ @logger.info("Load balancing doesn't work for private machines. Going ahead.")
16
+ return false
17
+ end
18
+ true
19
+ end
20
+
21
+ # Get existing stuff.
22
+ def read_load_balancers
23
+ mask = [
24
+ "id",
25
+ "ipAddress.ipAddress",
26
+ "virtualServers.serviceGroups.services.groupReferences",
27
+ "virtualServers.serviceGroups.services.healthChecks"
28
+ ].join(",")
29
+ @logger.debug("Looking for existing load balancers.")
30
+ @load_balancers = sl_warden { @services["Account"].object_mask("mask[#{mask}]").getAdcLoadBalancers }
31
+ @logger.debug("Got load balancer configuration:")
32
+ @logger.debug("-- #{@load_balancers}")
33
+ end
34
+
35
+ # For each load balancer, check if total connections
36
+ # are less than 100% and, if so, rebalance the allocations.
37
+ def rebalance!
38
+ read_load_balancers
39
+
40
+ @load_balancers.each do |load_balancer|
41
+ next if load_balancer["virtualServers"].empty?
42
+ next if 100 == load_balancer["virtualServers"].inject(0) { |sum, vs| sum += vs["allocation"] }
43
+
44
+ # Create allocation slots.
45
+ count = load_balancer["virtualServers"].count
46
+ allocation = [100 / count] * count
47
+ (100 % count).times { |i| allocation[i] += 1 }
48
+
49
+ # Rebalance allocations.
50
+ load_balancer["virtualServers"].each do |vs|
51
+ vs["allocation"] = allocation.pop
52
+ end
53
+
54
+ # Update the VIP object.
55
+ @logger.debug("Rebalancing VIP #{load_balancer['id']}")
56
+ @logger.debug("-- #{load_balancer}")
57
+ @services["VirtualIpAddress"].object_with_id(load_balancer["id"]).editObject("virtualServers" => load_balancer["virtualServers"])
58
+ end
59
+ end
60
+
61
+ # Initial setup.
62
+ def setup
63
+ # A plethora of service objects is required for managing
64
+ # load balancers. We instanciate'em all here.
65
+ @services = { "Account" => @env[:sl_client]["SoftLayer_Account"] }
66
+ [
67
+ "Health_Check_Type",
68
+ "Routing_Method",
69
+ "Routing_Type",
70
+ "Service",
71
+ "Service_Group",
72
+ "VirtualIpAddress",
73
+ "VirtualServer"
74
+ ].each { |service| @services[service] = @env[:sl_client]["SoftLayer_Network_Application_Delivery_Controller_LoadBalancer_#{service}"] }
75
+
76
+ # We create enumerations for the various configurables.
77
+ @enums = {}
78
+ [
79
+ "Health_Check_Type",
80
+ "Routing_Method",
81
+ "Routing_Type"
82
+ ].each do |service|
83
+ {}.tap do |enum|
84
+ sl_warden { @services[service].getAllObjects }.each do |record|
85
+ enum[record["name"].upcase] = record["id"]
86
+ end
87
+ @enums[service] = enum
88
+ end
89
+ end
90
+
91
+ read_load_balancers
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -1,75 +1,75 @@
1
- module VagrantPlugins
2
- module SoftLayer
3
- module Util
4
- module Network
5
- # Gets hostname of the instance starting from the environment.
6
- def hostname(env)
7
- env[:machine].provider_config.hostname || env[:machine].config.vm.hostname
8
- end
9
-
10
- # Gets IP address of the instance starting from the environment.
11
- #
12
- # Returns the private IP address if the instance has been
13
- # defined as private only, the public IP address otherwise.
14
- def ip_address(env)
15
- ip_address_record(env)[:address]
16
- end
17
-
18
- # Gets IP address ID of the instance starting from the environment.
19
- #
20
- # Returns the private IP address ID if the instance has been
21
- # defined as private only, the public IP address ID otherwise.
22
- def ip_address_id(env)
23
- ip_address_record(env)[:id]
24
- end
25
-
26
- # Gets IP address record of the instance starting from the environment.
27
- #
28
- # Returns an hash with the following structure:
29
- #
30
- # :address
31
- # :id
32
- #
33
- # Returns the private IP address record if the instance has been
34
- # defined as private only, the public IP address record otherwise
35
- # unless the force_private_ip override is true.
36
- def ip_address_record(env)
37
- data_type = env[:machine].provider_config.private_only ? "primaryBackendNetworkComponent" : "primaryNetworkComponent"
38
- data_type = "primaryBackendNetworkComponent" if env[:machine].provider_config.force_private_ip
39
- mask = { data_type => { "primaryIpAddressRecord" => ["id", "ipAddress"] } }
40
- record = sl_warden { env[:sl_machine].object_mask(mask).getObject }
41
- return {
42
- :address => record[data_type]["primaryIpAddressRecord"]["ipAddress"],
43
- :id => record[data_type]["primaryIpAddressRecord"]["id"]
44
- }
45
- end
46
-
47
- # Returns SSH keys starting from the configuration parameter.
48
- #
49
- # In the configuration, each key could be passed either as an
50
- # id or as a label. The routine will detect this and lookup
51
- # the id if needed.
52
- #
53
- # The first parameter is the current environment.
54
- #
55
- # The second parameter is useful for returning: if it is set
56
- # the routine will return just the array of ids (this is needed,
57
- # as an example, for reloading OS), otherwise an hash is
58
- # returned (this latter case is needed instead for creating
59
- # an instance).
60
- def ssh_keys(env, ids_only = false)
61
- account = ::SoftLayer::Service.new("SoftLayer_Account", env[:sl_credentials])
62
- acc_keys = sl_warden { account.object_mask("id", "label").getSshKeys }
63
- key_ids = []
64
- Array(env[:machine].provider_config.ssh_key).each do |key|
65
- pattern = key.is_a?(String) ? "label" : "id"
66
- key_hash = acc_keys.find { |acc_key| acc_key[pattern] == key }
67
- raise Errors::SLSshKeyNotFound, :key => key unless key_hash
68
- key_ids << key_hash["id"]
69
- end
70
- return (ids_only ? key_ids : key_ids.map { |key_id| { :id => key_id } })
71
- end
72
- end
73
- end
74
- end
75
- end
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ module Util
4
+ module Network
5
+ # Gets hostname of the instance starting from the environment.
6
+ def hostname(env)
7
+ env[:machine].provider_config.hostname || env[:machine].config.vm.hostname
8
+ end
9
+
10
+ # Gets IP address of the instance starting from the environment.
11
+ #
12
+ # Returns the private IP address if the instance has been
13
+ # defined as private only, the public IP address otherwise.
14
+ def ip_address(env)
15
+ ip_address_record(env)[:address]
16
+ end
17
+
18
+ # Gets IP address ID of the instance starting from the environment.
19
+ #
20
+ # Returns the private IP address ID if the instance has been
21
+ # defined as private only, the public IP address ID otherwise.
22
+ def ip_address_id(env)
23
+ ip_address_record(env)[:id]
24
+ end
25
+
26
+ # Gets IP address record of the instance starting from the environment.
27
+ #
28
+ # Returns an hash with the following structure:
29
+ #
30
+ # :address
31
+ # :id
32
+ #
33
+ # Returns the private IP address record if the instance has been
34
+ # defined as private only, the public IP address record otherwise
35
+ # unless the force_private_ip override is true.
36
+ def ip_address_record(env)
37
+ data_type = env[:machine].provider_config.private_only ? "primaryBackendNetworkComponent" : "primaryNetworkComponent"
38
+ data_type = "primaryBackendNetworkComponent" if env[:machine].provider_config.force_private_ip
39
+ mask = "#{data_type}.primaryIpAddressRecord.id,#{data_type}.primaryIpAddressRecord.ipAddress"
40
+ record = sl_warden { env[:sl_machine].object_mask("mask[#{mask}]").getObject }
41
+ return {
42
+ :address => record[data_type]["primaryIpAddressRecord"]["ipAddress"],
43
+ :id => record[data_type]["primaryIpAddressRecord"]["id"]
44
+ }
45
+ end
46
+
47
+ # Returns SSH keys starting from the configuration parameter.
48
+ #
49
+ # In the configuration, each key could be passed either as an
50
+ # id or as a label. The routine will detect this and lookup
51
+ # the id if needed.
52
+ #
53
+ # The first parameter is the current environment.
54
+ #
55
+ # The second parameter is useful for returning: if it is set
56
+ # the routine will return just the array of ids (this is needed,
57
+ # as an example, for reloading OS), otherwise an hash is
58
+ # returned (this latter case is needed instead for creating
59
+ # an instance).
60
+ def ssh_keys(env, ids_only = false)
61
+ account = env[:sl_client]["SoftLayer_Account"]
62
+ acc_keys = sl_warden { account.object_mask("mask[id,label]").getSshKeys }
63
+ key_ids = []
64
+ Array(env[:machine].provider_config.ssh_key).each do |key|
65
+ pattern = key.is_a?(String) ? "label" : "id"
66
+ key_hash = acc_keys.find { |acc_key| acc_key[pattern] == key }
67
+ raise Errors::SLSshKeyNotFound, :key => key unless key_hash
68
+ key_ids << key_hash["id"]
69
+ end
70
+ return (ids_only ? key_ids : key_ids.map { |key_id| { :id => key_id } })
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -1,38 +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") || e.message.start_with?("Object does not exist"))
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
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 Exception => e
22
+ if e.class != SocketError && (e.message.start_with?("Unable to find object") || e.message.start_with?("Object does not exist"))
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
@@ -1,5 +1,5 @@
1
- module VagrantPlugins
2
- module SoftLayer
3
- VERSION = "0.3.3"
4
- end
5
- end
1
+ module VagrantPlugins
2
+ module SoftLayer
3
+ VERSION = "0.4.0"
4
+ end
5
+ end
@@ -1,267 +1,271 @@
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("disk_capacity") { should be_nil }
21
- its("domain") { should be_nil }
22
- its("force_private_ip") { should be_false }
23
- its("hostname") { should be_nil }
24
- its("hourly_billing") { should be_true }
25
- its("image_guid") { should be_nil }
26
- its("local_disk") { should be_true }
27
- its("max_memory") { should eq 1024 }
28
- its("network_speed") { should eq 10 }
29
- its("operating_system") { should eq "UBUNTU_LATEST" }
30
- its("post_install") { should be_nil }
31
- its("private_only") { should be_false }
32
- its("provision_timeout") { should eq 1200 }
33
- its("rebuild_timeout") { should eq 1200 }
34
- its("ssh_key") { should be_nil }
35
- its("start_cpus") { should eq 1 }
36
- its("user_data") { should be_nil }
37
- its("vlan_private") { should be_nil }
38
- its("vlan_public") { should be_nil }
39
-
40
- its("load_balancers") { should eq [] }
41
- its("manage_dns") { should be_false }
42
- end
43
-
44
- describe "overriding defaults" do
45
- context "booleans" do
46
- [true, false].each do |bool|
47
- [:dedicated, :force_private_ip, :hourly_billing, :local_disk, :manage_dns, :private_only].each do |attribute|
48
- it "should accept both true and false for #{attribute}" do
49
- config.send("#{attribute}=".to_sym, bool)
50
- config.finalize!
51
- expect(config.send(attribute)).to eq bool
52
- end
53
- end
54
- end
55
- end
56
-
57
- context "integers" do
58
- [:max_memory, :network_speed, :provision_timeout, :rebuild_timeout, :ssh_key, :start_cpus, :vlan_private, :vlan_public].each do |attribute|
59
- it "should not default #{attribute} if overridden" do
60
- config.send("#{attribute}=".to_sym, 999)
61
- config.finalize!
62
- expect(config.send(attribute)).to eq 999
63
- end
64
- end
65
- end
66
-
67
- context "strings" do
68
- [:api_key, :datacenter, :endpoint_url, :username, :domain, :hostname, :image_guid, :operating_system, :post_install, :ssh_key, :user_data, :vlan_private, :vlan_public].each do |attribute|
69
- it "should not default #{attribute} if overridden" do
70
- config.send("#{attribute}=".to_sym, "foo")
71
- config.finalize!
72
- expect(config.send(attribute)).to eq "foo"
73
- end
74
- end
75
- end
76
-
77
- context "int hash" do
78
- it "should not default disk_capacity if overriden" do
79
- config.send("disk_capacity=".to_sym, { 0 => 100, 2 => 25 } )
80
- config.finalize!
81
- expect(config.send("disk_capacity")).to eq { 0 => 100, 2 => 25 }
82
- end
83
- end
84
- end
85
-
86
- describe "joining load balancer" do
87
- it "should set weight to 1 by default" do
88
- config.join_load_balancer :port => 443, :vip => "1.1.1.1"
89
- config.finalize!
90
- expect(config.load_balancers.first[:service].weight).to eq(1)
91
- end
92
-
93
- it "should set passed options" do
94
- config.join_load_balancer :foo => "bar", :port => 443, :vip => "1.1.1.1"
95
- config.finalize!
96
- expect(config.load_balancers.first[:foo]).to eq("bar")
97
- end
98
-
99
- it "should set service parameters" do
100
- config.join_load_balancer :port => 443, :vip => "1.1.1.1" do |srv|
101
- srv.destination_port = 443
102
- srv.health_check = "DNS"
103
- srv.notes = "Some notes"
104
- srv.weight = 9
105
- end
106
- config.finalize!
107
- expect(config.load_balancers.first[:service].destination_port).to eq(443)
108
- expect(config.load_balancers.first[:service].health_check).to eq("DNS")
109
- expect(config.load_balancers.first[:service].notes).to eq("Some notes")
110
- expect(config.load_balancers.first[:service].weight).to eq(9)
111
- end
112
- end
113
-
114
- describe "using SL_ environment variables" do
115
- before :each do
116
- ENV.stub(:[]).with("SL_API_KEY").and_return("env_api_key")
117
- ENV.stub(:[]).with("SL_USERNAME").and_return("env_username")
118
- end
119
-
120
- subject do
121
- config.tap do |o|
122
- o.finalize!
123
- end
124
- end
125
-
126
- its("api_key") { should eq "env_api_key" }
127
- its("username") { should eq "env_username" }
128
- end
129
-
130
- describe "validation" do
131
- before :each do
132
- # Setup some good configuration values
133
- config.api_key = "An API key"
134
- config.username = "An username"
135
-
136
- config.datacenter = "ams01"
137
- config.dedicated = false
138
- config.domain = "example.com"
139
- config.disk_capacity = { 0 => 25 }
140
- config.force_private_ip = false
141
- config.hostname = "vagrant"
142
- config.hourly_billing = true
143
- config.image_guid = nil
144
- config.local_disk = true
145
- config.max_memory = 1024
146
- config.network_speed = 10
147
- config.operating_system = "UBUNTU_LATEST"
148
- config.post_install = "http://example.com/foo"
149
- config.provision_timeout = 1200
150
- config.rebuild_timeout = 1200
151
- config.ssh_key = ["First key", "Second key"]
152
- config.start_cpus = 1
153
- config.user_data = "some metadata"
154
- config.vlan_private = 111
155
- config.vlan_public = 222
156
-
157
- config.manage_dns = false
158
-
159
- machine.stub_chain(:config, :vm, :hostname).and_return(nil)
160
- end
161
-
162
- it "should validate" do
163
- config.finalize!
164
- expect(config.validate(machine)["SoftLayer"]).to have(:no).item
165
- end
166
-
167
- it "should fail if API key is not given" do
168
- config.api_key = nil
169
- config.finalize!
170
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
171
- end
172
-
173
- it "should fail if username is not given" do
174
- config.username = nil
175
- config.finalize!
176
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
177
- end
178
-
179
- it "should fail if domain is not given" do
180
- config.domain = nil
181
- config.finalize!
182
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
183
- end
184
-
185
- it "should fail if hostname is not given" do
186
- config.hostname = nil
187
- config.finalize!
188
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
189
- end
190
-
191
- it "should validate if hostname is not given but config.vm.hostname is set" do
192
- config.hostname = nil
193
- config.finalize!
194
- machine.stub_chain(:config, :vm, :hostname).and_return("vagrant")
195
- expect(config.validate(machine)["SoftLayer"]).to have(:no).item
196
- end
197
-
198
- it "should fail if ssh key is not given" do
199
- config.ssh_key = nil
200
- config.finalize!
201
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
202
- end
203
-
204
- it "should fail if a load balancer is specified without vip" do
205
- config.join_load_balancer :port => 443 do |srv|
206
- srv.destination_port = 443
207
- end
208
- config.finalize!
209
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
210
- end
211
-
212
- it "should fail if a load balancer is specified without port" do
213
- config.join_load_balancer :vip => "1.1.1.1" do |srv|
214
- srv.destination_port = 443
215
- end
216
- config.finalize!
217
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
218
- end
219
-
220
- it "should fail if a load balancer is specified without destination port" do
221
- config.join_load_balancer :port => 443, :vip => "1.1.1.1"
222
- config.finalize!
223
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
224
- end
225
-
226
- it "should fail if two load balancers han been defined with same vip and port" do
227
- config.join_load_balancer :port => 443, :vip => "1.1.1.1" do |srv|
228
- srv.destination_port = 443
229
- end
230
- config.join_load_balancer :port => 443, :vip => "1.1.1.1" do |srv|
231
- srv.destination_port = 8443
232
- end
233
- config.finalize!
234
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
235
- end
236
-
237
- it "should validate if a load balancer if specified with vip, port and destination port" do
238
- config.join_load_balancer :port => 443, :vip => "1.1.1.1" do |srv|
239
- srv.destination_port = 443
240
- end
241
- config.finalize!
242
- expect(config.validate(machine)["SoftLayer"]).to have(:no).item
243
- end
244
-
245
- it "should fail if disk_capacity and image_guid are both specified" do
246
- config.disk_capacity = { 0 => 25 }
247
- config.image_guid = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"
248
- config.operating_system = nil
249
- config.finalize!
250
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
251
- end
252
-
253
- it "should fail if operating system and image_guid are both specified" do
254
- config.image_guid = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"
255
- config.operating_system = "UBUNTU_LATEST"
256
- config.finalize!
257
- expect(config.validate(machine)["SoftLayer"]).to have(1).item
258
- end
259
-
260
- it "should validate if operating_system and disk_capacity are both specified" do
261
- config.operating_system = "UBUNTU_LATEST"
262
- config.disk_capacity = { 0 => 25 }
263
- config.finalize!
264
- expect(config.validate(machine)["SoftLayer"]).to have(:no).item
265
- end
266
- end
267
- end
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("api_timeout") { should eq 60 }
16
+ its("endpoint_url") { should eq VagrantPlugins::SoftLayer::API_PUBLIC_ENDPOINT }
17
+ its("username") { should be_nil }
18
+
19
+ its("datacenter") { should be_nil }
20
+ its("dedicated") { should be_false }
21
+ its("disk_capacity") { should be_nil }
22
+ its("domain") { should be_nil }
23
+ its("force_private_ip") { should be_false }
24
+ its("hostname") { should be_nil }
25
+ its("hourly_billing") { should be_true }
26
+ its("image_guid") { should be_nil }
27
+ its("local_disk") { should be_true }
28
+ its("max_memory") { should eq 1024 }
29
+ its("network_speed") { should eq 10 }
30
+ its("operating_system") { should eq "UBUNTU_LATEST" }
31
+ its("post_install") { should be_nil }
32
+ its("private_only") { should be_false }
33
+ its("provision_timeout") { should eq 1200 }
34
+ its("rebuild_timeout") { should eq 1200 }
35
+ its("ssh_key") { should be_nil }
36
+ its("start_cpus") { should eq 1 }
37
+ its("transaction_wait") { should be_true }
38
+ its("user_data") { should be_nil }
39
+ its("vlan_private") { should be_nil }
40
+ its("vlan_public") { should be_nil }
41
+
42
+ its("load_balancers") { should eq [] }
43
+ its("manage_dns") { should be_false }
44
+ end
45
+
46
+ describe "overriding defaults" do
47
+ context "booleans" do
48
+ [true, false].each do |bool|
49
+ [:dedicated, :force_private_ip, :hourly_billing, :local_disk, :manage_dns, :private_only, :transaction_wait].each do |attribute|
50
+ it "should accept both true and false for #{attribute}" do
51
+ config.send("#{attribute}=".to_sym, bool)
52
+ config.finalize!
53
+ expect(config.send(attribute)).to eq bool
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ context "integers" do
60
+ [:api_timeout, :max_memory, :network_speed, :provision_timeout, :rebuild_timeout, :ssh_key, :start_cpus, :vlan_private, :vlan_public].each do |attribute|
61
+ it "should not default #{attribute} if overridden" do
62
+ config.send("#{attribute}=".to_sym, 999)
63
+ config.finalize!
64
+ expect(config.send(attribute)).to eq 999
65
+ end
66
+ end
67
+ end
68
+
69
+ context "strings" do
70
+ [:api_key, :datacenter, :endpoint_url, :username, :domain, :hostname, :image_guid, :operating_system, :post_install, :ssh_key, :user_data, :vlan_private, :vlan_public].each do |attribute|
71
+ it "should not default #{attribute} if overridden" do
72
+ config.send("#{attribute}=".to_sym, "foo")
73
+ config.finalize!
74
+ expect(config.send(attribute)).to eq "foo"
75
+ end
76
+ end
77
+ end
78
+
79
+ context "int hash" do
80
+ it "should not default disk_capacity if overriden" do
81
+ config.send("disk_capacity=".to_sym, { 0 => 100, 2 => 25 } )
82
+ config.finalize!
83
+ expect(config.send("disk_capacity")).to eq { 0 => 100, 2 => 25 }
84
+ end
85
+ end
86
+ end
87
+
88
+ describe "joining load balancer" do
89
+ it "should set weight to 1 by default" do
90
+ config.join_load_balancer :port => 443, :vip => "1.1.1.1"
91
+ config.finalize!
92
+ expect(config.load_balancers.first[:service].weight).to eq(1)
93
+ end
94
+
95
+ it "should set passed options" do
96
+ config.join_load_balancer :foo => "bar", :port => 443, :vip => "1.1.1.1"
97
+ config.finalize!
98
+ expect(config.load_balancers.first[:foo]).to eq("bar")
99
+ end
100
+
101
+ it "should set service parameters" do
102
+ config.join_load_balancer :port => 443, :vip => "1.1.1.1" do |srv|
103
+ srv.destination_port = 443
104
+ srv.health_check = "DNS"
105
+ srv.notes = "Some notes"
106
+ srv.weight = 9
107
+ end
108
+ config.finalize!
109
+ expect(config.load_balancers.first[:service].destination_port).to eq(443)
110
+ expect(config.load_balancers.first[:service].health_check).to eq("DNS")
111
+ expect(config.load_balancers.first[:service].notes).to eq("Some notes")
112
+ expect(config.load_balancers.first[:service].weight).to eq(9)
113
+ end
114
+ end
115
+
116
+ describe "using SL_ environment variables" do
117
+ before :each do
118
+ ENV.stub(:[]).with("SL_API_KEY").and_return("env_api_key")
119
+ ENV.stub(:[]).with("SL_USERNAME").and_return("env_username")
120
+ end
121
+
122
+ subject do
123
+ config.tap do |o|
124
+ o.finalize!
125
+ end
126
+ end
127
+
128
+ its("api_key") { should eq "env_api_key" }
129
+ its("username") { should eq "env_username" }
130
+ end
131
+
132
+ describe "validation" do
133
+ before :each do
134
+ # Setup some good configuration values
135
+ config.api_key = "An API key"
136
+ config.api_timeout = 60
137
+ config.username = "An username"
138
+
139
+ config.datacenter = "ams01"
140
+ config.dedicated = false
141
+ config.domain = "example.com"
142
+ config.disk_capacity = { 0 => 25 }
143
+ config.force_private_ip = false
144
+ config.hostname = "vagrant"
145
+ config.hourly_billing = true
146
+ config.image_guid = nil
147
+ config.local_disk = true
148
+ config.max_memory = 1024
149
+ config.network_speed = 10
150
+ config.operating_system = "UBUNTU_LATEST"
151
+ config.post_install = "http://example.com/foo"
152
+ config.provision_timeout = 1200
153
+ config.rebuild_timeout = 1200
154
+ config.ssh_key = ["First key", "Second key"]
155
+ config.start_cpus = 1
156
+ config.transaction_wait = true
157
+ config.user_data = "some metadata"
158
+ config.vlan_private = 111
159
+ config.vlan_public = 222
160
+
161
+ config.manage_dns = false
162
+
163
+ machine.stub_chain(:config, :vm, :hostname).and_return(nil)
164
+ end
165
+
166
+ it "should validate" do
167
+ config.finalize!
168
+ expect(config.validate(machine)["SoftLayer"]).to have(:no).item
169
+ end
170
+
171
+ it "should fail if API key is not given" do
172
+ config.api_key = nil
173
+ config.finalize!
174
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
175
+ end
176
+
177
+ it "should fail if username is not given" do
178
+ config.username = nil
179
+ config.finalize!
180
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
181
+ end
182
+
183
+ it "should fail if domain is not given" do
184
+ config.domain = nil
185
+ config.finalize!
186
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
187
+ end
188
+
189
+ it "should fail if hostname is not given" do
190
+ config.hostname = nil
191
+ config.finalize!
192
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
193
+ end
194
+
195
+ it "should validate if hostname is not given but config.vm.hostname is set" do
196
+ config.hostname = nil
197
+ config.finalize!
198
+ machine.stub_chain(:config, :vm, :hostname).and_return("vagrant")
199
+ expect(config.validate(machine)["SoftLayer"]).to have(:no).item
200
+ end
201
+
202
+ it "should fail if ssh key is not given" do
203
+ config.ssh_key = nil
204
+ config.finalize!
205
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
206
+ end
207
+
208
+ it "should fail if a load balancer is specified without vip" do
209
+ config.join_load_balancer :port => 443 do |srv|
210
+ srv.destination_port = 443
211
+ end
212
+ config.finalize!
213
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
214
+ end
215
+
216
+ it "should fail if a load balancer is specified without port" do
217
+ config.join_load_balancer :vip => "1.1.1.1" do |srv|
218
+ srv.destination_port = 443
219
+ end
220
+ config.finalize!
221
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
222
+ end
223
+
224
+ it "should fail if a load balancer is specified without destination port" do
225
+ config.join_load_balancer :port => 443, :vip => "1.1.1.1"
226
+ config.finalize!
227
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
228
+ end
229
+
230
+ it "should fail if two load balancers han been defined with same vip and port" do
231
+ config.join_load_balancer :port => 443, :vip => "1.1.1.1" do |srv|
232
+ srv.destination_port = 443
233
+ end
234
+ config.join_load_balancer :port => 443, :vip => "1.1.1.1" do |srv|
235
+ srv.destination_port = 8443
236
+ end
237
+ config.finalize!
238
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
239
+ end
240
+
241
+ it "should validate if a load balancer if specified with vip, port and destination port" do
242
+ config.join_load_balancer :port => 443, :vip => "1.1.1.1" do |srv|
243
+ srv.destination_port = 443
244
+ end
245
+ config.finalize!
246
+ expect(config.validate(machine)["SoftLayer"]).to have(:no).item
247
+ end
248
+
249
+ it "should fail if disk_capacity and image_guid are both specified" do
250
+ config.disk_capacity = { 0 => 25 }
251
+ config.image_guid = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"
252
+ config.operating_system = nil
253
+ config.finalize!
254
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
255
+ end
256
+
257
+ it "should fail if operating system and image_guid are both specified" do
258
+ config.image_guid = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE"
259
+ config.operating_system = "UBUNTU_LATEST"
260
+ config.finalize!
261
+ expect(config.validate(machine)["SoftLayer"]).to have(1).item
262
+ end
263
+
264
+ it "should validate if operating_system and disk_capacity are both specified" do
265
+ config.operating_system = "UBUNTU_LATEST"
266
+ config.disk_capacity = { 0 => 25 }
267
+ config.finalize!
268
+ expect(config.validate(machine)["SoftLayer"]).to have(:no).item
269
+ end
270
+ end
271
+ end