mcollective-client 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (186) hide show
  1. data/lib/mcollective/agent/discovery.rb +37 -0
  2. data/lib/mcollective/agent/rpcutil.ddl +220 -0
  3. data/lib/mcollective/agent/rpcutil.rb +108 -0
  4. data/lib/mcollective/aggregate/average.ddl +33 -0
  5. data/lib/mcollective/aggregate/average.rb +29 -0
  6. data/lib/mcollective/aggregate/result.rb +3 -3
  7. data/lib/mcollective/aggregate/sum.ddl +33 -0
  8. data/lib/mcollective/aggregate/sum.rb +18 -0
  9. data/lib/mcollective/aggregate/summary.ddl +33 -0
  10. data/lib/mcollective/aggregate/summary.rb +53 -0
  11. data/lib/mcollective/aggregate.rb +2 -2
  12. data/lib/mcollective/application/completion.rb +104 -0
  13. data/lib/mcollective/application/facts.rb +62 -0
  14. data/lib/mcollective/application/find.rb +21 -0
  15. data/lib/mcollective/application/help.rb +28 -0
  16. data/lib/mcollective/application/inventory.rb +344 -0
  17. data/lib/mcollective/application/ping.rb +77 -0
  18. data/lib/mcollective/application/plugin.rb +369 -0
  19. data/lib/mcollective/application/rpc.rb +121 -0
  20. data/lib/mcollective/application.rb +2 -0
  21. data/lib/mcollective/audit/logfile.rb +26 -0
  22. data/lib/mcollective/config.rb +16 -9
  23. data/lib/mcollective/connector/activemq.ddl +9 -0
  24. data/lib/mcollective/connector/activemq.rb +572 -0
  25. data/lib/mcollective/connector/rabbitmq.ddl +9 -0
  26. data/lib/mcollective/connector/rabbitmq.rb +484 -0
  27. data/lib/mcollective/connector.rb +1 -1
  28. data/lib/mcollective/data/agent_data.ddl +22 -0
  29. data/lib/mcollective/data/agent_data.rb +17 -0
  30. data/lib/mcollective/data/collective_data.ddl +20 -0
  31. data/lib/mcollective/data/collective_data.rb +9 -0
  32. data/lib/mcollective/data/fact_data.ddl +28 -0
  33. data/lib/mcollective/data/fact_data.rb +55 -0
  34. data/lib/mcollective/data/fstat_data.ddl +89 -0
  35. data/lib/mcollective/data/fstat_data.rb +56 -0
  36. data/lib/mcollective/data.rb +2 -2
  37. data/lib/mcollective/ddl.rb +4 -4
  38. data/lib/mcollective/discovery/flatfile.ddl +11 -0
  39. data/lib/mcollective/discovery/flatfile.rb +48 -0
  40. data/lib/mcollective/discovery/mc.ddl +11 -0
  41. data/lib/mcollective/discovery/mc.rb +30 -0
  42. data/lib/mcollective/discovery/stdin.ddl +11 -0
  43. data/lib/mcollective/discovery/stdin.rb +66 -0
  44. data/lib/mcollective/facts/yaml_facts.rb +61 -0
  45. data/lib/mcollective/facts.rb +1 -1
  46. data/lib/mcollective/generators.rb +3 -3
  47. data/lib/mcollective/logger.rb +1 -1
  48. data/lib/mcollective/matcher/scanner.rb +1 -1
  49. data/lib/mcollective/matcher.rb +2 -2
  50. data/lib/mcollective/pluginpackager/debpackage_packager.rb +237 -0
  51. data/lib/mcollective/pluginpackager/modulepackage_packager.rb +127 -0
  52. data/lib/mcollective/pluginpackager/ospackage_packager.rb +59 -0
  53. data/lib/mcollective/pluginpackager/rpmpackage_packager.rb +180 -0
  54. data/lib/mcollective/pluginpackager/templates/debian/Makefile.erb +7 -0
  55. data/lib/mcollective/pluginpackager/templates/debian/changelog.erb +5 -0
  56. data/lib/mcollective/pluginpackager/templates/debian/compat.erb +1 -0
  57. data/lib/mcollective/pluginpackager/templates/debian/control.erb +15 -0
  58. data/lib/mcollective/pluginpackager/templates/debian/copyright.erb +8 -0
  59. data/lib/mcollective/pluginpackager/templates/debian/rules.erb +6 -0
  60. data/lib/mcollective/pluginpackager/templates/module/Modulefile.erb +5 -0
  61. data/lib/mcollective/pluginpackager/templates/module/README.md.erb +37 -0
  62. data/lib/mcollective/pluginpackager/templates/module/_manifest.pp.erb +9 -0
  63. data/lib/mcollective/pluginpackager/templates/redhat/rpm_spec.erb +63 -0
  64. data/lib/mcollective/pluginpackager.rb +2 -2
  65. data/lib/mcollective/registration/agentlist.rb +10 -0
  66. data/lib/mcollective/registration.rb +1 -1
  67. data/lib/mcollective/rpc/stats.rb +0 -1
  68. data/lib/mcollective/rpc.rb +11 -11
  69. data/lib/mcollective/security/aes_security.rb +394 -0
  70. data/lib/mcollective/security/psk.rb +117 -0
  71. data/lib/mcollective/security/ssl.rb +328 -0
  72. data/lib/mcollective/security.rb +1 -1
  73. data/lib/mcollective/util.rb +18 -18
  74. data/lib/mcollective/validator/array_validator.ddl +7 -0
  75. data/lib/mcollective/validator/array_validator.rb +9 -0
  76. data/lib/mcollective/validator/ipv4address_validator.ddl +7 -0
  77. data/lib/mcollective/validator/ipv4address_validator.rb +16 -0
  78. data/lib/mcollective/validator/ipv6address_validator.ddl +7 -0
  79. data/lib/mcollective/validator/ipv6address_validator.rb +16 -0
  80. data/lib/mcollective/validator/length_validator.ddl +7 -0
  81. data/lib/mcollective/validator/length_validator.rb +11 -0
  82. data/lib/mcollective/validator/regex_validator.ddl +7 -0
  83. data/lib/mcollective/validator/regex_validator.rb +9 -0
  84. data/lib/mcollective/validator/shellsafe_validator.ddl +7 -0
  85. data/lib/mcollective/validator/shellsafe_validator.rb +13 -0
  86. data/lib/mcollective/validator/typecheck_validator.ddl +7 -0
  87. data/lib/mcollective/validator/typecheck_validator.rb +28 -0
  88. data/lib/mcollective.rb +31 -31
  89. data/spec/spec_helper.rb +0 -5
  90. data/spec/unit/{plugins/mcollective → mcollective}/agent/rpcutil_spec.rb +1 -1
  91. data/spec/unit/{agents_spec.rb → mcollective/agents_spec.rb} +0 -0
  92. data/spec/unit/{plugins/mcollective → mcollective}/aggregate/average_spec.rb +1 -1
  93. data/spec/unit/{aggregate → mcollective/aggregate}/base_spec.rb +0 -0
  94. data/spec/unit/{aggregate → mcollective/aggregate}/result/base_spec.rb +0 -0
  95. data/spec/unit/{aggregate → mcollective/aggregate}/result/collection_result_spec.rb +0 -0
  96. data/spec/unit/{aggregate → mcollective/aggregate}/result/numeric_result_spec.rb +0 -0
  97. data/spec/unit/{plugins/mcollective → mcollective}/aggregate/sum_spec.rb +1 -1
  98. data/spec/unit/{plugins/mcollective → mcollective}/aggregate/summary_spec.rb +1 -1
  99. data/spec/unit/{aggregate_spec.rb → mcollective/aggregate_spec.rb} +0 -0
  100. data/spec/unit/{plugins/mcollective → mcollective}/application/plugin_spec.rb +1 -1
  101. data/spec/unit/{application_spec.rb → mcollective/application_spec.rb} +0 -0
  102. data/spec/unit/{applications_spec.rb → mcollective/applications_spec.rb} +1 -1
  103. data/spec/unit/{array_spec.rb → mcollective/array_spec.rb} +0 -0
  104. data/spec/unit/{plugins/mcollective → mcollective}/audit/logfile_spec.rb +1 -1
  105. data/spec/unit/{cache_spec.rb → mcollective/cache_spec.rb} +0 -0
  106. data/spec/unit/{client_spec.rb → mcollective/client_spec.rb} +0 -0
  107. data/spec/unit/{config_spec.rb → mcollective/config_spec.rb} +12 -7
  108. data/spec/unit/{plugins/mcollective → mcollective}/connector/activemq_spec.rb +1 -1
  109. data/spec/unit/{connector → mcollective/connector}/base_spec.rb +0 -0
  110. data/spec/unit/{plugins/mcollective → mcollective}/connector/rabbitmq_spec.rb +1 -1
  111. data/spec/unit/{plugins/mcollective → mcollective}/data/agent_data_spec.rb +1 -1
  112. data/spec/unit/{data → mcollective/data}/base_spec.rb +0 -0
  113. data/spec/unit/{plugins/mcollective → mcollective}/data/collective_data_spec.rb +1 -1
  114. data/spec/unit/{plugins/mcollective → mcollective}/data/fact_data_spec.rb +1 -1
  115. data/spec/unit/{plugins/mcollective → mcollective}/data/fstat_data_spec.rb +1 -1
  116. data/spec/unit/{data → mcollective/data}/result_spec.rb +0 -0
  117. data/spec/unit/{data_spec.rb → mcollective/data_spec.rb} +0 -0
  118. data/spec/unit/{ddl → mcollective/ddl}/agentddl_spec.rb +0 -0
  119. data/spec/unit/{ddl → mcollective/ddl}/base_spec.rb +0 -0
  120. data/spec/unit/{ddl → mcollective/ddl}/dataddl_spec.rb +0 -0
  121. data/spec/unit/{ddl → mcollective/ddl}/discoveryddl_spec.rb +0 -0
  122. data/spec/unit/{ddl_spec.rb → mcollective/ddl_spec.rb} +0 -0
  123. data/spec/unit/{plugins/mcollective → mcollective}/discovery/flatfile_spec.rb +1 -1
  124. data/spec/unit/{plugins/mcollective → mcollective}/discovery/mc_spec.rb +1 -1
  125. data/spec/unit/{plugins/mcollective → mcollective}/discovery/stdin_spec.rb +1 -1
  126. data/spec/unit/{discovery_spec.rb → mcollective/discovery_spec.rb} +0 -0
  127. data/spec/unit/{facts → mcollective/facts}/base_spec.rb +0 -0
  128. data/spec/unit/{plugins/mcollective → mcollective}/facts/yaml_facts_spec.rb +1 -1
  129. data/spec/unit/{facts_spec.rb → mcollective/facts_spec.rb} +0 -0
  130. data/spec/unit/{generators → mcollective/generators}/agent_generator_spec.rb +0 -0
  131. data/spec/unit/{generators → mcollective/generators}/base_spec.rb +0 -0
  132. data/spec/unit/{generators → mcollective/generators}/data_generator_spec.rb +0 -0
  133. data/spec/unit/{generators → mcollective/generators}/snippets/agent_ddl +0 -0
  134. data/spec/unit/{generators → mcollective/generators}/snippets/data_ddl +0 -0
  135. data/spec/unit/{log_spec.rb → mcollective/log_spec.rb} +0 -0
  136. data/spec/unit/{logger → mcollective/logger}/base_spec.rb +0 -0
  137. data/spec/unit/{logger → mcollective/logger}/console_logger_spec.rb +0 -0
  138. data/spec/unit/{logger → mcollective/logger}/file_logger_spec.rb +0 -0
  139. data/spec/unit/{logger → mcollective/logger}/syslog_logger_spec.rb +0 -0
  140. data/spec/unit/{matcher → mcollective/matcher}/parser_spec.rb +0 -0
  141. data/spec/unit/{matcher → mcollective/matcher}/scanner_spec.rb +0 -0
  142. data/spec/unit/{matcher_spec.rb → mcollective/matcher_spec.rb} +0 -0
  143. data/spec/unit/{message_spec.rb → mcollective/message_spec.rb} +0 -0
  144. data/spec/unit/{monkey_patches_spec.rb → mcollective/monkey_patches_spec.rb} +0 -0
  145. data/spec/unit/{optionparser_spec.rb → mcollective/optionparser_spec.rb} +0 -0
  146. data/spec/unit/{plugins/mcollective → mcollective}/packagers/debpackage_packager_spec.rb +1 -1
  147. data/spec/unit/{plugins/mcollective → mcollective}/packagers/modulepackage_packager_spec.rb +1 -1
  148. data/spec/unit/{plugins/mcollective → mcollective}/packagers/ospackage_spec.rb +1 -1
  149. data/spec/unit/{plugins/mcollective → mcollective}/packagers/rpmpackage_packager_spec.rb +1 -1
  150. data/spec/unit/{pluginmanager_spec.rb → mcollective/pluginmanager_spec.rb} +0 -0
  151. data/spec/unit/{pluginpackager → mcollective/pluginpackager}/agent_definition_spec.rb +0 -0
  152. data/spec/unit/{pluginpackager → mcollective/pluginpackager}/standard_definition_spec.rb +0 -0
  153. data/spec/unit/{pluginpackager_spec.rb → mcollective/pluginpackager_spec.rb} +0 -0
  154. data/spec/unit/{registration → mcollective/registration}/base_spec.rb +0 -0
  155. data/spec/unit/{rpc → mcollective/rpc}/actionrunner_spec.rb +0 -0
  156. data/spec/unit/{rpc → mcollective/rpc}/agent_spec.rb +0 -0
  157. data/spec/unit/{rpc → mcollective/rpc}/client_spec.rb +0 -0
  158. data/spec/unit/{rpc → mcollective/rpc}/helpers_spec.rb +0 -0
  159. data/spec/unit/{rpc → mcollective/rpc}/reply_spec.rb +0 -0
  160. data/spec/unit/{rpc → mcollective/rpc}/request_spec.rb +0 -0
  161. data/spec/unit/{rpc → mcollective/rpc}/result_spec.rb +0 -0
  162. data/spec/unit/{rpc → mcollective/rpc}/stats_spec.rb +0 -0
  163. data/spec/unit/{rpc_spec.rb → mcollective/rpc_spec.rb} +0 -0
  164. data/spec/unit/{runner_spec.rb → mcollective/runner_spec.rb} +0 -0
  165. data/spec/unit/{runnerstats_spec.rb → mcollective/runnerstats_spec.rb} +0 -0
  166. data/spec/unit/{plugins/mcollective → mcollective}/security/aes_security_spec.rb +1 -1
  167. data/spec/unit/{security → mcollective/security}/base_spec.rb +0 -0
  168. data/spec/unit/{plugins/mcollective → mcollective}/security/psk_spec.rb +1 -1
  169. data/spec/unit/{shell_spec.rb → mcollective/shell_spec.rb} +0 -0
  170. data/spec/unit/{ssl_spec.rb → mcollective/ssl_spec.rb} +12 -12
  171. data/spec/unit/{string_spec.rb → mcollective/string_spec.rb} +0 -0
  172. data/spec/unit/{symbol_spec.rb → mcollective/symbol_spec.rb} +0 -0
  173. data/spec/unit/{unix_daemon_spec.rb → mcollective/unix_daemon_spec.rb} +0 -0
  174. data/spec/unit/{util_spec.rb → mcollective/util_spec.rb} +28 -6
  175. data/spec/unit/{plugins/mcollective → mcollective}/validator/array_validator_spec.rb +1 -1
  176. data/spec/unit/{plugins/mcollective → mcollective}/validator/ipv4address_validator_spec.rb +1 -1
  177. data/spec/unit/{plugins/mcollective → mcollective}/validator/ipv6address_validator_spec.rb +1 -1
  178. data/spec/unit/{plugins/mcollective → mcollective}/validator/length_validator_spec.rb +1 -1
  179. data/spec/unit/{plugins/mcollective → mcollective}/validator/regex_validator_spec.rb +1 -1
  180. data/spec/unit/{plugins/mcollective → mcollective}/validator/shellsafe_validator_spec.rb +1 -1
  181. data/spec/unit/{plugins/mcollective → mcollective}/validator/typecheck_validator_spec.rb +1 -1
  182. data/spec/unit/{validator_spec.rb → mcollective/validator_spec.rb} +1 -1
  183. data/spec/unit/{vendor_spec.rb → mcollective/vendor_spec.rb} +2 -2
  184. data/spec/unit/{windows_daemon_spec.rb → mcollective/windows_daemon_spec.rb} +0 -0
  185. metadata +361 -284
  186. checksums.yaml +0 -7
@@ -0,0 +1,62 @@
1
+ class MCollective::Application::Facts<MCollective::Application
2
+ description "Reports on usage for a specific fact"
3
+
4
+ def post_option_parser(configuration)
5
+ configuration[:fact] = ARGV.shift if ARGV.size > 0
6
+ end
7
+
8
+ def validate_configuration(configuration)
9
+ raise "Please specify a fact to report for" unless configuration.include?(:fact)
10
+ end
11
+
12
+ def show_single_fact_report(fact, facts, verbose=false)
13
+ puts("Report for fact: #{fact}\n\n")
14
+
15
+ field_size = MCollective::Util.field_size(facts.keys)
16
+ facts.keys.sort.each do |k|
17
+ printf(" %-#{field_size}s found %d times\n", k, facts[k].size)
18
+
19
+ if verbose
20
+ puts
21
+
22
+ facts[k].sort.each do |f|
23
+ puts(" #{f}")
24
+ end
25
+
26
+ puts
27
+ end
28
+ end
29
+ end
30
+
31
+ def main
32
+ rpcutil = rpcclient("rpcutil")
33
+ rpcutil.progress = false
34
+
35
+ facts = {}
36
+
37
+ rpcutil.get_fact(:fact => configuration[:fact]) do |resp|
38
+ begin
39
+ value = resp[:body][:data][:value]
40
+ if value
41
+ if facts.include?(value)
42
+ facts[value] << resp[:senderid]
43
+ else
44
+ facts[value] = [ resp[:senderid] ]
45
+ end
46
+ end
47
+ rescue Exception => e
48
+ STDERR.puts "Could not parse facts for #{resp[:senderid]}: #{e.class}: #{e}"
49
+ end
50
+ end
51
+
52
+ if facts.empty?
53
+ puts "No values found for fact #{configuration[:fact]}\n"
54
+ else
55
+ show_single_fact_report(configuration[:fact], facts, options[:verbose])
56
+ end
57
+
58
+ printrpcstats
59
+
60
+ halt rpcutil.stats
61
+ end
62
+ end
@@ -0,0 +1,21 @@
1
+ class MCollective::Application::Find<MCollective::Application
2
+ description "Find hosts using the discovery system matching filter criteria"
3
+
4
+ def main
5
+ mc = rpcclient("rpcutil")
6
+
7
+ starttime = Time.now
8
+
9
+ nodes = mc.discover
10
+
11
+ discoverytime = Time.now - starttime
12
+
13
+ STDERR.puts if options[:verbose]
14
+
15
+ nodes.each {|c| puts c}
16
+
17
+ STDERR.puts "\nDiscovered %s nodes in %.2f seconds using the %s discovery plugin" % [nodes.size, discoverytime, mc.client.discoverer.discovery_method] if options[:verbose]
18
+
19
+ nodes.size > 0 ? exit(0) : exit(1)
20
+ end
21
+ end
@@ -0,0 +1,28 @@
1
+ module MCollective
2
+ class Application::Help<Application
3
+ description "Application list and help"
4
+ usage "rpc help [application name]"
5
+
6
+ def post_option_parser(configuration)
7
+ configuration[:application] = ARGV.shift if ARGV.size > 0
8
+ end
9
+
10
+ def main
11
+ if configuration.include?(:application)
12
+ puts Applications[configuration[:application]].help
13
+ else
14
+ puts "The Marionette Collective version #{MCollective.version}"
15
+ puts
16
+
17
+ Applications.list.sort.each do |app|
18
+ begin
19
+ puts " %-15s %s" % [app, Applications[app].application_description]
20
+ rescue
21
+ end
22
+ end
23
+
24
+ puts
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,344 @@
1
+ class MCollective::Application::Inventory<MCollective::Application
2
+ description "General reporting tool for nodes, collectives and subcollectives"
3
+
4
+ option :script,
5
+ :description => "Script to run",
6
+ :arguments => ["--script SCRIPT"]
7
+
8
+ option :collectives,
9
+ :description => "List all known collectives",
10
+ :arguments => ["--list-collectives", "--lc"],
11
+ :default => false,
12
+ :type => :bool
13
+
14
+ option :collectivemap,
15
+ :description => "Create a DOT graph of all collectives",
16
+ :arguments => ["--collective-graph MAP", "--cg MAP", "--map MAP"]
17
+
18
+ def post_option_parser(configuration)
19
+ configuration[:node] = ARGV.shift if ARGV.size > 0
20
+ end
21
+
22
+ def validate_configuration(configuration)
23
+ unless configuration[:node] || configuration[:script] || configuration[:collectives] || configuration[:collectivemap]
24
+ raise "Need to specify either a node name, script to run or other options"
25
+ end
26
+ end
27
+
28
+ # Get all the known collectives and nodes that belong to them
29
+ def get_collectives
30
+ util = rpcclient("rpcutil")
31
+ util.progress = false
32
+
33
+ collectives = {}
34
+ nodes = 0
35
+ total = 0
36
+
37
+ util.collective_info do |r, cinfo|
38
+ begin
39
+ if cinfo[:data] && cinfo[:data][:collectives]
40
+ cinfo[:data][:collectives].each do |collective|
41
+ collectives[collective] ||= []
42
+ collectives[collective] << cinfo[:sender]
43
+ end
44
+
45
+ nodes += 1
46
+ total += 1
47
+ end
48
+ end
49
+ end
50
+
51
+ {:collectives => collectives, :nodes => nodes, :total_nodes => total}
52
+ end
53
+
54
+ # Writes a crude DOT graph to a file
55
+ def collectives_map(file)
56
+ File.open(file, "w") do |graph|
57
+ puts "Retrieving collective info...."
58
+ collectives = get_collectives
59
+
60
+ graph.puts 'graph {'
61
+
62
+ collectives[:collectives].keys.sort.each do |collective|
63
+ graph.puts ' subgraph "%s" {' % [ collective ]
64
+
65
+ collectives[:collectives][collective].each do |member|
66
+ graph.puts ' "%s" -- "%s"' % [ member, collective ]
67
+ end
68
+
69
+ graph.puts ' }'
70
+ end
71
+
72
+ graph.puts '}'
73
+
74
+ puts "Graph of #{collectives[:total_nodes]} nodes has been written to #{file}"
75
+ end
76
+ end
77
+
78
+ # Prints a report of all known sub collectives
79
+ def collectives_report
80
+ collectives = get_collectives
81
+
82
+ puts " %-30s %s" % [ "Collective", "Nodes" ]
83
+ puts " %-30s %s" % [ "==========", "=====" ]
84
+
85
+ collectives[:collectives].sort_by {|key,count| count.size}.each do |collective|
86
+ puts " %-30s %d" % [ collective[0], collective[1].size ]
87
+ end
88
+
89
+ puts
90
+ puts " %30s %d" % [ "Total nodes:", collectives[:nodes] ]
91
+ puts
92
+ end
93
+
94
+ def node_inventory
95
+ node = configuration[:node]
96
+
97
+ util = rpcclient("rpcutil")
98
+ util.identity_filter node
99
+ util.progress = false
100
+
101
+ nodestats = util.custom_request("daemon_stats", {}, node, {"identity" => node}).first
102
+
103
+ unless nodestats
104
+ STDERR.puts "Did not receive any results from node #{node}"
105
+ exit 1
106
+ end
107
+
108
+ unless nodestats[:statuscode] == 0
109
+ STDERR.puts "Failed to retrieve daemon_stats from #{node}: #{nodestats[:statusmsg]}"
110
+ else
111
+ util.custom_request("inventory", {}, node, {"identity" => node}).each do |resp|
112
+ unless resp[:statuscode] == 0
113
+ STDERR.puts "Failed to retrieve inventory for #{node}: #{resp[:statusmsg]}"
114
+ next
115
+ end
116
+
117
+ data = resp[:data]
118
+
119
+ begin
120
+ puts "Inventory for #{resp[:sender]}:"
121
+ puts
122
+
123
+ nodestats = nodestats[:data]
124
+
125
+ puts " Server Statistics:"
126
+ puts " Version: #{nodestats[:version]}"
127
+ puts " Start Time: #{Time.at(nodestats[:starttime])}"
128
+ puts " Config File: #{nodestats[:configfile]}"
129
+ puts " Collectives: #{data[:collectives].join(', ')}" if data.include?(:collectives)
130
+ puts " Main Collective: #{data[:main_collective]}" if data.include?(:main_collective)
131
+ puts " Process ID: #{nodestats[:pid]}"
132
+ puts " Total Messages: #{nodestats[:total]}"
133
+ puts " Messages Passed Filters: #{nodestats[:passed]}"
134
+ puts " Messages Filtered: #{nodestats[:filtered]}"
135
+ puts " Expired Messages: #{nodestats[:ttlexpired]}"
136
+ puts " Replies Sent: #{nodestats[:replies]}"
137
+ puts " Total Processor Time: #{nodestats[:times][:utime]} seconds"
138
+ puts " System Time: #{nodestats[:times][:stime]} seconds"
139
+
140
+ puts
141
+
142
+ puts " Agents:"
143
+ if data[:agents].size > 0
144
+ data[:agents].sort.in_groups_of(3, "") do |agents|
145
+ puts " %-15s %-15s %-15s" % agents
146
+ end
147
+ else
148
+ puts " No agents installed"
149
+ end
150
+
151
+ puts
152
+
153
+ puts " Data Plugins:"
154
+ if data[:data_plugins].size > 0
155
+ data[:data_plugins].sort.in_groups_of(3, "") do |plugins|
156
+ puts " %-15s %-15s %-15s" % plugins.map{|p| p.gsub("_data", "")}
157
+ end
158
+ else
159
+ puts " No data plugins installed"
160
+ end
161
+
162
+ puts
163
+
164
+ puts " Configuration Management Classes:"
165
+ if data[:classes].size > 0
166
+ field_size = MCollective::Util.field_size(data[:classes], 30)
167
+ fields_num = MCollective::Util.field_number(field_size)
168
+ format = " " + (" %-#{field_size}s" * fields_num)
169
+
170
+ data[:classes].sort.in_groups_of(fields_num, "") do |klasses|
171
+ puts format % klasses
172
+ end
173
+ else
174
+ puts " No classes applied"
175
+ end
176
+
177
+ puts
178
+
179
+ puts " Facts:"
180
+ if data[:facts].size > 0
181
+ data[:facts].sort_by{|f| f[0]}.each do |f|
182
+ puts " #{f[0]} => #{f[1]}"
183
+ end
184
+ else
185
+ puts " No facts known"
186
+ end
187
+
188
+ break
189
+ rescue Exception => e
190
+ STDERR.puts "Failed to display node inventory: #{e.class}: #{e}"
191
+ end
192
+ end
193
+ end
194
+
195
+ halt util.stats
196
+ end
197
+
198
+ # Helpers to create a simple DSL for scriptlets
199
+ def format(fmt)
200
+ @fmt = fmt
201
+ end
202
+
203
+ def fields(&blk)
204
+ @flds = blk
205
+ end
206
+
207
+ def identity
208
+ @node[:identity]
209
+ end
210
+
211
+ def facts
212
+ @node[:facts]
213
+ end
214
+
215
+ def classes
216
+ @node[:classes]
217
+ end
218
+
219
+ def agents
220
+ @node[:agents]
221
+ end
222
+
223
+ def page_length(len)
224
+ @page_length = len
225
+ end
226
+
227
+ def page_heading(fmt)
228
+ @page_heading = fmt
229
+ end
230
+
231
+ def page_body(fmt)
232
+ @page_body = fmt
233
+ end
234
+
235
+ # Expects a simple printf style format and apply it to
236
+ # each node:
237
+ #
238
+ # inventory do
239
+ # format "%s:\t\t%s\t\t%s"
240
+ #
241
+ # fields { [ identity, facts["serialnumber"], facts["productname"] ] }
242
+ # end
243
+ def inventory(&blk)
244
+ raise "Need to give a block to inventory" unless block_given?
245
+
246
+ blk.call if block_given?
247
+
248
+ raise "Need to define a format" if @fmt.nil?
249
+ raise "Need to define inventory fields" if @flds.nil?
250
+
251
+ util = rpcclient("rpcutil")
252
+ util.progress = false
253
+
254
+ util.inventory do |t, resp|
255
+ @node = {:identity => resp[:sender],
256
+ :facts => resp[:data][:facts],
257
+ :classes => resp[:data][:classes],
258
+ :agents => resp[:data][:agents]}
259
+
260
+ puts @fmt % @flds.call
261
+ end
262
+ end
263
+
264
+ # Use the ruby formatr gem to build reports using Perls formats
265
+ #
266
+ # It is kind of ugly but brings a lot of flexibility in report
267
+ # writing without building an entire reporting language.
268
+ #
269
+ # You need to have formatr installed to enable reports like:
270
+ #
271
+ # formatted_inventory do
272
+ # page_length 20
273
+ #
274
+ # page_heading <<TOP
275
+ #
276
+ # Node Report @<<<<<<<<<<<<<<<<<<<<<<<<<
277
+ # time
278
+ #
279
+ # Hostname: Customer: Distribution:
280
+ # -------------------------------------------------------------------------
281
+ # TOP
282
+ #
283
+ # page_body <<BODY
284
+ #
285
+ # @<<<<<<<<<<<<<<<< @<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
286
+ # identity, facts["customer"], facts["lsbdistdescription"]
287
+ # @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
288
+ # facts["processor0"]
289
+ # BODY
290
+ # end
291
+ def formatted_inventory(&blk)
292
+ require 'formatr'
293
+
294
+ raise "Need to give a block to formatted_inventory" unless block_given?
295
+
296
+ blk.call if block_given?
297
+
298
+ raise "Need to define page body format" if @page_body.nil?
299
+
300
+ body_fmt = FormatR::Format.new(@page_heading, @page_body)
301
+ body_fmt.setPageLength(@page_length)
302
+ time = Time.now
303
+
304
+ util = rpcclient("rpcutil")
305
+ util.progress = false
306
+
307
+ util.inventory do |t, resp|
308
+ @node = {:identity => resp[:sender],
309
+ :facts => resp[:data][:facts],
310
+ :classes => resp[:data][:classes],
311
+ :agents => resp[:data][:agents]}
312
+
313
+ body_fmt.printFormat(binding)
314
+ end
315
+ rescue Exception => e
316
+ STDERR.puts "Could not create report: #{e.class}: #{e}"
317
+ exit 1
318
+ end
319
+
320
+ @fmt = nil
321
+ @flds = nil
322
+ @page_heading = nil
323
+ @page_body = nil
324
+ @page_length = 40
325
+
326
+ def main
327
+ if configuration[:script]
328
+ if File.exist?(configuration[:script])
329
+ eval(File.read(configuration[:script]))
330
+ else
331
+ raise "Could not find script to run: #{configuration[:script]}"
332
+ end
333
+
334
+ elsif configuration[:collectivemap]
335
+ collectives_map(configuration[:collectivemap])
336
+
337
+ elsif configuration[:collectives]
338
+ collectives_report
339
+
340
+ else
341
+ node_inventory
342
+ end
343
+ end
344
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+ module MCollective
3
+ class Application::Ping<Application
4
+ description "Ping all nodes"
5
+
6
+ option :graph,
7
+ :description => "Shows a graph of ping distribution",
8
+ :arguments => ["--graph", "-g"],
9
+ :default => false,
10
+ :type => :bool
11
+
12
+ # Convert the times structure into a array representing
13
+ # buckets of responses in 50 ms intervals. Return a small
14
+ # sparkline graph using UTF8 characters
15
+ def spark(resp_times)
16
+ return "" unless configuration[:graph] || Config.instance.pluginconf["rpc.graph"]
17
+
18
+ ticks=%w[▁ ▂ ▃ ▄ ▅ ▆ ▇]
19
+
20
+ histo = {}
21
+
22
+ # round each time to its nearest 50ms
23
+ # and keep a count for each 50ms
24
+ resp_times.each do |time|
25
+ time = Integer(time + 50 - (time % 50))
26
+ histo[time] ||= 0
27
+ histo[time] += 1
28
+ end
29
+
30
+ # set the 50ms intervals that saw no traffic to 0
31
+ ((histo.keys.max - histo.keys.min) / 50).times do |i|
32
+ time = (i * 50) + histo.keys.min
33
+ histo[time] = 0 unless histo[time]
34
+ end
35
+
36
+ # get a numerically sorted list of times
37
+ histo = histo.keys.sort.map{|k| histo[k]}
38
+
39
+ range = histo.max - histo.min
40
+ scale = ticks.size - 1
41
+ distance = histo.max.to_f / scale
42
+
43
+ histo.map do |val|
44
+ tick = (val / distance).round
45
+ tick = 0 if tick < 0
46
+
47
+ ticks[tick]
48
+ end.join
49
+ end
50
+
51
+ def main
52
+ client = MCollective::Client.new(options)
53
+
54
+ start = Time.now.to_f
55
+ times = []
56
+
57
+ client.req("ping", "discovery") do |resp|
58
+ times << (Time.now.to_f - start) * 1000
59
+
60
+ puts "%-40s time=%.2f ms" % [resp[:senderid], times.last]
61
+ end
62
+
63
+ puts("\n\n---- ping statistics ----")
64
+
65
+ if times.size > 0
66
+ sum = times.inject(0){|acc,i|acc +i}
67
+ avg = sum / times.length.to_f
68
+
69
+ puts "%d replies max: %.2f min: %.2f avg: %.2f %s" % [times.size, times.max, times.min, avg, spark(times)]
70
+ else
71
+ puts("No responses received")
72
+ end
73
+
74
+ halt client.stats
75
+ end
76
+ end
77
+ end