knife-openstack 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +7 -3
- data/README.md +4 -0
- data/lib/chef/knife/openstack_base.rb +15 -8
- data/lib/chef/knife/openstack_server_create.rb +216 -183
- data/lib/chef/knife/openstack_server_delete.rb +4 -3
- data/lib/chef/knife/openstack_server_list.rb +5 -1
- data/lib/knife-openstack/version.rb +1 -1
- data/spec/unit/openstack_server_create_spec.rb +15 -5
- metadata +21 -37
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 95a3012f4a18397d8840ffad36f4aa5545b15d17
|
|
4
|
+
data.tar.gz: a3a46d384665f841b14f8a25c3db3a6e9ff844ef
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d10c999e511ea659c126a0d03584e9c3bea328620013e885de993426ccd8734503835e0a35dc138c460734451bd81b49a7f48d11d12189c05eec03fc6dfc46ef
|
|
7
|
+
data.tar.gz: c6abb54a3f2a3119e727c981828f59bcfe41522c7b264d82c7476a4687619f91fc776efeaa613f331c325b079ccb0092367d6c39e1a84bfeb20d658796cf268c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
## v0.
|
|
1
|
+
## v0.9.0
|
|
2
|
+
* KNIFE-231 added ability to specify arbitrary bootstrap network ID
|
|
3
|
+
* KNIFE-277 knife openstack "ERROR: No IP address available for bootstrapping."
|
|
4
|
+
* KNIFE-310 "knife openstack server list" will fail with boot from volume instances
|
|
5
|
+
* KNIFE-435 Support user data for OpenStack server create
|
|
6
|
+
* https://github.com/opscode/chef-rfc/pull/7/
|
|
2
7
|
|
|
8
|
+
## v0.8.1
|
|
3
9
|
* KNIFE-296 knife-windows overrides -i, -p, -P and -x options with winrm values
|
|
4
10
|
* KNIFE-304 enable setting the ssh port for knife-openstack
|
|
5
11
|
|
|
6
12
|
## v0.8.0
|
|
7
|
-
|
|
8
13
|
* KNIFE-221 Windows bootstrapping (winrm-based) support for knife-openstack (Chirag Jog)
|
|
9
14
|
|
|
10
15
|
## v0.7.1
|
|
11
|
-
|
|
12
16
|
* KNIFE-261 file permissions fixed
|
|
13
17
|
|
|
14
18
|
## v0.7.0
|
data/README.md
CHANGED
|
@@ -38,6 +38,10 @@ If your OpenStack deployment is over SSL, but does not have a valid certificate,
|
|
|
38
38
|
|
|
39
39
|
knife[:openstack_insecure] = true
|
|
40
40
|
|
|
41
|
+
If you need to use alternate service endpoints for communicating with OpenStack, you can set the following option:
|
|
42
|
+
|
|
43
|
+
knife[:openstack_endpoint_type] = "internalURL"
|
|
44
|
+
|
|
41
45
|
You also have the option of passing your OpenStack API Username/Password into the individual knife subcommands using the `-A` (or `--openstack-username`) `-K` (or `--openstack-password`) command options
|
|
42
46
|
|
|
43
47
|
# provision a new image named kb01
|
|
@@ -59,18 +59,25 @@ class Chef
|
|
|
59
59
|
:description => "Your OpenStack API endpoint",
|
|
60
60
|
:proc => Proc.new { |endpoint| Chef::Config[:knife][:openstack_auth_url] = endpoint }
|
|
61
61
|
|
|
62
|
+
option :openstack_endpoint_type,
|
|
63
|
+
:long => "--openstack-endpoint-type ENDPOINT_TYPE",
|
|
64
|
+
:description => "OpenStack endpoint type to use (publicURL, internalURL, adminURL)",
|
|
65
|
+
:proc => Proc.new { |type| Chef::Config[:knife][:openstack_endpoint_type] = type }
|
|
66
|
+
|
|
62
67
|
option :openstack_insecure,
|
|
63
68
|
:long => "--insecure",
|
|
64
69
|
:description => "Ignore SSL certificate on the Auth URL",
|
|
65
70
|
:boolean => true,
|
|
66
71
|
:default => false,
|
|
67
72
|
:proc => Proc.new { |key| Chef::Config[:knife][:openstack_insecure] = key }
|
|
73
|
+
|
|
68
74
|
end
|
|
69
75
|
end
|
|
70
76
|
|
|
71
77
|
def connection
|
|
72
78
|
Chef::Log.debug("openstack_username #{Chef::Config[:knife][:openstack_username]}")
|
|
73
79
|
Chef::Log.debug("openstack_auth_url #{Chef::Config[:knife][:openstack_auth_url]}")
|
|
80
|
+
Chef::Log.debug("openstack_endpoint_type #{Chef::Config[:knife][:openstack_endpoint_type] || 'publicURL' }")
|
|
74
81
|
Chef::Log.debug("openstack_tenant #{Chef::Config[:knife][:openstack_tenant]}")
|
|
75
82
|
Chef::Log.debug("openstack_insecure #{Chef::Config[:knife][:openstack_insecure].to_s}")
|
|
76
83
|
|
|
@@ -80,6 +87,7 @@ class Chef
|
|
|
80
87
|
:openstack_username => Chef::Config[:knife][:openstack_username],
|
|
81
88
|
:openstack_api_key => Chef::Config[:knife][:openstack_password],
|
|
82
89
|
:openstack_auth_url => Chef::Config[:knife][:openstack_auth_url],
|
|
90
|
+
:openstack_endpoint_type => Chef::Config[:knife][:openstack_endpoint_type],
|
|
83
91
|
:openstack_tenant => Chef::Config[:knife][:openstack_tenant],
|
|
84
92
|
:connection_options => {
|
|
85
93
|
:ssl_verify_peer => !Chef::Config[:knife][:openstack_insecure]
|
|
@@ -120,22 +128,21 @@ class Chef
|
|
|
120
128
|
end
|
|
121
129
|
end
|
|
122
130
|
|
|
123
|
-
# http://tickets.opscode.com/browse/KNIFE-248
|
|
124
131
|
def primary_private_ip_address(addresses)
|
|
125
|
-
|
|
126
|
-
return addresses['private'].last['addr']
|
|
127
|
-
end
|
|
132
|
+
primary_network_ip_address(addresses, 'private')
|
|
128
133
|
end
|
|
129
134
|
|
|
130
135
|
#we use last since the floating IP goes there
|
|
131
136
|
def primary_public_ip_address(addresses)
|
|
132
|
-
|
|
133
|
-
|
|
137
|
+
primary_network_ip_address(addresses, 'public')
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def primary_network_ip_address(addresses, network_name)
|
|
141
|
+
if addresses[network_name]
|
|
142
|
+
return addresses[network_name].last['addr']
|
|
134
143
|
end
|
|
135
144
|
end
|
|
136
145
|
|
|
137
146
|
end
|
|
138
147
|
end
|
|
139
148
|
end
|
|
140
|
-
|
|
141
|
-
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#
|
|
2
|
-
# Author:: Seth Chisamore (<schisamo@
|
|
3
|
-
# Author:: Matt Ray (<matt@
|
|
2
|
+
# Author:: Seth Chisamore (<schisamo@getchef.com>)
|
|
3
|
+
# Author:: Matt Ray (<matt@getchef.com>)
|
|
4
4
|
# Author:: Chirag Jog (<chirag@clogeny.com>)
|
|
5
|
-
# Copyright:: Copyright (c) 2011-
|
|
5
|
+
# Copyright:: Copyright (c) 2011-2014 Chef Software, Inc.
|
|
6
6
|
# License:: Apache License, Version 2.0
|
|
7
7
|
#
|
|
8
8
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -24,7 +24,6 @@ require 'chef/knife/winrm_base'
|
|
|
24
24
|
class Chef
|
|
25
25
|
class Knife
|
|
26
26
|
class OpenstackServerCreate < Knife
|
|
27
|
-
|
|
28
27
|
include Knife::OpenstackBase
|
|
29
28
|
include Chef::Knife::WinrmBase
|
|
30
29
|
|
|
@@ -70,6 +69,17 @@ class Chef
|
|
|
70
69
|
:default => "-1",
|
|
71
70
|
:description => "Request to associate a floating IP address to the new OpenStack node. Assumes IPs have been allocated to the project. Specific IP is optional."
|
|
72
71
|
|
|
72
|
+
option :bootstrap_network,
|
|
73
|
+
:long => '--bootstrap-network NAME',
|
|
74
|
+
:default => 'public',
|
|
75
|
+
:description => "Specify network for bootstrapping. Default is 'public'."
|
|
76
|
+
|
|
77
|
+
option :network,
|
|
78
|
+
:long => "--no-network",
|
|
79
|
+
:boolean => true,
|
|
80
|
+
:default => true,
|
|
81
|
+
:description => "Use first available network for bootstrapping if 'public' and 'private' are unavailable."
|
|
82
|
+
|
|
73
83
|
option :private_network,
|
|
74
84
|
:long => "--private-network",
|
|
75
85
|
:description => "Use the private IP for bootstrapping rather than the public IP",
|
|
@@ -154,7 +164,19 @@ class Chef
|
|
|
154
164
|
:long => "--server-create-timeout timeout",
|
|
155
165
|
:description => "How long to wait until the server is ready; default is 600 seconds",
|
|
156
166
|
:default => 600,
|
|
157
|
-
:proc => Proc.new { |v| Chef::Config[:knife][:server_create_timeouts] = v}
|
|
167
|
+
:proc => Proc.new { |v| Chef::Config[:knife][:server_create_timeouts] = v }
|
|
168
|
+
|
|
169
|
+
option :first_boot_attributes,
|
|
170
|
+
:short => "-j JSON_ATTRIBS",
|
|
171
|
+
:long => "--json-attributes JSON_ATTRIBS",
|
|
172
|
+
:description => "A JSON string to be added to the first run of chef-client",
|
|
173
|
+
:proc => lambda { |o| JSON.parse(o) },
|
|
174
|
+
:default => {}
|
|
175
|
+
|
|
176
|
+
option :user_data,
|
|
177
|
+
:long => "--user-data USER_DATA",
|
|
178
|
+
:description => "The file path containing user data information for this server",
|
|
179
|
+
:proc => Proc.new { |user_data| open(user_data) { |f| f.read } }
|
|
158
180
|
|
|
159
181
|
def tcp_test_ssh(hostname, port)
|
|
160
182
|
tcp_socket = TCPSocket.new(hostname, port)
|
|
@@ -240,217 +262,228 @@ class Chef
|
|
|
240
262
|
config[:identity_file] = locate_config_value(:kerberos_keytab_file)
|
|
241
263
|
end
|
|
242
264
|
end
|
|
243
|
-
#servers require a name, generate one if not passed
|
|
265
|
+
# servers require a name, generate one if not passed
|
|
244
266
|
node_name = get_node_name(config[:chef_node_name])
|
|
245
267
|
|
|
246
268
|
server_def = {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
+
:name => node_name,
|
|
270
|
+
:image_ref => locate_config_value(:image),
|
|
271
|
+
:flavor_ref => locate_config_value(:flavor),
|
|
272
|
+
:security_groups => locate_config_value(:security_groups),
|
|
273
|
+
:key_name => locate_config_value(:openstack_ssh_key_id),
|
|
274
|
+
:user_data => locate_config_value(:user_data)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
Chef::Log.debug("Name #{node_name}")
|
|
278
|
+
Chef::Log.debug("Image #{locate_config_value(:image)}")
|
|
279
|
+
Chef::Log.debug("Flavor #{locate_config_value(:flavor)}")
|
|
280
|
+
Chef::Log.debug("Requested Floating IP #{locate_config_value(:floating_ip)}")
|
|
281
|
+
Chef::Log.debug("Security Groups #{locate_config_value(:security_groups)}")
|
|
282
|
+
Chef::Log.debug("User Data #{locate_config_value(:user_data)}")
|
|
283
|
+
Chef::Log.debug("Creating server #{server_def}")
|
|
284
|
+
|
|
285
|
+
begin
|
|
286
|
+
server = connection.servers.create(server_def)
|
|
287
|
+
rescue Excon::Errors::BadRequest => e
|
|
288
|
+
response = Chef::JSONCompat.from_json(e.response.body)
|
|
289
|
+
if response['badRequest']['code'] == 400
|
|
290
|
+
if response['badRequest']['message'] =~ /Invalid flavorRef/
|
|
291
|
+
ui.fatal("Bad request (400): Invalid flavor specified: #{server_def[:flavor_ref]}")
|
|
292
|
+
exit 1
|
|
293
|
+
else
|
|
294
|
+
ui.fatal("Bad request (400): #{response['badRequest']['message']}")
|
|
295
|
+
exit 1
|
|
296
|
+
end
|
|
269
297
|
else
|
|
270
|
-
ui.fatal("
|
|
271
|
-
|
|
298
|
+
ui.fatal("Unknown server error (#{response['badRequest']['code']}): #{response['badRequest']['message']}")
|
|
299
|
+
raise e
|
|
272
300
|
end
|
|
273
|
-
else
|
|
274
|
-
ui.fatal("Unknown server error (#{response['badRequest']['code']}): #{response['badRequest']['message']}")
|
|
275
|
-
raise e
|
|
276
301
|
end
|
|
277
|
-
end
|
|
278
302
|
|
|
279
|
-
|
|
280
|
-
|
|
303
|
+
msg_pair("Instance Name", server.name)
|
|
304
|
+
msg_pair("Instance ID", server.id)
|
|
305
|
+
|
|
306
|
+
print "\n#{ui.color("Waiting for server", :magenta)}"
|
|
307
|
+
|
|
308
|
+
# wait for it to be ready to do stuff
|
|
309
|
+
server.wait_for(Integer(locate_config_value(:server_create_timeout))) { print "."; ready? }
|
|
310
|
+
|
|
311
|
+
puts("\n")
|
|
312
|
+
|
|
313
|
+
msg_pair("Flavor", server.flavor['id'])
|
|
314
|
+
msg_pair("Image", server.image['id'])
|
|
315
|
+
msg_pair("SSH Identity File", config[:identity_file])
|
|
316
|
+
msg_pair("SSH Keypair", server.key_name) if server.key_name
|
|
317
|
+
msg_pair("SSH Password", server.password) if (server.password && !server.key_name)
|
|
318
|
+
Chef::Log.debug("Addresses #{server.addresses}")
|
|
319
|
+
|
|
320
|
+
msg_pair("Public IP Address", primary_public_ip_address(server.addresses)) if primary_public_ip_address(server.addresses)
|
|
321
|
+
msg_pair("Private IP Address", primary_private_ip_address(server.addresses)) if primary_private_ip_address(server.addresses)
|
|
322
|
+
|
|
323
|
+
floating_address = locate_config_value(:floating_ip)
|
|
324
|
+
Chef::Log.debug("Floating IP Address requested #{floating_address}")
|
|
325
|
+
unless (floating_address == '-1') # no floating IP requested
|
|
326
|
+
addresses = connection.addresses
|
|
327
|
+
# floating requested without value
|
|
328
|
+
if floating_address.nil?
|
|
329
|
+
free_floating = addresses.find_index { |a| a.fixed_ip.nil? }
|
|
330
|
+
if free_floating.nil? # no free floating IP found
|
|
331
|
+
ui.error("Unable to assign a Floating IP from allocated IPs.")
|
|
332
|
+
exit 1
|
|
333
|
+
else
|
|
334
|
+
floating_address = addresses[free_floating].ip
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
server.associate_address(floating_address)
|
|
338
|
+
# bit of a hack, but server.reload takes a long time
|
|
339
|
+
(server.addresses['public'] ||= []) << { "version" => 4, "addr" => floating_address }
|
|
340
|
+
msg_pair("Floating IP Address", floating_address)
|
|
341
|
+
end
|
|
281
342
|
|
|
282
|
-
|
|
343
|
+
Chef::Log.debug("Addresses #{server.addresses}")
|
|
344
|
+
Chef::Log.debug("Public IP Address actual: #{primary_public_ip_address(server.addresses)}") if primary_public_ip_address(server.addresses)
|
|
283
345
|
|
|
284
|
-
|
|
285
|
-
|
|
346
|
+
# private_network means bootstrap_network = 'private'
|
|
347
|
+
config[:bootstrap_network] = 'private' if config[:private_network]
|
|
286
348
|
|
|
287
|
-
|
|
349
|
+
unless config[:network] # --no-network
|
|
350
|
+
bootstrap_ip_address = primary_public_ip_address(server.addresses) ||
|
|
351
|
+
primary_private_ip_address(server.addresses) ||
|
|
352
|
+
server.addresses.first
|
|
353
|
+
Chef::Log.debug("No Bootstrap Network: #{config[:bootstrap_network]}")
|
|
354
|
+
else
|
|
355
|
+
bootstrap_ip_address = primary_network_ip_address(server.addresses, config[:bootstrap_network])
|
|
356
|
+
Chef::Log.debug("Bootstrap Network: #{config[:bootstrap_network]}")
|
|
357
|
+
end
|
|
288
358
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
Chef::Log.debug("Addresses #{server.addresses}")
|
|
295
|
-
msg_pair("Public IP Address", primary_public_ip_address(server.addresses)) if primary_public_ip_address(server.addresses)
|
|
359
|
+
Chef::Log.debug("Bootstrap IP Address: #{bootstrap_ip_address}")
|
|
360
|
+
if bootstrap_ip_address.nil?
|
|
361
|
+
ui.error("No IP address available for bootstrapping.")
|
|
362
|
+
exit 1
|
|
363
|
+
end
|
|
296
364
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
365
|
+
if locate_config_value(:bootstrap_protocol) == 'winrm'
|
|
366
|
+
print "\n#{ui.color("Waiting for winrm", :magenta)}"
|
|
367
|
+
print(".") until tcp_test_winrm(bootstrap_ip_address, locate_config_value(:winrm_port))
|
|
368
|
+
bootstrap_for_windows_node(server, bootstrap_ip_address).run
|
|
369
|
+
else
|
|
370
|
+
Chef::Log.debug("Waiting for sshd on IP address: #{bootstrap_ip_address} and port: #{locate_config_value(:ssh_port)}")
|
|
371
|
+
print "\n#{ui.color("Waiting for sshd", :magenta)}"
|
|
372
|
+
print(".") until tcp_test_ssh(bootstrap_ip_address, locate_config_value(:ssh_port)) {
|
|
373
|
+
sleep @initial_sleep_delay ||= 10
|
|
374
|
+
puts("done")
|
|
375
|
+
}
|
|
376
|
+
bootstrap_for_node(server, bootstrap_ip_address).run
|
|
377
|
+
end
|
|
378
|
+
puts "\n"
|
|
379
|
+
msg_pair("Instance Name", server.name)
|
|
380
|
+
msg_pair("Instance ID", server.id)
|
|
381
|
+
msg_pair("Flavor", server.flavor['id'])
|
|
382
|
+
msg_pair("Image", server.image['id'])
|
|
383
|
+
msg_pair("SSH Keypair", server.key_name) if server.key_name
|
|
384
|
+
msg_pair("SSH Password", server.password) if (server.password && !server.key_name)
|
|
385
|
+
server.addresses.each do |name,addr|
|
|
386
|
+
msg_pair("Network", name)
|
|
387
|
+
msg_pair(" IP Address", addr[0]['addr'])
|
|
310
388
|
end
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
(server.addresses['public'] ||= []) << {"version"=>4,"addr"=>floating_address}
|
|
314
|
-
msg_pair("Floating IP Address", floating_address)
|
|
389
|
+
msg_pair("Environment", config[:environment] || '_default')
|
|
390
|
+
msg_pair("Run List", config[:run_list].join(', '))
|
|
315
391
|
end
|
|
316
392
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
bootstrap_ip_address = primary_private_ip_address(server.addresses)
|
|
393
|
+
def bootstrap_for_windows_node(server, bootstrap_ip_address)
|
|
394
|
+
bootstrap = Chef::Knife::BootstrapWindowsWinrm.new
|
|
395
|
+
bootstrap.name_args = [bootstrap_ip_address]
|
|
396
|
+
bootstrap.config[:winrm_user] = locate_config_value(:winrm_user) || 'Administrator'
|
|
397
|
+
bootstrap.config[:winrm_password] = locate_config_value(:winrm_password)
|
|
398
|
+
bootstrap.config[:winrm_transport] = locate_config_value(:winrm_transport)
|
|
399
|
+
bootstrap.config[:winrm_port] = locate_config_value(:winrm_port)
|
|
400
|
+
bootstrap_common_params(bootstrap, server.name)
|
|
326
401
|
end
|
|
327
402
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
403
|
+
def bootstrap_common_params(bootstrap, server_name)
|
|
404
|
+
bootstrap.config[:chef_node_name] = config[:chef_node_name] || server_name
|
|
405
|
+
bootstrap.config[:run_list] = config[:run_list]
|
|
406
|
+
bootstrap.config[:prerelease] = config[:prerelease]
|
|
407
|
+
bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
|
|
408
|
+
bootstrap.config[:distro] = locate_config_value(:distro)
|
|
409
|
+
bootstrap.config[:template_file] = locate_config_value(:template_file)
|
|
410
|
+
bootstrap.config[:bootstrap_proxy] = locate_config_value(:bootstrap_proxy)
|
|
411
|
+
bootstrap.config[:environment] = config[:environment]
|
|
412
|
+
bootstrap.config[:encrypted_data_bag_secret] = config[:encrypted_data_bag_secret]
|
|
413
|
+
bootstrap.config[:encrypted_data_bag_secret_file] = config[:encrypted_data_bag_secret_file]
|
|
414
|
+
# let ohai know we're using OpenStack
|
|
415
|
+
Chef::Config[:knife][:hints] ||= {}
|
|
416
|
+
Chef::Config[:knife][:hints]['openstack'] ||= {}
|
|
417
|
+
bootstrap
|
|
332
418
|
end
|
|
333
419
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
puts("done")
|
|
344
|
-
}
|
|
345
|
-
bootstrap_for_node(server, bootstrap_ip_address).run
|
|
420
|
+
def bootstrap_for_node(server, bootstrap_ip_address)
|
|
421
|
+
bootstrap = Chef::Knife::Bootstrap.new
|
|
422
|
+
bootstrap.name_args = [bootstrap_ip_address]
|
|
423
|
+
bootstrap.config[:ssh_user] = config[:ssh_user]
|
|
424
|
+
bootstrap.config[:ssh_port] = config[:ssh_port]
|
|
425
|
+
bootstrap.config[:identity_file] = config[:identity_file]
|
|
426
|
+
bootstrap.config[:host_key_verify] = config[:host_key_verify]
|
|
427
|
+
bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
|
|
428
|
+
bootstrap_common_params(bootstrap, server.name)
|
|
346
429
|
end
|
|
347
|
-
puts "\n"
|
|
348
|
-
msg_pair("Instance Name", server.name)
|
|
349
|
-
msg_pair("Instance ID", server.id)
|
|
350
|
-
msg_pair("Flavor", server.flavor['id'])
|
|
351
|
-
msg_pair("Image", server.image['id'])
|
|
352
|
-
msg_pair("SSH Keypair", server.key_name) if server.key_name
|
|
353
|
-
msg_pair("SSH Password", server.password) if (server.password && !server.key_name)
|
|
354
|
-
msg_pair("Public IP Address", primary_public_ip_address(server.addresses)) if primary_public_ip_address(server.addresses)
|
|
355
|
-
msg_pair("Private IP Address", primary_private_ip_address(server.addresses)) if primary_private_ip_address(server.addresses)
|
|
356
|
-
msg_pair("Environment", config[:environment] || '_default')
|
|
357
|
-
msg_pair("Run List", config[:run_list].join(', '))
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
def bootstrap_for_windows_node(server, bootstrap_ip_address)
|
|
361
|
-
bootstrap = Chef::Knife::BootstrapWindowsWinrm.new
|
|
362
|
-
bootstrap.name_args = [bootstrap_ip_address]
|
|
363
|
-
bootstrap.config[:winrm_user] = locate_config_value(:winrm_user) || 'Administrator'
|
|
364
|
-
bootstrap.config[:winrm_password] = locate_config_value(:winrm_password)
|
|
365
|
-
bootstrap.config[:winrm_transport] = locate_config_value(:winrm_transport)
|
|
366
|
-
bootstrap.config[:winrm_port] = locate_config_value(:winrm_port)
|
|
367
|
-
bootstrap_common_params(bootstrap, server.name)
|
|
368
|
-
end
|
|
369
430
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
bootstrap.config[:prerelease] = config[:prerelease]
|
|
374
|
-
bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
|
|
375
|
-
bootstrap.config[:distro] = locate_config_value(:distro)
|
|
376
|
-
bootstrap.config[:template_file] = locate_config_value(:template_file)
|
|
377
|
-
bootstrap.config[:bootstrap_proxy] = locate_config_value(:bootstrap_proxy)
|
|
378
|
-
bootstrap.config[:environment] = config[:environment]
|
|
379
|
-
bootstrap.config[:encrypted_data_bag_secret] = config[:encrypted_data_bag_secret]
|
|
380
|
-
bootstrap.config[:encrypted_data_bag_secret_file] = config[:encrypted_data_bag_secret_file]
|
|
381
|
-
# let ohai know we're using OpenStack
|
|
382
|
-
Chef::Config[:knife][:hints] ||= {}
|
|
383
|
-
Chef::Config[:knife][:hints]['openstack'] ||= {}
|
|
384
|
-
bootstrap
|
|
385
|
-
end
|
|
386
|
-
|
|
387
|
-
def bootstrap_for_node(server, bootstrap_ip_address)
|
|
388
|
-
bootstrap = Chef::Knife::Bootstrap.new
|
|
389
|
-
bootstrap.name_args = [bootstrap_ip_address]
|
|
390
|
-
bootstrap.config[:ssh_user] = config[:ssh_user]
|
|
391
|
-
bootstrap.config[:ssh_port] = config[:ssh_port]
|
|
392
|
-
bootstrap.config[:identity_file] = config[:identity_file]
|
|
393
|
-
bootstrap.config[:host_key_verify] = config[:host_key_verify]
|
|
394
|
-
bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
|
|
395
|
-
bootstrap_common_params(bootstrap, server.name)
|
|
396
|
-
end
|
|
397
|
-
|
|
398
|
-
def flavor
|
|
399
|
-
@flavor ||= connection.flavors.get(locate_config_value(:flavor))
|
|
400
|
-
end
|
|
401
|
-
|
|
402
|
-
def image
|
|
403
|
-
@image ||= connection.images.get(locate_config_value(:image))
|
|
404
|
-
end
|
|
431
|
+
def flavor
|
|
432
|
+
@flavor ||= connection.flavors.get(locate_config_value(:flavor))
|
|
433
|
+
end
|
|
405
434
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
if address == '-1' #no floating IP requested
|
|
409
|
-
return true
|
|
435
|
+
def image
|
|
436
|
+
@image ||= connection.images.get(locate_config_value(:image))
|
|
410
437
|
end
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
438
|
+
|
|
439
|
+
def is_floating_ip_valid
|
|
440
|
+
address = locate_config_value(:floating_ip)
|
|
441
|
+
if address == '-1' # no floating IP requested
|
|
442
|
+
return true
|
|
443
|
+
end
|
|
444
|
+
addresses = connection.addresses
|
|
445
|
+
return false if addresses.empty? # no floating IPs
|
|
446
|
+
# floating requested without value
|
|
447
|
+
if address.nil?
|
|
448
|
+
if addresses.find_index { |a| a.fixed_ip.nil? }
|
|
449
|
+
return true
|
|
450
|
+
else
|
|
451
|
+
return false # no floating IPs available
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
# floating requested with value
|
|
455
|
+
if addresses.find_index { |a| a.ip == address }
|
|
416
456
|
return true
|
|
417
457
|
else
|
|
418
|
-
return false #
|
|
458
|
+
return false # requested floating IP does not exist
|
|
419
459
|
end
|
|
420
460
|
end
|
|
421
|
-
#floating requested with value
|
|
422
|
-
if addresses.find_index {|a| a.ip == address}
|
|
423
|
-
return true
|
|
424
|
-
else
|
|
425
|
-
return false #requested floating IP does not exist
|
|
426
|
-
end
|
|
427
|
-
end
|
|
428
461
|
|
|
429
|
-
|
|
430
|
-
|
|
462
|
+
def validate!
|
|
463
|
+
super([:image, :openstack_username, :openstack_password, :openstack_auth_url])
|
|
431
464
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
465
|
+
if flavor.nil?
|
|
466
|
+
ui.error("You have not provided a valid flavor ID. Please note the options for this value are -f or --flavor.")
|
|
467
|
+
exit 1
|
|
468
|
+
end
|
|
436
469
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
470
|
+
if image.nil?
|
|
471
|
+
ui.error("You have not provided a valid image ID. Please note the options for this value are -I or --image.")
|
|
472
|
+
exit 1
|
|
473
|
+
end
|
|
441
474
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
475
|
+
if !is_floating_ip_valid
|
|
476
|
+
ui.error("You have either requested an invalid floating IP address or none are available.")
|
|
477
|
+
exit 1
|
|
478
|
+
end
|
|
445
479
|
end
|
|
446
|
-
end
|
|
447
480
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
481
|
+
# generate a random name if chef_node_name is empty
|
|
482
|
+
def get_node_name(chef_node_name)
|
|
483
|
+
return chef_node_name unless chef_node_name.nil?
|
|
484
|
+
# lazy uuids
|
|
485
|
+
chef_node_name = "os-" + rand.to_s.split('.')[1]
|
|
486
|
+
end
|
|
453
487
|
end
|
|
454
488
|
end
|
|
455
489
|
end
|
|
456
|
-
end
|
|
@@ -70,9 +70,10 @@ class Chef
|
|
|
70
70
|
msg_pair("Instance ID", server.id)
|
|
71
71
|
msg_pair("Flavor", server.flavor['id'])
|
|
72
72
|
msg_pair("Image", server.image['id'])
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
server.addresses.each do |name,addr|
|
|
74
|
+
msg_pair("Network", name)
|
|
75
|
+
msg_pair(" IP Address", addr[0]['addr'])
|
|
76
|
+
end
|
|
76
77
|
|
|
77
78
|
puts "\n"
|
|
78
79
|
confirm("Do you really want to delete this server")
|
|
@@ -58,7 +58,11 @@ class Chef
|
|
|
58
58
|
server_list << ''
|
|
59
59
|
end
|
|
60
60
|
server_list << server.flavor['id'].to_s
|
|
61
|
-
|
|
61
|
+
if server.image
|
|
62
|
+
server_list << server.image['id']
|
|
63
|
+
else
|
|
64
|
+
server_list << ""
|
|
65
|
+
end
|
|
62
66
|
server_list << server.key_name
|
|
63
67
|
server_list << begin
|
|
64
68
|
state = server.state.to_s.downcase
|
|
@@ -10,10 +10,10 @@ require 'chef/knife/bootstrap_windows_winrm'
|
|
|
10
10
|
describe Chef::Knife::OpenstackServerCreate do
|
|
11
11
|
before do
|
|
12
12
|
|
|
13
|
-
@openstack_connection =
|
|
13
|
+
@openstack_connection = double(Fog::Compute::OpenStack)
|
|
14
14
|
@openstack_connection.stub_chain(:flavors, :get).and_return ('flavor_id')
|
|
15
|
-
@openstack_connection.stub_chain(:images, :get).and_return
|
|
16
|
-
@openstack_connection.stub_chain(:addresses).and_return [
|
|
15
|
+
@openstack_connection.stub_chain(:images, :get).and_return double('image_id')
|
|
16
|
+
@openstack_connection.stub_chain(:addresses).and_return [double('addresses', {
|
|
17
17
|
:instance_id => nil,
|
|
18
18
|
:ip => '111.111.111.111',
|
|
19
19
|
:fixed_ip => true
|
|
@@ -39,8 +39,8 @@ describe Chef::Knife::OpenstackServerCreate do
|
|
|
39
39
|
@knife_openstack_create.stub(:print)
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
@openstack_servers =
|
|
43
|
-
@new_openstack_server =
|
|
42
|
+
@openstack_servers = double()
|
|
43
|
+
@new_openstack_server = double()
|
|
44
44
|
|
|
45
45
|
@openstack_server_attribs = { :name => 'Mock Server',
|
|
46
46
|
:id => 'id-123456',
|
|
@@ -71,12 +71,22 @@ describe Chef::Knife::OpenstackServerCreate do
|
|
|
71
71
|
@options[:floating_ip][:default].should == '-1'
|
|
72
72
|
@options[:host_key_verify][:default].should == true
|
|
73
73
|
@options[:private_network][:default].should == false
|
|
74
|
+
@options[:network][:default].should == true
|
|
75
|
+
@options[:bootstrap_network][:default].should == 'public'
|
|
74
76
|
@options[:run_list][:default].should == []
|
|
75
77
|
@options[:security_groups][:default].should == ['default']
|
|
76
78
|
@options[:server_create_timeout][:default].should == 600
|
|
77
79
|
@options[:ssh_port][:default].should == '22'
|
|
78
80
|
@options[:ssh_user][:default].should == 'root'
|
|
79
81
|
end
|
|
82
|
+
|
|
83
|
+
it "doesn't set an OpenStack endpoint type by default" do
|
|
84
|
+
Chef::Config[:knife][:openstack_endpoint_type].should == nil
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "user_data should be empty" do
|
|
88
|
+
Chef::Config[:knife][:user_data].should == nil
|
|
89
|
+
end
|
|
80
90
|
end
|
|
81
91
|
|
|
82
92
|
describe "run" do
|
metadata
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: knife-openstack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: 0.9.0
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- Seth Chisamore
|
|
@@ -10,118 +9,104 @@ authors:
|
|
|
10
9
|
autorequire:
|
|
11
10
|
bindir: bin
|
|
12
11
|
cert_chain: []
|
|
13
|
-
date:
|
|
12
|
+
date: 2014-03-07 00:00:00.000000000 Z
|
|
14
13
|
dependencies:
|
|
15
14
|
- !ruby/object:Gem::Dependency
|
|
16
15
|
name: fog
|
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
|
18
|
-
none: false
|
|
19
17
|
requirements:
|
|
20
|
-
- -
|
|
18
|
+
- - '>='
|
|
21
19
|
- !ruby/object:Gem::Version
|
|
22
20
|
version: 1.10.0
|
|
23
21
|
type: :runtime
|
|
24
22
|
prerelease: false
|
|
25
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
|
-
none: false
|
|
27
24
|
requirements:
|
|
28
|
-
- -
|
|
25
|
+
- - '>='
|
|
29
26
|
- !ruby/object:Gem::Version
|
|
30
27
|
version: 1.10.0
|
|
31
28
|
- !ruby/object:Gem::Dependency
|
|
32
29
|
name: chef
|
|
33
30
|
requirement: !ruby/object:Gem::Requirement
|
|
34
|
-
none: false
|
|
35
31
|
requirements:
|
|
36
|
-
- -
|
|
32
|
+
- - '>='
|
|
37
33
|
- !ruby/object:Gem::Version
|
|
38
34
|
version: 0.10.10
|
|
39
35
|
type: :runtime
|
|
40
36
|
prerelease: false
|
|
41
37
|
version_requirements: !ruby/object:Gem::Requirement
|
|
42
|
-
none: false
|
|
43
38
|
requirements:
|
|
44
|
-
- -
|
|
39
|
+
- - '>='
|
|
45
40
|
- !ruby/object:Gem::Version
|
|
46
41
|
version: 0.10.10
|
|
47
42
|
- !ruby/object:Gem::Dependency
|
|
48
43
|
name: knife-windows
|
|
49
44
|
requirement: !ruby/object:Gem::Requirement
|
|
50
|
-
none: false
|
|
51
45
|
requirements:
|
|
52
|
-
- -
|
|
46
|
+
- - '>='
|
|
53
47
|
- !ruby/object:Gem::Version
|
|
54
48
|
version: '0'
|
|
55
49
|
type: :runtime
|
|
56
50
|
prerelease: false
|
|
57
51
|
version_requirements: !ruby/object:Gem::Requirement
|
|
58
|
-
none: false
|
|
59
52
|
requirements:
|
|
60
|
-
- -
|
|
53
|
+
- - '>='
|
|
61
54
|
- !ruby/object:Gem::Version
|
|
62
55
|
version: '0'
|
|
63
56
|
- !ruby/object:Gem::Dependency
|
|
64
57
|
name: rspec-core
|
|
65
58
|
requirement: !ruby/object:Gem::Requirement
|
|
66
|
-
none: false
|
|
67
59
|
requirements:
|
|
68
|
-
- -
|
|
60
|
+
- - '>='
|
|
69
61
|
- !ruby/object:Gem::Version
|
|
70
62
|
version: '0'
|
|
71
63
|
type: :development
|
|
72
64
|
prerelease: false
|
|
73
65
|
version_requirements: !ruby/object:Gem::Requirement
|
|
74
|
-
none: false
|
|
75
66
|
requirements:
|
|
76
|
-
- -
|
|
67
|
+
- - '>='
|
|
77
68
|
- !ruby/object:Gem::Version
|
|
78
69
|
version: '0'
|
|
79
70
|
- !ruby/object:Gem::Dependency
|
|
80
71
|
name: rspec-expectations
|
|
81
72
|
requirement: !ruby/object:Gem::Requirement
|
|
82
|
-
none: false
|
|
83
73
|
requirements:
|
|
84
|
-
- -
|
|
74
|
+
- - '>='
|
|
85
75
|
- !ruby/object:Gem::Version
|
|
86
76
|
version: '0'
|
|
87
77
|
type: :development
|
|
88
78
|
prerelease: false
|
|
89
79
|
version_requirements: !ruby/object:Gem::Requirement
|
|
90
|
-
none: false
|
|
91
80
|
requirements:
|
|
92
|
-
- -
|
|
81
|
+
- - '>='
|
|
93
82
|
- !ruby/object:Gem::Version
|
|
94
83
|
version: '0'
|
|
95
84
|
- !ruby/object:Gem::Dependency
|
|
96
85
|
name: rspec-mocks
|
|
97
86
|
requirement: !ruby/object:Gem::Requirement
|
|
98
|
-
none: false
|
|
99
87
|
requirements:
|
|
100
|
-
- -
|
|
88
|
+
- - '>='
|
|
101
89
|
- !ruby/object:Gem::Version
|
|
102
90
|
version: '0'
|
|
103
91
|
type: :development
|
|
104
92
|
prerelease: false
|
|
105
93
|
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
-
none: false
|
|
107
94
|
requirements:
|
|
108
|
-
- -
|
|
95
|
+
- - '>='
|
|
109
96
|
- !ruby/object:Gem::Version
|
|
110
97
|
version: '0'
|
|
111
98
|
- !ruby/object:Gem::Dependency
|
|
112
99
|
name: rspec_junit_formatter
|
|
113
100
|
requirement: !ruby/object:Gem::Requirement
|
|
114
|
-
none: false
|
|
115
101
|
requirements:
|
|
116
|
-
- -
|
|
102
|
+
- - '>='
|
|
117
103
|
- !ruby/object:Gem::Version
|
|
118
104
|
version: '0'
|
|
119
105
|
type: :development
|
|
120
106
|
prerelease: false
|
|
121
107
|
version_requirements: !ruby/object:Gem::Requirement
|
|
122
|
-
none: false
|
|
123
108
|
requirements:
|
|
124
|
-
- -
|
|
109
|
+
- - '>='
|
|
125
110
|
- !ruby/object:Gem::Version
|
|
126
111
|
version: '0'
|
|
127
112
|
description: OpenStack Compute Support for Chef's Knife Command
|
|
@@ -153,27 +138,26 @@ files:
|
|
|
153
138
|
- spec/unit/openstack_server_create_spec.rb
|
|
154
139
|
homepage: https://github.com/opscode/knife-openstack
|
|
155
140
|
licenses: []
|
|
141
|
+
metadata: {}
|
|
156
142
|
post_install_message:
|
|
157
143
|
rdoc_options: []
|
|
158
144
|
require_paths:
|
|
159
145
|
- lib
|
|
160
146
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
161
|
-
none: false
|
|
162
147
|
requirements:
|
|
163
|
-
- -
|
|
148
|
+
- - '>='
|
|
164
149
|
- !ruby/object:Gem::Version
|
|
165
150
|
version: '0'
|
|
166
151
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
|
-
none: false
|
|
168
152
|
requirements:
|
|
169
|
-
- -
|
|
153
|
+
- - '>='
|
|
170
154
|
- !ruby/object:Gem::Version
|
|
171
155
|
version: '0'
|
|
172
156
|
requirements: []
|
|
173
157
|
rubyforge_project:
|
|
174
|
-
rubygems_version:
|
|
158
|
+
rubygems_version: 2.0.14
|
|
175
159
|
signing_key:
|
|
176
|
-
specification_version:
|
|
160
|
+
specification_version: 4
|
|
177
161
|
summary: OpenStack Compute Support for Chef's Knife Command
|
|
178
162
|
test_files:
|
|
179
163
|
- spec/spec_helper.rb
|