| Class | MCollective::Application::Inventory |
| In: |
plugins/mcollective/application/inventory.rb
|
| Parent: | MCollective::Application |
# File plugins/mcollective/application/inventory.rb, line 200
200: def agents
201: @node[:agents]
202: end
# File plugins/mcollective/application/inventory.rb, line 196
196: def classes
197: @node[:classes]
198: end
Writes a crude DOT graph to a file
# File plugins/mcollective/application/inventory.rb, line 86
86: def collectives_map(file)
87: File.open(file, "w") do |graph|
88: puts "Retrieving collective info...."
89: collectives = get_collectives
90:
91: graph.puts 'graph {'
92:
93: collectives[:collectives].keys.sort.each do |collective|
94: graph.puts ' subgraph "%s" {' % [ collective ]
95:
96: collectives[:collectives][collective].each do |member|
97: graph.puts ' "%s" -- "%s"' % [ member, collective ]
98: end
99:
100: graph.puts ' }'
101: end
102:
103: graph.puts '}'
104:
105: puts "Graph of #{collectives[:total_nodes]} nodes has been written to #{file}"
106: end
107: end
Prints a report of all known sub collectives
# File plugins/mcollective/application/inventory.rb, line 110
110: def collectives_report
111: collectives = get_collectives
112:
113: puts " %-30s %s" % [ "Collective", "Nodes" ]
114: puts " %-30s %s" % [ "==========", "=====" ]
115:
116: collectives[:collectives].sort_by {|key,count| count.size}.each do |collective|
117: puts " %-30s %d" % [ collective[0], collective[1].size ]
118: end
119:
120: puts
121: puts " %30s %d" % [ "Total nodes:", collectives[:nodes] ]
122: puts
123: end
# File plugins/mcollective/application/inventory.rb, line 192
192: def facts
193: @node[:facts]
194: end
# File plugins/mcollective/application/inventory.rb, line 184
184: def fields(&blk)
185: @flds = blk
186: end
Helpers to create a simple DSL for scriptlets
# File plugins/mcollective/application/inventory.rb, line 180
180: def format(fmt)
181: @fmt = fmt
182: end
Use the ruby formatr gem to build reports using Perls formats
It is kind of ugly but brings a lot of flexibility in report writing without building an entire reporting language.
You need to have formatr installed to enable reports like:
formatted_inventory do
page_length 20
page_heading <<TOP
Node Report @<<<<<<<<<<<<<<<<<<<<<<<<<
time
Hostname: Customer: Distribution:
-------------------------------------------------------------------------
TOP
page_body <<BODY
@<<<<<<<<<<<<<<<< @<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
identity, facts["customer"], facts["lsbdistdescription"]
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
facts["processor0"]
BODY
end
# File plugins/mcollective/application/inventory.rb, line 272
272: def formatted_inventory(&blk)
273: require 'formatr'
274:
275: raise "Need to give a block to formatted_inventory" unless block_given?
276:
277: blk.call if block_given?
278:
279: raise "Need to define page body format" if @page_body.nil?
280:
281: body_fmt = FormatR::Format.new(@page_heading, @page_body)
282: body_fmt.setPageLength(@page_length)
283: time = Time.now
284:
285: util = rpcclient("rpcutil")
286: util.progress = false
287:
288: util.inventory do |t, resp|
289: @node = {:identity => resp[:sender],
290: :facts => resp[:data][:facts],
291: :classes => resp[:data][:classes],
292: :agents => resp[:data][:agents]}
293:
294: body_fmt.printFormat(binding)
295: end
296: rescue Exception => e
297: STDERR.puts "Could not create report: #{e.class}: #{e}"
298: exit 1
299: end
Get all the known collectives and nodes that belong to them
# File plugins/mcollective/application/inventory.rb, line 60
60: def get_collectives
61: util = rpcclient("rpcutil")
62: util.progress = false
63:
64: collectives = {}
65: nodes = 0
66: total = 0
67:
68: util.collective_info do |r, cinfo|
69: begin
70: if cinfo[:data] && cinfo[:data][:collectives]
71: cinfo[:data][:collectives].each do |collective|
72: collectives[collective] ||= []
73: collectives[collective] << cinfo[:sender]
74: end
75:
76: nodes += 1
77: total += 1
78: end
79: end
80: end
81:
82: {:collectives => collectives, :nodes => nodes, :total_nodes => total}
83: end
# File plugins/mcollective/application/inventory.rb, line 188
188: def identity
189: @node[:identity]
190: end
Expects a simple printf style format and apply it to each node:
inventory do
format "%s:\t\t%s\t\t%s"
fields { [ identity, facts["serialnumber"], facts["productname"] ] }
end
# File plugins/mcollective/application/inventory.rb, line 224
224: def inventory(&blk)
225: raise "Need to give a block to inventory" unless block_given?
226:
227: blk.call if block_given?
228:
229: raise "Need to define a format" if @fmt.nil?
230: raise "Need to define inventory fields" if @flds.nil?
231:
232: util = rpcclient("rpcutil")
233: util.progress = false
234:
235: util.inventory do |t, resp|
236: @node = {:identity => resp[:sender],
237: :facts => resp[:data][:facts],
238: :classes => resp[:data][:classes],
239: :agents => resp[:data][:agents]}
240:
241: puts @fmt % @flds.call
242: end
243: end
# File plugins/mcollective/application/inventory.rb, line 307
307: def main
308: if configuration[:script]
309: if File.exist?(configuration[:script])
310: eval(File.read(configuration[:script]))
311: else
312: raise "Could not find script to run: #{configuration[:script]}"
313: end
314:
315: elsif configuration[:collectivemap]
316: collectives_map(configuration[:collectivemap])
317:
318: elsif configuration[:collectives]
319: collectives_report
320:
321: else
322: node_inventory
323: end
324: end
# File plugins/mcollective/application/inventory.rb, line 125
125: def node_inventory
126: node = configuration[:node]
127:
128: util = rpcclient("rpcutil")
129: util.identity_filter node
130: util.progress = false
131:
132: nodestats = util.custom_request("daemon_stats", {}, node, {"identity" => node})
133:
134: util.custom_request("inventory", {}, node, {"identity" => node}).each do |resp|
135: puts "Inventory for #{resp[:sender]}:"
136: puts
137:
138: if nodestats.is_a?(Array)
139: nodestats = nodestats.first[:data]
140:
141: puts " Server Statistics:"
142: puts " Version: #{nodestats[:version]}"
143: puts " Start Time: #{Time.at(nodestats[:starttime])}"
144: puts " Config File: #{nodestats[:configfile]}"
145: puts " Collectives: #{resp[:data][:collectives].join(', ')}" if resp[:data].include?(:collectives)
146: puts " Main Collective: #{resp[:data][:main_collective]}" if resp[:data].include?(:main_collective)
147: puts " Process ID: #{nodestats[:pid]}"
148: puts " Total Messages: #{nodestats[:total]}"
149: puts " Messages Passed Filters: #{nodestats[:passed]}"
150: puts " Messages Filtered: #{nodestats[:filtered]}"
151: puts " Replies Sent: #{nodestats[:replies]}"
152: puts " Total Processor Time: #{nodestats[:times][:utime]} seconds"
153: puts " System Time: #{nodestats[:times][:stime]} seconds"
154:
155: puts
156: end
157:
158: puts " Agents:"
159: resp[:data][:agents].sort.in_groups_of(3, "") do |agents|
160: puts " %-15s %-15s %-15s" % agents
161: end
162: puts
163:
164: puts " Configuration Management Classes:"
165: resp[:data][:classes].sort.in_groups_of(2, "") do |klasses|
166: puts " %-30s %-30s" % klasses
167: end
168: puts
169:
170: puts " Facts:"
171: resp[:data][:facts].sort_by{|f| f[0]}.each do |f|
172: puts " #{f[0]} => #{f[1]}"
173: end
174:
175: break
176: end
177: end
# File plugins/mcollective/application/inventory.rb, line 212
212: def page_body(fmt)
213: @page_body = fmt
214: end
# File plugins/mcollective/application/inventory.rb, line 208
208: def page_heading(fmt)
209: @page_heading = fmt
210: end
# File plugins/mcollective/application/inventory.rb, line 204
204: def page_length(len)
205: @page_length = len
206: end
# File plugins/mcollective/application/inventory.rb, line 49
49: def post_option_parser(configuration)
50: configuration[:node] = ARGV.shift if ARGV.size > 0
51: end
# File plugins/mcollective/application/inventory.rb, line 53
53: def validate_configuration(configuration)
54: unless configuration[:node] || configuration[:script] || configuration[:collectives] || configuration[:collectivemap]
55: raise "Need to specify either a node name, script to run or other options"
56: end
57: end