knife-vsphere 0.9.6 → 0.9.7
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/base_vsphere_command.rb +324 -311
- data/lib/knife-vsphere/version.rb +1 -1
- metadata +45 -38
@@ -1,311 +1,324 @@
|
|
1
|
-
#
|
2
|
-
# Author:: Ezra Pagel (<ezra@cpan.org>)
|
3
|
-
# Contributor:: Jesse Campbell (<hikeit@gmail.com>)
|
4
|
-
# License:: Apache License, Version 2.0
|
5
|
-
#
|
6
|
-
|
7
|
-
require 'chef/knife'
|
8
|
-
require 'rbvmomi'
|
9
|
-
|
10
|
-
# Base class for vsphere knife commands
|
11
|
-
class Chef
|
12
|
-
class Knife
|
13
|
-
class BaseVsphereCommand < Knife
|
14
|
-
|
15
|
-
deps do
|
16
|
-
require 'chef/knife/bootstrap'
|
17
|
-
Chef::Knife::Bootstrap.load_deps
|
18
|
-
require 'fog'
|
19
|
-
require 'socket'
|
20
|
-
require 'net/ssh/multi'
|
21
|
-
require 'readline'
|
22
|
-
require 'chef/json_compat'
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.get_common_options
|
26
|
-
unless defined? $default
|
27
|
-
$default = Hash.new
|
28
|
-
end
|
29
|
-
|
30
|
-
option :vsphere_user,
|
31
|
-
:short => "-u USERNAME",
|
32
|
-
:long => "--vsuser USERNAME",
|
33
|
-
:description => "The username for vsphere"
|
34
|
-
|
35
|
-
option :vsphere_pass,
|
36
|
-
:short => "-p PASSWORD",
|
37
|
-
:long => "--vspass PASSWORD",
|
38
|
-
:description => "The password for vsphere"
|
39
|
-
|
40
|
-
option :vsphere_host,
|
41
|
-
:long => "--vshost HOST",
|
42
|
-
:description => "The vsphere host"
|
43
|
-
|
44
|
-
option :vsphere_dc,
|
45
|
-
:short => "-d DATACENTER",
|
46
|
-
:long => "--vsdc DATACENTER",
|
47
|
-
:description => "The Datacenter for vsphere"
|
48
|
-
|
49
|
-
option :vsphere_path,
|
50
|
-
:long => "--vspath SOAP_PATH",
|
51
|
-
:description => "The vsphere SOAP endpoint path"
|
52
|
-
$default[:vsphere_path] = "/sdk"
|
53
|
-
|
54
|
-
option :vsphere_port,
|
55
|
-
:long => "--vsport PORT",
|
56
|
-
:description => "The VI SDK port number to use"
|
57
|
-
$default[:vsphere_port] = 443
|
58
|
-
|
59
|
-
option :vshere_nossl,
|
60
|
-
:long => "--vsnossl",
|
61
|
-
:description => "Disable SSL connectivity"
|
62
|
-
|
63
|
-
option :vsphere_insecure,
|
64
|
-
:long => "--vsinsecure",
|
65
|
-
:description => "Disable SSL certificate verification"
|
66
|
-
|
67
|
-
option :folder,
|
68
|
-
:short => "-f FOLDER",
|
69
|
-
:long => "--folder FOLDER",
|
70
|
-
:description => "The folder to get VMs from"
|
71
|
-
|
72
|
-
option :proxy_host,
|
73
|
-
:long => '--proxyhost PROXY_HOSTNAME',
|
74
|
-
:description => 'Proxy hostname'
|
75
|
-
|
76
|
-
option :proxy_port,
|
77
|
-
:long => '--proxyport PROXY_PORT',
|
78
|
-
:description => 'Proxy port'
|
79
|
-
|
80
|
-
$default[:folder] = ''
|
81
|
-
end
|
82
|
-
|
83
|
-
def get_config(key)
|
84
|
-
key = key.to_sym
|
85
|
-
rval = config[key] || Chef::Config[:knife][key] || $default[key]
|
86
|
-
Chef::Log.debug("value for config item #{key}: #{rval}")
|
87
|
-
rval
|
88
|
-
end
|
89
|
-
|
90
|
-
def get_vim_connection
|
91
|
-
|
92
|
-
conn_opts = {
|
93
|
-
:host => get_config(:vsphere_host),
|
94
|
-
:path => get_config(:vshere_path),
|
95
|
-
:port => get_config(:vsphere_port),
|
96
|
-
:use_ssl => !get_config(:vsphere_nossl),
|
97
|
-
:user => get_config(:vsphere_user),
|
98
|
-
:password => get_config(:vsphere_pass),
|
99
|
-
:insecure => get_config(:vsphere_insecure),
|
100
|
-
:proxyHost => get_config(:proxy_host),
|
101
|
-
:proxyPort => get_config(:proxy_port)
|
102
|
-
}
|
103
|
-
|
104
|
-
# Grab the password from the command line
|
105
|
-
# if tt is not in the config file
|
106
|
-
if not conn_opts[:password]
|
107
|
-
conn_opts[:password] = get_password
|
108
|
-
end
|
109
|
-
|
110
|
-
# opt :debug, "Log SOAP messages", :short => 'd', :default => (ENV['RBVMOMI_DEBUG'] || false)
|
111
|
-
|
112
|
-
vim = RbVmomi::VIM.connect conn_opts
|
113
|
-
config[:vim] = vim
|
114
|
-
return vim
|
115
|
-
end
|
116
|
-
|
117
|
-
def get_password
|
118
|
-
@password ||= ui.ask("Enter your password: ") { |q| q.echo = false }
|
119
|
-
end
|
120
|
-
|
121
|
-
def get_vm(vmname)
|
122
|
-
vim = get_vim_connection
|
123
|
-
baseFolder = find_folder(get_config(:folder));
|
124
|
-
retval = traverse_folders_for_vm(baseFolder, vmname)
|
125
|
-
return retval
|
126
|
-
end
|
127
|
-
|
128
|
-
def traverse_folders_for_vm(folder, vmname)
|
129
|
-
# not sure why @vm is necessary, but it returns class Array
|
130
|
-
# instead of class VirtualMachine without it... ugh
|
131
|
-
@vm = nil
|
132
|
-
folders = find_all_in_folder(folder, RbVmomi::VIM::Folder)
|
133
|
-
folders.each do |child|
|
134
|
-
traverse_folders_for_vm(child, vmname)
|
135
|
-
vms = find_all_in_folder(folder, RbVmomi::VIM::VirtualMachine)
|
136
|
-
vms.each do |vm|
|
137
|
-
if vm.name == vmname
|
138
|
-
@vm = vm
|
139
|
-
return @vm
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
return @vm
|
144
|
-
end
|
145
|
-
|
146
|
-
def
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
end
|
163
|
-
|
164
|
-
def
|
165
|
-
dc = get_datacenter
|
166
|
-
baseEntity = dc.
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
def
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
end
|
251
|
-
|
252
|
-
end
|
253
|
-
|
254
|
-
def
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
1
|
+
#
|
2
|
+
# Author:: Ezra Pagel (<ezra@cpan.org>)
|
3
|
+
# Contributor:: Jesse Campbell (<hikeit@gmail.com>)
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'chef/knife'
|
8
|
+
require 'rbvmomi'
|
9
|
+
|
10
|
+
# Base class for vsphere knife commands
|
11
|
+
class Chef
|
12
|
+
class Knife
|
13
|
+
class BaseVsphereCommand < Knife
|
14
|
+
|
15
|
+
deps do
|
16
|
+
require 'chef/knife/bootstrap'
|
17
|
+
Chef::Knife::Bootstrap.load_deps
|
18
|
+
require 'fog'
|
19
|
+
require 'socket'
|
20
|
+
require 'net/ssh/multi'
|
21
|
+
require 'readline'
|
22
|
+
require 'chef/json_compat'
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.get_common_options
|
26
|
+
unless defined? $default
|
27
|
+
$default = Hash.new
|
28
|
+
end
|
29
|
+
|
30
|
+
option :vsphere_user,
|
31
|
+
:short => "-u USERNAME",
|
32
|
+
:long => "--vsuser USERNAME",
|
33
|
+
:description => "The username for vsphere"
|
34
|
+
|
35
|
+
option :vsphere_pass,
|
36
|
+
:short => "-p PASSWORD",
|
37
|
+
:long => "--vspass PASSWORD",
|
38
|
+
:description => "The password for vsphere"
|
39
|
+
|
40
|
+
option :vsphere_host,
|
41
|
+
:long => "--vshost HOST",
|
42
|
+
:description => "The vsphere host"
|
43
|
+
|
44
|
+
option :vsphere_dc,
|
45
|
+
:short => "-d DATACENTER",
|
46
|
+
:long => "--vsdc DATACENTER",
|
47
|
+
:description => "The Datacenter for vsphere"
|
48
|
+
|
49
|
+
option :vsphere_path,
|
50
|
+
:long => "--vspath SOAP_PATH",
|
51
|
+
:description => "The vsphere SOAP endpoint path"
|
52
|
+
$default[:vsphere_path] = "/sdk"
|
53
|
+
|
54
|
+
option :vsphere_port,
|
55
|
+
:long => "--vsport PORT",
|
56
|
+
:description => "The VI SDK port number to use"
|
57
|
+
$default[:vsphere_port] = 443
|
58
|
+
|
59
|
+
option :vshere_nossl,
|
60
|
+
:long => "--vsnossl",
|
61
|
+
:description => "Disable SSL connectivity"
|
62
|
+
|
63
|
+
option :vsphere_insecure,
|
64
|
+
:long => "--vsinsecure",
|
65
|
+
:description => "Disable SSL certificate verification"
|
66
|
+
|
67
|
+
option :folder,
|
68
|
+
:short => "-f FOLDER",
|
69
|
+
:long => "--folder FOLDER",
|
70
|
+
:description => "The folder to get VMs from"
|
71
|
+
|
72
|
+
option :proxy_host,
|
73
|
+
:long => '--proxyhost PROXY_HOSTNAME',
|
74
|
+
:description => 'Proxy hostname'
|
75
|
+
|
76
|
+
option :proxy_port,
|
77
|
+
:long => '--proxyport PROXY_PORT',
|
78
|
+
:description => 'Proxy port'
|
79
|
+
|
80
|
+
$default[:folder] = ''
|
81
|
+
end
|
82
|
+
|
83
|
+
def get_config(key)
|
84
|
+
key = key.to_sym
|
85
|
+
rval = config[key] || Chef::Config[:knife][key] || $default[key]
|
86
|
+
Chef::Log.debug("value for config item #{key}: #{rval}")
|
87
|
+
rval
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_vim_connection
|
91
|
+
|
92
|
+
conn_opts = {
|
93
|
+
:host => get_config(:vsphere_host),
|
94
|
+
:path => get_config(:vshere_path),
|
95
|
+
:port => get_config(:vsphere_port),
|
96
|
+
:use_ssl => !get_config(:vsphere_nossl),
|
97
|
+
:user => get_config(:vsphere_user),
|
98
|
+
:password => get_config(:vsphere_pass),
|
99
|
+
:insecure => get_config(:vsphere_insecure),
|
100
|
+
:proxyHost => get_config(:proxy_host),
|
101
|
+
:proxyPort => get_config(:proxy_port)
|
102
|
+
}
|
103
|
+
|
104
|
+
# Grab the password from the command line
|
105
|
+
# if tt is not in the config file
|
106
|
+
if not conn_opts[:password]
|
107
|
+
conn_opts[:password] = get_password
|
108
|
+
end
|
109
|
+
|
110
|
+
# opt :debug, "Log SOAP messages", :short => 'd', :default => (ENV['RBVMOMI_DEBUG'] || false)
|
111
|
+
|
112
|
+
vim = RbVmomi::VIM.connect conn_opts
|
113
|
+
config[:vim] = vim
|
114
|
+
return vim
|
115
|
+
end
|
116
|
+
|
117
|
+
def get_password
|
118
|
+
@password ||= ui.ask("Enter your password: ") { |q| q.echo = false }
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_vm(vmname)
|
122
|
+
vim = get_vim_connection
|
123
|
+
baseFolder = find_folder(get_config(:folder));
|
124
|
+
retval = traverse_folders_for_vm(baseFolder, vmname)
|
125
|
+
return retval
|
126
|
+
end
|
127
|
+
|
128
|
+
def traverse_folders_for_vm(folder, vmname)
|
129
|
+
# not sure why @vm is necessary, but it returns class Array
|
130
|
+
# instead of class VirtualMachine without it... ugh
|
131
|
+
@vm = nil
|
132
|
+
folders = find_all_in_folder(folder, RbVmomi::VIM::Folder)
|
133
|
+
folders.each do |child|
|
134
|
+
traverse_folders_for_vm(child, vmname)
|
135
|
+
vms = find_all_in_folder(folder, RbVmomi::VIM::VirtualMachine)
|
136
|
+
vms.each do |vm|
|
137
|
+
if vm.name == vmname
|
138
|
+
@vm = vm
|
139
|
+
return @vm
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
return @vm
|
144
|
+
end
|
145
|
+
|
146
|
+
def traverse_folders_for_dc(folder, dcname)
|
147
|
+
children = folder.children.find_all
|
148
|
+
children.each do |child|
|
149
|
+
if child.class == RbVmomi::VIM::Datacenter && child.name == dcname
|
150
|
+
return child
|
151
|
+
elsif child.class == RbVmomi::VIM::Folder
|
152
|
+
dc = traverse_folders_for_dc(child, dcname)
|
153
|
+
if dc then return dc end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
return false
|
157
|
+
end
|
158
|
+
|
159
|
+
def get_datacenter
|
160
|
+
dcname = get_config(:vsphere_dc)
|
161
|
+
traverse_folders_for_dc(config[:vim].rootFolder, dcname) or abort "datacenter not found"
|
162
|
+
end
|
163
|
+
|
164
|
+
def find_folder(folderName)
|
165
|
+
dc = get_datacenter
|
166
|
+
baseEntity = dc.vmFolder
|
167
|
+
entityArray = folderName.split('/')
|
168
|
+
entityArray.each do |entityArrItem|
|
169
|
+
if entityArrItem != ''
|
170
|
+
baseEntity = baseEntity.childEntity.grep(RbVmomi::VIM::Folder).find { |f| f.name == entityArrItem } or
|
171
|
+
abort "no such folder #{folderName} while looking for #{entityArrItem}"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
baseEntity
|
175
|
+
end
|
176
|
+
|
177
|
+
def find_network(networkName)
|
178
|
+
dc = get_datacenter
|
179
|
+
baseEntity = dc.network
|
180
|
+
baseEntity.find { |f| f.name == networkName } or abort "no such network #{networkName}"
|
181
|
+
end
|
182
|
+
|
183
|
+
def find_pool(poolName)
|
184
|
+
dc = get_datacenter
|
185
|
+
baseEntity = dc.hostFolder
|
186
|
+
entityArray = poolName.split('/')
|
187
|
+
entityArray.each do |entityArrItem|
|
188
|
+
if entityArrItem != ''
|
189
|
+
if baseEntity.is_a? RbVmomi::VIM::Folder
|
190
|
+
baseEntity = baseEntity.childEntity.find { |f| f.name == entityArrItem } or
|
191
|
+
abort "no such pool #{poolName} while looking for #{entityArrItem}"
|
192
|
+
elsif baseEntity.is_a? RbVmomi::VIM::ClusterComputeResource or baseEntity.is_a? RbVmomi::VIM::ComputeResource
|
193
|
+
baseEntity = baseEntity.resourcePool.resourcePool.find { |f| f.name == entityArrItem } or
|
194
|
+
abort "no such pool #{poolName} while looking for #{entityArrItem}"
|
195
|
+
elsif baseEntity.is_a? RbVmomi::VIM::ResourcePool
|
196
|
+
baseEntity = baseEntity.resourcePool.find { |f| f.name == entityArrItem } or
|
197
|
+
abort "no such pool #{poolName} while looking for #{entityArrItem}"
|
198
|
+
else
|
199
|
+
abort "Unexpected Object type encountered #{baseEntity.type} while finding resourcePool"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
baseEntity = baseEntity.resourcePool if not baseEntity.is_a?(RbVmomi::VIM::ResourcePool) and baseEntity.respond_to?(:resourcePool)
|
205
|
+
baseEntity
|
206
|
+
end
|
207
|
+
|
208
|
+
def choose_datastore(dstores, size)
|
209
|
+
vmdk_size_kb = size.to_i * 1024 * 1024
|
210
|
+
vmdk_size_B = size.to_i * 1024 * 1024 * 1024
|
211
|
+
|
212
|
+
candidates = []
|
213
|
+
dstores.each do |store|
|
214
|
+
avail = number_to_human_size(store.summary[:freeSpace])
|
215
|
+
cap = number_to_human_size(store.summary[:capacity])
|
216
|
+
puts "#{ui.color("Datastore", :cyan)}: #{store.name} (#{avail}(#{store.summary[:freeSpace]}) / #{cap})"
|
217
|
+
|
218
|
+
# vm's can span multiple datastores, so instead of grabbing the first one
|
219
|
+
# let's find the first datastore with the available space on a LUN the vm
|
220
|
+
# is already using, or use a specified LUN (if given)
|
221
|
+
|
222
|
+
|
223
|
+
if (store.summary[:freeSpace] - vmdk_size_B) > 0
|
224
|
+
# also let's not use more than 90% of total space to save room for snapshots.
|
225
|
+
cap_remains = 100 * ((store.summary[:freeSpace].to_f - vmdk_size_B.to_f) / store.summary[:capacity].to_f)
|
226
|
+
if (cap_remains.to_i > 10)
|
227
|
+
candidates.push(store)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
if candidates.length > 0
|
232
|
+
vmdk_datastore = candidates[0]
|
233
|
+
else
|
234
|
+
puts "Insufficient space on all LUNs designated or assigned to the virtual machine. Please specify a new target."
|
235
|
+
vmdk_datastore = nil
|
236
|
+
end
|
237
|
+
return vmdk_datastore
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
def find_datastores_regex(regex)
|
242
|
+
stores = Array.new()
|
243
|
+
puts "Looking for all datastores that match /#{regex}/"
|
244
|
+
dc = get_datacenter
|
245
|
+
baseEntity = dc.datastore
|
246
|
+
baseEntity.each do |ds|
|
247
|
+
if ds.name.match /#{regex}/
|
248
|
+
stores.push ds
|
249
|
+
end
|
250
|
+
end
|
251
|
+
return stores
|
252
|
+
end
|
253
|
+
|
254
|
+
def find_datastore(dsName)
|
255
|
+
dc = get_datacenter
|
256
|
+
baseEntity = dc.datastore
|
257
|
+
baseEntity.find { |f| f.info.name == dsName } or abort "no such datastore #{dsName}"
|
258
|
+
end
|
259
|
+
|
260
|
+
def find_device(vm, deviceName)
|
261
|
+
vm.config.hardware.device.each do |device|
|
262
|
+
return device if device.deviceInfo.label == deviceName
|
263
|
+
end
|
264
|
+
nil
|
265
|
+
end
|
266
|
+
|
267
|
+
def find_all_in_folder(folder, type)
|
268
|
+
if folder.instance_of?(RbVmomi::VIM::ClusterComputeResource) or folder.instance_of?(RbVmomi::VIM::ComputeResource)
|
269
|
+
folder = folder.resourcePool
|
270
|
+
end
|
271
|
+
if folder.instance_of?(RbVmomi::VIM::ResourcePool)
|
272
|
+
folder.resourcePool.grep(type)
|
273
|
+
elsif folder.instance_of?(RbVmomi::VIM::Folder)
|
274
|
+
folder.childEntity.grep(type)
|
275
|
+
else
|
276
|
+
puts "Unknown type #{folder.class}, not enumerating"
|
277
|
+
nil
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
def find_in_folder(folder, type, name)
|
282
|
+
folder.childEntity.grep(type).find { |o| o.name == name }
|
283
|
+
end
|
284
|
+
|
285
|
+
def fatal_exit(msg)
|
286
|
+
ui.fatal(msg)
|
287
|
+
exit 1
|
288
|
+
end
|
289
|
+
|
290
|
+
def tcp_test_port_vm(vm, port)
|
291
|
+
ip = vm.guest.ipAddress
|
292
|
+
if ip.nil?
|
293
|
+
sleep 2
|
294
|
+
return false
|
295
|
+
end
|
296
|
+
tcp_test_port(ip, port)
|
297
|
+
end
|
298
|
+
|
299
|
+
def tcp_test_port(hostname, port)
|
300
|
+
tcp_socket = TCPSocket.new(hostname, port)
|
301
|
+
readable = IO.select([tcp_socket], nil, nil, 5)
|
302
|
+
if readable
|
303
|
+
Chef::Log.debug("sshd accepting connections on #{hostname}, banner is #{tcp_socket.gets}") if port == 22
|
304
|
+
true
|
305
|
+
else
|
306
|
+
false
|
307
|
+
end
|
308
|
+
rescue Errno::ETIMEDOUT
|
309
|
+
false
|
310
|
+
rescue Errno::EPERM
|
311
|
+
false
|
312
|
+
rescue Errno::ECONNREFUSED
|
313
|
+
sleep 2
|
314
|
+
false
|
315
|
+
rescue Errno::EHOSTUNREACH, Errno::ENETUNREACH
|
316
|
+
sleep 2
|
317
|
+
false
|
318
|
+
ensure
|
319
|
+
tcp_socket && tcp_socket.close
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
metadata
CHANGED
@@ -1,56 +1,60 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-vsphere
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.6
|
3
|
+
version: !ruby/object:Gem::Version
|
5
4
|
prerelease:
|
5
|
+
version: 0.9.7
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Ezra Pagel
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
12
|
+
|
13
|
+
date: 2013-12-09 00:00:00 -06:00
|
13
14
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
16
17
|
name: netaddr
|
17
|
-
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
18
20
|
none: false
|
19
|
-
requirements:
|
21
|
+
requirements:
|
20
22
|
- - ~>
|
21
|
-
- !ruby/object:Gem::Version
|
23
|
+
- !ruby/object:Gem::Version
|
22
24
|
version: 1.5.0
|
23
25
|
type: :runtime
|
24
|
-
|
25
|
-
|
26
|
-
- !ruby/object:Gem::Dependency
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
27
28
|
name: chef
|
28
|
-
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
29
31
|
none: false
|
30
|
-
requirements:
|
31
|
-
- -
|
32
|
-
- !ruby/object:Gem::Version
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
33
35
|
version: 0.10.0
|
34
36
|
type: :runtime
|
35
|
-
|
36
|
-
|
37
|
-
- !ruby/object:Gem::Dependency
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
38
39
|
name: rbvmomi
|
39
|
-
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
40
42
|
none: false
|
41
|
-
requirements:
|
43
|
+
requirements:
|
42
44
|
- - ~>
|
43
|
-
- !ruby/object:Gem::Version
|
45
|
+
- !ruby/object:Gem::Version
|
44
46
|
version: 1.5.1
|
45
47
|
type: :runtime
|
46
|
-
|
47
|
-
version_requirements: *70243821492260
|
48
|
+
version_requirements: *id003
|
48
49
|
description: VMware vSphere Support for Chef's Knife Command
|
49
50
|
email: ezra@cpan.org
|
50
51
|
executables: []
|
52
|
+
|
51
53
|
extensions: []
|
54
|
+
|
52
55
|
extra_rdoc_files: []
|
53
|
-
|
56
|
+
|
57
|
+
files:
|
54
58
|
- lib/chef/knife/base_vsphere_command.rb
|
55
59
|
- lib/chef/knife/vshpere_vm_move.rb
|
56
60
|
- lib/chef/knife/vsphere_customization_list.rb
|
@@ -71,28 +75,31 @@ files:
|
|
71
75
|
- lib/knife-vsphere/version.rb
|
72
76
|
has_rdoc: true
|
73
77
|
homepage: http://github.com/ezrapagel/knife-vsphere
|
74
|
-
licenses:
|
78
|
+
licenses:
|
75
79
|
- Apache
|
76
80
|
post_install_message:
|
77
81
|
rdoc_options: []
|
78
|
-
|
82
|
+
|
83
|
+
require_paths:
|
79
84
|
- lib
|
80
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
86
|
none: false
|
82
|
-
requirements:
|
83
|
-
- -
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version:
|
86
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
92
|
none: false
|
88
|
-
requirements:
|
89
|
-
- -
|
90
|
-
- !ruby/object:Gem::Version
|
91
|
-
version:
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: "0"
|
92
97
|
requirements: []
|
98
|
+
|
93
99
|
rubyforge_project:
|
94
100
|
rubygems_version: 1.6.2
|
95
101
|
signing_key:
|
96
102
|
specification_version: 3
|
97
103
|
summary: vSphere Support for Knife
|
98
104
|
test_files: []
|
105
|
+
|