choria-mcorpc-support 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,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
|