nventory-client 1.65.4 → 1.67
Sign up to get free protection for your applications and to get access to all the features.
- data/{README → README.md} +1 -1
- data/bin/nv +27 -2
- data/lib/nventory-client/version.rb +1 -1
- data/lib/nventory.rb +255 -58
- data/nventory-client.gemspec +12 -11
- metadata +43 -57
- data/Gemfile +0 -4
data/{README → README.md}
RENAMED
data/bin/nv
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
#!/usr/bin/ruby
|
1
|
+
#!/usr/bin/env ruby
|
2
2
|
##############################################################################
|
3
3
|
# A client to query a nVentory server
|
4
|
+
# $Id: nv 343 2013-02-15 23:09:46Z saltmanm $
|
4
5
|
##############################################################################
|
5
6
|
|
6
7
|
require 'optparse'
|
@@ -35,6 +36,8 @@ $addtonodegroup = nil
|
|
35
36
|
$removefromnodegroup = nil
|
36
37
|
$addnodegrouptonodegroup = nil
|
37
38
|
$addcomment = nil
|
39
|
+
$addgraffiti= nil
|
40
|
+
$deletegraffiti = nil
|
38
41
|
$removenodegroupfromnodegroup = nil
|
39
42
|
$createtag = nil
|
40
43
|
$addtagtonodegroup = nil
|
@@ -59,6 +62,10 @@ def singularize(string)
|
|
59
62
|
return singular;
|
60
63
|
end
|
61
64
|
|
65
|
+
def camelize(string)
|
66
|
+
string.split(/[^a-z0-9]/i).map{|w| w.capitalize}.join
|
67
|
+
end
|
68
|
+
|
62
69
|
def opt_hash_parse(opt)
|
63
70
|
opthash = {}
|
64
71
|
current_field = nil
|
@@ -142,6 +149,12 @@ end
|
|
142
149
|
opts.on('--addcomment "add your comment here"', Array) do |opt|
|
143
150
|
$addcomment = opt
|
144
151
|
end
|
152
|
+
opts.on('--addgraffiti "key:value pair"') do |opt|
|
153
|
+
$addgraffiti = opt
|
154
|
+
end
|
155
|
+
opts.on('--deletegraffiti "graffiti name"') do |opt|
|
156
|
+
$deletegraffiti = opt
|
157
|
+
end
|
145
158
|
opts.on('--allfields [excludefield1[,excludefield2]]', Array,
|
146
159
|
'Display all fields for selected objects.',
|
147
160
|
'One or more fields may be specified to be excluded from the',
|
@@ -407,7 +420,7 @@ if $nodegroup
|
|
407
420
|
getdata[:includes] = ['child_groups', 'nodes']
|
408
421
|
results = nvclient.get_objects(getdata)
|
409
422
|
matches = results.keys.grep(/\b#{$nodegroup}\b/i)
|
410
|
-
matches.size == 1 ? ( $nodegroup = matches.first ) :
|
423
|
+
matches.size == 1 ? ( $nodegroup = matches.first ) : (puts "nodegroup #{$nodegroup} not found."; exit)
|
411
424
|
puts "Child groups:"
|
412
425
|
results[$nodegroup]['child_groups'].sort{|a,b| a['name'] <=> b['name']}.each do |child_group|
|
413
426
|
puts " #{child_group['name']}"
|
@@ -565,6 +578,18 @@ if $addcomment
|
|
565
578
|
end
|
566
579
|
end
|
567
580
|
|
581
|
+
if $addgraffiti
|
582
|
+
obj_type = camelize(singularize($objecttype))
|
583
|
+
nvclient.add_graffiti(obj_type, results, $addgraffiti, $username)
|
584
|
+
exit
|
585
|
+
end
|
586
|
+
|
587
|
+
if $deletegraffiti
|
588
|
+
obj_type = camelize(singularize($objecttype))
|
589
|
+
nvclient.delete_graffiti(obj_type, results, $deletegraffiti, $username)
|
590
|
+
exit
|
591
|
+
end
|
592
|
+
|
568
593
|
if $nodegroupexpanded
|
569
594
|
names_hash = {}
|
570
595
|
$nodegroupexpanded.each do |nge|
|
data/lib/nventory.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# $Id: nventory.rb 343 2013-02-15 23:09:46Z saltmanm $
|
1
2
|
begin
|
2
3
|
# Try loading facter w/o gems first so that we don't introduce a
|
3
4
|
# dependency on gems if it is not needed.
|
@@ -6,6 +7,7 @@ rescue LoadError
|
|
6
7
|
require 'rubygems'
|
7
8
|
require 'facter'
|
8
9
|
end
|
10
|
+
require 'facter/util/memory' # used for converting MB to GB and stuff
|
9
11
|
require 'uri'
|
10
12
|
require 'net/http'
|
11
13
|
require 'net/https'
|
@@ -13,7 +15,22 @@ require 'cgi'
|
|
13
15
|
require 'rexml/document'
|
14
16
|
require 'yaml'
|
15
17
|
|
16
|
-
#
|
18
|
+
# Only use json gem if its there
|
19
|
+
begin
|
20
|
+
require 'rubygems'
|
21
|
+
require 'json'
|
22
|
+
HAS_JSON_GEM = true
|
23
|
+
rescue LoadError
|
24
|
+
HAS_JSON_GEM = false
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# 1.9 compatible solution for ruby 1.8 net/http bug that improperly encodes params in an array.
|
29
|
+
# Example:
|
30
|
+
# params = {:param1 => ["1", "2", "3"]}
|
31
|
+
# bad = param1=123
|
32
|
+
# good = param1=1¶m1=2¶m1=3
|
33
|
+
#
|
17
34
|
class Net::HTTP::Put
|
18
35
|
def set_form_data(params, sep = '&')
|
19
36
|
params_array = params.map do |k,v|
|
@@ -25,7 +42,7 @@ class Net::HTTP::Put
|
|
25
42
|
end
|
26
43
|
self.body = params_array.join(sep)
|
27
44
|
self.content_type = 'application/x-www-form-urlencoded'
|
28
|
-
end
|
45
|
+
end if method_defined? :urlencode
|
29
46
|
end
|
30
47
|
|
31
48
|
module PasswordCallback
|
@@ -71,8 +88,8 @@ class NVentory::Client
|
|
71
88
|
end
|
72
89
|
@ca_file = nil
|
73
90
|
@ca_path = nil
|
74
|
-
@dhparams = '/etc/nventory/dhparams'
|
75
91
|
@delete = false # Initialize the variable, see attr_accessor above
|
92
|
+
@dmi_data = nil
|
76
93
|
|
77
94
|
CONFIG_FILES << configfile if configfile
|
78
95
|
|
@@ -101,9 +118,6 @@ class NVentory::Client
|
|
101
118
|
elsif key == 'ca_path'
|
102
119
|
@ca_path = value
|
103
120
|
warn "Using ca_path #{@ca_path} from #{configfile}" if (@debug)
|
104
|
-
elsif key == 'dhparams'
|
105
|
-
@dhparams = value
|
106
|
-
warn "Using dhparams #{@dhparams} from #{configfile}" if (@debug)
|
107
121
|
elsif key == 'cookiefile'
|
108
122
|
@cookiefile = value
|
109
123
|
warn "Using cookiefile #{@cookiefile} from #{configfile}" if (@debug)
|
@@ -300,7 +314,18 @@ class NVentory::Client
|
|
300
314
|
# Send the query to the server
|
301
315
|
#
|
302
316
|
|
303
|
-
|
317
|
+
if parms[:format] == 'json'
|
318
|
+
if HAS_JSON_GEM
|
319
|
+
uri = URI::join(@server, "#{objecttype}.json?#{querystring}")
|
320
|
+
else
|
321
|
+
warn "Warning: Cannot use json format because json gem is not installed. Using xml format instead."
|
322
|
+
parms[:format] = 'xml'
|
323
|
+
uri = URI::join(@server, "#{objecttype}.xml?#{querystring}")
|
324
|
+
end
|
325
|
+
else
|
326
|
+
uri = URI::join(@server, "#{objecttype}.xml?#{querystring}")
|
327
|
+
end
|
328
|
+
|
304
329
|
req = Net::HTTP::Get.new(uri.request_uri)
|
305
330
|
warn "GET URL: #{uri}" if (@debug)
|
306
331
|
response = send_request(req, uri, login, password_callback)
|
@@ -314,26 +339,28 @@ class NVentory::Client
|
|
314
339
|
response.error!
|
315
340
|
end
|
316
341
|
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
results_xml.root.elements["/#{objecttype}"]
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
342
|
+
if parms[:format] == 'json'
|
343
|
+
results = JSON.parse(response.body)
|
344
|
+
else
|
345
|
+
#
|
346
|
+
# Parse the XML data from the server
|
347
|
+
# This tries to render the XML into the best possible representation
|
348
|
+
# as a Perl hash. It may need to evolve over time.
|
349
|
+
puts response.body if (@debug)
|
350
|
+
results_xml = REXML::Document.new(response.body)
|
351
|
+
results = {}
|
352
|
+
if results_xml.root.elements["/#{objecttype}"]
|
353
|
+
results_xml.root.elements["/#{objecttype}"].each do |elem|
|
354
|
+
# For some reason Elements[] is returning things other than elements,
|
355
|
+
# like text nodes
|
356
|
+
next if elem.node_type != :element
|
357
|
+
data = xml_to_ruby(elem)
|
358
|
+
name = data['name'] || data['id']
|
359
|
+
if !results[name].nil?
|
360
|
+
warn "Duplicate entries for #{name}. Only one will be shown."
|
361
|
+
end
|
362
|
+
results[name] = data
|
335
363
|
end
|
336
|
-
results[name] = data
|
337
364
|
end
|
338
365
|
end
|
339
366
|
|
@@ -541,11 +568,11 @@ class NVentory::Client
|
|
541
568
|
data['operating_system[architecture]'] = Facter['hardwaremodel'].value
|
542
569
|
end
|
543
570
|
data['kernel_version'] = Facter['kernelrelease'].value
|
544
|
-
if Facter
|
545
|
-
data['os_memory'] = Facter
|
546
|
-
elsif Facter
|
571
|
+
if Facter.value('memorysize')
|
572
|
+
data['os_memory'] = Facter.value('memorysize')
|
573
|
+
elsif Facter.value('sp_physical_memory') # Mac OS X
|
547
574
|
# More or less a safe bet that OS memory == physical memory on Mac OS X
|
548
|
-
data['os_memory'] = Facter
|
575
|
+
data['os_memory'] = Facter.value('sp_physical_memory')
|
549
576
|
end
|
550
577
|
if Facter['swapsize']
|
551
578
|
data['swap'] = Facter['swapsize'].value
|
@@ -634,9 +661,11 @@ class NVentory::Client
|
|
634
661
|
data['processor_core_count'] = get_cpu_core_count
|
635
662
|
#data['processor_socket_count'] =
|
636
663
|
#data['power_supply_count'] =
|
637
|
-
#data['physical_memory'] =
|
638
664
|
#data['physical_memory_sizes'] =
|
639
665
|
|
666
|
+
physical_memory = get_physical_memory
|
667
|
+
data['physical_memory'] = Facter::Memory.scale_number(physical_memory, "MB") if physical_memory
|
668
|
+
|
640
669
|
nics = []
|
641
670
|
if Facter['interfaces'] && Facter['interfaces'].value
|
642
671
|
nics = Facter['interfaces'].value.split(',')
|
@@ -773,11 +802,8 @@ class NVentory::Client
|
|
773
802
|
end
|
774
803
|
end
|
775
804
|
|
776
|
-
# If we failed to find an existing entry based on the unique id
|
777
|
-
# fall back to the hostname.
|
778
|
-
# if this is a new host, but that's OK as it will leave %results
|
779
|
-
# as undef, which triggers set_nodes to create a new entry on the
|
780
|
-
# server.
|
805
|
+
# If we failed to find an existing entry based on the unique id,
|
806
|
+
# fall back to the hostname.
|
781
807
|
if results.empty? && data['name']
|
782
808
|
getdata = {}
|
783
809
|
getdata[:objecttype] = 'nodes'
|
@@ -786,6 +812,21 @@ class NVentory::Client
|
|
786
812
|
results = get_objects(getdata)
|
787
813
|
end
|
788
814
|
|
815
|
+
# If we failed to find an existing entry based on the uniqueid and hostname,
|
816
|
+
# fall back to using serial number. This may still fail to find an entry,
|
817
|
+
# if this is a new host, but that's OK as it will leave %results
|
818
|
+
# as undef, which triggers set_nodes to create a new entry on the
|
819
|
+
# server.
|
820
|
+
if results.empty? && data['serial_number'] &&
|
821
|
+
!data['serial_number'].empty? &&
|
822
|
+
data['serial_number'] != "Not Specified"
|
823
|
+
getdata = {}
|
824
|
+
getdata[:objecttype] = 'nodes'
|
825
|
+
getdata[:exactget] = {'serial_number' => [data['serial_number']]}
|
826
|
+
getdata[:login] = 'autoreg'
|
827
|
+
results = get_objects(getdata)
|
828
|
+
end
|
829
|
+
|
789
830
|
setresults = set_objects('nodes', results, data, 'autoreg')
|
790
831
|
puts "Command successful" if setresults == 1
|
791
832
|
end
|
@@ -900,9 +941,9 @@ class NVentory::Client
|
|
900
941
|
# eliminate duplicates
|
901
942
|
merged_nodegroups = child_groups
|
902
943
|
|
903
|
-
if parent_group[child_groups]
|
904
|
-
parent_group[child_groups].each do |child_group|
|
905
|
-
name = child_group[name]
|
944
|
+
if parent_group['child_groups']
|
945
|
+
parent_group['child_groups'].each do |child_group|
|
946
|
+
name = child_group['name']
|
906
947
|
merged_nodegroups[name] = child_group
|
907
948
|
end
|
908
949
|
end
|
@@ -923,9 +964,9 @@ class NVentory::Client
|
|
923
964
|
# method currently suffers from.
|
924
965
|
parent_groups.each_pair do |parent_group_name, parent_group|
|
925
966
|
desired_child_groups = {}
|
926
|
-
if
|
927
|
-
parent_group[child_groups].each do |child_group|
|
928
|
-
name = child_group[name]
|
967
|
+
if parent_group['child_groups']
|
968
|
+
parent_group['child_groups'].each do |child_group|
|
969
|
+
name = child_group['name']
|
929
970
|
if !child_groups.has_key?(name)
|
930
971
|
desired_child_groups[name] = child_group
|
931
972
|
end
|
@@ -935,6 +976,7 @@ class NVentory::Client
|
|
935
976
|
set_nodegroup_nodegroup_assignments(desired_child_groups, {parent_group_name => parent_group}, login, password_callback)
|
936
977
|
end
|
937
978
|
end
|
979
|
+
|
938
980
|
# Both arguments are hashes returned by a 'node_groups' call to get_objects
|
939
981
|
def set_nodegroup_nodegroup_assignments(child_groups, parent_groups, login, password_callback=PasswordCallback)
|
940
982
|
child_ids = []
|
@@ -993,6 +1035,60 @@ class NVentory::Client
|
|
993
1035
|
end
|
994
1036
|
end
|
995
1037
|
|
1038
|
+
# Add a new graffiti to given objects. We're assuming that graffiti is a string
|
1039
|
+
# of "key:value" format
|
1040
|
+
# obj_type is a string that describe the type of the obj (e.g NodeGroup)
|
1041
|
+
# obj_hash is the hash returned from calling get_objects
|
1042
|
+
def add_graffiti(obj_type, obj_hash, graffiti, login, password_callback=PasswordCallback)
|
1043
|
+
name,value = graffiti.split(':')
|
1044
|
+
obj_hash.each_value do |obj|
|
1045
|
+
set_objects('graffitis', nil,
|
1046
|
+
{ :name => name,
|
1047
|
+
:value => value,
|
1048
|
+
:graffitiable_id => obj['id'],
|
1049
|
+
:graffitiable_type => obj_type,
|
1050
|
+
},
|
1051
|
+
login, password_callback);
|
1052
|
+
end
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
# Delete the graffiti (based on the name) from the given objects
|
1056
|
+
# obj_type is a string that describe the type of the obj (e.g NodeGroup)
|
1057
|
+
# obj_hash is the hash returned from calling get_objects
|
1058
|
+
def delete_graffiti(obj_type, obj_hash, graffiti_name, login, password_callback=PasswordCallback)
|
1059
|
+
obj_hash.each_value do |obj|
|
1060
|
+
getdata = {:objecttype => 'graffitis',
|
1061
|
+
:exactget => {:name => graffiti_name,
|
1062
|
+
:graffitiable_id => obj['id'],
|
1063
|
+
:graffitiable_type => obj_type}
|
1064
|
+
}
|
1065
|
+
graffitis_to_delete = get_objects(getdata)
|
1066
|
+
delete_objects('graffitis', graffitis_to_delete, login, password_callback)
|
1067
|
+
end
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
def get_service_tree(service_name)
|
1071
|
+
getdata = {}
|
1072
|
+
getdata[:objecttype] = 'services'
|
1073
|
+
getdata[:exactget] = {'name' => [service_name]}
|
1074
|
+
getdata[:includes] = ['nodes', 'parent_services']
|
1075
|
+
services = {service_name => []}
|
1076
|
+
results = get_objects(getdata)
|
1077
|
+
|
1078
|
+
if results.has_key?(service_name)
|
1079
|
+
if results[service_name].has_key?('parent_services') && !results[service_name]['parent_services'].empty?
|
1080
|
+
results[service_name]['parent_services'].each do |service|
|
1081
|
+
services[service_name] << get_service_tree(service['name'])
|
1082
|
+
end
|
1083
|
+
else
|
1084
|
+
return service_name
|
1085
|
+
end
|
1086
|
+
else # no such service
|
1087
|
+
return {}
|
1088
|
+
end
|
1089
|
+
return services
|
1090
|
+
end
|
1091
|
+
|
996
1092
|
#
|
997
1093
|
# Helper methods
|
998
1094
|
#
|
@@ -1039,7 +1135,11 @@ class NVentory::Client
|
|
1039
1135
|
if uuid_entry
|
1040
1136
|
uuid = uuid_entry.split(":")[1]
|
1041
1137
|
end
|
1042
|
-
|
1138
|
+
if uuid
|
1139
|
+
return uuid.strip
|
1140
|
+
else
|
1141
|
+
return nil
|
1142
|
+
end
|
1043
1143
|
end
|
1044
1144
|
|
1045
1145
|
def self.get_hardware_profile
|
@@ -1070,12 +1170,6 @@ class NVentory::Client
|
|
1070
1170
|
http = Net::HTTP.new(uri.host, uri.port)
|
1071
1171
|
end
|
1072
1172
|
if uri.scheme == "https"
|
1073
|
-
# Eliminate the OpenSSL "using default DH parameters" warning
|
1074
|
-
if File.exist?(@dhparams)
|
1075
|
-
dh = OpenSSL::PKey::DH.new(IO.read(@dhparams))
|
1076
|
-
Net::HTTP.ssl_context_accessor(:tmp_dh_callback)
|
1077
|
-
http.tmp_dh_callback = proc { dh }
|
1078
|
-
end
|
1079
1173
|
http.use_ssl = true
|
1080
1174
|
if @ca_file && File.exist?(@ca_file)
|
1081
1175
|
http.ca_file = @ca_file
|
@@ -1212,14 +1306,22 @@ class NVentory::Client
|
|
1212
1306
|
|
1213
1307
|
# Extract cookie from response and save it to the user's cookie store
|
1214
1308
|
def extract_cookie(response, uri, login=nil)
|
1215
|
-
|
1216
|
-
|
1309
|
+
# response['set-cookie'] returns multiple cookies comma-separated,
|
1310
|
+
# which is difficult to parse since Expires field also uses comma in it.
|
1311
|
+
# Fortunately, response.get_fields('set-cookie') returns an array of cookies.
|
1312
|
+
cookies = response.get_fields('set-cookie')
|
1313
|
+
if cookies.nil?
|
1314
|
+
puts "extract_cookie finds no cookie in response" if (@debug)
|
1315
|
+
return
|
1316
|
+
end
|
1317
|
+
cookiefile = get_cookiefile(login)
|
1318
|
+
cookies.each do |one_cookie|
|
1217
1319
|
# It doesn't look like it matters for our purposes at the moment, but
|
1218
1320
|
# according to rfc2965, 3.2.2 the Set-Cookie header can contain more
|
1219
1321
|
# than one cookie, separated by commas.
|
1220
|
-
puts "extract_cookie processing #{
|
1221
|
-
newcookie = parse_cookie('Set-Cookie: ' +
|
1222
|
-
|
1322
|
+
puts "extract_cookie processing #{one_cookie}" if (@debug)
|
1323
|
+
newcookie = parse_cookie('Set-Cookie: ' + one_cookie)
|
1324
|
+
next if newcookie.nil?
|
1223
1325
|
|
1224
1326
|
# Some cookie fields are optional, and should default to the
|
1225
1327
|
# values in the request. We need to insert these so that we
|
@@ -1267,8 +1369,6 @@ class NVentory::Client
|
|
1267
1369
|
else
|
1268
1370
|
puts "No cookie changes, leaving cookiefile untouched" if (@debug)
|
1269
1371
|
end
|
1270
|
-
else
|
1271
|
-
puts "extract_cookie finds no cookie in response" if (@debug)
|
1272
1372
|
end
|
1273
1373
|
end
|
1274
1374
|
|
@@ -1664,8 +1764,7 @@ class NVentory::Client
|
|
1664
1764
|
|
1665
1765
|
def getvmstatus
|
1666
1766
|
# facter virtual makes calls to commands that are under /sbin
|
1667
|
-
|
1668
|
-
vmstatus = `facter virtual`
|
1767
|
+
vmstatus = Facter.virtual
|
1669
1768
|
vmstatus.chomp!
|
1670
1769
|
|
1671
1770
|
# extra check to see if we're running kvm hypervisor
|
@@ -1889,4 +1988,102 @@ class NVentory::Client
|
|
1889
1988
|
end
|
1890
1989
|
return info
|
1891
1990
|
end
|
1991
|
+
|
1992
|
+
# Parse dmidecode data and put it into a hash
|
1993
|
+
# This method is based on the corresponding method in the perl client
|
1994
|
+
def get_dmi_data
|
1995
|
+
return @dmi_data if @dmi_data
|
1996
|
+
|
1997
|
+
case Facter.value(:kernel)
|
1998
|
+
when 'Linux'
|
1999
|
+
return nil unless FileTest.exists?("/usr/sbin/dmidecode")
|
2000
|
+
|
2001
|
+
output=%x{/usr/sbin/dmidecode 2>/dev/null}
|
2002
|
+
when 'FreeBSD'
|
2003
|
+
return nil unless FileTest.exists?("/usr/local/sbin/dmidecode")
|
2004
|
+
|
2005
|
+
output=%x{/usr/local/sbin/dmidecode 2>/dev/null}
|
2006
|
+
when 'NetBSD'
|
2007
|
+
return nil unless FileTest.exists?("/usr/pkg/sbin/dmidecode")
|
2008
|
+
|
2009
|
+
output=%x{/usr/pkg/sbin/dmidecode 2>/dev/null}
|
2010
|
+
when 'SunOS'
|
2011
|
+
return nil unless FileTest.exists?("/usr/sbin/smbios")
|
2012
|
+
|
2013
|
+
output=%x{/usr/sbin/smbios 2>/dev/null}
|
2014
|
+
else
|
2015
|
+
warn "Can't get dmi_data because of unsupported OS"
|
2016
|
+
return
|
2017
|
+
end
|
2018
|
+
|
2019
|
+
look_for_section_name = false
|
2020
|
+
dmi_section = nil
|
2021
|
+
dmi_section_data = {}
|
2022
|
+
dmi_section_array = nil
|
2023
|
+
@dmi_data = {}
|
2024
|
+
|
2025
|
+
output.split("\n").each do |line|
|
2026
|
+
if line =~ /^Handle/
|
2027
|
+
if dmi_section && !dmi_section_data.empty?
|
2028
|
+
@dmi_data[dmi_section] ||= []
|
2029
|
+
@dmi_data[dmi_section] << dmi_section_data
|
2030
|
+
end
|
2031
|
+
dmi_section = nil
|
2032
|
+
dmi_section_data = {}
|
2033
|
+
dmi_section_array = nil
|
2034
|
+
look_for_section_name = true
|
2035
|
+
elsif look_for_section_name
|
2036
|
+
next if line =~ /^\s*DMI type/
|
2037
|
+
if line =~ /^\s*(.*)/
|
2038
|
+
dmi_section = $1
|
2039
|
+
look_for_section_name = false
|
2040
|
+
end
|
2041
|
+
elsif dmi_section && line =~ /^\s*([^:]+):\s*(\S.*)/
|
2042
|
+
dmi_section_data[$1] = $2;
|
2043
|
+
dmi_section_array = nil
|
2044
|
+
elsif dmi_section && line =~ /^\s*([^:]+):$/
|
2045
|
+
dmi_section_array = $1
|
2046
|
+
elsif dmi_section && dmi_section_array && line =~ /^\s*(\S.+)$/
|
2047
|
+
dmi_section_data[dmi_section_array] ||= []
|
2048
|
+
dmi_section_data[dmi_section_array] << $1
|
2049
|
+
end
|
2050
|
+
end
|
2051
|
+
@dmi_data
|
2052
|
+
end
|
2053
|
+
|
2054
|
+
# This method is based on the one in the perl client
|
2055
|
+
def get_physical_memory
|
2056
|
+
# only support Linux and FreeBSD right now
|
2057
|
+
os = Facter['kernel']
|
2058
|
+
return if os.nil? or (os.value != 'Linux' and os.value != 'FreeBSD')
|
2059
|
+
|
2060
|
+
physical_memory = 0
|
2061
|
+
dmi_data = get_dmi_data
|
2062
|
+
|
2063
|
+
return if dmi_data.nil? or dmi_data['Memory Device'].nil?
|
2064
|
+
|
2065
|
+
dmi_data['Memory Device'].each do |mem_dev|
|
2066
|
+
|
2067
|
+
size = mem_dev['Size']
|
2068
|
+
form_factor = mem_dev['Form Factor']
|
2069
|
+
locator = mem_dev['Locator']
|
2070
|
+
# Some systems report little chunks of memory other than
|
2071
|
+
# main system memory as Memory Devices, the 'DIMM' as
|
2072
|
+
# form factor seems to indicate main system memory.
|
2073
|
+
# Unfortunately some DIMMs are reported with a form
|
2074
|
+
# factor of '<OUT OF SPEC>'. In that case fall back to
|
2075
|
+
# checking for signs of it being a DIMM in the locator
|
2076
|
+
# field.
|
2077
|
+
if (size != 'No Module Installed' &&
|
2078
|
+
((form_factor == 'DIMM' || form_factor == 'FB-DIMM' || form_factor == 'SODIMM') ||
|
2079
|
+
(form_factor == '<OUT OF SPEC>' && locator =~ /DIMM/)))
|
2080
|
+
megs, units = size.split(' ')
|
2081
|
+
|
2082
|
+
next if units != 'MB'
|
2083
|
+
physical_memory += megs.to_i;
|
2084
|
+
end
|
2085
|
+
end
|
2086
|
+
physical_memory
|
2087
|
+
end
|
2088
|
+
|
1892
2089
|
end
|
data/nventory-client.gemspec
CHANGED
@@ -1,22 +1,23 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
4
|
require "nventory-client/version"
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
6
|
-
s.name
|
7
|
-
s.version
|
8
|
-
s.platform
|
9
|
-
s.authors
|
10
|
-
s.email
|
11
|
-
s.homepage
|
12
|
-
s.summary
|
13
|
-
s.description
|
7
|
+
s.name = "nventory-client"
|
8
|
+
s.version = Nventory::Client::VERSION
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Darren Dao", "John Tran", "Jason Heiss", "Marjorie"]
|
11
|
+
s.email = ["nventory-users@lists.sourceforge.net"]
|
12
|
+
s.homepage = "http://nventory.sourceforge.net"
|
13
|
+
s.summary = "Client for nVentory"
|
14
|
+
s.description = "The client provides a command line tool and library for interacting with an nVentory database-- you can register nodes, retrieve information, or set values for your assets."
|
14
15
|
|
15
16
|
s.rubyforge_project = "nventory-client"
|
16
17
|
|
17
18
|
s.files = `git ls-files`.split("\n")
|
18
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
|
-
s.
|
21
|
+
s.add_runtime_dependency("facter")
|
22
22
|
end
|
23
|
+
|
metadata
CHANGED
@@ -1,89 +1,75 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: nventory-client
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 65
|
9
|
-
- 4
|
10
|
-
version: 1.65.4
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.67'
|
5
|
+
prerelease:
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
8
|
+
- Darren Dao
|
13
9
|
- John Tran
|
10
|
+
- Jason Heiss
|
11
|
+
- Marjorie
|
14
12
|
autorequire:
|
15
13
|
bindir: bin
|
16
14
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
dependencies:
|
21
|
-
- !ruby/object:Gem::Dependency
|
15
|
+
date: 2013-02-15 00:00:00.000000000 Z
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
22
18
|
name: facter
|
23
|
-
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
25
20
|
none: false
|
26
|
-
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
21
|
+
requirements:
|
22
|
+
- - ! '>='
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '0'
|
33
25
|
type: :runtime
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
description: The client provides a command line tool and library for interacting with
|
34
|
+
an nVentory database-- you can register nodes, retrieve information, or set values
|
35
|
+
for your assets.
|
36
|
+
email:
|
37
|
+
- nventory-users@lists.sourceforge.net
|
38
|
+
executables:
|
39
39
|
- nv
|
40
40
|
extensions: []
|
41
|
-
|
42
41
|
extra_rdoc_files: []
|
43
|
-
|
44
|
-
files:
|
42
|
+
files:
|
45
43
|
- .gitignore
|
46
|
-
-
|
47
|
-
- README
|
44
|
+
- README.md
|
48
45
|
- Rakefile
|
49
46
|
- bin/nv
|
50
47
|
- lib/nventory-client.rb
|
51
48
|
- lib/nventory-client/version.rb
|
52
49
|
- lib/nventory.rb
|
53
50
|
- nventory-client.gemspec
|
54
|
-
has_rdoc: true
|
55
51
|
homepage: http://nventory.sourceforge.net
|
56
52
|
licenses: []
|
57
|
-
|
58
53
|
post_install_message:
|
59
54
|
rdoc_options: []
|
60
|
-
|
61
|
-
require_paths:
|
55
|
+
require_paths:
|
62
56
|
- lib
|
63
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
58
|
none: false
|
65
|
-
requirements:
|
66
|
-
- -
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
|
69
|
-
|
70
|
-
- 0
|
71
|
-
version: "0"
|
72
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
64
|
none: false
|
74
|
-
requirements:
|
75
|
-
- -
|
76
|
-
- !ruby/object:Gem::Version
|
77
|
-
|
78
|
-
segments:
|
79
|
-
- 0
|
80
|
-
version: "0"
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
81
69
|
requirements: []
|
82
|
-
|
83
70
|
rubyforge_project: nventory-client
|
84
|
-
rubygems_version: 1.
|
71
|
+
rubygems_version: 1.8.23
|
85
72
|
signing_key:
|
86
73
|
specification_version: 3
|
87
74
|
summary: Client for nVentory
|
88
75
|
test_files: []
|
89
|
-
|
data/Gemfile
DELETED