knife-vsphere 0.1.8 → 0.1.9

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.
@@ -22,73 +22,71 @@ class Chef
22
22
  require 'chef/json_compat'
23
23
  end
24
24
 
25
-
26
25
  def self.get_common_options
26
+ $default = Hash.new
27
27
 
28
28
  option :vsphere_user,
29
29
  :short => "-u USERNAME",
30
- :long => "--user USERNAME",
31
- :description => "The username for the host"
30
+ :long => "--vsuser USERNAME",
31
+ :description => "The username for vsphere"
32
32
 
33
33
  option :vsphere_pass,
34
34
  :short => "-p PASSWORD",
35
- :long => "--password PASSWORD",
36
- :description => "The password for the host"
35
+ :long => "--vspass PASSWORD",
36
+ :description => "The password for vsphere"
37
+
38
+ option :vsphere_host,
39
+ :long => "--vshost",
40
+ :description => "The vsphere host"
37
41
 
38
- option :datacenter,
42
+ option :vsphere_dc,
39
43
  :short => "-d DATACENTER",
40
- :long => "--datacenter DATACENTER",
41
- :description => "The Datacenter to create the VM in"
42
-
43
- option :path,
44
- :long => "--path SOAP_PATH",
45
- :description => "The SOAP endpoint path",
46
- :proc => Proc.new { |p| Chef::Config[:knife][:path] = p },
47
- :default => "/sdk"
48
-
49
- option :port,
50
- :long => "--port PORT",
51
- :description => "The VI SDK port number to use",
52
- :proc => Proc.new { |p| Chef::Config[:knife][:port] = p },
53
- :default => 443
54
-
55
- option :use_ssl,
56
- :long => "--ssl USE_SSL",
57
- :description => "Whether to use SSL connection",
58
- :default => true
59
-
60
- option :insecure,
61
- :short => "-i USE_INSECURE_SSL",
62
- :long => "--insecure USE_INSECURE_SSL",
63
- :description => "Determines whether SSL certificate verification is skipped",
64
- :default => true
44
+ :long => "--vsdc DATACENTER",
45
+ :description => "The Datacenter for vsphere"
46
+
47
+ option :vsphere_path,
48
+ :long => "--vspath SOAP_PATH",
49
+ :description => "The vsphere SOAP endpoint path"
50
+ $default[:vsphere_path] = "/sdk"
51
+
52
+ option :vsphere_port,
53
+ :long => "--vsport PORT",
54
+ :description => "The VI SDK port number to use"
55
+ $default[:vsphere_port] = 443
56
+
57
+ option :vshere_ssl,
58
+ :long => "--vsssl USE_SSL",
59
+ :description => "Whether to use SSL connection"
60
+ $default[:vsphere_ssl] = true
61
+
62
+ option :vsphere_insecure,
63
+ :long => "--vsinsecure USE_INSECURE_SSL",
64
+ :description => "Determines whether SSL certificate verification is skipped"
65
65
 
66
66
  option :folder,
67
67
  :short => "-f FOLDER",
68
68
  :long => "--folder FOLDER",
69
- :description => "The folder to get VMs from",
70
- :default => ''
71
-
69
+ :description => "The folder to get VMs from"
70
+ $default[:folder] = ''
72
71
  end
73
72
 
74
- def locate_config_value(key)
73
+ def get_config(key)
75
74
  key = key.to_sym
76
- Chef::Config[:knife][key] || config[key]
75
+ config[key] || Chef::Config[:knife][key] || $default[key]
77
76
  end
78
77
 
79
78
  def get_vim_connection
80
79
 
81
80
  conn_opts = {
82
- :host => locate_config_value(:vsphere_host),
83
- :path => config[:path],
84
- :port => config[:port],
85
- :use_ssl => config[:ssl],
86
- :user => locate_config_value(:vsphere_user),
87
- :password => locate_config_value(:vsphere_pass),
88
- :insecure => config[:insecure]
81
+ :host => get_config(:vsphere_host),
82
+ :path => get_config(:vshere_path),
83
+ :port => get_config(:vsphere_port),
84
+ :use_ssl => get_config(:vsphere_ssl),
85
+ :user => get_config(:vsphere_user),
86
+ :password => get_config(:vsphere_pass),
87
+ :insecure => get_config(:vsphere_insecure)
89
88
  }
90
89
 
91
- # opt :insecure, "don't verify ssl certificate", :short => 'k', :default => (ENV['RBVMOMI_INSECURE'] == '1')
92
90
  # opt :debug, "Log SOAP messages", :short => 'd', :default => (ENV['RBVMOMI_DEBUG'] || false)
93
91
 
94
92
  vim = RbVmomi::VIM.connect conn_opts
@@ -97,7 +95,7 @@ class Chef
97
95
  end
98
96
 
99
97
  def find_folder(folderName)
100
- dcname = config[:vsphere_dc] || Chef::Config[:knife][:vsphere_dc]
98
+ dcname = get_config(:vsphere_dc)
101
99
  dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
102
100
  baseEntity = dc.vmFolder
103
101
  entityArray = folderName.split('/')
@@ -111,14 +109,14 @@ class Chef
111
109
  end
112
110
 
113
111
  def find_network(networkName)
114
- dcname = config[:vsphere_dc] || Chef::Config[:knife][:vsphere_dc]
112
+ dcname = get_config(:vsphere_dc)
115
113
  dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
116
114
  baseEntity = dc.network
117
115
  baseEntity.find { |f| f.name == networkName } or abort "no such network #{networkName}"
118
116
  end
119
117
 
120
118
  def find_pool(poolName)
121
- dcname = config[:vsphere_dc] || Chef::Config[:knife][:vsphere_dc]
119
+ dcname = get_config(:vsphere_dc)
122
120
  dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
123
121
  baseEntity = dc.hostFolder
124
122
  entityArray = poolName.split('/')
@@ -144,7 +142,7 @@ class Chef
144
142
  end
145
143
 
146
144
  def find_datastore(dsName)
147
- dcname = config[:vsphere_dc] || Chef::Config[:knife][:vsphere_dc]
145
+ dcname = get_config(:vsphere_dc)
148
146
  dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
149
147
  baseEntity = dc.datastore
150
148
  baseEntity.find { |f| f.info.name == dsName } or abort "no such datastore #{dsName}"
@@ -46,7 +46,7 @@ class Chef::Knife::VsphereDatastoreList < Chef::Knife::BaseVsphereCommand
46
46
  $stdout.sync = true
47
47
 
48
48
  vim = get_vim_connection
49
- dcname = config[:vsphere_dc] || Chef::Config[:knife][:vsphere_dc]
49
+ dcname = get_config(:vsphere_dc)
50
50
  dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
51
51
  dc.datastore.each do |store|
52
52
  avail = number_to_human_size(store.summary[:freeSpace])
@@ -20,7 +20,7 @@ class Chef::Knife::VsphereTemplateList < Chef::Knife::BaseVsphereCommand
20
20
 
21
21
  vim = get_vim_connection
22
22
 
23
- baseFolder = find_folder(config[:folder]);
23
+ baseFolder = find_folder(get_config(:folder));
24
24
 
25
25
  vms = find_all_in_folder(baseFolder, RbVmomi::VIM::VirtualMachine).
26
26
  select {|v| !v.config.nil? && v.config.template == true }
@@ -0,0 +1,37 @@
1
+ # Author: Jesse Campbell
2
+ #
3
+ # Permission to use, copy, modify, and/or distribute this software for
4
+ # any purpose with or without fee is hereby granted, provided that the
5
+ # above copyright notice and this permission notice appear in all
6
+ # copies.
7
+ #
8
+ # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
9
+ # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
10
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
11
+ # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12
+ # DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
13
+ # OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
14
+ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ # PERFORMANCE OF THIS SOFTWARE
16
+
17
+ require 'chef/knife'
18
+ require 'chef/knife/BaseVsphereCommand'
19
+
20
+ # Lists all known data stores in datacenter with sizes
21
+ class Chef::Knife::VsphereVlanList < Chef::Knife::BaseVsphereCommand
22
+
23
+ banner "knife vsphere vlan list"
24
+
25
+ get_common_options
26
+ def run
27
+ $stdout.sync = true
28
+
29
+ vim = get_vim_connection
30
+ dcname = get_config(:vsphere_dc)
31
+ dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
32
+ dc.network.each do |network|
33
+ puts "#{ui.color("VLAN", :cyan)}: #{network.name}"
34
+ end
35
+ end
36
+ end
37
+
@@ -84,13 +84,11 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
84
84
 
85
85
  option :power,
86
86
  :long => "--start STARTVM",
87
- :description => "Indicates whether to start the VM after a successful clone",
88
- :default => false
87
+ :description => "Indicates whether to start the VM after a successful clone"
89
88
 
90
89
  option :bootstrap,
91
90
  :long => "--bootstrap FALSE",
92
- :description => "Indicates whether to bootstrap the VM",
93
- :default => false
91
+ :description => "Indicates whether to bootstrap the VM"
94
92
 
95
93
  option :fqdn,
96
94
  :long => "--fqdn SERVER_FQDN",
@@ -99,8 +97,8 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
99
97
  option :ssh_user,
100
98
  :short => "-x USERNAME",
101
99
  :long => "--ssh-user USERNAME",
102
- :description => "The ssh username",
103
- :default => "root"
100
+ :description => "The ssh username"
101
+ $default[:ssh_user] = "root"
104
102
 
105
103
  option :ssh_password,
106
104
  :short => "-P PASSWORD",
@@ -110,9 +108,8 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
110
108
  option :ssh_port,
111
109
  :short => "-p PORT",
112
110
  :long => "--ssh-port PORT",
113
- :description => "The ssh port",
114
- :default => "22",
115
- :proc => Proc.new { |key| Chef::Config[:knife][:ssh_port] = key }
111
+ :description => "The ssh port"
112
+ $default[:ssh_port] = 22
116
113
 
117
114
  option :identity_file,
118
115
  :short => "-i IDENTITY_FILE",
@@ -131,7 +128,7 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
131
128
  option :bootstrap_version,
132
129
  :long => "--bootstrap-version VERSION",
133
130
  :description => "The version of Chef to install",
134
- :proc => lambda { |v| Chef::Config[:knife][:bootstrap_version] = v }
131
+ :proc => Proc.new { |v| Chef::Config[:knife][:bootstrap_version] = v }
135
132
 
136
133
  option :bootstrap_proxy,
137
134
  :long => "--bootstrap-proxy PROXY_URL",
@@ -141,26 +138,23 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
141
138
  option :distro,
142
139
  :short => "-d DISTRO",
143
140
  :long => "--distro DISTRO",
144
- :description => "Bootstrap a distro using a template",
145
- :default => "ubuntu10.04-gems"
141
+ :description => "Bootstrap a distro using a template"
142
+ $default[:distro] = "ubuntu10.04-gems"
146
143
 
147
144
  option :template_file,
148
145
  :long => "--template-file TEMPLATE",
149
- :description => "Full path to location of template to use",
150
- :default => false
146
+ :description => "Full path to location of template to use"
151
147
 
152
148
  option :run_list,
153
149
  :short => "-r RUN_LIST",
154
150
  :long => "--run-list RUN_LIST",
155
- :description => "Comma separated list of roles/recipes to apply",
156
- :proc => lambda { |o| o.split(/[\s,]+/) },
157
- :default => []
151
+ :description => "Comma separated list of roles/recipes to apply"
152
+ $default[:run_list] = ''
158
153
 
159
154
  option :no_host_key_verify,
160
155
  :long => "--no-host-key-verify",
161
156
  :description => "Disable host key verification",
162
- :boolean => true,
163
- :default => false
157
+ :boolean => true
164
158
 
165
159
  def run
166
160
  $stdout.sync = true
@@ -176,17 +170,17 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
176
170
 
177
171
  vim = get_vim_connection
178
172
 
179
- dcname = config[:vsphere_dc] || Chef::Config[:knife][:vsphere_dc]
173
+ dcname = get_config(:vsphere_dc)
180
174
  dc = vim.serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
181
175
 
182
- src_folder = find_folder(config[:folder]) || dc.vmFolder
176
+ src_folder = find_folder(get_config(:folder)) || dc.vmFolder
183
177
 
184
178
  src_vm = find_in_folder(src_folder, RbVmomi::VIM::VirtualMachine, config[:source_vm]) or
185
179
  abort "VM/Template not found"
186
180
 
187
181
  clone_spec = generate_clone_spec(src_vm.config)
188
182
 
189
- cust_folder = config[:dest_folder] || config[:folder]
183
+ cust_folder = config[:dest_folder] || get_config(:folder)
190
184
 
191
185
  dest_folder = cust_folder.nil? ? src_vm.vmFolder : find_folder(cust_folder)
192
186
 
@@ -195,14 +189,14 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
195
189
  task.wait_for_completion
196
190
  puts "Finished creating virtual machine #{vmname}"
197
191
 
198
- if config[:power] || config[:bootstrap]
192
+ if get_config(:power) || get_config(:bootstrap)
199
193
  vm = find_in_folder(dest_folder, RbVmomi::VIM::VirtualMachine, vmname) or
200
194
  fatal_exit("VM #{vmname} not found")
201
195
  vm.PowerOnVM_Task.wait_for_completion
202
196
  puts "Powered on virtual machine #{vmname}"
203
197
  end
204
198
 
205
- if config[:bootstrap]
199
+ if get_config(:bootstrap)
206
200
  print "Waiting for sshd..."
207
201
  print "." until tcp_test_ssh(config[:fqdn])
208
202
  puts "done"
@@ -215,18 +209,18 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
215
209
  def generate_clone_spec (src_config)
216
210
 
217
211
  rspec = nil
218
- if config[:resource_pool]
219
- rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => find_pool(config[:resource_pool]))
212
+ if get_config(:resource_pool)
213
+ rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => find_pool(get_config(:resource_pool)))
220
214
  else
221
- dcname = config[:vsphere_dc] || Chef::Config[:knife][:vsphere_dc]
215
+ dcname = get_config(:vsphere_dc)
222
216
  dc = config[:vim].serviceInstance.find_datacenter(dcname) or abort "datacenter not found"
223
217
  hosts = find_all_in_folder(dc.hostFolder, RbVmomi::VIM::ComputeResource)
224
218
  rp = hosts.first.resourcePool
225
219
  rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => rp)
226
220
  end
227
221
 
228
- if config[:datastore]
229
- rspec.datastore = find_datastore(config[:datastore])
222
+ if get_config(:datastore)
223
+ rspec.datastore = find_datastore(get_config(:datastore))
230
224
  end
231
225
 
232
226
  clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(:location => rspec,
@@ -235,16 +229,16 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
235
229
 
236
230
  clone_spec.config = RbVmomi::VIM.VirtualMachineConfigSpec(:deviceChange => Array.new)
237
231
 
238
- if config[:customization_cpucount]
239
- clone_spec.config.numCPUs = config[:customization_cpucount]
232
+ if get_config(:customization_cpucount)
233
+ clone_spec.config.numCPUs = get_config(:customization_cpucount)
240
234
  end
241
235
 
242
- if config[:customization_memory]
243
- clone_spec.config.memoryMB = Integer(config[:customization_memory]) * 1024
236
+ if get_config(:customization_memory)
237
+ clone_spec.config.memoryMB = Integer(get_config(:customization_memory)) * 1024
244
238
  end
245
239
 
246
- if config[:customization_vlan]
247
- network = find_network(config[:customization_vlan])
240
+ if get_config(:customization_vlan)
241
+ network = find_network(get_config(:customization_vlan))
248
242
  switch_port = RbVmomi::VIM.DistributedVirtualSwitchPortConnection(:switchUuid => network.config.distributedVirtualSwitch.uuid ,:portgroupKey => network.key)
249
243
  card = src_config.hardware.device.find { |d| d.deviceInfo.label == "Network adapter 1" } or
250
244
  abort "Can't find source network card to customize"
@@ -253,9 +247,9 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
253
247
  clone_spec.config.deviceChange.push dev_spec
254
248
  end
255
249
 
256
- if config[:customization_spec]
257
- csi = find_customization(config[:customization_spec]) or
258
- fatal_exit("failed to find customization specification named #{config[:customization_spec]}")
250
+ if get_config(:customization_spec)
251
+ csi = find_customization(get_config(:customization_spec)) or
252
+ fatal_exit("failed to find customization specification named #{get_config(:customization_spec)}")
259
253
 
260
254
  if csi.info.type != "Linux"
261
255
  fatal_exit("Only Linux customization specifications are currently supported")
@@ -266,23 +260,23 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
266
260
  cust_spec = RbVmomi::VIM.CustomizationSpec(:globalIPSettings => global_ipset)
267
261
  end
268
262
 
269
- if config[:customization_dns_ips]
270
- cust_spec.globalIPSettings.dnsServerList = config[:customization_dns_ips].split(',')
263
+ if get_config(:customization_dns_ips)
264
+ cust_spec.globalIPSettings.dnsServerList = get_config(:customization_dns_ips).split(',')
271
265
  end
272
266
 
273
- if config[:customization_dns_suffixes]
274
- cust_spec.globalIPSettings.dnsSuffixList = config[:customization_dns_suffixes].split(',')
267
+ if get_config(:customization_dns_suffixes)
268
+ cust_spec.globalIPSettings.dnsSuffixList = get_config(:customization_dns_suffixes).split(',')
275
269
  end
276
270
 
277
271
  if config[:customization_ips]
278
- if config[:customization_gw]
279
- cust_spec.nicSettingMap = config[:customization_ips].split(',').map { |i| generate_adapter_map(i,config[:customization_gw]) }
272
+ if get_config(:customization_gw)
273
+ cust_spec.nicSettingMap = config[:customization_ips].split(',').map { |i| generate_adapter_map(i,get_config(:customization_gw)) }
280
274
  else
281
275
  cust_spec.nicSettingMap = config[:customization_ips].split(',').map { |i| generate_adapter_map(i) }
282
276
  end
283
277
  end
284
278
 
285
- use_ident = !config[:customization_hostname].nil? || !config[:customization_domain].nil? || cust_spec.identity.nil?
279
+ use_ident = !config[:customization_hostname].nil? || !get_config(:customization_domain).nil? || cust_spec.identity.nil?
286
280
 
287
281
  if use_ident
288
282
  # TODO - verify that we're deploying a linux spec, at least warn
@@ -291,14 +285,12 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
291
285
  ident.hostName = RbVmomi::VIM.CustomizationFixedName
292
286
  if config[:customization_hostname]
293
287
  ident.hostName.name = config[:customization_hostname]
294
- elsif config[:customization_domain]
295
- ident.hostName.name = config[:customization_domain]
296
288
  else
297
289
  ident.hostName.name = config[:vmname]
298
290
  end
299
291
 
300
- if config[:customization_domain]
301
- ident.domain = config[:customization_domain]
292
+ if get_config(:customization_domain)
293
+ ident.domain = get_config(:customization_domain)
302
294
  else
303
295
  ident.domain = ''
304
296
  end
@@ -355,25 +347,25 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
355
347
  Chef::Knife::Bootstrap.load_deps
356
348
  bootstrap = Chef::Knife::Bootstrap.new
357
349
  bootstrap.name_args = [config[:fqdn]]
358
- bootstrap.config[:run_list] = config[:run_list]
359
- bootstrap.config[:ssh_user] = config[:ssh_user]
360
- bootstrap.config[:ssh_password] = config[:ssh_password]
361
- bootstrap.config[:ssh_port] = config[:ssh_port]
362
- bootstrap.config[:identity_file] = config[:identity_file]
363
- bootstrap.config[:chef_node_name] = config[:chef_node_name]
364
- bootstrap.config[:prerelease] = config[:prerelease]
365
- bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
366
- bootstrap.config[:distro] = locate_config_value(:distro)
367
- bootstrap.config[:use_sudo] = true unless config[:ssh_user] == 'root'
368
- bootstrap.config[:template_file] = locate_config_value(:template_file)
369
- bootstrap.config[:environment] = config[:environment]
350
+ bootstrap.config[:run_list] = get_config(:run_list).split(/[\s,]+/)
351
+ bootstrap.config[:ssh_user] = get_config(:ssh_user)
352
+ bootstrap.config[:ssh_password] = get_config(:ssh_password)
353
+ bootstrap.config[:ssh_port] = get_config(:ssh_port)
354
+ bootstrap.config[:identity_file] = get_config(:identity_file)
355
+ bootstrap.config[:chef_node_name] = get_config(:chef_node_name)
356
+ bootstrap.config[:prerelease] = get_config(:prerelease)
357
+ bootstrap.config[:bootstrap_version] = get_config(:bootstrap_version)
358
+ bootstrap.config[:distro] = get_config(:distro)
359
+ bootstrap.config[:use_sudo] = true unless get_config(:ssh_user) == 'root'
360
+ bootstrap.config[:template_file] = get_config(:template_file)
361
+ bootstrap.config[:environment] = get_config(:environment)
370
362
  # may be needed for vpc_mode
371
- bootstrap.config[:no_host_key_verify] = config[:no_host_key_verify]
363
+ bootstrap.config[:no_host_key_verify] = get_config(:no_host_key_verify)
372
364
  bootstrap
373
365
  end
374
366
 
375
367
  def tcp_test_ssh(hostname)
376
- tcp_socket = TCPSocket.new(hostname, 22)
368
+ tcp_socket = TCPSocket.new(hostname, get_config(:ssh_port))
377
369
  readable = IO.select([tcp_socket], nil, nil, 5)
378
370
  if readable
379
371
  Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}")
@@ -7,33 +7,60 @@ require 'chef/knife'
7
7
  require 'chef/knife/BaseVsphereCommand'
8
8
  require 'rbvmomi'
9
9
 
10
+ # These two are needed for the '--purge' deletion case
11
+ require 'chef/node'
12
+ require 'chef/api_client'
13
+
10
14
  # Delete a virtual machine from vCenter
11
15
  class Chef::Knife::VsphereVmDelete < Chef::Knife::BaseVsphereCommand
12
16
 
13
- banner "knife vsphere vm delete VMNAME"
17
+ banner "knife vsphere vm delete VMNAME"
18
+
19
+ option :purge,
20
+ :short => "-P",
21
+ :long => "--purge",
22
+ :boolean => true,
23
+ :description => "Destroy corresponding node and client on the Chef Server, in addition to destroying the EC2 node itself."
24
+
25
+ get_common_options
26
+
27
+ # Extracted from Chef::Knife.delete_object, because it has a
28
+ # confirmation step built in... By specifying the '--purge'
29
+ # flag (and also explicitly confirming the server destruction!)
30
+ # the user is already making their intent known. It is not
31
+ # necessary to make them confirm two more times.
32
+ def destroy_item(itemClass, name, type_name)
33
+ object = itemClass.load(name)
34
+ object.destroy
35
+ puts "Deleted #{type_name} #{name}"
36
+ end
37
+
38
+ def run
39
+ $stdout.sync = true
14
40
 
15
- get_common_options
16
-
17
- def run
18
- $stdout.sync = true
41
+ vmname = @name_args[0]
19
42
 
20
- vmname = @name_args[0]
43
+ if vmname.nil?
44
+ show_usage
45
+ fatal_exit("You must specify a virtual machine name")
46
+ end
21
47
 
22
- if vmname.nil?
23
- show_usage
24
- fatal_exit("You must specify a virtual machine name")
25
- end
26
-
27
- vim = get_vim_connection
48
+ vim = get_vim_connection
28
49
 
29
- baseFolder = find_folder(config[:folder]);
50
+ baseFolder = find_folder(get_config(:folder));
30
51
 
31
- vm = find_in_folder(baseFolder, RbVmomi::VIM::VirtualMachine, vmname) or
32
- fatal_exit("VM #{vmname} not found")
52
+ vm = find_in_folder(baseFolder, RbVmomi::VIM::VirtualMachine, vmname) or
53
+ fatal_exit("VM #{vmname} not found")
33
54
 
34
- vm.PowerOffVM_Task.wait_for_completion unless vm.runtime.powerState == "poweredOff"
35
- vm.Destroy_Task
36
- puts "Deleted virtual machine #{vmname}"
55
+ vm.PowerOffVM_Task.wait_for_completion unless vm.runtime.powerState == "poweredOff"
56
+ vm.Destroy_Task
57
+ puts "Deleted virtual machine #{vmname}"
37
58
 
38
- end
59
+ if config[:purge]
60
+ destroy_item(Chef::Node, vmname, "node")
61
+ destroy_item(Chef::ApiClient, vmname, "client")
62
+ else
63
+ puts "Corresponding node and client for the #{vmname} server were not deleted and remain registered with the Chef Server"
64
+ end
65
+ end
39
66
  end
@@ -8,25 +8,51 @@ require 'chef/knife/BaseVsphereCommand'
8
8
  # Lists all known virtual machines in the configured datacenter
9
9
  class Chef::Knife::VsphereVmList < Chef::Knife::BaseVsphereCommand
10
10
 
11
- banner "knife vsphere vm list"
11
+ banner "knife vsphere vm list"
12
12
 
13
- get_common_options
14
-
15
- def run
13
+ get_common_options
16
14
 
17
- $stdout.sync = true
15
+ option :recursive,
16
+ :long => "--recursive",
17
+ :short => "-r",
18
+ :description => "Recurse down through sub-folders"
18
19
 
19
- vim = get_vim_connection
20
+ option :only_folders,
21
+ :long => "--only-folders",
22
+ :description => "Print only sub-folders"
20
23
 
21
- baseFolder = find_folder(config[:folder]);
24
+ def traverse_folders(folder)
25
+ puts "#{ui.color("Folder", :cyan)}: "+(folder.path[3..-1].map{|x| x[1]}.*'/')
26
+ print_vms_in_folder(folder) unless get_config(:only_folders)
27
+ folders = find_all_in_folder(folder, RbVmomi::VIM::Folder)
28
+ folders.each do |child|
29
+ traverse_folders(child)
30
+ end
31
+ end
22
32
 
23
- vms = find_all_in_folder(baseFolder, RbVmomi::VIM::VirtualMachine)
24
- vms.each do |vm|
25
- puts "#{ui.color("VM Name", :cyan)}: #{vm.name}"
26
- end
27
- folders = find_all_in_folder(baseFolder, RbVmomi::VIM::Folder)
28
- folders.each do |folder|
29
- puts "#{ui.color("Folder Name", :cyan)}: #{folder.name}"
33
+ def print_vms_in_folder(folder)
34
+ vms = find_all_in_folder(folder, RbVmomi::VIM::VirtualMachine)
35
+ vms.each do |vm|
36
+ puts "#{ui.color("VM Name", :cyan)}: #{vm.name}"
37
+ end
38
+ end
39
+
40
+ def print_subfolders(folder)
41
+ folders = find_all_in_folder(folder, RbVmomi::VIM::Folder)
42
+ folders.each do |subfolder|
43
+ puts "#{ui.color("Folder Name", :cyan)}: #{subfolder.name}"
30
44
  end
31
- end
45
+ end
46
+
47
+ def run
48
+ $stdout.sync = true
49
+ vim = get_vim_connection
50
+ baseFolder = find_folder(get_config(:folder));
51
+ if get_config(:recursive)
52
+ traverse_folders(baseFolder)
53
+ else
54
+ print_subfolders(baseFolder)
55
+ print_vms_in_folder(baseFolder)
56
+ end
57
+ end
32
58
  end
@@ -43,7 +43,7 @@ class Chef::Knife::VsphereVmState < Chef::Knife::BaseVsphereCommand
43
43
 
44
44
  vim = get_vim_connection
45
45
 
46
- baseFolder = find_folder(config[:folder]);
46
+ baseFolder = find_folder(get_config(:folder));
47
47
 
48
48
  vm = find_in_folder(baseFolder, RbVmomi::VIM::VirtualMachine, vmname) or
49
49
  abort "VM #{vmname} not found"
@@ -1,4 +1,4 @@
1
1
  module KnifeVsphere
2
- VERSION = "0.1.8"
2
+ VERSION = "0.1.9"
3
3
  end
4
4
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-vsphere
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-06 00:00:00.000000000 +01:00
12
+ date: 2012-04-16 00:00:00.000000000 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: netaddr
17
- requirement: &70237366117520 !ruby/object:Gem::Requirement
17
+ requirement: &70231050321420 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 1.5.0
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70237366117520
25
+ version_requirements: *70231050321420
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: chef
28
- requirement: &70237366113920 !ruby/object:Gem::Requirement
28
+ requirement: &70231050320800 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 0.10.0
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70237366113920
36
+ version_requirements: *70231050320800
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: rbvmomi
39
- requirement: &70237366111900 !ruby/object:Gem::Requirement
39
+ requirement: &70231050320140 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,7 +44,7 @@ dependencies:
44
44
  version: 1.2.3
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *70237366111900
47
+ version_requirements: *70231050320140
48
48
  description: VMware vSphere Support for Chef's Knife Command
49
49
  email: ezra@cpan.org
50
50
  executables: []
@@ -55,6 +55,7 @@ files:
55
55
  - lib/chef/knife/vsphere_customization_list.rb
56
56
  - lib/chef/knife/vsphere_datastore_list.rb
57
57
  - lib/chef/knife/vsphere_template_list.rb
58
+ - lib/chef/knife/vsphere_vlan_list.rb
58
59
  - lib/chef/knife/vsphere_vm_clone.rb
59
60
  - lib/chef/knife/vsphere_vm_delete.rb
60
61
  - lib/chef/knife/vsphere_vm_list.rb