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 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.8.1
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
- if addresses['private']
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
- if addresses['public']
133
- return addresses['public'].last['addr']
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@opscode.com>)
3
- # Author:: Matt Ray (<matt@opscode.com>)
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-2013 Opscode, Inc.
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
- :name => node_name,
248
- :image_ref => locate_config_value(:image),
249
- :flavor_ref => locate_config_value(:flavor),
250
- :security_groups => locate_config_value(:security_groups),
251
- :key_name => locate_config_value(:openstack_ssh_key_id)
252
- }
253
-
254
- Chef::Log.debug("Name #{node_name}")
255
- Chef::Log.debug("Image #{locate_config_value(:image)}")
256
- Chef::Log.debug("Flavor #{locate_config_value(:flavor)}")
257
- Chef::Log.debug("Requested Floating IP #{locate_config_value(:floating_ip)}")
258
- Chef::Log.debug("Security Groups #{locate_config_value(:security_groups)}")
259
- Chef::Log.debug("Creating server #{server_def}")
260
-
261
- begin
262
- server = connection.servers.create(server_def)
263
- rescue Excon::Errors::BadRequest => e
264
- response = Chef::JSONCompat.from_json(e.response.body)
265
- if response['badRequest']['code'] == 400
266
- if response['badRequest']['message'] =~ /Invalid flavorRef/
267
- ui.fatal("Bad request (400): Invalid flavor specified: #{server_def[:flavor_ref]}")
268
- exit 1
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("Bad request (400): #{response['badRequest']['message']}")
271
- exit 1
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
- msg_pair("Instance Name", server.name)
280
- msg_pair("Instance ID", server.id)
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
- print "\n#{ui.color("Waiting for server", :magenta)}"
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
- # wait for it to be ready to do stuff
285
- server.wait_for(Integer(locate_config_value(:server_create_timeout))) { print "."; ready? }
346
+ # private_network means bootstrap_network = 'private'
347
+ config[:bootstrap_network] = 'private' if config[:private_network]
286
348
 
287
- puts("\n")
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
- msg_pair("Flavor", server.flavor['id'])
290
- msg_pair("Image", server.image['id'])
291
- msg_pair("SSH Identity File", config[:identity_file])
292
- msg_pair("SSH Keypair", server.key_name) if server.key_name
293
- msg_pair("SSH Password", server.password) if (server.password && !server.key_name)
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
- floating_address = locate_config_value(:floating_ip)
298
- Chef::Log.debug("Floating IP Address requested #{floating_address}")
299
- unless (floating_address == '-1') #no floating IP requested
300
- addresses = connection.addresses
301
- #floating requested without value
302
- if floating_address.nil?
303
- free_floating = addresses.find_index {|a| a.fixed_ip.nil?}
304
- if free_floating.nil? #no free floating IP found
305
- ui.error("Unable to assign a Floating IP from allocated IPs.")
306
- exit 1
307
- else
308
- floating_address = addresses[free_floating].ip
309
- end
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
- server.associate_address(floating_address)
312
- #a bit of a hack, but server.reload takes a long time
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
- Chef::Log.debug("Addresses #{server.addresses}")
318
- Chef::Log.debug("Public IP Address actual: #{primary_public_ip_address(server.addresses)}") if primary_public_ip_address(server.addresses)
319
-
320
- msg_pair("Private IP Address", primary_private_ip_address(server.addresses)) if primary_private_ip_address(server.addresses)
321
-
322
- #which IP address to bootstrap
323
- bootstrap_ip_address = primary_public_ip_address(server.addresses) if primary_public_ip_address(server.addresses)
324
- if config[:private_network]
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
- Chef::Log.debug("Bootstrap IP Address: #{bootstrap_ip_address}")
329
- if bootstrap_ip_address.nil?
330
- ui.error("No IP address available for bootstrapping.")
331
- exit 1
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
- if locate_config_value(:bootstrap_protocol) == 'winrm'
335
- print "\n#{ui.color("Waiting for winrm", :magenta)}"
336
- print(".") until tcp_test_winrm(bootstrap_ip_address, locate_config_value(:winrm_port))
337
- bootstrap_for_windows_node(server, bootstrap_ip_address).run
338
- else
339
- Chef::Log.debug("Waiting for sshd on IP address: #{bootstrap_ip_address} and port: #{locate_config_value(:ssh_port)}")
340
- print "\n#{ui.color("Waiting for sshd", :magenta)}"
341
- print(".") until tcp_test_ssh(bootstrap_ip_address, locate_config_value(:ssh_port)) {
342
- sleep @initial_sleep_delay ||= 10
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
- def bootstrap_common_params(bootstrap, server_name)
371
- bootstrap.config[:chef_node_name] = config[:chef_node_name] || server_name
372
- bootstrap.config[:run_list] = config[:run_list]
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
- def is_floating_ip_valid
407
- address = locate_config_value(:floating_ip)
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
- addresses = connection.addresses
412
- return false if addresses.empty? #no floating IPs
413
- #floating requested without value
414
- if address.nil?
415
- if addresses.find_index {|a| a.fixed_ip.nil?}
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 #no floating IPs available
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
- def validate!
430
- super([:image, :openstack_username, :openstack_password, :openstack_auth_url])
462
+ def validate!
463
+ super([:image, :openstack_username, :openstack_password, :openstack_auth_url])
431
464
 
432
- if flavor.nil?
433
- ui.error("You have not provided a valid flavor ID. Please note the options for this value are -f or --flavor.")
434
- exit 1
435
- end
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
- if image.nil?
438
- ui.error("You have not provided a valid image ID. Please note the options for this value are -I or --image.")
439
- exit 1
440
- end
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
- if !is_floating_ip_valid
443
- ui.error("You have either requested an invalid floating IP address or none are available.")
444
- exit 1
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
- #generate a random name if chef_node_name is empty
449
- def get_node_name(chef_node_name)
450
- return chef_node_name unless chef_node_name.nil?
451
- #lazy uuids
452
- chef_node_name = "os-"+rand.to_s.split('.')[1]
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
- msg_pair("Public IP Address", primary_public_ip_address(server.addresses)) if primary_public_ip_address(server.addresses)
74
- msg_pair("Private IP Address", primary_private_ip_address(server.addresses)) if primary_private_ip_address(server.addresses)
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
- server_list << server.image['id'].to_s
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
@@ -1,6 +1,6 @@
1
1
  module Knife
2
2
  module OpenStack
3
- VERSION = "0.8.1"
3
+ VERSION = '0.9.0'
4
4
  MAJOR, MINOR, TINY = VERSION.split('.')
5
5
  end
6
6
  end
@@ -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 = mock(Fog::Compute::OpenStack)
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 mock('image_id')
16
- @openstack_connection.stub_chain(:addresses).and_return [mock('addresses', {
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 = mock()
43
- @new_openstack_server = mock()
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.8.1
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: 2013-06-14 00:00:00.000000000 Z
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: 1.8.25
158
+ rubygems_version: 2.0.14
175
159
  signing_key:
176
- specification_version: 3
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