knife-openstack 0.8.1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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