knife-vsphere 2.0.5 → 2.1.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28d327261e11658b4d6f926e93b136a1c4979e55
|
4
|
+
data.tar.gz: 4c0499b076d8197ccdbd44f9aba9834989e65743
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfdd72ab2858dc5ae00bc8e688c737562a68eb65e52a34e004629a7d7b40a1acb3776dc061c16cfc6699b788ea2f9c66c222af7608b8f3f174cee4fc0de775c1
|
7
|
+
data.tar.gz: 11f6c48d15e56559a0b6181d9e6506ae0c7d77ad9eec8f70dacbfaf4ab4103d31d18c8551c8a0c468097573c1e1fc4dcad753cded01d84a86a898b94e46a8e26
|
@@ -64,7 +64,7 @@ class Chef::Knife::VsphereVmCdrom < Chef::Knife::BaseVsphereCommand
|
|
64
64
|
fatal_exit 'You must specify the name and path of an ISO with --iso' if get_config(:attach) && !get_config(:iso)
|
65
65
|
fatal_exit 'You must specify the datastore containing the ISO with --datastore' if get_config(:attach) && !get_config(:datastore)
|
66
66
|
|
67
|
-
vm = get_vm_by_name(vmname,
|
67
|
+
vm = get_vm_by_name(vmname, get_config(:folder)) || fatal_exit("Could not find #{vmname}")
|
68
68
|
|
69
69
|
cdrom_obj = vm.config.hardware.device.find { |hw| hw.class == RbVmomi::VIM::VirtualCdrom }
|
70
70
|
fatal_exit 'Could not find a cd drive' unless cdrom_obj
|
@@ -8,12 +8,12 @@
|
|
8
8
|
|
9
9
|
require 'chef/knife'
|
10
10
|
require 'chef/knife/base_vsphere_command'
|
11
|
-
require 'rbvmomi'
|
12
|
-
require 'netaddr'
|
13
|
-
require 'securerandom'
|
14
|
-
require 'chef/knife/winrm_base'
|
15
11
|
require 'chef/knife/customization_helper'
|
12
|
+
require 'chef/knife/search_helper'
|
13
|
+
require 'chef/knife/winrm_base'
|
16
14
|
require 'ipaddr'
|
15
|
+
require 'netaddr'
|
16
|
+
require 'securerandom'
|
17
17
|
|
18
18
|
# VsphereVmClone extends the BaseVspherecommand
|
19
19
|
class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
|
@@ -28,6 +28,7 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
|
|
28
28
|
|
29
29
|
include Chef::Knife::WinrmBase
|
30
30
|
include CustomizationHelper
|
31
|
+
include SearchHelper
|
31
32
|
deps do
|
32
33
|
require 'chef/json_compat'
|
33
34
|
require 'chef/knife/bootstrap'
|
@@ -351,17 +352,13 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
|
|
351
352
|
end
|
352
353
|
|
353
354
|
config[:chef_node_name] = vmname unless get_config(:chef_node_name)
|
354
|
-
config[:vmname] = vmname
|
355
355
|
|
356
356
|
vim = vim_connection
|
357
357
|
vim.serviceContent.virtualDiskManager
|
358
358
|
|
359
359
|
dc = datacenter
|
360
360
|
|
361
|
-
|
362
|
-
|
363
|
-
src_vm = find_in_folder(src_folder, RbVmomi::VIM::VirtualMachine, config[:source_vm]) ||
|
364
|
-
abort('VM/Template not found')
|
361
|
+
src_vm = get_vm_by_name(get_config(:source_vm), get_config(:folder)) || fatal_exit("Could not find template #{vmname}")
|
365
362
|
|
366
363
|
create_delta_disk(src_vm) if get_config(:linked_clone)
|
367
364
|
|
@@ -372,7 +369,7 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
|
|
372
369
|
dest_folder = cust_folder.nil? ? src_vm.vmFolder : find_folder(cust_folder)
|
373
370
|
|
374
371
|
task = src_vm.CloneVM_Task(folder: dest_folder, name: vmname, spec: clone_spec)
|
375
|
-
puts "Cloning template #{
|
372
|
+
puts "Cloning template #{get_config(:source_vm)} to new VM #{vmname}"
|
376
373
|
|
377
374
|
pp clone_spec if log_verbose?
|
378
375
|
|
@@ -398,8 +395,7 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
|
|
398
395
|
|
399
396
|
return if get_config(:mark_as_template)
|
400
397
|
if get_config(:power) || get_config(:bootstrap)
|
401
|
-
vm =
|
402
|
-
fatal_exit("VM #{vmname} not found")
|
398
|
+
vm = get_vm_by_name(vmname, cust_folder) || fatal_exit("VM #{vmname} not found")
|
403
399
|
begin
|
404
400
|
vm.PowerOnVM_Task.wait_for_completion
|
405
401
|
rescue RbVmomi::Fault => e
|
@@ -704,7 +700,7 @@ class Chef::Knife::VsphereVmClone < Chef::Knife::BaseVsphereCommand
|
|
704
700
|
|
705
701
|
# TODO: How could we not take this? Only if the identity were empty, but that's statically defined as empty above
|
706
702
|
if use_ident
|
707
|
-
hostname = config[:customization_hostname] ||
|
703
|
+
hostname = config[:customization_hostname] || vmname
|
708
704
|
|
709
705
|
if windows?(src_config)
|
710
706
|
# We should get here with the customizations set, either by a plugin or a --cspec
|
@@ -1,24 +1,26 @@
|
|
1
|
-
#
|
2
1
|
# Author:: Raducu Deaconu (<rhadoo_io@yahoo.com>)
|
3
2
|
# License:: Apache License, Version 2.0
|
4
3
|
#
|
5
4
|
|
6
5
|
require 'chef/knife'
|
7
6
|
require 'chef/knife/base_vsphere_command'
|
8
|
-
require '
|
9
|
-
require 'netaddr'
|
7
|
+
require 'chef/knife/search_helper'
|
10
8
|
|
11
9
|
# find vms belonging to pool that match criteria, display specified fields
|
12
10
|
class Chef::Knife::VsphereVmFind < Chef::Knife::BaseVsphereCommand
|
11
|
+
include SearchHelper
|
13
12
|
banner 'knife vsphere vm find'
|
14
13
|
|
14
|
+
VMFOLDER = 'vm'.freeze
|
15
|
+
|
15
16
|
common_options
|
16
17
|
|
18
|
+
# Deprecating
|
17
19
|
option :pool,
|
18
20
|
long: '--pool pool',
|
19
21
|
short: '-h',
|
20
22
|
description: 'Target pool'
|
21
|
-
|
23
|
+
# Deprecating
|
22
24
|
option :poolpath,
|
23
25
|
long: '--pool-path',
|
24
26
|
description: 'Pool is full-path'
|
@@ -55,10 +57,6 @@ class Chef::Knife::VsphereVmFind < Chef::Knife::BaseVsphereCommand
|
|
55
57
|
long: '--ip',
|
56
58
|
description: 'Show primary ip'
|
57
59
|
|
58
|
-
option :ips,
|
59
|
-
long: '--ips',
|
60
|
-
description: 'Show all ips, with networks - DEPRECATED use --networks'
|
61
|
-
|
62
60
|
option :networks,
|
63
61
|
long: '--networks',
|
64
62
|
description: 'Show all networks with their IPs'
|
@@ -83,6 +81,10 @@ class Chef::Knife::VsphereVmFind < Chef::Knife::BaseVsphereCommand
|
|
83
81
|
long: '--match-name VMNAME',
|
84
82
|
description: 'match name'
|
85
83
|
|
84
|
+
option :matchtools,
|
85
|
+
long: '--match-tools TOOLSSTATE',
|
86
|
+
description: 'match tools state'
|
87
|
+
|
86
88
|
option :hostname,
|
87
89
|
long: '--hostname',
|
88
90
|
description: 'show hostname of the guest'
|
@@ -103,189 +105,145 @@ class Chef::Knife::VsphereVmFind < Chef::Knife::BaseVsphereCommand
|
|
103
105
|
long: '--tools',
|
104
106
|
description: 'show tools status'
|
105
107
|
|
106
|
-
option :matchtools,
|
107
|
-
long: '--match-tools TOOLSSTATE',
|
108
|
-
description: 'match tools state'
|
109
|
-
|
110
108
|
option :full_path,
|
111
109
|
long: '--full-path',
|
112
|
-
description: 'Show full path'
|
110
|
+
description: 'Show full folder path to the VM'
|
113
111
|
|
114
|
-
|
112
|
+
option :short_path,
|
113
|
+
long: '--short-path',
|
114
|
+
description: 'Show the VM\'s enclosing folder name'
|
115
115
|
|
116
|
-
|
117
|
-
# @param folder [RbVmomi::VIM::Folder] the folder from which to start the search, most likely dc.hostFolder
|
118
|
-
# @param objectname [String] name of the object (pool or cluster/compute) to find
|
119
|
-
# @return [RbVmomi::VIM::ClusterComputeResource, RbVmomi::VIM::ComputeResource, RbVmomi::VIM::ResourcePool]
|
120
|
-
def traverse_folders_for_pool_clustercompute(folder, objectname)
|
121
|
-
children = find_all_in_folder(folder, RbVmomi::VIM::ManagedObject)
|
122
|
-
children.each do |child|
|
123
|
-
next unless child.class == RbVmomi::VIM::ClusterComputeResource || child.class == RbVmomi::VIM::ComputeResource || child.class == RbVmomi::VIM::ResourcePool
|
124
|
-
if child.name == objectname
|
125
|
-
return child
|
126
|
-
elsif child.class == RbVmomi::VIM::Folder || child.class == RbVmomi::VIM::ComputeResource || child.class == RbVmomi::VIM::ClusterComputeResource || child.class == RbVmomi::VIM::ResourcePool
|
127
|
-
pool = traverse_folders_for_pool_clustercompute(child, objectname)
|
128
|
-
end
|
129
|
-
return pool if pool
|
130
|
-
end
|
131
|
-
false
|
132
|
-
end
|
116
|
+
$stdout.sync = true # smoother output from print
|
133
117
|
|
134
118
|
# Main entry point to the command
|
135
119
|
def run
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
output = vm_list.map do |vm|
|
161
|
-
thisvm = {}
|
162
|
-
if get_config(:matchname)
|
163
|
-
next unless vm.name.include? config[:matchname]
|
164
|
-
end
|
165
|
-
|
166
|
-
if get_config(:matchtools)
|
167
|
-
next unless vm.guest.toolsStatus == config[:matchtools]
|
168
|
-
end
|
169
|
-
|
170
|
-
power_state = vm.runtime.powerState
|
171
|
-
|
172
|
-
thisvm['state'] = case power_state
|
173
|
-
when PS_ON
|
174
|
-
'on'
|
175
|
-
when PS_OFF
|
176
|
-
'off'
|
177
|
-
when PS_SUSPENDED
|
178
|
-
'suspended'
|
179
|
-
end
|
180
|
-
|
181
|
-
|
182
|
-
next if get_config(:soff) && (power_state == PS_ON)
|
183
|
-
|
184
|
-
next if get_config(:son) && (power_state == PS_OFF)
|
185
|
-
|
186
|
-
if get_config(:matchip)
|
187
|
-
if !vm.guest.ipAddress.nil? && vm.guest.ipAddress != ''
|
188
|
-
next unless vm.guest.ipAddress.include? config[:matchip]
|
189
|
-
else
|
190
|
-
next
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
unless vm.guest.guestFullName.nil?
|
195
|
-
if get_config(:matchos)
|
196
|
-
next unless vm.guest.guestFullName.include? config[:matchos]
|
120
|
+
property_map('name' => 'name')
|
121
|
+
property_map('runtime.powerState' => 'state') { |value| state_to_english(value) }
|
122
|
+
|
123
|
+
property_map('config.cpuHotAddEnabled' => 'cpu_hot_add_enabled') if get_config(:cpu_hot_add_enabled)
|
124
|
+
property_map('config.memoryHotAddEnabled' => 'memory_hot_add_enabled') if get_config(:memory_hot_add_enabled)
|
125
|
+
property_map('guest.guestFullName' => 'os') if get_config(:matchos) || get_config(:os)
|
126
|
+
property_map('guest.hostName' => 'hostname') if get_config(:hostname)
|
127
|
+
property_map('guest.ipAddress' => 'ip') if get_config(:matchip) || get_config(:ip)
|
128
|
+
property_map('guest.toolsStatus' => 'tools') if get_config(:matchtools) || get_config(:tools)
|
129
|
+
property_map('summary.config.memorySizeMB' => 'ram') if get_config(:ram)
|
130
|
+
property_map('summary.config.numCpu' => 'cpu') if get_config(:cpu)
|
131
|
+
property_map('summary.overallStatus' => 'alarms') if get_config(:alarms)
|
132
|
+
property_map('summary.runtime.host' => 'host_name', &:name) if get_config(:host_name)
|
133
|
+
|
134
|
+
# TODO: https://www.vmware.com/support/developer/converter-sdk/conv55_apireference/vim.VirtualMachine.html#field_detail says this is deprecated
|
135
|
+
property_map('layout.disk' => 'esx_disk') { |disks| disks.map(&:diskFile) } if get_config(:esx_disk)
|
136
|
+
property_map('snapshot.rootSnapshotList' => 'snapshots') { |snapshots| Array(snapshots).map(&:name) } if get_config(:snapshots)
|
137
|
+
|
138
|
+
if get_config(:networks)
|
139
|
+
property_map('guest.net' => 'networks') do |nets|
|
140
|
+
ipregex = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/
|
141
|
+
nets.map do |net|
|
142
|
+
firstip = net.ipConfig.ipAddress.first { |i| i.ipAddress[ipregex] }
|
143
|
+
{ 'name' => net.network, 'ip' => firstip.ipAddress, 'prefix' => firstip.prefixLength }
|
197
144
|
end
|
198
145
|
end
|
146
|
+
end
|
199
147
|
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
thisvm['host_name'] = vm.summary.runtime.host.name
|
207
|
-
end
|
208
|
-
|
209
|
-
if get_config(:full_path)
|
210
|
-
fullpath = ''
|
211
|
-
iterator = vm
|
212
|
-
|
213
|
-
while iterator = iterator.parent
|
214
|
-
break if iterator.name == 'vm'
|
215
|
-
fullpath = fullpath.empty? ? iterator.name : "#{iterator.name}/#{fullpath}"
|
148
|
+
if get_config(:os_disk)
|
149
|
+
property_map('guest.disk' => 'disks') do |disks|
|
150
|
+
disks.map do |disk|
|
151
|
+
{ 'name' => disk.diskPath,
|
152
|
+
'capacity' => disk.capacity / 1024 / 1024,
|
153
|
+
'free' => disk.freeSpace / 1024 / 1024 }
|
216
154
|
end
|
217
|
-
thisvm['folder'] = fullpath
|
218
|
-
else
|
219
|
-
thisvm['folder'] = vm.parent.name
|
220
155
|
end
|
156
|
+
end
|
221
157
|
|
222
|
-
|
223
|
-
|
158
|
+
output = matched_vms.map do |vm|
|
159
|
+
thisvm = {}
|
160
|
+
@output_pairs.each do |property, out_key|
|
161
|
+
thisvm[out_key] = if @blocks[out_key]
|
162
|
+
@blocks[out_key].call(vm[property])
|
163
|
+
else
|
164
|
+
vm[property]
|
165
|
+
end
|
224
166
|
end
|
225
167
|
|
226
|
-
if get_config(:
|
227
|
-
|
228
|
-
thisvm['networks'] = vm.guest.net.map do |net|
|
229
|
-
firstip = net.ipConfig.ipAddress.first { |i| i.ipAddress[ipregex] }
|
168
|
+
thisvm['folder'] = full_path_to(vm) if get_config(:full_path)
|
169
|
+
thisvm['folder'] = vm.obj.parent.name if get_config(:short_path)
|
230
170
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
end
|
236
|
-
end
|
171
|
+
thisvm
|
172
|
+
end
|
173
|
+
ui.output(output.compact)
|
174
|
+
end
|
237
175
|
|
238
|
-
|
239
|
-
|
240
|
-
|
176
|
+
private
|
177
|
+
|
178
|
+
# property_map sets up the things we'll ask from vmware, and how they'll be displayed
|
179
|
+
# If it's passed a Hash then we'll request the key from vmware and the output will appear
|
180
|
+
# in the item specified by key.
|
181
|
+
# If you pass a block, then the result from vsphere will be passed to the block and that value used instead
|
182
|
+
def property_map(property_pair, &block)
|
183
|
+
@properties ||= []
|
184
|
+
@output_pairs ||= {}
|
185
|
+
@blocks ||= {}
|
186
|
+
|
187
|
+
(prop, out_key) = property_pair.first
|
188
|
+
@properties << prop
|
189
|
+
@output_pairs[prop] = out_key
|
190
|
+
@blocks[out_key] = block if block
|
191
|
+
end
|
241
192
|
|
242
|
-
|
243
|
-
|
244
|
-
|
193
|
+
def matched_vms
|
194
|
+
get_all_vm_objects(properties: @properties).select { |vm| match_vm? vm }
|
195
|
+
end
|
245
196
|
|
246
|
-
|
247
|
-
|
248
|
-
|
197
|
+
def match_vm?(vm)
|
198
|
+
match_name?(vm['name']) &&
|
199
|
+
match_tools?(vm['guest.toolsStatus']) &&
|
200
|
+
match_power_state?(vm['runtime.powerState']) &&
|
201
|
+
match_ip?(vm['guest.ipAddress']) &&
|
202
|
+
match_os?(vm['guest.guestFullName'])
|
203
|
+
end
|
249
204
|
|
250
|
-
|
251
|
-
|
252
|
-
|
205
|
+
def match_name?(name)
|
206
|
+
!get_config(:matchname) || name.include?(get_config(:matchname))
|
207
|
+
end
|
253
208
|
|
254
|
-
|
255
|
-
|
256
|
-
|
209
|
+
def match_tools?(tools)
|
210
|
+
!get_config(:matchtools) || tools == get_config(:matchtools)
|
211
|
+
end
|
257
212
|
|
258
|
-
|
259
|
-
|
260
|
-
|
213
|
+
def match_power_state?(power_state)
|
214
|
+
!(get_config(:son) || get_config(:soff)) ||
|
215
|
+
get_config(:son) && power_state == PS_ON ||
|
216
|
+
get_config(:soff) && power_state == PS_OFF
|
217
|
+
end
|
261
218
|
|
262
|
-
|
263
|
-
|
264
|
-
|
219
|
+
def match_ip?(ip)
|
220
|
+
ip ||= 'NOTANIP'
|
221
|
+
!get_config(:matchip) || ip.include?(get_config(:matchip))
|
222
|
+
end
|
265
223
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
'capacity' => disk.capacity / 1024 / 1024,
|
270
|
-
'free' => disk.freeSpace / 1024 / 1024
|
271
|
-
}
|
272
|
-
end
|
273
|
-
end
|
224
|
+
def match_os?(os)
|
225
|
+
!get_config(:matchos) || (os && os.include?(get_config(:matchos)))
|
226
|
+
end
|
274
227
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
228
|
+
def state_to_english(power_state)
|
229
|
+
case power_state
|
230
|
+
when PS_ON
|
231
|
+
'on'
|
232
|
+
when PS_OFF
|
233
|
+
'off'
|
234
|
+
when PS_SUSPENDED
|
235
|
+
'suspended'
|
236
|
+
end
|
237
|
+
end
|
279
238
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
end
|
287
|
-
thisvm
|
239
|
+
def full_path_to(vm)
|
240
|
+
path = []
|
241
|
+
iterator = vm.obj
|
242
|
+
while (iterator = iterator.parent)
|
243
|
+
break if iterator.name == VMFOLDER
|
244
|
+
path.unshift iterator.name
|
288
245
|
end
|
289
|
-
|
246
|
+
|
247
|
+
path.join '/'
|
290
248
|
end
|
291
249
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-vsphere
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ezra Pagel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: knife-windows
|
@@ -237,7 +237,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
237
237
|
version: '0'
|
238
238
|
requirements: []
|
239
239
|
rubyforge_project:
|
240
|
-
rubygems_version: 2.6.
|
240
|
+
rubygems_version: 2.6.11
|
241
241
|
signing_key:
|
242
242
|
specification_version: 4
|
243
243
|
summary: vSphere Support for Knife
|