choria-mcorpc-support 0.0.1
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.
- checksums.yaml +7 -0
- data/bin/mco +64 -0
- data/lib/mcollective.rb +63 -0
- data/lib/mcollective/agent.rb +5 -0
- data/lib/mcollective/agents.rb +149 -0
- data/lib/mcollective/aggregate.rb +85 -0
- data/lib/mcollective/aggregate/average.ddl +33 -0
- data/lib/mcollective/aggregate/average.rb +29 -0
- data/lib/mcollective/aggregate/base.rb +40 -0
- data/lib/mcollective/aggregate/result.rb +9 -0
- data/lib/mcollective/aggregate/result/base.rb +25 -0
- data/lib/mcollective/aggregate/result/collection_result.rb +19 -0
- data/lib/mcollective/aggregate/result/numeric_result.rb +13 -0
- data/lib/mcollective/aggregate/sum.ddl +33 -0
- data/lib/mcollective/aggregate/sum.rb +18 -0
- data/lib/mcollective/aggregate/summary.ddl +33 -0
- data/lib/mcollective/aggregate/summary.rb +53 -0
- data/lib/mcollective/application.rb +365 -0
- data/lib/mcollective/application/completion.rb +104 -0
- data/lib/mcollective/application/describe_filter.rb +87 -0
- data/lib/mcollective/application/facts.rb +62 -0
- data/lib/mcollective/application/find.rb +23 -0
- data/lib/mcollective/application/help.rb +28 -0
- data/lib/mcollective/application/inventory.rb +344 -0
- data/lib/mcollective/application/ping.rb +82 -0
- data/lib/mcollective/application/plugin.rb +369 -0
- data/lib/mcollective/application/rpc.rb +111 -0
- data/lib/mcollective/applications.rb +134 -0
- data/lib/mcollective/cache.rb +145 -0
- data/lib/mcollective/client.rb +353 -0
- data/lib/mcollective/config.rb +245 -0
- data/lib/mcollective/connector.rb +18 -0
- data/lib/mcollective/connector/base.rb +26 -0
- data/lib/mcollective/data.rb +91 -0
- data/lib/mcollective/data/agent_data.ddl +22 -0
- data/lib/mcollective/data/agent_data.rb +17 -0
- data/lib/mcollective/data/base.rb +67 -0
- data/lib/mcollective/data/collective_data.ddl +20 -0
- data/lib/mcollective/data/collective_data.rb +9 -0
- data/lib/mcollective/data/fact_data.ddl +28 -0
- data/lib/mcollective/data/fact_data.rb +55 -0
- data/lib/mcollective/data/fstat_data.ddl +89 -0
- data/lib/mcollective/data/fstat_data.rb +56 -0
- data/lib/mcollective/data/result.rb +45 -0
- data/lib/mcollective/ddl.rb +113 -0
- data/lib/mcollective/ddl/agentddl.rb +253 -0
- data/lib/mcollective/ddl/base.rb +217 -0
- data/lib/mcollective/ddl/dataddl.rb +56 -0
- data/lib/mcollective/ddl/discoveryddl.rb +52 -0
- data/lib/mcollective/ddl/validatorddl.rb +6 -0
- data/lib/mcollective/discovery.rb +143 -0
- data/lib/mcollective/discovery/flatfile.ddl +11 -0
- data/lib/mcollective/discovery/flatfile.rb +48 -0
- data/lib/mcollective/discovery/mc.ddl +11 -0
- data/lib/mcollective/discovery/mc.rb +30 -0
- data/lib/mcollective/discovery/stdin.ddl +11 -0
- data/lib/mcollective/discovery/stdin.rb +68 -0
- data/lib/mcollective/exceptions.rb +28 -0
- data/lib/mcollective/facts.rb +39 -0
- data/lib/mcollective/facts/base.rb +100 -0
- data/lib/mcollective/facts/yaml_facts.rb +65 -0
- data/lib/mcollective/generators.rb +7 -0
- data/lib/mcollective/generators/agent_generator.rb +51 -0
- data/lib/mcollective/generators/base.rb +46 -0
- data/lib/mcollective/generators/data_generator.rb +51 -0
- data/lib/mcollective/generators/templates/action_snippet.erb +13 -0
- data/lib/mcollective/generators/templates/data_input_snippet.erb +7 -0
- data/lib/mcollective/generators/templates/ddl.erb +8 -0
- data/lib/mcollective/generators/templates/plugin.erb +7 -0
- data/lib/mcollective/log.rb +118 -0
- data/lib/mcollective/logger.rb +5 -0
- data/lib/mcollective/logger/base.rb +77 -0
- data/lib/mcollective/logger/console_logger.rb +61 -0
- data/lib/mcollective/logger/file_logger.rb +53 -0
- data/lib/mcollective/logger/syslog_logger.rb +53 -0
- data/lib/mcollective/matcher.rb +224 -0
- data/lib/mcollective/matcher/parser.rb +128 -0
- data/lib/mcollective/matcher/scanner.rb +241 -0
- data/lib/mcollective/message.rb +248 -0
- data/lib/mcollective/monkey_patches.rb +152 -0
- data/lib/mcollective/optionparser.rb +197 -0
- data/lib/mcollective/pluginmanager.rb +180 -0
- data/lib/mcollective/pluginpackager.rb +98 -0
- data/lib/mcollective/pluginpackager/agent_definition.rb +94 -0
- data/lib/mcollective/pluginpackager/debpackage_packager.rb +237 -0
- data/lib/mcollective/pluginpackager/modulepackage_packager.rb +127 -0
- data/lib/mcollective/pluginpackager/ospackage_packager.rb +59 -0
- data/lib/mcollective/pluginpackager/rpmpackage_packager.rb +180 -0
- data/lib/mcollective/pluginpackager/standard_definition.rb +69 -0
- data/lib/mcollective/pluginpackager/templates/debian/Makefile.erb +7 -0
- data/lib/mcollective/pluginpackager/templates/debian/changelog.erb +5 -0
- data/lib/mcollective/pluginpackager/templates/debian/compat.erb +1 -0
- data/lib/mcollective/pluginpackager/templates/debian/control.erb +15 -0
- data/lib/mcollective/pluginpackager/templates/debian/copyright.erb +8 -0
- data/lib/mcollective/pluginpackager/templates/debian/rules.erb +6 -0
- data/lib/mcollective/pluginpackager/templates/module/Modulefile.erb +5 -0
- data/lib/mcollective/pluginpackager/templates/module/README.md.erb +37 -0
- data/lib/mcollective/pluginpackager/templates/module/_manifest.pp.erb +9 -0
- data/lib/mcollective/pluginpackager/templates/redhat/rpm_spec.erb +63 -0
- data/lib/mcollective/registration/base.rb +91 -0
- data/lib/mcollective/rpc.rb +182 -0
- data/lib/mcollective/rpc/actionrunner.rb +158 -0
- data/lib/mcollective/rpc/agent.rb +374 -0
- data/lib/mcollective/rpc/audit.rb +38 -0
- data/lib/mcollective/rpc/client.rb +1066 -0
- data/lib/mcollective/rpc/helpers.rb +321 -0
- data/lib/mcollective/rpc/progress.rb +63 -0
- data/lib/mcollective/rpc/reply.rb +87 -0
- data/lib/mcollective/rpc/request.rb +86 -0
- data/lib/mcollective/rpc/result.rb +90 -0
- data/lib/mcollective/rpc/stats.rb +294 -0
- data/lib/mcollective/runnerstats.rb +90 -0
- data/lib/mcollective/security.rb +26 -0
- data/lib/mcollective/security/base.rb +244 -0
- data/lib/mcollective/shell.rb +126 -0
- data/lib/mcollective/ssl.rb +285 -0
- data/lib/mcollective/util.rb +579 -0
- data/lib/mcollective/validator.rb +85 -0
- data/lib/mcollective/validator/array_validator.ddl +7 -0
- data/lib/mcollective/validator/array_validator.rb +9 -0
- data/lib/mcollective/validator/ipv4address_validator.ddl +7 -0
- data/lib/mcollective/validator/ipv4address_validator.rb +16 -0
- data/lib/mcollective/validator/ipv6address_validator.ddl +7 -0
- data/lib/mcollective/validator/ipv6address_validator.rb +16 -0
- data/lib/mcollective/validator/length_validator.ddl +7 -0
- data/lib/mcollective/validator/length_validator.rb +11 -0
- data/lib/mcollective/validator/regex_validator.ddl +7 -0
- data/lib/mcollective/validator/regex_validator.rb +9 -0
- data/lib/mcollective/validator/shellsafe_validator.ddl +7 -0
- data/lib/mcollective/validator/shellsafe_validator.rb +13 -0
- data/lib/mcollective/validator/typecheck_validator.ddl +7 -0
- data/lib/mcollective/validator/typecheck_validator.rb +28 -0
- metadata +215 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module RPC
|
|
3
|
+
# Simple class to manage compliant requests for MCollective::RPC agents
|
|
4
|
+
class Request
|
|
5
|
+
attr_accessor :time, :action, :data, :sender, :agent, :uniqid, :caller, :ddl
|
|
6
|
+
|
|
7
|
+
def initialize(msg, ddl)
|
|
8
|
+
@time = msg[:msgtime]
|
|
9
|
+
@action = msg[:body][:action] || msg[:body]["action"]
|
|
10
|
+
@data = msg[:body][:data] || msg[:body]["data"]
|
|
11
|
+
@sender = msg[:senderid]
|
|
12
|
+
@agent = msg[:body][:agent] || msg[:body]["agent"]
|
|
13
|
+
@uniqid = msg[:requestid]
|
|
14
|
+
@caller = msg[:callerid] || "unknown"
|
|
15
|
+
@ddl = ddl
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# In a scenario where a request came from a JSON pure medium like a REST
|
|
19
|
+
# service or other language client DDL::AgentDDL#validate_rpc_request will
|
|
20
|
+
# check "package" against the intput :package should the input "package" not
|
|
21
|
+
# also be known
|
|
22
|
+
#
|
|
23
|
+
# Thus once the request is built it will also have "package" and not :package
|
|
24
|
+
# data, so we need to fetch the correct key out of the hash.
|
|
25
|
+
def compatible_key(key)
|
|
26
|
+
return key if data.include?(key)
|
|
27
|
+
|
|
28
|
+
if ddl
|
|
29
|
+
input = ddl.action_interface(action)[:input]
|
|
30
|
+
|
|
31
|
+
# if :package is requested and the DDL also declares "package" we cant tell it to fetch
|
|
32
|
+
# "package", hence the check against the input here
|
|
33
|
+
return key.to_s if key.is_a?(Symbol) && !input.include?(key.to_s) && data.include?(key.to_s)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
key
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# If data is a hash, quick helper to get access to it's include? method
|
|
40
|
+
# else returns false
|
|
41
|
+
def include?(key)
|
|
42
|
+
return false unless @data.is_a?(Hash)
|
|
43
|
+
|
|
44
|
+
@data.include?(compatible_key(key))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# If no :process_results is specified always respond else respond
|
|
48
|
+
# based on the supplied property
|
|
49
|
+
def should_respond?
|
|
50
|
+
return false unless @data.is_a?(Hash)
|
|
51
|
+
return @data[:process_results] if @data.include?(:process_results)
|
|
52
|
+
return @data["process_results"] if @data.include?("process_results")
|
|
53
|
+
|
|
54
|
+
true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# If data is a hash, gives easy access to its members, else returns nil
|
|
58
|
+
def [](key)
|
|
59
|
+
return nil unless @data.is_a?(Hash)
|
|
60
|
+
return @data[compatible_key(key)]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def fetch(key, default)
|
|
64
|
+
return nil unless @data.is_a?(Hash)
|
|
65
|
+
return @data.fetch(compatible_key(key), default)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def to_hash
|
|
69
|
+
{:agent => @agent,
|
|
70
|
+
:action => @action,
|
|
71
|
+
:data => @data}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Validate the request against the DDL
|
|
75
|
+
def validate!
|
|
76
|
+
@ddl.validate_rpc_request(@action, @data)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def to_json
|
|
80
|
+
to_hash.merge!({:sender => @sender,
|
|
81
|
+
:callerid => @callerid,
|
|
82
|
+
:uniqid => @uniqid}).to_json
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module RPC
|
|
3
|
+
# Simple class to manage compliant results from MCollective::RPC agents
|
|
4
|
+
#
|
|
5
|
+
# Currently it just fakes Hash behaviour to the result to remain backward
|
|
6
|
+
# compatible but it also knows which agent and action produced it so you
|
|
7
|
+
# can associate results to a DDL
|
|
8
|
+
class Result
|
|
9
|
+
attr_reader :agent, :action, :results
|
|
10
|
+
|
|
11
|
+
include Enumerable
|
|
12
|
+
|
|
13
|
+
def initialize(agent, action, result={})
|
|
14
|
+
@agent = agent
|
|
15
|
+
@action = action
|
|
16
|
+
@results = result
|
|
17
|
+
|
|
18
|
+
convert_data_based_on_ddl if ddl
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def ddl
|
|
22
|
+
@_ddl ||= DDL.new(agent)
|
|
23
|
+
rescue
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def data
|
|
28
|
+
@results[:data] = @results.delete("data") if @results.include?("data")
|
|
29
|
+
|
|
30
|
+
self[:data]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Converts keys on the supplied data to those listed as outputs
|
|
34
|
+
# in the DDL. This is to facilitate JSON based transports
|
|
35
|
+
# without forcing everyone to rewrite DDLs and clients to
|
|
36
|
+
# convert symbols to strings, the data will be on symbol keys
|
|
37
|
+
# if the DDL has a symbol and not a string output defined
|
|
38
|
+
def convert_data_based_on_ddl
|
|
39
|
+
interface = ddl.action_interface(action)
|
|
40
|
+
|
|
41
|
+
return if interface.fetch(:output, {}).empty?
|
|
42
|
+
|
|
43
|
+
interface[:output].each do |output, properties|
|
|
44
|
+
next if data.include?(output)
|
|
45
|
+
|
|
46
|
+
if output.is_a?(Symbol) && data.include?(output.to_s)
|
|
47
|
+
data[output] = data.delete(output.to_s)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def compatible_key(key)
|
|
53
|
+
if key.is_a?(Symbol) && @results.include?(key.to_s)
|
|
54
|
+
key.to_s
|
|
55
|
+
else
|
|
56
|
+
key
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def [](key)
|
|
61
|
+
@results[compatible_key(key)]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def []=(key, item)
|
|
65
|
+
@results[key] = item
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def fetch(key, default)
|
|
69
|
+
@results.fetch(compatible_key(key), default)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def each
|
|
73
|
+
@results.each_pair {|k,v| yield(k,v) }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def to_json(*a)
|
|
77
|
+
{:agent => @agent,
|
|
78
|
+
:action => @action,
|
|
79
|
+
:sender => self[:sender],
|
|
80
|
+
:statuscode => self[:statuscode],
|
|
81
|
+
:statusmsg => self[:statusmsg],
|
|
82
|
+
:data => data}.to_json(*a)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def <=>(other)
|
|
86
|
+
self[:sender] <=> other[:sender]
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module RPC
|
|
3
|
+
# Class to wrap all the stats and to keep track of some timings
|
|
4
|
+
class Stats
|
|
5
|
+
attr_accessor :noresponsefrom, :unexpectedresponsefrom, :starttime, :discoverytime, :blocktime, :responses
|
|
6
|
+
attr_accessor :totaltime, :discovered, :discovered_nodes, :okcount, :failcount, :noresponsefrom
|
|
7
|
+
attr_accessor :responsesfrom, :requestid, :aggregate_summary, :ddl, :aggregate_failures
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
reset
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Resets stats, if discovery time is set we keep it as it was
|
|
14
|
+
def reset
|
|
15
|
+
@noresponsefrom = []
|
|
16
|
+
@unexpectedresponsefrom = []
|
|
17
|
+
@responsesfrom = []
|
|
18
|
+
@responses = 0
|
|
19
|
+
@starttime = Time.now.to_f
|
|
20
|
+
@discoverytime = 0 unless @discoverytime
|
|
21
|
+
@blocktime = 0
|
|
22
|
+
@totaltime = 0
|
|
23
|
+
@discovered = 0
|
|
24
|
+
@discovered_nodes = []
|
|
25
|
+
@okcount = 0
|
|
26
|
+
@failcount = 0
|
|
27
|
+
@requestid = nil
|
|
28
|
+
@aggregate_summary = []
|
|
29
|
+
@aggregate_failures = []
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# returns a hash of our stats
|
|
33
|
+
def to_hash
|
|
34
|
+
{:noresponsefrom => @noresponsefrom,
|
|
35
|
+
:unexpectedresponsefrom => @unexpectedresponsefrom,
|
|
36
|
+
:starttime => @starttime,
|
|
37
|
+
:discoverytime => @discoverytime,
|
|
38
|
+
:blocktime => @blocktime,
|
|
39
|
+
:responses => @responses,
|
|
40
|
+
:totaltime => @totaltime,
|
|
41
|
+
:discovered => @discovered,
|
|
42
|
+
:discovered_nodes => @discovered_nodes,
|
|
43
|
+
:okcount => @okcount,
|
|
44
|
+
:requestid => @requestid,
|
|
45
|
+
:failcount => @failcount,
|
|
46
|
+
:aggregate_summary => @aggregate_summary,
|
|
47
|
+
:aggregate_failures => @aggregate_failures}
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Fake hash access to keep things backward compatible
|
|
51
|
+
def [](key)
|
|
52
|
+
to_hash[key]
|
|
53
|
+
rescue
|
|
54
|
+
nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# increment the count of ok hosts
|
|
58
|
+
def ok
|
|
59
|
+
@okcount += 1
|
|
60
|
+
rescue
|
|
61
|
+
@okcount = 1
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# increment the count of failed hosts
|
|
65
|
+
def fail
|
|
66
|
+
@failcount += 1
|
|
67
|
+
rescue
|
|
68
|
+
@failcount = 1
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Re-initializes the object with stats from the basic client
|
|
72
|
+
def client_stats=(stats)
|
|
73
|
+
@noresponsefrom = stats[:noresponsefrom]
|
|
74
|
+
@unexpectedresponsefrom = stats[:unexpectedresponsefrom]
|
|
75
|
+
@responses = stats[:responses]
|
|
76
|
+
@starttime = stats[:starttime]
|
|
77
|
+
@blocktime = stats[:blocktime]
|
|
78
|
+
@totaltime = stats[:totaltime]
|
|
79
|
+
@requestid = stats[:requestid]
|
|
80
|
+
@discoverytime = stats[:discoverytime] if @discoverytime == 0
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Utility to time discovery from :start to :end
|
|
84
|
+
def time_discovery(action)
|
|
85
|
+
if action == :start
|
|
86
|
+
@discovery_start = Time.now.to_f
|
|
87
|
+
elsif action == :end
|
|
88
|
+
@discoverytime = Time.now.to_f - @discovery_start
|
|
89
|
+
else
|
|
90
|
+
raise("Uknown discovery action #{action}")
|
|
91
|
+
end
|
|
92
|
+
rescue
|
|
93
|
+
@discoverytime = 0
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# helper to time block execution time
|
|
97
|
+
def time_block_execution(action)
|
|
98
|
+
if action == :start
|
|
99
|
+
@block_start = Time.now.to_f
|
|
100
|
+
elsif action == :end
|
|
101
|
+
@blocktime += Time.now.to_f - @block_start
|
|
102
|
+
else
|
|
103
|
+
raise("Uknown block action #{action}")
|
|
104
|
+
end
|
|
105
|
+
rescue
|
|
106
|
+
@blocktime = 0
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Update discovered and discovered_nodes based on
|
|
110
|
+
# discovery results
|
|
111
|
+
def discovered_agents(agents)
|
|
112
|
+
@discovered_nodes = agents
|
|
113
|
+
@discovered = agents.size
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Helper to calculate total time etc
|
|
117
|
+
def finish_request
|
|
118
|
+
@totaltime = @blocktime + @discoverytime
|
|
119
|
+
|
|
120
|
+
# figure out who responded unexpectedly
|
|
121
|
+
@unexpectedresponsefrom = @responsesfrom - @discovered_nodes
|
|
122
|
+
|
|
123
|
+
# figure out who we had no responses from
|
|
124
|
+
@noresponsefrom = @discovered_nodes - @responsesfrom
|
|
125
|
+
rescue
|
|
126
|
+
@totaltime = 0
|
|
127
|
+
@noresponsefrom = []
|
|
128
|
+
@unexpectedresponsefrom = []
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Helper to keep track of who we received responses from
|
|
132
|
+
def node_responded(node)
|
|
133
|
+
@responsesfrom << node
|
|
134
|
+
rescue
|
|
135
|
+
@responsesfrom = [node]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def text_for_aggregates
|
|
139
|
+
result = StringIO.new
|
|
140
|
+
|
|
141
|
+
@aggregate_summary.each do |aggregate|
|
|
142
|
+
output_item = aggregate.result[:output]
|
|
143
|
+
|
|
144
|
+
begin
|
|
145
|
+
action_interface = @ddl.action_interface(aggregate.action)
|
|
146
|
+
display_as = action_interface[:output][output_item][:display_as]
|
|
147
|
+
rescue
|
|
148
|
+
display_as = output_item
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
if aggregate.is_a?(Aggregate::Result::Base)
|
|
152
|
+
aggregate_report = aggregate.to_s
|
|
153
|
+
else
|
|
154
|
+
next
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
result.puts Util.colorize(:bold, "Summary of %s:" % display_as)
|
|
158
|
+
result.puts
|
|
159
|
+
unless aggregate_report == ""
|
|
160
|
+
result.puts aggregate.to_s.split("\n").map{|x| " " + x}.join("\n")
|
|
161
|
+
else
|
|
162
|
+
result.puts Util.colorize(:yellow, " No aggregate summary could be computed")
|
|
163
|
+
end
|
|
164
|
+
result.puts
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
@aggregate_failures.each do |failed|
|
|
168
|
+
case(failed[:type])
|
|
169
|
+
when :startup
|
|
170
|
+
message = "exception raised while processing startup hook"
|
|
171
|
+
when :create
|
|
172
|
+
message = "unspecified output '#{failed[:name]}' for the action"
|
|
173
|
+
when :process_result
|
|
174
|
+
message = "exception raised while processing result data"
|
|
175
|
+
when :summarize
|
|
176
|
+
message = "exception raised while summarizing"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
result.puts Util.colorize(:bold, "Summary of %s:" % failed[:name])
|
|
180
|
+
result.puts
|
|
181
|
+
result.puts Util.colorize(:yellow, " Could not compute summary - %s" % message)
|
|
182
|
+
result.puts
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
result.string
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Returns a blob of text representing the request status based on the
|
|
189
|
+
# stats contained in this class
|
|
190
|
+
def report(caption = "rpc stats", summarize = true, verbose = false)
|
|
191
|
+
result_text = []
|
|
192
|
+
|
|
193
|
+
if verbose
|
|
194
|
+
if @aggregate_summary.size > 0 && summarize
|
|
195
|
+
result_text << text_for_aggregates
|
|
196
|
+
else
|
|
197
|
+
result_text << ""
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
result_text << Util.colorize(:yellow, "---- #{caption} ----")
|
|
201
|
+
|
|
202
|
+
if @discovered
|
|
203
|
+
@responses < @discovered ? color = :red : color = :reset
|
|
204
|
+
result_text << " Nodes: %s / %s" % [ Util.colorize(color, @discovered), Util.colorize(color, @responses) ]
|
|
205
|
+
else
|
|
206
|
+
result_text << " Nodes: #{@responses}"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
@failcount < 0 ? color = :red : color = :reset
|
|
210
|
+
|
|
211
|
+
result_text << " Pass / Fail: %s / %s" % [Util.colorize(color, @okcount), Util.colorize(color, @failcount) ]
|
|
212
|
+
result_text << " Start Time: %s" % [Time.at(@starttime)]
|
|
213
|
+
result_text << " Discovery Time: %.2fms" % [@discoverytime * 1000]
|
|
214
|
+
result_text << " Agent Time: %.2fms" % [@blocktime * 1000]
|
|
215
|
+
result_text << " Total Time: %.2fms" % [@totaltime * 1000]
|
|
216
|
+
else
|
|
217
|
+
if @discovered
|
|
218
|
+
@responses < @discovered ? color = :red : color = :green
|
|
219
|
+
|
|
220
|
+
if @aggregate_summary.size + @aggregate_failures.size > 0 && summarize
|
|
221
|
+
result_text << text_for_aggregates
|
|
222
|
+
else
|
|
223
|
+
result_text << ""
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
result_text << "Finished processing %s / %s hosts in %.2f ms" % [Util.colorize(color, @responses), Util.colorize(color, @discovered), @blocktime * 1000]
|
|
227
|
+
else
|
|
228
|
+
result_text << "Finished processing %s hosts in %.2f ms" % [Util.colorize(:bold, @responses), @blocktime * 1000]
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
no_response_r = no_response_report
|
|
233
|
+
unexpected_response_r = unexpected_response_report
|
|
234
|
+
if no_response_r || unexpected_response_r
|
|
235
|
+
result_text << ""
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
if no_response_r != ""
|
|
239
|
+
result_text << "" << no_response_r
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
if unexpected_response_r != ""
|
|
243
|
+
result_text << "" << unexpected_response_r
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
if no_response_r || unexpected_response_r
|
|
247
|
+
result_text << ""
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
result_text.join("\n")
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Returns a blob of text indicating what nodes did not respond
|
|
254
|
+
def no_response_report
|
|
255
|
+
result_text = StringIO.new
|
|
256
|
+
|
|
257
|
+
if @noresponsefrom.size > 0
|
|
258
|
+
result_text.puts Util.colorize(:red, "No response from:")
|
|
259
|
+
result_text.puts
|
|
260
|
+
|
|
261
|
+
field_size = Util.field_size(@noresponsefrom, 30)
|
|
262
|
+
fields_num = Util.field_number(field_size)
|
|
263
|
+
format = " " + ( " %-#{field_size}s" * fields_num )
|
|
264
|
+
|
|
265
|
+
@noresponsefrom.sort.in_groups_of(fields_num) do |c|
|
|
266
|
+
result_text.puts format % c
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
result_text.string
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# Returns a blob of text indicating what nodes responded but weren't discovered
|
|
274
|
+
def unexpected_response_report
|
|
275
|
+
result_text = StringIO.new
|
|
276
|
+
|
|
277
|
+
if @unexpectedresponsefrom.size > 0
|
|
278
|
+
result_text.puts Util.colorize(:red, "Unexpected response from:")
|
|
279
|
+
result_text.puts
|
|
280
|
+
|
|
281
|
+
field_size = Util.field_size(@unexpectedresponsefrom, 30)
|
|
282
|
+
fields_num = Util.field_number(field_size)
|
|
283
|
+
format = " " + ( " %-#{field_size}s" * fields_num )
|
|
284
|
+
|
|
285
|
+
@unexpectedresponsefrom.sort.in_groups_of(fields_num) do |c|
|
|
286
|
+
result_text.puts format % c
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
result_text.string
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|