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.
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