choria-mcorpc-support 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/bin/mco +64 -0
  3. data/lib/mcollective.rb +63 -0
  4. data/lib/mcollective/agent.rb +5 -0
  5. data/lib/mcollective/agents.rb +149 -0
  6. data/lib/mcollective/aggregate.rb +85 -0
  7. data/lib/mcollective/aggregate/average.ddl +33 -0
  8. data/lib/mcollective/aggregate/average.rb +29 -0
  9. data/lib/mcollective/aggregate/base.rb +40 -0
  10. data/lib/mcollective/aggregate/result.rb +9 -0
  11. data/lib/mcollective/aggregate/result/base.rb +25 -0
  12. data/lib/mcollective/aggregate/result/collection_result.rb +19 -0
  13. data/lib/mcollective/aggregate/result/numeric_result.rb +13 -0
  14. data/lib/mcollective/aggregate/sum.ddl +33 -0
  15. data/lib/mcollective/aggregate/sum.rb +18 -0
  16. data/lib/mcollective/aggregate/summary.ddl +33 -0
  17. data/lib/mcollective/aggregate/summary.rb +53 -0
  18. data/lib/mcollective/application.rb +365 -0
  19. data/lib/mcollective/application/completion.rb +104 -0
  20. data/lib/mcollective/application/describe_filter.rb +87 -0
  21. data/lib/mcollective/application/facts.rb +62 -0
  22. data/lib/mcollective/application/find.rb +23 -0
  23. data/lib/mcollective/application/help.rb +28 -0
  24. data/lib/mcollective/application/inventory.rb +344 -0
  25. data/lib/mcollective/application/ping.rb +82 -0
  26. data/lib/mcollective/application/plugin.rb +369 -0
  27. data/lib/mcollective/application/rpc.rb +111 -0
  28. data/lib/mcollective/applications.rb +134 -0
  29. data/lib/mcollective/cache.rb +145 -0
  30. data/lib/mcollective/client.rb +353 -0
  31. data/lib/mcollective/config.rb +245 -0
  32. data/lib/mcollective/connector.rb +18 -0
  33. data/lib/mcollective/connector/base.rb +26 -0
  34. data/lib/mcollective/data.rb +91 -0
  35. data/lib/mcollective/data/agent_data.ddl +22 -0
  36. data/lib/mcollective/data/agent_data.rb +17 -0
  37. data/lib/mcollective/data/base.rb +67 -0
  38. data/lib/mcollective/data/collective_data.ddl +20 -0
  39. data/lib/mcollective/data/collective_data.rb +9 -0
  40. data/lib/mcollective/data/fact_data.ddl +28 -0
  41. data/lib/mcollective/data/fact_data.rb +55 -0
  42. data/lib/mcollective/data/fstat_data.ddl +89 -0
  43. data/lib/mcollective/data/fstat_data.rb +56 -0
  44. data/lib/mcollective/data/result.rb +45 -0
  45. data/lib/mcollective/ddl.rb +113 -0
  46. data/lib/mcollective/ddl/agentddl.rb +253 -0
  47. data/lib/mcollective/ddl/base.rb +217 -0
  48. data/lib/mcollective/ddl/dataddl.rb +56 -0
  49. data/lib/mcollective/ddl/discoveryddl.rb +52 -0
  50. data/lib/mcollective/ddl/validatorddl.rb +6 -0
  51. data/lib/mcollective/discovery.rb +143 -0
  52. data/lib/mcollective/discovery/flatfile.ddl +11 -0
  53. data/lib/mcollective/discovery/flatfile.rb +48 -0
  54. data/lib/mcollective/discovery/mc.ddl +11 -0
  55. data/lib/mcollective/discovery/mc.rb +30 -0
  56. data/lib/mcollective/discovery/stdin.ddl +11 -0
  57. data/lib/mcollective/discovery/stdin.rb +68 -0
  58. data/lib/mcollective/exceptions.rb +28 -0
  59. data/lib/mcollective/facts.rb +39 -0
  60. data/lib/mcollective/facts/base.rb +100 -0
  61. data/lib/mcollective/facts/yaml_facts.rb +65 -0
  62. data/lib/mcollective/generators.rb +7 -0
  63. data/lib/mcollective/generators/agent_generator.rb +51 -0
  64. data/lib/mcollective/generators/base.rb +46 -0
  65. data/lib/mcollective/generators/data_generator.rb +51 -0
  66. data/lib/mcollective/generators/templates/action_snippet.erb +13 -0
  67. data/lib/mcollective/generators/templates/data_input_snippet.erb +7 -0
  68. data/lib/mcollective/generators/templates/ddl.erb +8 -0
  69. data/lib/mcollective/generators/templates/plugin.erb +7 -0
  70. data/lib/mcollective/log.rb +118 -0
  71. data/lib/mcollective/logger.rb +5 -0
  72. data/lib/mcollective/logger/base.rb +77 -0
  73. data/lib/mcollective/logger/console_logger.rb +61 -0
  74. data/lib/mcollective/logger/file_logger.rb +53 -0
  75. data/lib/mcollective/logger/syslog_logger.rb +53 -0
  76. data/lib/mcollective/matcher.rb +224 -0
  77. data/lib/mcollective/matcher/parser.rb +128 -0
  78. data/lib/mcollective/matcher/scanner.rb +241 -0
  79. data/lib/mcollective/message.rb +248 -0
  80. data/lib/mcollective/monkey_patches.rb +152 -0
  81. data/lib/mcollective/optionparser.rb +197 -0
  82. data/lib/mcollective/pluginmanager.rb +180 -0
  83. data/lib/mcollective/pluginpackager.rb +98 -0
  84. data/lib/mcollective/pluginpackager/agent_definition.rb +94 -0
  85. data/lib/mcollective/pluginpackager/debpackage_packager.rb +237 -0
  86. data/lib/mcollective/pluginpackager/modulepackage_packager.rb +127 -0
  87. data/lib/mcollective/pluginpackager/ospackage_packager.rb +59 -0
  88. data/lib/mcollective/pluginpackager/rpmpackage_packager.rb +180 -0
  89. data/lib/mcollective/pluginpackager/standard_definition.rb +69 -0
  90. data/lib/mcollective/pluginpackager/templates/debian/Makefile.erb +7 -0
  91. data/lib/mcollective/pluginpackager/templates/debian/changelog.erb +5 -0
  92. data/lib/mcollective/pluginpackager/templates/debian/compat.erb +1 -0
  93. data/lib/mcollective/pluginpackager/templates/debian/control.erb +15 -0
  94. data/lib/mcollective/pluginpackager/templates/debian/copyright.erb +8 -0
  95. data/lib/mcollective/pluginpackager/templates/debian/rules.erb +6 -0
  96. data/lib/mcollective/pluginpackager/templates/module/Modulefile.erb +5 -0
  97. data/lib/mcollective/pluginpackager/templates/module/README.md.erb +37 -0
  98. data/lib/mcollective/pluginpackager/templates/module/_manifest.pp.erb +9 -0
  99. data/lib/mcollective/pluginpackager/templates/redhat/rpm_spec.erb +63 -0
  100. data/lib/mcollective/registration/base.rb +91 -0
  101. data/lib/mcollective/rpc.rb +182 -0
  102. data/lib/mcollective/rpc/actionrunner.rb +158 -0
  103. data/lib/mcollective/rpc/agent.rb +374 -0
  104. data/lib/mcollective/rpc/audit.rb +38 -0
  105. data/lib/mcollective/rpc/client.rb +1066 -0
  106. data/lib/mcollective/rpc/helpers.rb +321 -0
  107. data/lib/mcollective/rpc/progress.rb +63 -0
  108. data/lib/mcollective/rpc/reply.rb +87 -0
  109. data/lib/mcollective/rpc/request.rb +86 -0
  110. data/lib/mcollective/rpc/result.rb +90 -0
  111. data/lib/mcollective/rpc/stats.rb +294 -0
  112. data/lib/mcollective/runnerstats.rb +90 -0
  113. data/lib/mcollective/security.rb +26 -0
  114. data/lib/mcollective/security/base.rb +244 -0
  115. data/lib/mcollective/shell.rb +126 -0
  116. data/lib/mcollective/ssl.rb +285 -0
  117. data/lib/mcollective/util.rb +579 -0
  118. data/lib/mcollective/validator.rb +85 -0
  119. data/lib/mcollective/validator/array_validator.ddl +7 -0
  120. data/lib/mcollective/validator/array_validator.rb +9 -0
  121. data/lib/mcollective/validator/ipv4address_validator.ddl +7 -0
  122. data/lib/mcollective/validator/ipv4address_validator.rb +16 -0
  123. data/lib/mcollective/validator/ipv6address_validator.ddl +7 -0
  124. data/lib/mcollective/validator/ipv6address_validator.rb +16 -0
  125. data/lib/mcollective/validator/length_validator.ddl +7 -0
  126. data/lib/mcollective/validator/length_validator.rb +11 -0
  127. data/lib/mcollective/validator/regex_validator.ddl +7 -0
  128. data/lib/mcollective/validator/regex_validator.rb +9 -0
  129. data/lib/mcollective/validator/shellsafe_validator.ddl +7 -0
  130. data/lib/mcollective/validator/shellsafe_validator.rb +13 -0
  131. data/lib/mcollective/validator/typecheck_validator.ddl +7 -0
  132. data/lib/mcollective/validator/typecheck_validator.rb +28 -0
  133. metadata +215 -0
@@ -0,0 +1,245 @@
1
+ module MCollective
2
+ # A pretty sucky config class, ripe for refactoring/improving
3
+ class Config
4
+ include Singleton
5
+
6
+ attr_accessor :mode
7
+
8
+ attr_reader :daemonize, :pluginconf, :configured
9
+ attr_reader :logfile, :keeplogs, :max_log_size, :loglevel, :logfacility
10
+ attr_reader :identity, :daemonize, :connector, :securityprovider, :factsource
11
+ attr_reader :registration, :registerinterval, :classesfile
12
+ attr_reader :rpcauditprovider, :rpcaudit, :configdir, :rpcauthprovider
13
+ attr_reader :rpcauthorization, :color, :configfile
14
+ attr_reader :rpclimitmethod, :logger_type, :fact_cache_time, :collectives
15
+ attr_reader :main_collective, :ssl_cipher, :registration_collective
16
+ attr_reader :direct_addressing, :direct_addressing_threshold, :ttl
17
+ attr_reader :default_discovery_method, :default_discovery_options
18
+ attr_reader :publish_timeout, :threaded, :soft_shutdown, :activate_agents
19
+ attr_reader :registration_splay, :discovery_timeout, :soft_shutdown_timeout
20
+ attr_reader :connection_timeout, :default_batch_size, :default_batch_sleep_time
21
+
22
+ def initialize
23
+ @configured = false
24
+ end
25
+
26
+ def loadconfig(configfile)
27
+ set_config_defaults(configfile)
28
+
29
+ if File.exists?(configfile)
30
+ libdirs = []
31
+ File.readlines(configfile).each do |line|
32
+
33
+ # strip blank spaces, tabs etc off the end of all lines
34
+ line.gsub!(/\s*$/, "")
35
+
36
+ unless line =~ /^#|^$/
37
+ if (line =~ /(.+?)\s*=\s*(.+)/)
38
+ key = $1.strip
39
+ val = $2
40
+
41
+ begin
42
+ case key
43
+ when "registration"
44
+ @registration = val.capitalize
45
+ when "registration_collective"
46
+ @registration_collective = val
47
+ when "registerinterval"
48
+ @registerinterval = Integer(val)
49
+ when "registration_splay"
50
+ @registration_splay = Util.str_to_bool(val)
51
+ when "collectives"
52
+ @collectives = val.split(",").map {|c| c.strip}
53
+ when "main_collective"
54
+ @main_collective = val
55
+ when "logfile"
56
+ @logfile = val
57
+ when "keeplogs"
58
+ @keeplogs = Integer(val)
59
+ when "max_log_size"
60
+ @max_log_size = Integer(val)
61
+ when "loglevel"
62
+ @loglevel = val
63
+ when "logfacility"
64
+ @logfacility = val
65
+ when "libdir"
66
+ paths = val.split(File::PATH_SEPARATOR)
67
+ paths.each do |path|
68
+ raise("libdir paths should be absolute paths but '%s' is relative" % path) unless Util.absolute_path?(path)
69
+
70
+ libdirs << path
71
+ end
72
+ when "identity"
73
+ @identity = val
74
+ when "direct_addressing"
75
+ @direct_addressing = Util.str_to_bool(val)
76
+ when "direct_addressing_threshold"
77
+ @direct_addressing_threshold = Integer(val)
78
+ when "color"
79
+ @color = Util.str_to_bool(val)
80
+ when "daemonize"
81
+ @daemonize = Util.str_to_bool(val)
82
+ when "securityprovider"
83
+ @securityprovider = val.capitalize
84
+ when "factsource"
85
+ @factsource = val.capitalize
86
+ when "connector"
87
+ @connector = val.capitalize
88
+ when "classesfile"
89
+ @classesfile = val
90
+ when /^plugin.(.+)$/
91
+ @pluginconf[$1] = val
92
+ when "discovery_timeout"
93
+ @discovery_timeout = Integer(val)
94
+ when "publish_timeout"
95
+ @publish_timeout = Integer(val)
96
+ when "connection_timeout"
97
+ @connection_timeout = Integer(val)
98
+ when "rpcaudit"
99
+ @rpcaudit = Util.str_to_bool(val)
100
+ when "rpcauditprovider"
101
+ @rpcauditprovider = val.capitalize
102
+ when "rpcauthorization"
103
+ @rpcauthorization = Util.str_to_bool(val)
104
+ when "rpcauthprovider"
105
+ @rpcauthprovider = val.capitalize
106
+ when "rpclimitmethod"
107
+ @rpclimitmethod = val.to_sym
108
+ when "logger_type"
109
+ @logger_type = val
110
+ when "fact_cache_time"
111
+ @fact_cache_time = Integer(val)
112
+ when "ssl_cipher"
113
+ @ssl_cipher = val
114
+ when "threaded"
115
+ @threaded = Util.str_to_bool(val)
116
+ when "ttl"
117
+ @ttl = Integer(val)
118
+ when "default_discovery_options"
119
+ @default_discovery_options << val
120
+ when "default_discovery_method"
121
+ @default_discovery_method = val
122
+ when "soft_shutdown"
123
+ @soft_shutdown = Util.str_to_bool(val)
124
+ when "soft_shutdown_timeout"
125
+ @soft_shutdown_timeout = Integer(val)
126
+ when "activate_agents"
127
+ @activate_agents = Util.str_to_bool(val)
128
+ when "default_batch_size"
129
+ @default_batch_size = Integer(val)
130
+ when "default_batch_sleep_time"
131
+ @default_batch_sleep_time = Float(val)
132
+ when "topicprefix", "topicsep", "queueprefix", "rpchelptemplate", "helptemplatedir"
133
+ Log.warn("Use of deprecated '#{key}' option. This option is ignored and should be removed from '#{configfile}'")
134
+ else
135
+ raise("Unknown config parameter '#{key}'")
136
+ end
137
+ rescue ArgumentError => e
138
+ raise "Could not parse value for configuration option '#{key}' with value '#{val}'"
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ read_plugin_config_dir("#{@configdir}/plugin.d")
145
+
146
+ raise 'Identities can only match /\w\.\-/' unless @identity.match(/^[\w\.\-]+$/)
147
+
148
+ @configured = true
149
+
150
+ libdirs.each do |dir|
151
+ unless File.directory?(dir)
152
+ Log.debug("Cannot find libdir: #{dir}")
153
+ end
154
+
155
+ # remove the old one if it exists, we're moving it to the front
156
+ $LOAD_PATH.reject! { |elem| elem == dir }
157
+ $LOAD_PATH.unshift dir
158
+ end
159
+
160
+ if @logger_type == "syslog"
161
+ raise "The sylog logger is not usable on the Windows platform" if Util.windows?
162
+ end
163
+
164
+ PluginManager.loadclass("Mcollective::Facts::#{@factsource}_facts")
165
+ PluginManager.loadclass("Mcollective::Connector::#{@connector}")
166
+ PluginManager.loadclass("Mcollective::Security::#{@securityprovider}")
167
+ PluginManager << {:type => "global_stats", :class => RunnerStats.new}
168
+
169
+ Log.info("The Marionette Collective version #{MCollective::VERSION} started by #{$0} using config file #{configfile}")
170
+ else
171
+ raise("Cannot find config file '#{configfile}'")
172
+ end
173
+ end
174
+
175
+ def set_config_defaults(configfile)
176
+ @stomp = Hash.new
177
+ @subscribe = Array.new
178
+ @pluginconf = Hash.new
179
+ @connector = "base"
180
+ @securityprovider = "Base"
181
+ @factsource = "Yaml"
182
+ @identity = Socket.gethostname
183
+ @registration = "Base"
184
+ @registerinterval = 0
185
+ @registration_collective = nil
186
+ @registration_splay = false
187
+ @classesfile = "/var/lib/puppet/state/classes.txt"
188
+ @rpcaudit = false
189
+ @rpcauditprovider = ""
190
+ @rpcauthorization = false
191
+ @rpcauthprovider = ""
192
+ @configdir = File.dirname(configfile)
193
+ @color = !Util.windows?
194
+ @configfile = configfile
195
+ @logger_type = "file"
196
+ @keeplogs = 5
197
+ @max_log_size = 2097152
198
+ @rpclimitmethod = :first
199
+ @fact_cache_time = 300
200
+ @loglevel = "info"
201
+ @logfacility = "user"
202
+ @collectives = ["mcollective"]
203
+ @main_collective = @collectives.first
204
+ @ssl_cipher = "aes-256-cbc"
205
+ @direct_addressing = true
206
+ @direct_addressing_threshold = 10
207
+ @default_discovery_method = "mc"
208
+ @default_discovery_options = []
209
+ @ttl = 60
210
+ @mode = :client
211
+ @publish_timeout = 2
212
+ @threaded = false
213
+ @soft_shutdown = false
214
+ @soft_shutdown_timeout = nil
215
+ @activate_agents = true
216
+ @connection_timeout = nil
217
+ @default_batch_size = 0
218
+ @default_batch_sleep_time = 1
219
+ end
220
+
221
+ def libdir
222
+ $LOAD_PATH
223
+ end
224
+
225
+ def read_plugin_config_dir(dir)
226
+ return unless File.directory?(dir)
227
+
228
+ Dir.new(dir).each do |pluginconfigfile|
229
+ next unless pluginconfigfile =~ /^([\w]+).cfg$/
230
+
231
+ plugin = $1
232
+ File.open("#{dir}/#{pluginconfigfile}", "r").each do |line|
233
+ # strip blank lines
234
+ line.gsub!(/\s*$/, "")
235
+ next if line =~ /^#|^$/
236
+ if (line =~ /(.+?)\s*=\s*(.+)/)
237
+ key = $1.strip
238
+ val = $2
239
+ @pluginconf["#{plugin}.#{key}"] = val
240
+ end
241
+ end
242
+ end
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,18 @@
1
+ module MCollective
2
+ # Connectors take care of transporting messages between clients and agents,
3
+ # the design doesn't your middleware to be very rich in features. All it
4
+ # really needs is the ability to send and receive messages to named queues/topics.
5
+ #
6
+ # At present there are assumptions about the naming of topics and queues that is
7
+ # compatible with Stomp, ie.
8
+ #
9
+ # /topic/foo.bar/baz
10
+ # /queue/foo.bar/baz
11
+ #
12
+ # This is the only naming format that is supported, but you could replace Stomp
13
+ # with something else that supports the above, see MCollective::Connector::Stomp
14
+ # for the default connector.
15
+ module Connector
16
+ require "mcollective/connector/base"
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ module MCollective
2
+ # Connector plugins handle the communications with the middleware, you can provide your own to speak
3
+ # to something other than Stomp, your plugins must inherit from MCollective::Connector::Base and should
4
+ # provide the following methods:
5
+ #
6
+ # connect - Creates a connection to the middleware, no arguments should get its parameters from the config
7
+ # receive - Receive data from the middleware, should act like a blocking call only returning if/when data
8
+ # was received. It should get data from all subscribed channels/topics. Individual messages
9
+ # should be returned as MCollective::Request objects with the payload provided
10
+ # publish - Takes a target and msg, should send the message to the supplied target topic or destination
11
+ # subscribe - Adds a subscription to a specific message source
12
+ # unsubscribe - Removes a subscription to a specific message source
13
+ # disconnect - Disconnects from the middleware
14
+ #
15
+ # These methods are all that's needed for a new connector protocol and should hopefully be simple
16
+ # enough to not have tied us to Stomp.
17
+ module Connector
18
+ class Base
19
+ def self.inherited(klass)
20
+ plugin_name = klass.to_s.split("::").last.downcase
21
+ ddl = DDL.new(plugin_name, :connector)
22
+ PluginManager << {:type => "connector_plugin", :class => klass.to_s}
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,91 @@
1
+ module MCollective
2
+ module Data
3
+ require "mcollective/data/base"
4
+ require "mcollective/data/result"
5
+
6
+ def self.load_data_sources
7
+ PluginManager.find_and_load("data")
8
+
9
+ PluginManager.grep(/_data$/).each do |plugin|
10
+ begin
11
+ unless PluginManager[plugin].class.activate?
12
+ Log.debug("Disabling data plugin %s due to plugin activation policy" % plugin)
13
+ PluginManager.delete(plugin)
14
+ end
15
+ rescue Exception => e
16
+ Log.debug("Disabling data plugin %s due to exception #{e.class}: #{e}" % plugin)
17
+ PluginManager.delete(plugin)
18
+ end
19
+ end
20
+ end
21
+
22
+ def self.pluginname(plugin)
23
+ plugin.to_s =~ /_data$/i ? plugin.to_s.downcase : "%s_data" % plugin.to_s.downcase
24
+ end
25
+
26
+ def self.[](plugin)
27
+ PluginManager[pluginname(plugin)]
28
+ end
29
+
30
+ # Data.package("httpd").architecture
31
+ def self.method_missing(method, *args)
32
+ super unless PluginManager.include?(pluginname(method))
33
+
34
+ PluginManager[pluginname(method)].lookup(args.first)
35
+ end
36
+
37
+ def self.ddl(plugin)
38
+ DDL.new(pluginname(plugin), :data)
39
+ end
40
+
41
+ def self.ddl_validate(ddl, argument)
42
+ name = ddl.meta[:name]
43
+ query = ddl.entities[:data]
44
+
45
+ raise DDLValidationError, "No dataquery has been defined in the DDL for data plugin #{name}" unless query
46
+
47
+ input = query.fetch(:input, {})
48
+ output = query.fetch(:output, {})
49
+
50
+ raise DDLValidationError, "No output has been defined in the DDL for data plugin #{name}" if output.keys.empty?
51
+
52
+ if input[:query]
53
+ return true if argument.nil? && input[:query][:optional]
54
+
55
+ ddl.validate_input_argument(input, :query, argument)
56
+ else
57
+ raise("No data plugin argument was declared in the %s DDL but an input was supplied" % name) if argument
58
+ return true
59
+ end
60
+ end
61
+
62
+ def self.ddl_has_output?(ddl, output)
63
+ ddl.entities[:data][:output].include?(output.to_sym) rescue false
64
+ end
65
+
66
+ # For an input where the DDL requests a boolean or some number
67
+ # this will convert the input to the right type where possible
68
+ # else just returns the origin input unedited
69
+ #
70
+ # if anything here goes wrong just return the input value
71
+ # this is not really the end of the world or anything since
72
+ # all that will happen is that DDL validation will fail and
73
+ # the user will get an error, no need to be too defensive here
74
+ def self.ddl_transform_input(ddl, input)
75
+ begin
76
+ type = ddl.entities[:data][:input][:query][:type]
77
+
78
+ case type
79
+ when :boolean
80
+ return DDL.string_to_boolean(input)
81
+
82
+ when :number, :integer, :float
83
+ return DDL.string_to_number(input)
84
+ end
85
+ rescue
86
+ end
87
+
88
+ return input
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,22 @@
1
+ metadata :name => "Agent",
2
+ :description => "Meta data about installed MColletive Agents",
3
+ :author => "R.I.Pienaar <rip@devco.net>",
4
+ :license => "ASL 2.0",
5
+ :version => "1.0",
6
+ :url => "https://docs.puppetlabs.com/mcollective/",
7
+ :timeout => 1
8
+
9
+ dataquery :description => "Agent Meta Data" do
10
+ input :query,
11
+ :prompt => "Agent Name",
12
+ :description => "Valid agent name",
13
+ :type => :string,
14
+ :validation => /^[\w\_]+$/,
15
+ :maxlength => 20
16
+
17
+ [:license, :timeout, :description, :url, :version, :author].each do |item|
18
+ output item,
19
+ :description => "Agent #{item}",
20
+ :display_as => item.to_s.capitalize
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ module MCollective
2
+ module Data
3
+ class Agent_data<Base
4
+ query do |plugin|
5
+ raise "No agent called #{plugin} found" unless PluginManager.include?("#{plugin}_agent")
6
+
7
+ agent = PluginManager["#{plugin}_agent"]
8
+
9
+ result[:agent] = plugin
10
+
11
+ [:license, :timeout, :description, :url, :version, :author].each do |item|
12
+ result[item] = agent.meta[item]
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,67 @@
1
+ module MCollective
2
+ module Data
3
+ class Base
4
+ attr_reader :name, :result, :ddl, :timeout
5
+
6
+ # Register plugins that inherits base
7
+ def self.inherited(klass)
8
+ type = klass.to_s.split("::").last.downcase
9
+
10
+ PluginManager << {:type => type, :class => klass.to_s, :single_instance => false}
11
+ end
12
+
13
+ def initialize
14
+ @name = self.class.to_s.split("::").last.downcase
15
+ @ddl = DDL.new(@name, :data)
16
+ @result = Result.new(@ddl.dataquery_interface[:output])
17
+ @timeout = @ddl.meta[:timeout] || 1
18
+
19
+ startup_hook
20
+ end
21
+
22
+ def lookup(what)
23
+ ddl_validate(what)
24
+
25
+ Log.debug("Doing data query %s for '%s'" % [ @name, what ])
26
+
27
+ Timeout::timeout(@timeout) do
28
+ query_data(what)
29
+ end
30
+
31
+ @result
32
+ rescue Timeout::Error
33
+ # Timeout::Error is a inherited from Interrupt which seems a really
34
+ # strange choice, making it an equivelant of ^C and such. Catch it
35
+ # and raise something less critical that will not the runner to just
36
+ # give up the ghost
37
+ msg = "Data plugin %s timed out on query '%s'" % [@name, what]
38
+ Log.error(msg)
39
+ raise MsgTTLExpired, msg
40
+ end
41
+
42
+ def self.query(&block)
43
+ self.module_eval { define_method("query_data", &block) }
44
+ end
45
+
46
+ def ddl_validate(what)
47
+ Data.ddl_validate(@ddl, what)
48
+ end
49
+
50
+ # activate_when do
51
+ # file.exist?("/usr/bin/puppet")
52
+ # end
53
+ def self.activate_when(&block)
54
+ (class << self; self; end).instance_eval do
55
+ define_method("activate?", &block)
56
+ end
57
+ end
58
+
59
+ # Always be active unless a specific block is given with activate_when
60
+ def self.activate?
61
+ return true
62
+ end
63
+
64
+ def startup_hook;end
65
+ end
66
+ end
67
+ end