choria-mcorpc-support 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/mco +64 -0
- data/lib/mcollective.rb +63 -0
- data/lib/mcollective/agent.rb +5 -0
- data/lib/mcollective/agents.rb +149 -0
- data/lib/mcollective/aggregate.rb +85 -0
- data/lib/mcollective/aggregate/average.ddl +33 -0
- data/lib/mcollective/aggregate/average.rb +29 -0
- data/lib/mcollective/aggregate/base.rb +40 -0
- data/lib/mcollective/aggregate/result.rb +9 -0
- data/lib/mcollective/aggregate/result/base.rb +25 -0
- data/lib/mcollective/aggregate/result/collection_result.rb +19 -0
- data/lib/mcollective/aggregate/result/numeric_result.rb +13 -0
- data/lib/mcollective/aggregate/sum.ddl +33 -0
- data/lib/mcollective/aggregate/sum.rb +18 -0
- data/lib/mcollective/aggregate/summary.ddl +33 -0
- data/lib/mcollective/aggregate/summary.rb +53 -0
- data/lib/mcollective/application.rb +365 -0
- data/lib/mcollective/application/completion.rb +104 -0
- data/lib/mcollective/application/describe_filter.rb +87 -0
- data/lib/mcollective/application/facts.rb +62 -0
- data/lib/mcollective/application/find.rb +23 -0
- data/lib/mcollective/application/help.rb +28 -0
- data/lib/mcollective/application/inventory.rb +344 -0
- data/lib/mcollective/application/ping.rb +82 -0
- data/lib/mcollective/application/plugin.rb +369 -0
- data/lib/mcollective/application/rpc.rb +111 -0
- data/lib/mcollective/applications.rb +134 -0
- data/lib/mcollective/cache.rb +145 -0
- data/lib/mcollective/client.rb +353 -0
- data/lib/mcollective/config.rb +245 -0
- data/lib/mcollective/connector.rb +18 -0
- data/lib/mcollective/connector/base.rb +26 -0
- data/lib/mcollective/data.rb +91 -0
- data/lib/mcollective/data/agent_data.ddl +22 -0
- data/lib/mcollective/data/agent_data.rb +17 -0
- data/lib/mcollective/data/base.rb +67 -0
- data/lib/mcollective/data/collective_data.ddl +20 -0
- data/lib/mcollective/data/collective_data.rb +9 -0
- data/lib/mcollective/data/fact_data.ddl +28 -0
- data/lib/mcollective/data/fact_data.rb +55 -0
- data/lib/mcollective/data/fstat_data.ddl +89 -0
- data/lib/mcollective/data/fstat_data.rb +56 -0
- data/lib/mcollective/data/result.rb +45 -0
- data/lib/mcollective/ddl.rb +113 -0
- data/lib/mcollective/ddl/agentddl.rb +253 -0
- data/lib/mcollective/ddl/base.rb +217 -0
- data/lib/mcollective/ddl/dataddl.rb +56 -0
- data/lib/mcollective/ddl/discoveryddl.rb +52 -0
- data/lib/mcollective/ddl/validatorddl.rb +6 -0
- data/lib/mcollective/discovery.rb +143 -0
- data/lib/mcollective/discovery/flatfile.ddl +11 -0
- data/lib/mcollective/discovery/flatfile.rb +48 -0
- data/lib/mcollective/discovery/mc.ddl +11 -0
- data/lib/mcollective/discovery/mc.rb +30 -0
- data/lib/mcollective/discovery/stdin.ddl +11 -0
- data/lib/mcollective/discovery/stdin.rb +68 -0
- data/lib/mcollective/exceptions.rb +28 -0
- data/lib/mcollective/facts.rb +39 -0
- data/lib/mcollective/facts/base.rb +100 -0
- data/lib/mcollective/facts/yaml_facts.rb +65 -0
- data/lib/mcollective/generators.rb +7 -0
- data/lib/mcollective/generators/agent_generator.rb +51 -0
- data/lib/mcollective/generators/base.rb +46 -0
- data/lib/mcollective/generators/data_generator.rb +51 -0
- data/lib/mcollective/generators/templates/action_snippet.erb +13 -0
- data/lib/mcollective/generators/templates/data_input_snippet.erb +7 -0
- data/lib/mcollective/generators/templates/ddl.erb +8 -0
- data/lib/mcollective/generators/templates/plugin.erb +7 -0
- data/lib/mcollective/log.rb +118 -0
- data/lib/mcollective/logger.rb +5 -0
- data/lib/mcollective/logger/base.rb +77 -0
- data/lib/mcollective/logger/console_logger.rb +61 -0
- data/lib/mcollective/logger/file_logger.rb +53 -0
- data/lib/mcollective/logger/syslog_logger.rb +53 -0
- data/lib/mcollective/matcher.rb +224 -0
- data/lib/mcollective/matcher/parser.rb +128 -0
- data/lib/mcollective/matcher/scanner.rb +241 -0
- data/lib/mcollective/message.rb +248 -0
- data/lib/mcollective/monkey_patches.rb +152 -0
- data/lib/mcollective/optionparser.rb +197 -0
- data/lib/mcollective/pluginmanager.rb +180 -0
- data/lib/mcollective/pluginpackager.rb +98 -0
- data/lib/mcollective/pluginpackager/agent_definition.rb +94 -0
- data/lib/mcollective/pluginpackager/debpackage_packager.rb +237 -0
- data/lib/mcollective/pluginpackager/modulepackage_packager.rb +127 -0
- data/lib/mcollective/pluginpackager/ospackage_packager.rb +59 -0
- data/lib/mcollective/pluginpackager/rpmpackage_packager.rb +180 -0
- data/lib/mcollective/pluginpackager/standard_definition.rb +69 -0
- data/lib/mcollective/pluginpackager/templates/debian/Makefile.erb +7 -0
- data/lib/mcollective/pluginpackager/templates/debian/changelog.erb +5 -0
- data/lib/mcollective/pluginpackager/templates/debian/compat.erb +1 -0
- data/lib/mcollective/pluginpackager/templates/debian/control.erb +15 -0
- data/lib/mcollective/pluginpackager/templates/debian/copyright.erb +8 -0
- data/lib/mcollective/pluginpackager/templates/debian/rules.erb +6 -0
- data/lib/mcollective/pluginpackager/templates/module/Modulefile.erb +5 -0
- data/lib/mcollective/pluginpackager/templates/module/README.md.erb +37 -0
- data/lib/mcollective/pluginpackager/templates/module/_manifest.pp.erb +9 -0
- data/lib/mcollective/pluginpackager/templates/redhat/rpm_spec.erb +63 -0
- data/lib/mcollective/registration/base.rb +91 -0
- data/lib/mcollective/rpc.rb +182 -0
- data/lib/mcollective/rpc/actionrunner.rb +158 -0
- data/lib/mcollective/rpc/agent.rb +374 -0
- data/lib/mcollective/rpc/audit.rb +38 -0
- data/lib/mcollective/rpc/client.rb +1066 -0
- data/lib/mcollective/rpc/helpers.rb +321 -0
- data/lib/mcollective/rpc/progress.rb +63 -0
- data/lib/mcollective/rpc/reply.rb +87 -0
- data/lib/mcollective/rpc/request.rb +86 -0
- data/lib/mcollective/rpc/result.rb +90 -0
- data/lib/mcollective/rpc/stats.rb +294 -0
- data/lib/mcollective/runnerstats.rb +90 -0
- data/lib/mcollective/security.rb +26 -0
- data/lib/mcollective/security/base.rb +244 -0
- data/lib/mcollective/shell.rb +126 -0
- data/lib/mcollective/ssl.rb +285 -0
- data/lib/mcollective/util.rb +579 -0
- data/lib/mcollective/validator.rb +85 -0
- data/lib/mcollective/validator/array_validator.ddl +7 -0
- data/lib/mcollective/validator/array_validator.rb +9 -0
- data/lib/mcollective/validator/ipv4address_validator.ddl +7 -0
- data/lib/mcollective/validator/ipv4address_validator.rb +16 -0
- data/lib/mcollective/validator/ipv6address_validator.ddl +7 -0
- data/lib/mcollective/validator/ipv6address_validator.rb +16 -0
- data/lib/mcollective/validator/length_validator.ddl +7 -0
- data/lib/mcollective/validator/length_validator.rb +11 -0
- data/lib/mcollective/validator/regex_validator.ddl +7 -0
- data/lib/mcollective/validator/regex_validator.rb +9 -0
- data/lib/mcollective/validator/shellsafe_validator.ddl +7 -0
- data/lib/mcollective/validator/shellsafe_validator.rb +13 -0
- data/lib/mcollective/validator/typecheck_validator.ddl +7 -0
- data/lib/mcollective/validator/typecheck_validator.rb +28 -0
- metadata +215 -0
|
@@ -0,0 +1,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
|