nv-client 1.66.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in nventory-client.gemspec
4
+ gemspec
data/README ADDED
@@ -0,0 +1,5 @@
1
+ version 1.66.0 of the nVentory ruby client.
2
+
3
+ You'll need to create an /etc/nventory.conf or $HOME/.nventory.conf with at least the following parameter:
4
+
5
+ server = http://nventory.myserver.com
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
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
+