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.
- data/lib/chef/knife/BaseVsphereCommand.rb +46 -48
- data/lib/chef/knife/vsphere_datastore_list.rb +1 -1
- data/lib/chef/knife/vsphere_template_list.rb +1 -1
- data/lib/chef/knife/vsphere_vlan_list.rb +37 -0
- data/lib/chef/knife/vsphere_vm_clone.rb +55 -63
- data/lib/chef/knife/vsphere_vm_delete.rb +46 -19
- data/lib/chef/knife/vsphere_vm_list.rb +41 -15
- data/lib/chef/knife/vsphere_vm_state.rb +1 -1
- data/lib/knife-vsphere/version.rb +1 -1
- metadata +9 -8
|
@@ -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 => "--
|
|
31
|
-
:description => "The username for
|
|
30
|
+
:long => "--vsuser USERNAME",
|
|
31
|
+
:description => "The username for vsphere"
|
|
32
32
|
|
|
33
33
|
option :vsphere_pass,
|
|
34
34
|
:short => "-p PASSWORD",
|
|
35
|
-
:long => "--
|
|
36
|
-
:description => "The password for
|
|
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 :
|
|
42
|
+
option :vsphere_dc,
|
|
39
43
|
:short => "-d DATACENTER",
|
|
40
|
-
:long => "--
|
|
41
|
-
:description => "The Datacenter
|
|
42
|
-
|
|
43
|
-
option :
|
|
44
|
-
:long => "--
|
|
45
|
-
:description => "The SOAP endpoint path"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
71
|
-
|
|
69
|
+
:description => "The folder to get VMs from"
|
|
70
|
+
$default[:folder] = ''
|
|
72
71
|
end
|
|
73
72
|
|
|
74
|
-
def
|
|
73
|
+
def get_config(key)
|
|
75
74
|
key = key.to_sym
|
|
76
|
-
Chef::Config[:knife][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 =>
|
|
83
|
-
:path =>
|
|
84
|
-
:port =>
|
|
85
|
-
:use_ssl =>
|
|
86
|
-
:user =>
|
|
87
|
-
:password =>
|
|
88
|
-
: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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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 =>
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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(
|
|
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] ||
|
|
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
|
|
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
|
|
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
|
|
219
|
-
rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => find_pool(
|
|
212
|
+
if get_config(:resource_pool)
|
|
213
|
+
rspec = RbVmomi::VIM.VirtualMachineRelocateSpec(:pool => find_pool(get_config(:resource_pool)))
|
|
220
214
|
else
|
|
221
|
-
dcname =
|
|
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
|
|
229
|
-
rspec.datastore = find_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
|
|
239
|
-
clone_spec.config.numCPUs =
|
|
232
|
+
if get_config(:customization_cpucount)
|
|
233
|
+
clone_spec.config.numCPUs = get_config(:customization_cpucount)
|
|
240
234
|
end
|
|
241
235
|
|
|
242
|
-
if
|
|
243
|
-
clone_spec.config.memoryMB = Integer(
|
|
236
|
+
if get_config(:customization_memory)
|
|
237
|
+
clone_spec.config.memoryMB = Integer(get_config(:customization_memory)) * 1024
|
|
244
238
|
end
|
|
245
239
|
|
|
246
|
-
if
|
|
247
|
-
network = find_network(
|
|
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
|
|
257
|
-
csi = find_customization(
|
|
258
|
-
fatal_exit("failed to find customization specification named #{
|
|
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
|
|
270
|
-
cust_spec.globalIPSettings.dnsServerList =
|
|
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
|
|
274
|
-
cust_spec.globalIPSettings.dnsSuffixList =
|
|
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
|
|
279
|
-
cust_spec.nicSettingMap = config[:customization_ips].split(',').map { |i| generate_adapter_map(i,
|
|
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? || !
|
|
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
|
|
301
|
-
ident.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] =
|
|
359
|
-
bootstrap.config[:ssh_user] =
|
|
360
|
-
bootstrap.config[:ssh_password] =
|
|
361
|
-
bootstrap.config[:ssh_port] =
|
|
362
|
-
bootstrap.config[:identity_file] =
|
|
363
|
-
bootstrap.config[:chef_node_name] =
|
|
364
|
-
bootstrap.config[:prerelease] =
|
|
365
|
-
bootstrap.config[:bootstrap_version] =
|
|
366
|
-
bootstrap.config[:distro] =
|
|
367
|
-
bootstrap.config[:use_sudo] = true unless
|
|
368
|
-
bootstrap.config[:template_file] =
|
|
369
|
-
bootstrap.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] =
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
def run
|
|
18
|
-
$stdout.sync = true
|
|
41
|
+
vmname = @name_args[0]
|
|
19
42
|
|
|
20
|
-
|
|
43
|
+
if vmname.nil?
|
|
44
|
+
show_usage
|
|
45
|
+
fatal_exit("You must specify a virtual machine name")
|
|
46
|
+
end
|
|
21
47
|
|
|
22
|
-
|
|
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
|
-
|
|
50
|
+
baseFolder = find_folder(get_config(:folder));
|
|
30
51
|
|
|
31
|
-
|
|
32
|
-
|
|
52
|
+
vm = find_in_folder(baseFolder, RbVmomi::VIM::VirtualMachine, vmname) or
|
|
53
|
+
fatal_exit("VM #{vmname} not found")
|
|
33
54
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
11
|
+
banner "knife vsphere vm list"
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def run
|
|
13
|
+
get_common_options
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
option :recursive,
|
|
16
|
+
:long => "--recursive",
|
|
17
|
+
:short => "-r",
|
|
18
|
+
:description => "Recurse down through sub-folders"
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
option :only_folders,
|
|
21
|
+
:long => "--only-folders",
|
|
22
|
+
:description => "Print only sub-folders"
|
|
20
23
|
|
|
21
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
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(
|
|
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"
|
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.
|
|
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-
|
|
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: &
|
|
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: *
|
|
25
|
+
version_requirements: *70231050321420
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: chef
|
|
28
|
-
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: *
|
|
36
|
+
version_requirements: *70231050320800
|
|
37
37
|
- !ruby/object:Gem::Dependency
|
|
38
38
|
name: rbvmomi
|
|
39
|
-
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: *
|
|
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
|