nv-client 1.66.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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README +5 -0
- data/Rakefile +2 -0
- data/bin/nv +709 -0
- data/lib/nv-client.rb +5 -0
- data/lib/nv-client/version.rb +5 -0
- data/lib/nventory.rb +2086 -0
- data/nv-client.gemspec +22 -0
- metadata +85 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README
ADDED
data/Rakefile
ADDED
data/bin/nv
ADDED
|
@@ -0,0 +1,709 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
##############################################################################
|
|
3
|
+
# A client to query a nVentory server
|
|
4
|
+
##############################################################################
|
|
5
|
+
|
|
6
|
+
require 'optparse'
|
|
7
|
+
require 'nventory'
|
|
8
|
+
|
|
9
|
+
# Ensure we have a sane path, particularly since we might be run from
|
|
10
|
+
# cron in registration mode.
|
|
11
|
+
ENV['PATH'] = '/bin:/usr/bin:/sbin:/usr/sbin'
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# Process command line options
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
$objecttype = 'nodes'
|
|
18
|
+
$get = nil
|
|
19
|
+
$exactget = nil
|
|
20
|
+
$regexget = nil
|
|
21
|
+
$and = nil
|
|
22
|
+
$exclude = nil
|
|
23
|
+
$name = nil
|
|
24
|
+
$allfields = nil
|
|
25
|
+
$fields = nil
|
|
26
|
+
$set = nil
|
|
27
|
+
$yes = false
|
|
28
|
+
$getfieldnames = false
|
|
29
|
+
$getallvalues = nil
|
|
30
|
+
$nodegroup = nil
|
|
31
|
+
$nodegroupexpanded = nil
|
|
32
|
+
$createnodegroup = nil
|
|
33
|
+
$addnodegroupnodeassignments = nil
|
|
34
|
+
$addtonodegroup = nil
|
|
35
|
+
$removefromnodegroup = nil
|
|
36
|
+
$addnodegrouptonodegroup = nil
|
|
37
|
+
$addcomment = nil
|
|
38
|
+
$removenodegroupfromnodegroup = nil
|
|
39
|
+
$createtag = nil
|
|
40
|
+
$addtagtonodegroup = nil
|
|
41
|
+
$removetagfromnodegroup = nil
|
|
42
|
+
$register = false
|
|
43
|
+
$username = ENV['LOGNAME']
|
|
44
|
+
$delete = nil
|
|
45
|
+
$showtags = nil
|
|
46
|
+
$withaliases = nil
|
|
47
|
+
$debug = nil
|
|
48
|
+
$dryrun = nil
|
|
49
|
+
$server = nil
|
|
50
|
+
|
|
51
|
+
def singularize(string)
|
|
52
|
+
if string =~ /(.*s)es$/
|
|
53
|
+
singular = $1
|
|
54
|
+
elsif string =~ /(.*)s$/
|
|
55
|
+
singular = $1;
|
|
56
|
+
else
|
|
57
|
+
singular = string
|
|
58
|
+
end
|
|
59
|
+
return singular;
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def opt_hash_parse(opt)
|
|
63
|
+
opthash = {}
|
|
64
|
+
current_field = nil
|
|
65
|
+
opt.split(',').each do |entry|
|
|
66
|
+
if (entry =~ /(.+)=(.+)/)
|
|
67
|
+
current_field = $1
|
|
68
|
+
opthash[current_field] = [$2]
|
|
69
|
+
else
|
|
70
|
+
if current_field
|
|
71
|
+
opthash[current_field] << entry
|
|
72
|
+
else
|
|
73
|
+
abort "Failed to parse '#{opt}' as a series of name=value[,value] pairs"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
opthash
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
opts = OptionParser.new
|
|
81
|
+
opts.banner = 'Usage: nv [options]'
|
|
82
|
+
opts.on('--objecttype object',
|
|
83
|
+
'The type of object to get/set. Defaults to nodes.') do |opt|
|
|
84
|
+
$objecttype = opt
|
|
85
|
+
end
|
|
86
|
+
opts.on('--get [field=value1,value2][,field2=value1[,value2]]') do |opt|
|
|
87
|
+
if opt.nil?
|
|
88
|
+
$get = {}
|
|
89
|
+
else
|
|
90
|
+
$get = opt_hash_parse(opt)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
opts.on('--showtags', 'Lists all tags the node(s) belongs to') do |opt|
|
|
94
|
+
$showtags = opt
|
|
95
|
+
end
|
|
96
|
+
opts.on('--delete', 'Delete the object(s) returned') do |opt|
|
|
97
|
+
$delete = opt
|
|
98
|
+
end
|
|
99
|
+
opts.on('--exactget [field=value1,value2]',
|
|
100
|
+
'Select objects for display or updating. get does a substring',
|
|
101
|
+
'match, exactget does an exact match. Multiple fields and values ',
|
|
102
|
+
'can be specified seperated by commas.') do |opt|
|
|
103
|
+
if opt.nil?
|
|
104
|
+
$exactget = {}
|
|
105
|
+
else
|
|
106
|
+
$exactget = opt_hash_parse(opt)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
opts.on('--regexget [field=value1,value2]',
|
|
110
|
+
'Select objects for display or updating. get does a substring',
|
|
111
|
+
'match, regexget does an regexp match. Multiple fields and values ',
|
|
112
|
+
'can be specified seperated by commas.') do |opt|
|
|
113
|
+
if opt.nil?
|
|
114
|
+
$regexget = {}
|
|
115
|
+
else
|
|
116
|
+
$regexget = opt_hash_parse(opt)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
opts.on('--exclude [field=value1,value2]',
|
|
120
|
+
'Select objects for display or updating. get does a substring',
|
|
121
|
+
'match, exclude does an regexp match. Multiple fields and values ',
|
|
122
|
+
'can be specified seperated by commas.') do |opt|
|
|
123
|
+
if opt.nil?
|
|
124
|
+
$exclude = {}
|
|
125
|
+
else
|
|
126
|
+
$exclude = opt_hash_parse(opt)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
opts.on('--and [field=value1,value2]',
|
|
130
|
+
'when doing get, search AND values on same field',
|
|
131
|
+
'can be specified seperated by commas.') do |opt|
|
|
132
|
+
if opt.nil?
|
|
133
|
+
$and = {}
|
|
134
|
+
else
|
|
135
|
+
$and = opt_hash_parse(opt)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
opts.on('--name value[,value2]', Array,
|
|
139
|
+
'Shortcut for --get name=value') do |opt|
|
|
140
|
+
$name = opt
|
|
141
|
+
end
|
|
142
|
+
opts.on('--addcomment "add your comment here"', Array) do |opt|
|
|
143
|
+
$addcomment = opt
|
|
144
|
+
end
|
|
145
|
+
opts.on('--allfields [excludefield1[,excludefield2]]', Array,
|
|
146
|
+
'Display all fields for selected objects.',
|
|
147
|
+
'One or more fields may be specified to be excluded from the',
|
|
148
|
+
'query, seperate multiple fields with commas.') do |opt|
|
|
149
|
+
if opt.nil?
|
|
150
|
+
$allfields = []
|
|
151
|
+
else
|
|
152
|
+
$allfields = opt
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
opts.on('--fields field1[,field2]', Array,
|
|
156
|
+
'Display the specified fields for selected objects.',
|
|
157
|
+
'One or more fields may be specified, either by specifying this',
|
|
158
|
+
'option multiple times or by seperating the field names with',
|
|
159
|
+
'commas.') do |opt|
|
|
160
|
+
if opt.nil?
|
|
161
|
+
$fields = []
|
|
162
|
+
else
|
|
163
|
+
$fields = opt
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
opts.on('--set field=value1[,value2][,field2=value1[,value2]]',
|
|
167
|
+
'Update fields in objects selected via get/exactget/regexget/exclude, Multiple ',
|
|
168
|
+
'fields and values can be specified seperated by commas.') do |opt|
|
|
169
|
+
$set = opt_hash_parse(opt)
|
|
170
|
+
end
|
|
171
|
+
opts.on('--yes',
|
|
172
|
+
'Don\'t prompt for set confirmation') do |opt|
|
|
173
|
+
$yes = true
|
|
174
|
+
end
|
|
175
|
+
opts.on('--getfieldnames',
|
|
176
|
+
'Shows get/set fields supported by server') do |opt|
|
|
177
|
+
$getfieldnames = true
|
|
178
|
+
end
|
|
179
|
+
opts.on('--getallvalues field1[,field2]', Array,
|
|
180
|
+
'Display all values stored in the database for the specified fields') do |opt|
|
|
181
|
+
$getallvalues = opt
|
|
182
|
+
end
|
|
183
|
+
opts.on('--nodegroup nodegroup', '--ng nodegroup',
|
|
184
|
+
'Display the members of the given node group, member groups are',
|
|
185
|
+
'displayed as groups and are not expanded') do |opt|
|
|
186
|
+
$nodegroup = opt
|
|
187
|
+
end
|
|
188
|
+
opts.on('--nodegroupexpanded nodegroup[,nodegroup2]', '--nge nodegroup', '--get_nodegroup_nodes nodegroup', '--get_ngn nodegroup', Array,
|
|
189
|
+
'Display the members of the given node groups, member groups are',
|
|
190
|
+
'expanded') do |opt|
|
|
191
|
+
$nodegroupexpanded = opt
|
|
192
|
+
end
|
|
193
|
+
opts.on('--createnodegroup nodegroup1[,nodegroup2]', Array,
|
|
194
|
+
'Create one or more node groups') do |opt|
|
|
195
|
+
$createnodegroup = opt
|
|
196
|
+
end
|
|
197
|
+
opts.on('--addnodegroupnodeassignments nodegroup1[,nodegroup2]', Array,
|
|
198
|
+
'Assign nodes selected via get/exactget/regexget/exclude to one or more node groups') do |opt|
|
|
199
|
+
$addnodegroupnodeassignments = opt
|
|
200
|
+
end
|
|
201
|
+
opts.on('--addtonodegroup nodegroup1[,nodegroup2]', Array,
|
|
202
|
+
'Add nodes selected via get/exactget/regexget/exclude to one or more node groups') do |opt|
|
|
203
|
+
$addtonodegroup = opt
|
|
204
|
+
end
|
|
205
|
+
opts.on('--removefromnodegroup nodegroup1[,nodegroup2]', Array,
|
|
206
|
+
'Remove nodes selected via get/exactget/regexget/exclude from one or more node groups') do |opt|
|
|
207
|
+
$removefromnodegroup = opt
|
|
208
|
+
end
|
|
209
|
+
opts.on('--addnodegrouptonodegroup child_group,parent_group', Array,
|
|
210
|
+
'Takes two node group names seperated by a comma, adds the first',
|
|
211
|
+
'node group to the second') do |opt|
|
|
212
|
+
$addnodegrouptonodegroup = [opt[0],opt[1]]
|
|
213
|
+
end
|
|
214
|
+
opts.on('--removenodegroupfromnodegroup child_group,parent_group', Array,
|
|
215
|
+
'Takes two node group names seperated by a comma, removes the first',
|
|
216
|
+
'node group from the second') do |opt|
|
|
217
|
+
$removenodegroupfromnodegroup = [opt[0],opt[1]]
|
|
218
|
+
end
|
|
219
|
+
opts.on('--createtag tagname1[,tagname2]', Array,
|
|
220
|
+
'Create one or more tags by name') do |opt|
|
|
221
|
+
$createtag= opt
|
|
222
|
+
end
|
|
223
|
+
opts.on('--addtagtonodegroup tag,node_group', Array,
|
|
224
|
+
'adds a tag to a node_group') do |opt|
|
|
225
|
+
$addtagtonodegroup = [opt[0],opt[1]]
|
|
226
|
+
end
|
|
227
|
+
opts.on('--removetagfromnodegroup tag,node_group', Array,
|
|
228
|
+
'removes a tag from a node_group') do |opt|
|
|
229
|
+
$removetagfromnodegroup = [opt[0],opt[1]]
|
|
230
|
+
end
|
|
231
|
+
opts.on('--register',
|
|
232
|
+
'Gather as much information as possible about the local machine',
|
|
233
|
+
'and register that information into the nVentory database.') do |opt|
|
|
234
|
+
$register = true
|
|
235
|
+
end
|
|
236
|
+
opts.on('--username value', String,
|
|
237
|
+
'Username to use when authenticating to the server. If not',
|
|
238
|
+
'specified defaults to the current user.') do |opt|
|
|
239
|
+
$username = opt
|
|
240
|
+
end
|
|
241
|
+
opts.on('--server value', String, 'Specify alternate server to query.') do |opt|
|
|
242
|
+
$server = opt
|
|
243
|
+
end
|
|
244
|
+
opts.on('--debug') do |opt|
|
|
245
|
+
$debug = opt
|
|
246
|
+
end
|
|
247
|
+
opts.on('--withaliases') do |opt|
|
|
248
|
+
$withaliases = opt
|
|
249
|
+
end
|
|
250
|
+
opts.on('--dry-run') do |opt|
|
|
251
|
+
$dryrun = opt
|
|
252
|
+
end
|
|
253
|
+
opts.separator ''
|
|
254
|
+
opts.separator('All options can be shortened to anything that\'s unique.')
|
|
255
|
+
opts.on_tail('--help') do
|
|
256
|
+
puts opts
|
|
257
|
+
exit
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
opts.parse(ARGV)
|
|
261
|
+
|
|
262
|
+
(puts opts; exit) unless $get || $exactget || $regexget || $name || $getfieldnames || $getallvalues || $register || $nodegroup || $nodegroupexpanded || $createnodegroup || $addnodegrouptonodegroup || $removenodegroupfromnodegroup || $addtagtonodegroup || $createtag || $removetagfromnodegroup
|
|
263
|
+
# These options are mutually exclusive
|
|
264
|
+
(puts opts; exit) if $allfields && $fields
|
|
265
|
+
(puts opts; exit) if $getfieldnames && ($get || $exactget || $regexget || $name)
|
|
266
|
+
(puts opts; exit) if $getallvalues && ($get || $exactget || $regexget || $name)
|
|
267
|
+
# FIXME: Should support searches on node group membership and other characteristics
|
|
268
|
+
(puts opts; exit) if ($nodegroup || $nodegroupexpanded) && ($get || $exactget || $regexget || $exclude || $name || $and)
|
|
269
|
+
(puts opts; exit) if $register && ($get || $exactget || $regexget || $exclude || $name || $getfieldnames || $getallvalues || $nodegroup || $nodegroupexpanded || $createnodegroup || $addnodegrouptonodegroup || $removenodegroupfromnodegroup || $and || $createtag || $addtagtonodegroup || $removetagfromnodegroup)
|
|
270
|
+
(puts opts; exit) if ($addtonodegroup || $addnodegroupnodeassignments || $removefromnodegroup || $addtagtonodegroup || $removetagfromnodegroup) && $objecttype != 'nodes'
|
|
271
|
+
(puts '--showtags can only be used if objecttype = nodes'; exit) if $showtags && ($objecttype !~ /^(nodes|node_groups)$/)
|
|
272
|
+
|
|
273
|
+
if $name
|
|
274
|
+
$get = {} if !$get
|
|
275
|
+
$get['name'] = $name
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
SEARCH_SHORTCUTS = {
|
|
279
|
+
'hw' => 'hardware_profile[name]',
|
|
280
|
+
'hwmanuf' => 'hardware_profile[manufacturer]',
|
|
281
|
+
'hwmodel' => 'hardware_profile[model]',
|
|
282
|
+
'ip' => 'ip_addresses',
|
|
283
|
+
'ips' => 'ip_addresses',
|
|
284
|
+
'mac' => 'network_interfaces[hardware_address]',
|
|
285
|
+
'macs' => 'network_interfaces[hardware_address]',
|
|
286
|
+
'nic' => 'network_interfaces',
|
|
287
|
+
'nics' => 'network_interfaces',
|
|
288
|
+
'node_group' => 'node_group[name]',
|
|
289
|
+
'node_groups' => 'node_group[name]',
|
|
290
|
+
'os' => 'operating_system[name]',
|
|
291
|
+
'osvendor' => 'operating_system[vendor]',
|
|
292
|
+
'osvariant' => 'operating_system[variant]',
|
|
293
|
+
'osver' => 'operating_system[version_number]',
|
|
294
|
+
'osversion' => 'operating_system[version_number]',
|
|
295
|
+
'osarch' => 'operating_system[architecture]',
|
|
296
|
+
'serial' => 'serial_number',
|
|
297
|
+
'status' => 'status[name]',
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
# Convert any shortcut names to their full names
|
|
301
|
+
if $get
|
|
302
|
+
$get.each_pair do |key,value|
|
|
303
|
+
if SEARCH_SHORTCUTS.has_key?(key)
|
|
304
|
+
$get[SEARCH_SHORTCUTS[key]] = value
|
|
305
|
+
$get.delete(key)
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
if $exactget
|
|
310
|
+
$exactget.each_pair do |key,value|
|
|
311
|
+
if SEARCH_SHORTCUTS.has_key?(key)
|
|
312
|
+
$exactget[SEARCH_SHORTCUTS[key]] = value
|
|
313
|
+
$exactget.delete(key)
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
if $regexget
|
|
318
|
+
$regexget.each_pair do |key,value|
|
|
319
|
+
if SEARCH_SHORTCUTS.has_key?(key)
|
|
320
|
+
$regexget[SEARCH_SHORTCUTS[key]] = value
|
|
321
|
+
$regexget.delete(key)
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
if $exclude
|
|
326
|
+
$exclude.each_pair do |key,value|
|
|
327
|
+
if SEARCH_SHORTCUTS.has_key?(key)
|
|
328
|
+
$exclude[SEARCH_SHORTCUTS[key]] = value
|
|
329
|
+
$exclude.delete(key)
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
if $and
|
|
334
|
+
$and.each_pair do |key,value|
|
|
335
|
+
if SEARCH_SHORTCUTS.has_key?(key)
|
|
336
|
+
$and[SEARCH_SHORTCUTS[key]] = value
|
|
337
|
+
$and.delete(key)
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
if $set
|
|
342
|
+
$set.each_pair do |key,value|
|
|
343
|
+
if SEARCH_SHORTCUTS.has_key?(key)
|
|
344
|
+
$set[SEARCH_SHORTCUTS[key]] = value
|
|
345
|
+
$set.delete(key)
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
if $allfields
|
|
350
|
+
# The ideal behavior here is probably debatable. For now I'm _adding_
|
|
351
|
+
# the expanded value to the list of exclusions, so both the shortcut
|
|
352
|
+
# string and the expanded value are excluded. That allows the user to
|
|
353
|
+
# specify 'os' on the command line and get the probably expected behavior
|
|
354
|
+
# of excluding everything containing 'os' even though 'os' expands to
|
|
355
|
+
# something specific, but also allows them to specify 'hwmanuf' and have
|
|
356
|
+
# it exclude the expanded version of that.
|
|
357
|
+
# Perhaps we should do something like get and exactget?
|
|
358
|
+
$allfields.each do |key|
|
|
359
|
+
if SEARCH_SHORTCUTS.has_key?(key)
|
|
360
|
+
# Replace shortcut with expansion
|
|
361
|
+
#$allfields[$allfields.index(key)] = SEARCH_SHORTCUTS[key]
|
|
362
|
+
# Add expansion
|
|
363
|
+
$allfields << SEARCH_SHORTCUTS[key]
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
if $fields
|
|
368
|
+
$fields.each do |key|
|
|
369
|
+
if SEARCH_SHORTCUTS.has_key?(key)
|
|
370
|
+
$fields[$fields.index(key)] = SEARCH_SHORTCUTS[key]
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
#
|
|
376
|
+
# Perform requested actions
|
|
377
|
+
#
|
|
378
|
+
|
|
379
|
+
nvclient = NVentory::Client.new($debug, $dryrun, nil, $server)
|
|
380
|
+
|
|
381
|
+
# First handle the standalone actions where we perform a single
|
|
382
|
+
# operation and exit.
|
|
383
|
+
|
|
384
|
+
if $getfieldnames
|
|
385
|
+
field_names = nvclient.get_field_names($objecttype)
|
|
386
|
+
field_names.each do |field_name_entry|
|
|
387
|
+
field_name = field_name_entry.split(' ')
|
|
388
|
+
shortcut = nil
|
|
389
|
+
shortcut_field_name = nil
|
|
390
|
+
SEARCH_SHORTCUTS.each_pair do |shortcut, shortcut_field_name|
|
|
391
|
+
if field_name == shortcut_field_name
|
|
392
|
+
field_name_entry << " (#{shortcut})"
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
puts field_name_entry
|
|
396
|
+
end
|
|
397
|
+
exit
|
|
398
|
+
end
|
|
399
|
+
if $register
|
|
400
|
+
nvclient.register
|
|
401
|
+
exit
|
|
402
|
+
end
|
|
403
|
+
if $nodegroup
|
|
404
|
+
getdata = {}
|
|
405
|
+
getdata[:objecttype] = 'node_groups'
|
|
406
|
+
getdata[:exactget] = {'name' => [$nodegroup]}
|
|
407
|
+
getdata[:includes] = ['child_groups', 'nodes']
|
|
408
|
+
results = nvclient.get_objects(getdata)
|
|
409
|
+
matches = results.keys.grep(/\b#{$nodegroup}\b/i)
|
|
410
|
+
matches.size == 1 ? ( $nodegroup = matches.first ) : return
|
|
411
|
+
puts "Child groups:"
|
|
412
|
+
results[$nodegroup]['child_groups'].sort{|a,b| a['name'] <=> b['name']}.each do |child_group|
|
|
413
|
+
puts " #{child_group['name']}"
|
|
414
|
+
end
|
|
415
|
+
puts "===================="
|
|
416
|
+
puts "Real Nodes:"
|
|
417
|
+
if results[$nodegroup]['real_nodes_names']
|
|
418
|
+
results[$nodegroup]['real_nodes_names'].split(",").sort{|a,b| a <=> b}.each do |node|
|
|
419
|
+
puts " #{node}"
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
puts "===================="
|
|
423
|
+
puts "Virtual Nodes:"
|
|
424
|
+
if results[$nodegroup]['virtual_nodes_names']
|
|
425
|
+
results[$nodegroup]['virtual_nodes_names'].split(",").sort{|a,b| a <=> b}.each do |node|
|
|
426
|
+
puts " #{node}"
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
if $createnodegroup
|
|
431
|
+
$createnodegroup.each do |newgroup|
|
|
432
|
+
nvclient.set_objects('node_groups', nil, {'name' => newgroup}, $username)
|
|
433
|
+
end
|
|
434
|
+
exit
|
|
435
|
+
end
|
|
436
|
+
if $addnodegrouptonodegroup
|
|
437
|
+
getdata = {}
|
|
438
|
+
getdata[:objecttype] = 'node_groups'
|
|
439
|
+
getdata[:exactget] = {'name' => [$addnodegrouptonodegroup[0]]}
|
|
440
|
+
child_results = nvclient.get_objects(getdata)
|
|
441
|
+
abort "Child group '#{$addnodegrouptonodegroup[0]}' not found for 'addnodegrouptonodegroup'\n" if (child_results.length != 1)
|
|
442
|
+
getdata = {}
|
|
443
|
+
getdata[:objecttype] = 'node_groups'
|
|
444
|
+
getdata[:exactget] = {'name' => [$addnodegrouptonodegroup[1]]}
|
|
445
|
+
getdata[:includes] = ['child_groups']
|
|
446
|
+
parent_results = nvclient.get_objects(getdata)
|
|
447
|
+
abort "Parent group '#{$addnodegrouptonodegroup[1]}' not found for 'addnodegrouptonodegroup'\n" if (parent_results.length != 1)
|
|
448
|
+
nvclient.add_nodegroups_to_nodegroups(child_results, parent_results, $username)
|
|
449
|
+
exit
|
|
450
|
+
end
|
|
451
|
+
if $removenodegroupfromnodegroup
|
|
452
|
+
getdata = {}
|
|
453
|
+
getdata[:objecttype] = 'node_groups'
|
|
454
|
+
getdata[:exactget] = {'name' => [$removenodegroupfromnodegroup[0]]}
|
|
455
|
+
child_results = nvclient.get_objects(getdata)
|
|
456
|
+
abort "Child group '#{$removenodegroupfromnodegroup[0]}' not found for 'removenodegroupfromnodegroup'\n" if (child_results.length != 1)
|
|
457
|
+
getdata = {}
|
|
458
|
+
getdata[:objecttype] = 'node_groups'
|
|
459
|
+
getdata[:exactget] = {'name' => [$removenodegroupfromnodegroup[1]]}
|
|
460
|
+
getdata[:includes] = ['child_groups']
|
|
461
|
+
parent_results = nvclient.get_objects(getdata)
|
|
462
|
+
abort "Parent group '#{$removenodegroupfromnodegroup[1]}' not found for 'removenodegroupfromnodegroup'\n" if (parent_results.length != 1)
|
|
463
|
+
nvclient.remove_nodegroups_from_nodegroups(child_results, parent_results, $username)
|
|
464
|
+
exit
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
if $createtag
|
|
468
|
+
$createtag.each do |tag|
|
|
469
|
+
nvclient.set_objects('tags', nil, {'name' => tag}, $username)
|
|
470
|
+
end
|
|
471
|
+
exit
|
|
472
|
+
end
|
|
473
|
+
if $addtagtonodegroup
|
|
474
|
+
getdata = {}
|
|
475
|
+
getdata[:objecttype] = 'node_groups'
|
|
476
|
+
getdata[:exactget] = {'name' => [$addtagtonodegroup[1]]}
|
|
477
|
+
ng_results = nvclient.get_objects(getdata)
|
|
478
|
+
abort "Node group '#{$addtagtonodegroup[1]}' not found for 'addtagtonodegroup'\n" if (ng_results.length != 1)
|
|
479
|
+
nvclient.add_tag_to_node_group(ng_results, $addtagtonodegroup[0], $username)
|
|
480
|
+
exit
|
|
481
|
+
end
|
|
482
|
+
if $removetagfromnodegroup
|
|
483
|
+
getdata = {}
|
|
484
|
+
getdata[:objecttype] = 'node_groups'
|
|
485
|
+
getdata[:exactget] = {'name' => [$removetagfromnodegroup[1]]}
|
|
486
|
+
ng_results = nvclient.get_objects(getdata)
|
|
487
|
+
abort "Node group '#{$removetagfromnodegroup[1]}' not found for 'removetagfromnodegroup'\n" if (ng_results.length != 1)
|
|
488
|
+
nvclient.remove_tag_from_node_group(ng_results, $removetagfromnodegroup[0], $username)
|
|
489
|
+
exit
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
# Now handle the general case where we fetch a list of objects and then
|
|
493
|
+
# perform operations on them.
|
|
494
|
+
|
|
495
|
+
# If the user has requested data which lies outside the base object model
|
|
496
|
+
# then we need to tell the server to include that data in the results it
|
|
497
|
+
# sends us.
|
|
498
|
+
# For example, in a 'nodes' search the user requests the
|
|
499
|
+
# 'hardware_profile[name]' field then we need to request that
|
|
500
|
+
# 'hardware_profile' data be included in the results.
|
|
501
|
+
includes = nil
|
|
502
|
+
if $fields
|
|
503
|
+
includes_hash = {}
|
|
504
|
+
$fields.each do |field|
|
|
505
|
+
if field =~ /([^\[]+)\[.+\]/
|
|
506
|
+
includes_hash[$1] = true
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
includes = includes_hash.keys.sort
|
|
510
|
+
elsif $allfields
|
|
511
|
+
includes_hash = {}
|
|
512
|
+
field_names = nvclient.get_field_names($objecttype)
|
|
513
|
+
field_names.each do |field_name_entry|
|
|
514
|
+
field_name, rest = field_name_entry.split(' ')
|
|
515
|
+
if field_name =~ /([^\[]+)\[.+\]/
|
|
516
|
+
includes_hash[$1] = true
|
|
517
|
+
end
|
|
518
|
+
end
|
|
519
|
+
includes = includes_hash.keys.sort
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
results = nil
|
|
523
|
+
names = nil
|
|
524
|
+
if $get || $exactget || $regexget
|
|
525
|
+
$get['enable_aliases'] = 1 if $withaliases
|
|
526
|
+
getdata = {}
|
|
527
|
+
getdata[:objecttype] = $objecttype
|
|
528
|
+
getdata[:get] = $get
|
|
529
|
+
getdata[:exactget] = $exactget
|
|
530
|
+
getdata[:regexget] = $regexget
|
|
531
|
+
getdata[:exclude] = $exclude
|
|
532
|
+
getdata[:and] = $and
|
|
533
|
+
if $showtags
|
|
534
|
+
includes ||= []
|
|
535
|
+
includes.delete('node_groups') if includes.include?('node_groups')
|
|
536
|
+
$fields ||= []
|
|
537
|
+
if $objecttype == 'nodes'
|
|
538
|
+
$fields << 'node_groups[name]' unless $fields.include?('node_groups[name]')
|
|
539
|
+
$fields << 'node_groups[tags][name]' unless $fields.include?('node_groups[tags][name]')
|
|
540
|
+
includes << 'node_groups[tags]' unless includes.include?('node_groups[tags]')
|
|
541
|
+
elsif $objecttype == 'node_groups'
|
|
542
|
+
$fields << 'tags[name]' unless $fields.include?('tags[name]')
|
|
543
|
+
includes << 'tags' unless includes.include?('tags')
|
|
544
|
+
end
|
|
545
|
+
end # if $showtags
|
|
546
|
+
getdata[:includes] = includes
|
|
547
|
+
results = nvclient.get_objects(getdata)
|
|
548
|
+
if $delete
|
|
549
|
+
puts "Deleting objects"
|
|
550
|
+
nvclient.delete_objects($objecttype, results, $username)
|
|
551
|
+
else
|
|
552
|
+
names = results.keys.sort
|
|
553
|
+
end
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
if $addcomment
|
|
557
|
+
objtype = singularize($objecttype)
|
|
558
|
+
results.keys.each do |key|
|
|
559
|
+
nvclient.set_objects('comments', nil,
|
|
560
|
+
{ 'comment' => $addcomment,
|
|
561
|
+
'commentable_id' => results[key]['id'],
|
|
562
|
+
'commentable_type' => objtype.capitalize,
|
|
563
|
+
},
|
|
564
|
+
$username);
|
|
565
|
+
end
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
if $nodegroupexpanded
|
|
569
|
+
names_hash = {}
|
|
570
|
+
$nodegroupexpanded.each do |nge|
|
|
571
|
+
nvclient.get_expanded_nodegroup(nge).each { |name| names_hash[name] = true }
|
|
572
|
+
end
|
|
573
|
+
names = names_hash.keys.sort
|
|
574
|
+
if $allfields || $fields || $getallvalues
|
|
575
|
+
getdata = {}
|
|
576
|
+
getdata[:objecttype] = 'nodes'
|
|
577
|
+
getdata[:exactget] = {'name' => names}
|
|
578
|
+
getdata[:includes] = includes
|
|
579
|
+
results = nvclient.get_objects(getdata)
|
|
580
|
+
end
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
if names && !$delete
|
|
584
|
+
if names.length == 0
|
|
585
|
+
puts "No matching objects"
|
|
586
|
+
exit
|
|
587
|
+
end
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
# The results hash is a complex data structure. This function
|
|
591
|
+
# does its best to render that in a human readable format.
|
|
592
|
+
def fieldprint(fields, value)
|
|
593
|
+
# fields=['name'] => 'name'
|
|
594
|
+
# fields=['status', 'name'] => 'status[name]'
|
|
595
|
+
fieldname = ''
|
|
596
|
+
if fields.length > 0
|
|
597
|
+
fieldname << fields[0]
|
|
598
|
+
if fields.length > 1
|
|
599
|
+
fields[1..-1].each { |f| fieldname << "[#{f}]"}
|
|
600
|
+
end
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
if value.kind_of?(Hash)
|
|
604
|
+
value.each_pair do |subfield, subvalue|
|
|
605
|
+
fieldprint([fields, subfield].flatten, subvalue)
|
|
606
|
+
end
|
|
607
|
+
elsif value.kind_of?(Array)
|
|
608
|
+
value.each do |entry|
|
|
609
|
+
fieldprint(fields, entry)
|
|
610
|
+
end
|
|
611
|
+
elsif ($allfields && !$allfields.any?{|all| fieldname.include?(all)}) || ($fields && $fields.any?{|field| fieldname.include?(field)})
|
|
612
|
+
puts "#{fieldname}: #{value}"
|
|
613
|
+
end
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
if names && !$getallvalues && !$set && !$addtonodegroup && !$addnodegroupnodeassignments && !$removefromnodegroup && !$delete
|
|
617
|
+
names.each do |name|
|
|
618
|
+
puts name
|
|
619
|
+
if $allfields || $fields
|
|
620
|
+
fieldprint([], results[name])
|
|
621
|
+
puts
|
|
622
|
+
end
|
|
623
|
+
end
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
if $getallvalues
|
|
627
|
+
allvalues = {}
|
|
628
|
+
|
|
629
|
+
# FIXME: This is a terribly inefficient implementation
|
|
630
|
+
# A proper implementation would require something on the
|
|
631
|
+
# server side to pull this out of the database efficiently
|
|
632
|
+
names.each do |name|
|
|
633
|
+
results[name].each_pair do |field,value|
|
|
634
|
+
if $getallvalues.include?(field)
|
|
635
|
+
if !allvalues.has_key?(field)
|
|
636
|
+
allvalues[field] = {}
|
|
637
|
+
end
|
|
638
|
+
allvalues[field][value] = true
|
|
639
|
+
end
|
|
640
|
+
end
|
|
641
|
+
end
|
|
642
|
+
|
|
643
|
+
$getallvalues.each do |field|
|
|
644
|
+
puts "#{field}:"
|
|
645
|
+
allvalues.each_pair do |field,valuehash|
|
|
646
|
+
valuehash.keys.sort do |value|
|
|
647
|
+
puts " #{value}"
|
|
648
|
+
end
|
|
649
|
+
end
|
|
650
|
+
puts
|
|
651
|
+
end
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
if $set
|
|
655
|
+
if !$yes
|
|
656
|
+
number_of_matching_entries = names.length
|
|
657
|
+
entrystring = 'entry'
|
|
658
|
+
entrystring = 'entries' if (number_of_matching_entries > 1)
|
|
659
|
+
print "This will update #{number_of_matching_entries} #{entrystring}, continue? [y/N]: "
|
|
660
|
+
|
|
661
|
+
input = $stdin.gets
|
|
662
|
+
if input !~ /^y/i
|
|
663
|
+
puts "Canceled"
|
|
664
|
+
exit
|
|
665
|
+
end
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
nvclient.set_objects($objecttype, results, $set, $username)
|
|
669
|
+
end
|
|
670
|
+
|
|
671
|
+
if $addtonodegroup or $addnodegroupnodeassignments
|
|
672
|
+
getdata = {}
|
|
673
|
+
getdata[:objecttype] = 'node_groups'
|
|
674
|
+
ngnames = $addtonodegroup || $addnodegroupnodeassignments
|
|
675
|
+
getdata[:exactget] = {'name' => ngnames}
|
|
676
|
+
if $addtonodegroup
|
|
677
|
+
getdata[:includes] = ['nodes']
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
nodegroup_results = nvclient.get_objects(getdata)
|
|
681
|
+
if (nodegroup_results.length != ngnames.length)
|
|
682
|
+
warn "Not all requested node groups for 'addtonodegroup' were found:"
|
|
683
|
+
warn "Requested: #{$addtonodegroup.join(',')}"
|
|
684
|
+
warn "Found: #{nodegroup_results.keys.join(',')}"
|
|
685
|
+
abort
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
if $addtonodegroup
|
|
689
|
+
nvclient.add_nodes_to_nodegroups(results, nodegroup_results, $username);
|
|
690
|
+
elsif $addnodegroupnodeassignments
|
|
691
|
+
nvclient.add_node_group_node_assignments(results, nodegroup_results, $username);
|
|
692
|
+
end
|
|
693
|
+
end
|
|
694
|
+
|
|
695
|
+
if $removefromnodegroup
|
|
696
|
+
getdata = {}
|
|
697
|
+
getdata[:objecttype] = 'node_groups'
|
|
698
|
+
getdata[:exactget] = {'name' => $removefromnodegroup}
|
|
699
|
+
getdata[:includes] = ['nodes']
|
|
700
|
+
nodegroup_results = nvclient.get_objects(getdata)
|
|
701
|
+
if (nodegroup_results.length != $removefromnodegroup.length)
|
|
702
|
+
warn "Not all requested node groups for 'removefromnodegroup' were found:"
|
|
703
|
+
warn "Requested: #{$removefromnodegroup.join(',')}"
|
|
704
|
+
warn "Found: #{nodegroup_results.keys.join(',')}"
|
|
705
|
+
abort
|
|
706
|
+
end
|
|
707
|
+
nvclient.remove_nodes_from_nodegroups(results, nodegroup_results, $username);
|
|
708
|
+
end
|
|
709
|
+
|