chef-provisioning-fog 0.26.1 → 0.26.3
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.
- 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
|
|