chef-provisioning-fog 0.26.1 → 0.26.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +29 -8
- data/Rakefile +23 -12
- data/chef-provisioning-fog.gemspec +24 -27
- data/lib/chef/provider/fog_key_pair.rb +49 -53
- data/lib/chef/provider/scaleway_volume.rb +46 -48
- data/lib/chef/provisioning/driver_init/fog.rb +1 -1
- data/lib/chef/provisioning/fog_driver/driver.rb +646 -653
- data/lib/chef/provisioning/fog_driver/providers/aws.rb +411 -422
- data/lib/chef/provisioning/fog_driver/providers/aws/credentials.rb +88 -90
- data/lib/chef/provisioning/fog_driver/providers/cloudstack.rb +32 -34
- data/lib/chef/provisioning/fog_driver/providers/digitalocean.rb +98 -100
- data/lib/chef/provisioning/fog_driver/providers/google.rb +27 -34
- data/lib/chef/provisioning/fog_driver/providers/joyent.rb +53 -55
- data/lib/chef/provisioning/fog_driver/providers/openstack.rb +139 -146
- data/lib/chef/provisioning/fog_driver/providers/rackspace.rb +40 -44
- data/lib/chef/provisioning/fog_driver/providers/scaleway.rb +183 -189
- data/lib/chef/provisioning/fog_driver/providers/softlayer.rb +61 -64
- data/lib/chef/provisioning/fog_driver/providers/vcair.rb +72 -78
- data/lib/chef/provisioning/fog_driver/providers/xenserver.rb +56 -69
- data/lib/chef/provisioning/fog_driver/recipe_dsl.rb +11 -12
- data/lib/chef/provisioning/fog_driver/version.rb +1 -1
- data/lib/chef/resource/fog_key_pair.rb +8 -8
- data/lib/chef/resource/scaleway_volume.rb +8 -8
- data/spec/spec_helper.rb +7 -7
- data/spec/support/chef/provisioning/fog_driver/providers/testdriver.rb +3 -3
- data/spec/unit/chef/provisioning/fog_driver/driver_spec.rb +39 -38
- data/spec/unit/fog_driver_spec.rb +6 -8
- data/spec/unit/providers/aws/credentials_spec.rb +10 -10
- data/spec/unit/providers/rackspace_spec.rb +5 -6
- data/spec/unit/providers/scaleway_spec.rb +9 -9
- data/spec/unit/providers/softlayer.rb +7 -7
- metadata +6 -36
- data/README.md +0 -357
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "base64"
|
2
|
+
require "uri"
|
3
|
+
require "fog/softlayer"
|
4
|
+
require "fog/softlayer/models/compute/server"
|
5
5
|
|
6
6
|
# fog:SoftLayer:<datacenter>
|
7
7
|
class Chef
|
@@ -9,32 +9,31 @@ class Chef
|
|
9
9
|
module FogDriver
|
10
10
|
module Providers
|
11
11
|
class SoftLayer < FogDriver::Driver
|
12
|
-
Driver.register_provider_class(
|
12
|
+
Driver.register_provider_class("SoftLayer", FogDriver::Providers::SoftLayer)
|
13
13
|
|
14
|
-
POST_SCRIPT_DONE =
|
14
|
+
POST_SCRIPT_DONE = "post-script-done".freeze
|
15
15
|
|
16
16
|
def creator
|
17
17
|
compute_options[:softlayer_username]
|
18
18
|
end
|
19
19
|
|
20
20
|
def convergence_strategy_for(machine_spec, machine_options)
|
21
|
-
machine_options = Cheffish::MergedConfig.new(machine_options,
|
22
|
-
|
23
|
-
})
|
21
|
+
machine_options = Cheffish::MergedConfig.new(machine_options,
|
22
|
+
convergence_options: { ohai_hints: { "softlayer" => {} } })
|
24
23
|
super(machine_spec, machine_options)
|
25
24
|
end
|
26
25
|
|
27
26
|
def self.compute_options_for(provider, id, config)
|
28
27
|
new_compute_options = {}
|
29
28
|
new_compute_options[:provider] = provider
|
30
|
-
new_config = { :
|
29
|
+
new_config = { driver_options: { compute_options: new_compute_options } }
|
31
30
|
new_defaults = {
|
32
|
-
:
|
33
|
-
:
|
31
|
+
driver_options: { compute_options: Fog.credentials },
|
32
|
+
machine_options: { bootstrap_options: {} }
|
34
33
|
}
|
35
34
|
result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
|
36
|
-
id ||=
|
37
|
-
new_defaults[:machine_options][:bootstrap_options][:datacenter] = id
|
35
|
+
id ||= ""
|
36
|
+
new_defaults[:machine_options][:bootstrap_options][:datacenter] = id unless id.empty?
|
38
37
|
|
39
38
|
[result, id]
|
40
39
|
end
|
@@ -65,45 +64,43 @@ class Chef
|
|
65
64
|
# options
|
66
65
|
opts.delete(:vlan) if opts[:vlan] && opts[:private_network_only]
|
67
66
|
|
68
|
-
opts.keep_if do |opt,
|
67
|
+
opts.keep_if do |opt, _val|
|
69
68
|
::Fog::Compute::Softlayer::Server.attributes.include?(opt) || opt =~ /private_vlan|vlan/
|
70
69
|
end
|
71
70
|
# fog-softlayer defines :tags but SoftLayer_Hardware_Server rejects it...
|
72
|
-
#opts.delete :tags
|
71
|
+
# opts.delete :tags
|
73
72
|
|
74
73
|
# we hook in our own post-install script which uses userMetadata to
|
75
74
|
# tell us when post-install is complete. If the user supplies their
|
76
75
|
# own script it will be called by our hook before indicating
|
77
76
|
# completion in userData.
|
78
|
-
opts[:postInstallScriptUri] =
|
77
|
+
opts[:postInstallScriptUri] = "https://dal05.objectstorage.service.networklayer.com/v1/AUTH_b1b23a05-1c03-4961-8b08-2339886e476f/dist/sl-post-hook.sh"
|
79
78
|
|
80
79
|
super(num_servers, opts, parallelizer)
|
81
80
|
end
|
82
81
|
|
83
|
-
def find_floating_ips(
|
82
|
+
def find_floating_ips(_server, _action_handler)
|
84
83
|
[]
|
85
84
|
end
|
86
85
|
|
87
86
|
def server_for(machine_spec)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
else
|
93
|
-
sv = compute.servers.new(
|
94
|
-
:uid => machine_spec.reference['uid'],
|
95
|
-
:name => machine_spec.name,
|
96
|
-
:domain => machine_spec.reference['domain']
|
97
|
-
)
|
98
|
-
|
99
|
-
Chef::Log.info("waiting for server.id")
|
100
|
-
sv.wait_for_id
|
101
|
-
machine_spec.reference['server_id'] = sv.id
|
102
|
-
return sv
|
103
|
-
end
|
87
|
+
if machine_spec.reference
|
88
|
+
id = machine_spec.reference["server_id"]
|
89
|
+
if id && (id != 0)
|
90
|
+
compute.servers.get(id)
|
104
91
|
else
|
105
|
-
|
92
|
+
sv = compute.servers.new(
|
93
|
+
uid: machine_spec.reference["uid"],
|
94
|
+
name: machine_spec.name,
|
95
|
+
domain: machine_spec.reference["domain"]
|
96
|
+
)
|
97
|
+
|
98
|
+
Chef::Log.info("waiting for server.id")
|
99
|
+
sv.wait_for_id
|
100
|
+
machine_spec.reference["server_id"] = sv.id
|
101
|
+
return sv
|
106
102
|
end
|
103
|
+
end
|
107
104
|
end
|
108
105
|
|
109
106
|
def servers_for(specs_and_options)
|
@@ -117,45 +114,45 @@ class Chef
|
|
117
114
|
|
118
115
|
def create_servers(action_handler, specs_and_options, parallelizer, &block)
|
119
116
|
super do |machine_spec, server|
|
120
|
-
machine_spec.reference[
|
121
|
-
machine_spec.reference[
|
117
|
+
machine_spec.reference["uid"] = server.uid
|
118
|
+
machine_spec.reference["domain"] = server.domain
|
122
119
|
machine_spec.save(action_handler)
|
123
120
|
bootstrap_options = specs_and_options[machine_spec][:bootstrap_options]
|
124
121
|
create_timeout = bootstrap_options[:create_timeout] || 3600
|
125
122
|
wait_for_id(action_handler, server, create_timeout)
|
126
123
|
set_post_install_info(action_handler, server, bootstrap_options)
|
127
124
|
|
128
|
-
|
125
|
+
yield(machine_spec, server) if block
|
129
126
|
end
|
130
127
|
end
|
131
128
|
|
132
129
|
def request(server, path, **options)
|
133
|
-
|
134
|
-
|
130
|
+
service = server.bare_metal? ? :hardware_server : :virtual_guest
|
131
|
+
server.service.request(service, path, options)
|
135
132
|
end
|
136
133
|
|
137
134
|
def set_post_install_info(action_handler, server, bootstrap_options)
|
138
|
-
existing_user_data = request(server, server.id, :
|
135
|
+
existing_user_data = request(server, server.id, query: { objectMask: "userData" }).body["userData"]
|
139
136
|
Chef::Log.info("userData from SLAPI is #{existing_user_data.inspect}")
|
140
137
|
if existing_user_data.is_a? Array
|
141
|
-
if existing_user_data.
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
138
|
+
existing_user_data = if existing_user_data.empty?
|
139
|
+
""
|
140
|
+
else
|
141
|
+
existing_user_data.first.fetch("value", "")
|
142
|
+
end
|
146
143
|
end
|
147
144
|
Chef::Log.info("userData after processing is #{existing_user_data.inspect}")
|
148
145
|
# VSI userData is empty; bare metal userData will be an Array
|
149
146
|
if existing_user_data.empty?
|
150
147
|
action_handler.report_progress("Setting userData to detect post install status.")
|
151
|
-
sl_user = compute.instance_variable_get
|
152
|
-
sl_key = compute.instance_variable_get
|
153
|
-
service = server.bare_metal? ?
|
154
|
-
::Retryable.retryable(:
|
148
|
+
sl_user = compute.instance_variable_get "@softlayer_username"
|
149
|
+
sl_key = compute.instance_variable_get "@softlayer_api_key"
|
150
|
+
service = server.bare_metal? ? "Hardware_Server" : "Virtual_Guest"
|
151
|
+
::Retryable.retryable(tries: 60, sleep: 5) do
|
155
152
|
update_url = URI::HTTPS.build(
|
156
|
-
:
|
157
|
-
:
|
158
|
-
:
|
153
|
+
userinfo: "#{sl_user}:#{sl_key}",
|
154
|
+
host: "api.service.softlayer.com",
|
155
|
+
path: "/rest/v3/SoftLayer_#{service}/#{server.id}/setUserMetadata"
|
159
156
|
).to_s
|
160
157
|
|
161
158
|
post_install_info = <<SHELL
|
@@ -170,26 +167,26 @@ SHELL
|
|
170
167
|
res = request(
|
171
168
|
server,
|
172
169
|
"#{server.id}/setUserMetadata",
|
173
|
-
:
|
170
|
+
http_method: "POST", body: [
|
174
171
|
[
|
175
|
-
|
172
|
+
encoded_info
|
176
173
|
]
|
177
174
|
]
|
178
175
|
)
|
179
176
|
|
180
|
-
raise "Failed to setUserMetadata" unless TrueClass == res.body.class
|
177
|
+
raise "Failed to setUserMetadata" unless (TrueClass == res.body.class) || res.body.first["value"]
|
181
178
|
end
|
182
179
|
end
|
183
180
|
end
|
184
181
|
|
185
182
|
def wait_for_id(action_handler, server, create_timeout)
|
186
|
-
return if
|
183
|
+
return if server.id != 0
|
187
184
|
|
188
185
|
# Cannot use Fog.wait_for because it requires server.id which is
|
189
186
|
# not initially available for bare metal.
|
190
187
|
server.wait_for_id(create_timeout) do |srv_info|
|
191
|
-
|
192
|
-
|
188
|
+
srv_id = srv_info ? srv_info["id"] : "not set yet"
|
189
|
+
action_handler.report_progress "waiting for server.id on #{server.name} (#{server.uid}): #{srv_id} #{srv_info}"
|
193
190
|
end
|
194
191
|
end
|
195
192
|
|
@@ -198,11 +195,11 @@ SHELL
|
|
198
195
|
|
199
196
|
action_handler.report_progress "waiting for post-install script on #{server.name} to finish"
|
200
197
|
|
201
|
-
::Retryable.retryable(:
|
198
|
+
::Retryable.retryable(tries: 600, sleep: 2) do
|
202
199
|
action_handler.report_progress "checking post-install status on #{server.name}"
|
203
|
-
res = request(server, server.id, :
|
204
|
-
userData = res.body[
|
205
|
-
value = userData.first[
|
200
|
+
res = request(server, server.id, query: "objectMask=userData")
|
201
|
+
userData = res.body["userData"]
|
202
|
+
value = userData.first["value"]
|
206
203
|
|
207
204
|
raise "Waiting for post-install script" unless POST_SCRIPT_DONE == value
|
208
205
|
end
|
@@ -211,7 +208,7 @@ SHELL
|
|
211
208
|
end
|
212
209
|
|
213
210
|
def start_server(action_handler, machine_spec, server)
|
214
|
-
::Retryable.retryable(:
|
211
|
+
::Retryable.retryable(tries: 10, sleep: 2) do
|
215
212
|
super
|
216
213
|
end
|
217
214
|
end
|
@@ -4,7 +4,7 @@ class Chef
|
|
4
4
|
module FogDriver
|
5
5
|
module Providers
|
6
6
|
class Vcair < FogDriver::Driver
|
7
|
-
Driver.register_provider_class(
|
7
|
+
Driver.register_provider_class("vcair", FogDriver::Providers::Vcair)
|
8
8
|
|
9
9
|
def creator
|
10
10
|
driver_options[:username]
|
@@ -13,12 +13,12 @@ class Chef
|
|
13
13
|
def initialize(driver_url, config)
|
14
14
|
super(driver_url, config)
|
15
15
|
|
16
|
-
@auth_params = {provider:
|
17
|
-
_fog, _vcair, @auth_params[:vcloud_director_host] = driver_url.split(
|
16
|
+
@auth_params = { provider: "vclouddirector" }
|
17
|
+
_fog, _vcair, @auth_params[:vcloud_director_host] = driver_url.split(":", 3)
|
18
18
|
@auth_params[:vcloud_director_username] = "#{driver_options[:username]}@#{driver_options[:org]}"
|
19
19
|
@auth_params[:vcloud_director_password] = driver_options[:password]
|
20
20
|
@auth_params[:vcloud_director_show_progress] = driver_options[:show_progress] || false
|
21
|
-
Chef::Log.debug(
|
21
|
+
Chef::Log.debug("Initialized driver for vcair")
|
22
22
|
end
|
23
23
|
|
24
24
|
def compute
|
@@ -37,44 +37,43 @@ class Chef
|
|
37
37
|
|
38
38
|
# Overrides the parent method and adds some additional vCloud specific metadata
|
39
39
|
def create_servers(action_handler, specs_and_options, parallelizer, &block)
|
40
|
-
|
41
40
|
specs_and_options.each do |machine_spec, machine_options|
|
42
41
|
machine_spec.reference ||= {}
|
43
42
|
# Add some vCloud info to the machine_spec
|
44
43
|
bootstrap_options = bootstrap_options_for(machine_spec, machine_options)
|
45
|
-
machine_spec.reference[
|
46
|
-
machine_spec.reference[
|
44
|
+
machine_spec.reference["vdc"] = vdc(bootstrap_options).name
|
45
|
+
machine_spec.reference["net"] = net(bootstrap_options).name
|
47
46
|
|
48
47
|
# Save the key and whether we're using sudo
|
49
|
-
machine_spec.reference[
|
50
|
-
machine_spec.reference[
|
48
|
+
machine_spec.reference["key_name"] = bootstrap_options[:key_name] if bootstrap_options.key?(:key_name)
|
49
|
+
machine_spec.reference["sudo"] = bootstrap_options[:sudo] if bootstrap_options.key?(:sudo)
|
51
50
|
end
|
52
51
|
|
53
52
|
super
|
54
53
|
end
|
55
54
|
|
56
55
|
def create_many_servers(num_servers, bootstrap_options, parallelizer)
|
57
|
-
parallelizer.parallelize(1.upto(num_servers)) do |
|
56
|
+
parallelizer.parallelize(1.upto(num_servers)) do |_i|
|
58
57
|
clean_bootstrap_options = Marshal.load(Marshal.dump(bootstrap_options)) # Prevent destructive operations on bootstrap_options.
|
59
|
-
vm=nil
|
58
|
+
vm = nil
|
60
59
|
begin
|
61
60
|
begin
|
62
|
-
Chef::Log.debug(
|
61
|
+
Chef::Log.debug("Creating vApp...")
|
63
62
|
instantiate(clean_bootstrap_options)
|
64
|
-
Chef::Log.debug(
|
63
|
+
Chef::Log.debug("Created vApp")
|
65
64
|
rescue Fog::Errors::Error => e
|
66
65
|
unless e.minor_error_code == "DUPLICATE_NAME"
|
67
66
|
# if it's already there, just use the current one
|
68
67
|
raise e
|
69
68
|
end
|
70
|
-
Chef::Log.warn(
|
69
|
+
Chef::Log.warn("Found existing vApp with the same name!")
|
71
70
|
end
|
72
71
|
vdc = vdc(clean_bootstrap_options)
|
73
72
|
|
74
73
|
Chef::Log.debug("Searching for #{bootstrap_options[:name]}...")
|
75
74
|
vapp = vdc.vapps.get_by_name(clean_bootstrap_options[:name])
|
76
75
|
raise "Couldn't find vApp #{bootstrap_options[:name]} that was just created!" if vapp.nil?
|
77
|
-
vm = vapp.vms.find {|v| v.vapp_name == clean_bootstrap_options[:name]}
|
76
|
+
vm = vapp.vms.find { |v| v.vapp_name == clean_bootstrap_options[:name] }
|
78
77
|
raise "No VMs found in vApp!" if vm.nil?
|
79
78
|
Chef::Log.debug("Found #{vm.name}")
|
80
79
|
update_customization(clean_bootstrap_options, vm)
|
@@ -89,10 +88,9 @@ class Chef
|
|
89
88
|
Chef::Log.debug("Updating network for #{vm.name}...")
|
90
89
|
update_network(clean_bootstrap_options, vapp, vm)
|
91
90
|
Chef::Log.debug("Updated network for #{vm.name}")
|
92
|
-
|
93
91
|
rescue Excon::Errors::BadRequest => e
|
94
92
|
response = Chef::JSONCompat.from_json(e.response.body)
|
95
|
-
if response[
|
93
|
+
if response["badRequest"]["code"] == 400
|
96
94
|
message = "Bad request (400): #{response['badRequest']['message']}"
|
97
95
|
Chef::Log.error(message)
|
98
96
|
else
|
@@ -106,47 +104,41 @@ class Chef
|
|
106
104
|
|
107
105
|
yield vm if block_given?
|
108
106
|
vm
|
109
|
-
|
110
107
|
end.to_a
|
111
108
|
end
|
112
109
|
|
113
|
-
|
114
110
|
def start_server(action_handler, machine_spec, server)
|
115
|
-
|
116
111
|
# If it is stopping, wait for it to get out of "stopping" transition state before starting
|
117
|
-
if server.status ==
|
112
|
+
if server.status == "stopping"
|
118
113
|
action_handler.report_progress "wait for #{machine_spec.name} (#{server.id} on #{driver_url}) to finish stopping ..."
|
119
114
|
# vCloud Air
|
120
115
|
# NOTE: vCloud Air Fog does not get server.status via http every time
|
121
|
-
server.wait_for { server.reload
|
116
|
+
server.wait_for { server.reload; server.status != "stopping" }
|
122
117
|
action_handler.report_progress "#{machine_spec.name} is now stopped"
|
123
118
|
end
|
124
119
|
|
125
120
|
# NOTE: vCloud Air Fog does not get server.status via http every time
|
126
121
|
server.reload
|
127
122
|
|
128
|
-
if server.status ==
|
123
|
+
if server.status == "off" || server.status != "on"
|
129
124
|
action_handler.perform_action "start machine #{machine_spec.name} (#{server.id} on #{driver_url})" do
|
130
125
|
server.power_on
|
131
|
-
machine_spec.reference[
|
126
|
+
machine_spec.reference["started_at"] = Time.now.to_i
|
132
127
|
end
|
133
128
|
machine_spec.save(action_handler)
|
134
129
|
end
|
135
130
|
end
|
136
131
|
|
137
|
-
|
138
132
|
def server_for(machine_spec)
|
139
133
|
if machine_spec.reference
|
140
134
|
Chef::Log.debug("Checking for VDC #{machine_spec.reference['vdc']}...")
|
141
|
-
vapp = org.vdcs.get_by_name(machine_spec.reference[
|
135
|
+
vapp = org.vdcs.get_by_name(machine_spec.reference["vdc"]).vapps.get_by_name(machine_spec.name)
|
142
136
|
|
143
137
|
server = unless vapp.nil?
|
144
138
|
unless vapp.vms.first.nil?
|
145
|
-
vapp.vms.find{|vm| vm.id == machine_spec.reference[
|
139
|
+
vapp.vms.find { |vm| vm.id == machine_spec.reference["server_id"] }
|
146
140
|
end
|
147
141
|
end
|
148
|
-
else
|
149
|
-
nil
|
150
142
|
end
|
151
143
|
end
|
152
144
|
|
@@ -168,24 +160,24 @@ class Chef
|
|
168
160
|
|
169
161
|
def create_ssh_transport(machine_spec, machine_options, server)
|
170
162
|
ssh_options = ssh_options_for(machine_spec, machine_options, server)
|
171
|
-
username = machine_spec.reference[
|
163
|
+
username = machine_spec.reference["ssh_username"] || default_ssh_username
|
172
164
|
options = {}
|
173
|
-
if machine_spec.reference[:sudo] || (!machine_spec.reference.
|
174
|
-
options[:prefix] =
|
165
|
+
if machine_spec.reference[:sudo] || (!machine_spec.reference.key?(:sudo) && username != "root")
|
166
|
+
options[:prefix] = "sudo "
|
175
167
|
end
|
176
168
|
|
177
169
|
remote_host = nil
|
178
170
|
# vCloud Air networking is funky
|
179
|
-
#if machine_options[:use_private_ip_for_ssh] # vCloud Air probably needs private ip for now
|
171
|
+
# if machine_options[:use_private_ip_for_ssh] # vCloud Air probably needs private ip for now
|
180
172
|
if server.ip_address
|
181
173
|
remote_host = server.ip_address
|
182
174
|
else
|
183
175
|
raise "Server #{server.id} has no private or public IP address!"
|
184
176
|
end
|
185
177
|
|
186
|
-
#Enable pty by default
|
178
|
+
# Enable pty by default
|
187
179
|
options[:ssh_pty_enable] = true
|
188
|
-
options[:ssh_gateway] = machine_spec.reference[
|
180
|
+
options[:ssh_gateway] = machine_spec.reference["ssh_gateway"] if machine_spec.reference.key?("ssh_gateway")
|
189
181
|
|
190
182
|
Transport::SSH.new(remote_host, username, ssh_options, options, config)
|
191
183
|
end
|
@@ -204,13 +196,13 @@ class Chef
|
|
204
196
|
# vCloud Air is funky for network. VM has to be powered off or you get this error:
|
205
197
|
# Primary NIC cannot be changed when the VM is not in Powered-off state
|
206
198
|
# See code in update_network()
|
207
|
-
#DISABLED: converge_floating_ips(action_handler, machine_spec, machine_options, server)
|
199
|
+
# DISABLED: converge_floating_ips(action_handler, machine_spec, machine_options, server)
|
208
200
|
|
209
201
|
begin
|
210
202
|
wait_for_transport(action_handler, machine_spec, machine_options, server)
|
211
203
|
rescue Fog::Errors::TimeoutError
|
212
204
|
# Only ever reboot once, and only if it's been less than 10 minutes since we stopped waiting
|
213
|
-
if machine_spec.reference[
|
205
|
+
if machine_spec.reference["started_at"] || remaining_wait_time(machine_spec, machine_options) < -(10 * 60)
|
214
206
|
raise
|
215
207
|
else
|
216
208
|
# Sometimes (on EC2) the machine comes up but gets stuck or has
|
@@ -236,7 +228,7 @@ class Chef
|
|
236
228
|
raise "VDC #{bootstrap_options[:vdc]} not found" unless @vdc
|
237
229
|
else
|
238
230
|
@vdc ||= org.vdcs.first
|
239
|
-
raise
|
231
|
+
raise "No VDC found" unless @vdc
|
240
232
|
end
|
241
233
|
|
242
234
|
Chef::Log.debug("VDC set to #{@vdc.name}")
|
@@ -249,8 +241,8 @@ class Chef
|
|
249
241
|
raise "Network #{bootstrap_options[:net]} not found" unless @net
|
250
242
|
else
|
251
243
|
# Grab first non-isolated (bridged, natRouted) network
|
252
|
-
@net ||= org.networks.find { |n| n
|
253
|
-
raise
|
244
|
+
@net ||= org.networks.find { |n| n unless n.fence_mode.match("isolated") }
|
245
|
+
raise "No non-isolated network found" unless @net
|
254
246
|
end
|
255
247
|
|
256
248
|
Chef::Log.debug("Network set to #{@net.name}")
|
@@ -261,9 +253,9 @@ class Chef
|
|
261
253
|
# If we specify a catalog name, search for the image in it,
|
262
254
|
# otherwise return the first image we find in any catalog.
|
263
255
|
if bootstrap_options[:catalog_name].nil?
|
264
|
-
#TODO: maybe make a hash for caching
|
256
|
+
# TODO: maybe make a hash for caching
|
265
257
|
org.catalogs.map do |cat|
|
266
|
-
#cat.catalog_items.get_by_name(config_value(:image))
|
258
|
+
# cat.catalog_items.get_by_name(config_value(:image))
|
267
259
|
cat.catalog_items.get_by_name(bootstrap_options[:image_name])
|
268
260
|
end.compact.first
|
269
261
|
else
|
@@ -274,7 +266,7 @@ class Chef
|
|
274
266
|
end
|
275
267
|
|
276
268
|
def instantiate(bootstrap_options)
|
277
|
-
#node_name = config_value(:chef_node_name)
|
269
|
+
# node_name = config_value(:chef_node_name)
|
278
270
|
node_name = bootstrap_options[:name]
|
279
271
|
vdc = vdc(bootstrap_options)
|
280
272
|
net = net(bootstrap_options)
|
@@ -283,8 +275,9 @@ class Chef
|
|
283
275
|
node_name,
|
284
276
|
vdc_id: vdc.id,
|
285
277
|
network_id: net.id,
|
286
|
-
description: "id:#{node_name}"
|
287
|
-
|
278
|
+
description: "id:#{node_name}"
|
279
|
+
)
|
280
|
+
# rescue CloudExceptions::ServerCreateError => e
|
288
281
|
end
|
289
282
|
|
290
283
|
# Create a WinRM transport for a vCloud Air Vapp VM instance
|
@@ -293,7 +286,7 @@ class Chef
|
|
293
286
|
# @param [Fog::Compute::Server] server A Fog mapping to the AWS instance
|
294
287
|
# @return [ChefMetal::Transport::WinRM] A WinRM Transport object to talk to the server
|
295
288
|
def create_winrm_transport(machine_spec, machine_options, server)
|
296
|
-
port = machine_spec.reference[
|
289
|
+
port = machine_spec.reference["winrm_port"] || 5985
|
297
290
|
endpoint = "http://#{server.ip_address}:#{port}/wsman"
|
298
291
|
type = :plaintext
|
299
292
|
|
@@ -301,10 +294,10 @@ class Chef
|
|
301
294
|
# are using
|
302
295
|
# TODO: Improve that and support different users
|
303
296
|
options = {
|
304
|
-
:
|
305
|
-
:
|
306
|
-
:
|
307
|
-
:
|
297
|
+
user: "Administrator",
|
298
|
+
pass: machine_options[:winrm_options][:password],
|
299
|
+
disable_sspi: true,
|
300
|
+
basic_auth_only: true
|
308
301
|
}
|
309
302
|
Chef::Provisioning::Transport::WinRM.new(endpoint, type, options, {})
|
310
303
|
end
|
@@ -312,32 +305,32 @@ class Chef
|
|
312
305
|
def update_customization(bootstrap_options, server)
|
313
306
|
Chef::Log.debug("Customizing vApp: #{server.name}")
|
314
307
|
## Initialization before first power on.
|
315
|
-
custom=server.customization
|
308
|
+
custom = server.customization
|
316
309
|
|
317
310
|
if bootstrap_options[:customization_script]
|
318
311
|
custom.script = open(bootstrap_options[:customization_script]).read
|
319
312
|
end
|
320
313
|
|
321
314
|
bootstrap_options[:protocol] ||= case server.operating_system
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
315
|
+
when /Windows/
|
316
|
+
"winrm"
|
317
|
+
else
|
318
|
+
"ssh"
|
326
319
|
end
|
327
320
|
password = case bootstrap_options[:protocol]
|
328
|
-
when
|
321
|
+
when "ssh"
|
329
322
|
bootstrap_options[:ssh_options][:password] unless bootstrap_options[:ssh_options].nil?
|
330
|
-
when
|
323
|
+
when "winrm"
|
331
324
|
bootstrap_options[:winrm_options][:password] unless bootstrap_options[:winrm_options].nil?
|
332
325
|
end
|
333
326
|
|
334
327
|
if password
|
335
|
-
custom.admin_password =
|
328
|
+
custom.admin_password = password
|
336
329
|
custom.admin_password_auto = false
|
337
330
|
custom.reset_password_required = false
|
338
331
|
else
|
339
332
|
# Password will be autogenerated
|
340
|
-
custom.admin_password_auto=true
|
333
|
+
custom.admin_password_auto = true
|
341
334
|
# API will force password resets when auto is enabled
|
342
335
|
custom.reset_password_required = true
|
343
336
|
end
|
@@ -350,7 +343,7 @@ class Chef
|
|
350
343
|
# Windows can only handle 15 character hostnames
|
351
344
|
custom.computer_name = case server.operating_system
|
352
345
|
when /Windows/
|
353
|
-
bootstrap_options[:name].gsub(/\W/,"-").slice(0..14)
|
346
|
+
bootstrap_options[:name].gsub(/\W/, "-").slice(0..14)
|
354
347
|
else
|
355
348
|
bootstrap_options[:name]
|
356
349
|
end
|
@@ -368,16 +361,16 @@ class Chef
|
|
368
361
|
# Define network connection for vm based on existing routed network
|
369
362
|
|
370
363
|
# vCloud Air inlining vapp() and vm()
|
371
|
-
#vapp = vdc.vapps.get_by_name(bootstrap_options[:name])
|
372
|
-
#vm = vapp.vms.find {|v| v.vapp_name == bootstrap_options[:name]}
|
364
|
+
# vapp = vdc.vapps.get_by_name(bootstrap_options[:name])
|
365
|
+
# vm = vapp.vms.find {|v| v.vapp_name == bootstrap_options[:name]}
|
373
366
|
return if vm.ip_address != "" # return if ip address is set, as this isn't a new VM
|
374
|
-
Chef::Log.debug(
|
367
|
+
Chef::Log.debug("No IP address found. Must be a new VM.")
|
375
368
|
net = net(bootstrap_options)
|
376
369
|
Chef::Log.debug("Searching for network: #{net.name}")
|
377
370
|
nc = vapp.network_config.find { |netc| netc if netc[:networkName].match(net.name) }
|
378
371
|
Chef::Log.debug("Found network configuration: #{nc}")
|
379
372
|
networks_config = [nc]
|
380
|
-
section = {PrimaryNetworkConnectionIndex: 0}
|
373
|
+
section = { PrimaryNetworkConnectionIndex: 0 }
|
381
374
|
section[:NetworkConnection] = networks_config.compact.each_with_index.map do |network, i|
|
382
375
|
connection = {
|
383
376
|
network: network[:networkName],
|
@@ -387,12 +380,12 @@ class Chef
|
|
387
380
|
}
|
388
381
|
ip_address = network[:ip_address]
|
389
382
|
## TODO: support config options for allocation mode
|
390
|
-
#allocation_mode = network[:allocation_mode]
|
391
|
-
#allocation_mode = 'manual' if ip_address
|
392
|
-
#allocation_mode = 'dhcp' unless %w{dhcp manual pool}.include?(allocation_mode)
|
393
|
-
#allocation_mode = 'POOL'
|
394
|
-
#connection[:Dns1] = dns1 if dns1
|
395
|
-
allocation_mode =
|
383
|
+
# allocation_mode = network[:allocation_mode]
|
384
|
+
# allocation_mode = 'manual' if ip_address
|
385
|
+
# allocation_mode = 'dhcp' unless %w{dhcp manual pool}.include?(allocation_mode)
|
386
|
+
# allocation_mode = 'POOL'
|
387
|
+
# connection[:Dns1] = dns1 if dns1
|
388
|
+
allocation_mode = "pool"
|
396
389
|
connection[:IpAddressAllocationMode] = allocation_mode.upcase
|
397
390
|
connection[:IpAddress] = ip_address if ip_address
|
398
391
|
connection
|
@@ -400,7 +393,8 @@ class Chef
|
|
400
393
|
|
401
394
|
## attach the network to the vm
|
402
395
|
nc_task = compute.put_network_connection_system_section_vapp(
|
403
|
-
vm.id,section
|
396
|
+
vm.id, section
|
397
|
+
).body
|
404
398
|
compute.process_task(nc_task)
|
405
399
|
end
|
406
400
|
|
@@ -416,9 +410,9 @@ class Chef
|
|
416
410
|
Chef::Log.info("Destroying machine #{machine_spec.name}...")
|
417
411
|
bootstrap_options = bootstrap_options_for(machine_spec, machine_options)
|
418
412
|
vdc = vdc(bootstrap_options)
|
419
|
-
if server && server.status !=
|
413
|
+
if server && server.status != "archive" # TODO: does vCloud Air do archive?
|
420
414
|
action_handler.perform_action "destroy machine #{machine_spec.name} (#{machine_spec.reference['server_id']} at #{driver_url})" do
|
421
|
-
#NOTE: currently doing 1 vm for 1 vapp
|
415
|
+
# NOTE: currently doing 1 vm for 1 vapp
|
422
416
|
vapp = vdc.vapps.get_by_name(machine_spec.name)
|
423
417
|
if vapp
|
424
418
|
Chef::Log.debug("Found vApp #{machine_spec.name}")
|
@@ -435,13 +429,13 @@ class Chef
|
|
435
429
|
strategy.cleanup_convergence(action_handler, machine_spec)
|
436
430
|
end
|
437
431
|
|
438
|
-
def self.compute_options_for(
|
432
|
+
def self.compute_options_for(_provider, id, config)
|
439
433
|
new_compute_options = {}
|
440
|
-
new_compute_options[:provider] =
|
441
|
-
new_config = { :
|
434
|
+
new_compute_options[:provider] = "vclouddirector"
|
435
|
+
new_config = { driver_options: { compute_options: new_compute_options } }
|
442
436
|
new_defaults = {
|
443
|
-
:
|
444
|
-
:
|
437
|
+
driver_options: { compute_options: {} },
|
438
|
+
machine_options: { bootstrap_options: {}, ssh_options: {} }
|
445
439
|
}
|
446
440
|
result = Cheffish::MergedConfig.new(new_config, config, new_defaults)
|
447
441
|
|