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,217 @@
|
|
1
|
+
module MCollective
|
2
|
+
module DDL
|
3
|
+
# The base class for all kinds of DDL files. DDL files when
|
4
|
+
# run gets parsed and builds up a hash of the basic primitive
|
5
|
+
# types, ideally restricted so it can be converted to JSON though
|
6
|
+
# today there are some Ruby Symbols in them which might be fixed
|
7
|
+
# laster on.
|
8
|
+
#
|
9
|
+
# The Hash being built should be stored in @entities, the format
|
10
|
+
# is generally not prescribed but there's a definite feel to how
|
11
|
+
# DDL files look so study the agent and discovery ones to see how
|
12
|
+
# the structure applies to very different use cases.
|
13
|
+
#
|
14
|
+
# For every plugin type you should have a single word name - that
|
15
|
+
# corresponds to the directory in the libdir where these plugins
|
16
|
+
# live. If you need anything above and beyond 'metadata' in your
|
17
|
+
# plugin DDL then add a PlugintypeDDL class here and add your
|
18
|
+
# specific behaviors to those.
|
19
|
+
class Base
|
20
|
+
attr_reader :meta, :entities, :pluginname, :plugintype, :usage, :requirements
|
21
|
+
|
22
|
+
def initialize(plugin, plugintype=:agent, loadddl=true)
|
23
|
+
@entities = {}
|
24
|
+
@meta = {}
|
25
|
+
@usage = ""
|
26
|
+
@config = Config.instance
|
27
|
+
@pluginname = plugin
|
28
|
+
@plugintype = plugintype.to_sym
|
29
|
+
@requirements = {}
|
30
|
+
|
31
|
+
loadddlfile if loadddl
|
32
|
+
end
|
33
|
+
|
34
|
+
# Generates help using the template based on the data
|
35
|
+
# created with metadata and input.
|
36
|
+
#
|
37
|
+
# If no template name is provided one will be chosen based
|
38
|
+
# on the plugin type. If the provided template path is
|
39
|
+
# not absolute then the template will be loaded either from
|
40
|
+
# the config dir and if that does not exist, default to
|
41
|
+
# /etc/mcollective
|
42
|
+
def help(template=nil)
|
43
|
+
template = template_for_plugintype unless template
|
44
|
+
template = Util.templatepath(template) unless Util.absolute_path?(template)
|
45
|
+
|
46
|
+
template = File.read(template)
|
47
|
+
meta = @meta
|
48
|
+
entities = @entities
|
49
|
+
|
50
|
+
unless template == "metadata-help.erb"
|
51
|
+
metadata_template = Util.templatepath("metadata-help.erb")
|
52
|
+
metadata_template = File.read(metadata_template)
|
53
|
+
metastring = ERB.new(metadata_template, 0, '%')
|
54
|
+
metastring = metastring.result(binding)
|
55
|
+
end
|
56
|
+
|
57
|
+
erb = ERB.new(template, 0, '%')
|
58
|
+
erb.result(binding)
|
59
|
+
end
|
60
|
+
|
61
|
+
def usage(usage_text)
|
62
|
+
@usage = usage_text
|
63
|
+
end
|
64
|
+
|
65
|
+
def template_for_plugintype
|
66
|
+
case @plugintype
|
67
|
+
when :agent
|
68
|
+
return "rpc-help.erb"
|
69
|
+
else
|
70
|
+
if File.exists?(Util.templatepath("#{@plugintype}-help.erb"))
|
71
|
+
return "#{@plugintype}-help.erb"
|
72
|
+
else
|
73
|
+
# Default help template gets loaded if plugintype-help does not exist.
|
74
|
+
return "metadata-help.erb"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def loadddlfile
|
80
|
+
if ddlfile = findddlfile
|
81
|
+
instance_eval(File.read(ddlfile), ddlfile, 1)
|
82
|
+
else
|
83
|
+
raise("Can't find DDL for #{@plugintype} plugin '#{@pluginname}'")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def findddlfile(ddlname=nil, ddltype=nil)
|
88
|
+
ddlname = @pluginname unless ddlname
|
89
|
+
ddltype = @plugintype unless ddltype
|
90
|
+
|
91
|
+
@config.libdir.each do |libdir|
|
92
|
+
ddlfile = File.join([libdir, "mcollective", ddltype.to_s, "#{ddlname}.ddl"])
|
93
|
+
if File.exist?(ddlfile)
|
94
|
+
Log.debug("Found #{ddlname} ddl at #{ddlfile}")
|
95
|
+
return ddlfile
|
96
|
+
end
|
97
|
+
end
|
98
|
+
return false
|
99
|
+
end
|
100
|
+
|
101
|
+
def validate_requirements
|
102
|
+
if requirement = @requirements[:mcollective]
|
103
|
+
if Util.versioncmp(Util.mcollective_version, requirement) < 0
|
104
|
+
raise DDLValidationError, "%s plugin '%s' requires MCollective version %s or newer" % [@plugintype.to_s.capitalize, @pluginname, requirement]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
true
|
109
|
+
end
|
110
|
+
|
111
|
+
# validate strings, lists and booleans, we'll add more types of validators when
|
112
|
+
# all the use cases are clear
|
113
|
+
#
|
114
|
+
# only does validation for arguments actually given, since some might
|
115
|
+
# be optional. We validate the presense of the argument earlier so
|
116
|
+
# this is a safe assumption, just to skip them.
|
117
|
+
#
|
118
|
+
# :string can have maxlength and regex. A maxlength of 0 will bypasss checks
|
119
|
+
# :list has a array of valid values
|
120
|
+
def validate_input_argument(input, key, argument)
|
121
|
+
Validator.load_validators
|
122
|
+
|
123
|
+
case input[key][:type]
|
124
|
+
when :string
|
125
|
+
Validator.validate(argument, :string)
|
126
|
+
|
127
|
+
Validator.length(argument, input[key][:maxlength].to_i)
|
128
|
+
|
129
|
+
Validator.validate(argument, input[key][:validation])
|
130
|
+
|
131
|
+
when :list
|
132
|
+
Validator.validate(argument, input[key][:list])
|
133
|
+
|
134
|
+
else
|
135
|
+
Validator.validate(argument, input[key][:type])
|
136
|
+
end
|
137
|
+
|
138
|
+
return true
|
139
|
+
rescue => e
|
140
|
+
raise DDLValidationError, "Cannot validate input %s: %s" % [key, e.to_s]
|
141
|
+
end
|
142
|
+
|
143
|
+
# Registers an input argument for a given action
|
144
|
+
#
|
145
|
+
# See the documentation for action for how to use this
|
146
|
+
def input(argument, properties)
|
147
|
+
raise "Cannot figure out what entity input #{argument} belongs to" unless @current_entity
|
148
|
+
|
149
|
+
entity = @current_entity
|
150
|
+
|
151
|
+
[:prompt, :description, :type].each do |arg|
|
152
|
+
raise "Input needs a :#{arg} property" unless properties.include?(arg)
|
153
|
+
end
|
154
|
+
|
155
|
+
@entities[entity][:input][argument] = {:prompt => properties[:prompt],
|
156
|
+
:description => properties[:description],
|
157
|
+
:type => properties[:type],
|
158
|
+
:default => properties[:default],
|
159
|
+
:optional => properties[:optional]}
|
160
|
+
|
161
|
+
case properties[:type]
|
162
|
+
when :string
|
163
|
+
raise "Input type :string needs a :validation argument" unless properties.include?(:validation)
|
164
|
+
raise "Input type :string needs a :maxlength argument" unless properties.include?(:maxlength)
|
165
|
+
|
166
|
+
@entities[entity][:input][argument][:validation] = properties[:validation]
|
167
|
+
@entities[entity][:input][argument][:maxlength] = properties[:maxlength]
|
168
|
+
|
169
|
+
when :list
|
170
|
+
raise "Input type :list needs a :list argument" unless properties.include?(:list)
|
171
|
+
|
172
|
+
@entities[entity][:input][argument][:list] = properties[:list]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Registers an output argument for a given action
|
177
|
+
#
|
178
|
+
# See the documentation for action for how to use this
|
179
|
+
def output(argument, properties)
|
180
|
+
raise "Cannot figure out what action input #{argument} belongs to" unless @current_entity
|
181
|
+
raise "Output #{argument} needs a description argument" unless properties.include?(:description)
|
182
|
+
raise "Output #{argument} needs a display_as argument" unless properties.include?(:display_as)
|
183
|
+
|
184
|
+
action = @current_entity
|
185
|
+
|
186
|
+
@entities[action][:output][argument] = {:description => properties[:description],
|
187
|
+
:display_as => properties[:display_as],
|
188
|
+
:default => properties[:default]}
|
189
|
+
end
|
190
|
+
|
191
|
+
def requires(requirement)
|
192
|
+
raise "Requirement should be a hash in the form :item => 'requirement'" unless requirement.is_a?(Hash)
|
193
|
+
|
194
|
+
valid_requirements = [:mcollective]
|
195
|
+
|
196
|
+
requirement.keys.each do |key|
|
197
|
+
unless valid_requirements.include?(key)
|
198
|
+
raise "Requirement %s is not a valid requirement, only %s is supported" % [key, valid_requirements.join(", ")]
|
199
|
+
end
|
200
|
+
|
201
|
+
@requirements[key] = requirement[key]
|
202
|
+
end
|
203
|
+
|
204
|
+
validate_requirements
|
205
|
+
end
|
206
|
+
|
207
|
+
# Registers meta data for the introspection hash
|
208
|
+
def metadata(meta)
|
209
|
+
[:name, :description, :author, :license, :version, :url, :timeout].each do |arg|
|
210
|
+
raise "Metadata needs a :#{arg} property" unless meta.include?(arg)
|
211
|
+
end
|
212
|
+
|
213
|
+
@meta = meta
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module MCollective
|
2
|
+
module DDL
|
3
|
+
# A DDL file for the data query plugins.
|
4
|
+
#
|
5
|
+
# Query plugins can today take only one input by convention in the DDL that
|
6
|
+
# is called :query, otherwise the input is identical to the standard input.
|
7
|
+
#
|
8
|
+
# metadata :name => "Agent",
|
9
|
+
# :description => "Meta data about installed MColletive Agents",
|
10
|
+
# :author => "R.I.Pienaar <rip@devco.net>",
|
11
|
+
# :license => "ASL 2.0",
|
12
|
+
# :version => "1.0",
|
13
|
+
# :url => "https://docs.puppetlabs.com/mcollective/",
|
14
|
+
# :timeout => 1
|
15
|
+
#
|
16
|
+
# dataquery :description => "Agent Meta Data" do
|
17
|
+
# input :query,
|
18
|
+
# :prompt => "Agent Name",
|
19
|
+
# :description => "Valid agent name",
|
20
|
+
# :type => :string,
|
21
|
+
# :validation => /^[\w\_]+$/,
|
22
|
+
# :maxlength => 20
|
23
|
+
#
|
24
|
+
# [:license, :timeout, :description, :url, :version, :author].each do |item|
|
25
|
+
# output item,
|
26
|
+
# :description => "Agent #{item}",
|
27
|
+
# :display_as => item.to_s.capitalize
|
28
|
+
# end
|
29
|
+
# end
|
30
|
+
class DataDDL<Base
|
31
|
+
def dataquery(input, &block)
|
32
|
+
raise "Data queries need a :description" unless input.include?(:description)
|
33
|
+
raise "Data queries can only have one definition" if @entities[:data]
|
34
|
+
|
35
|
+
@entities[:data] = {:description => input[:description],
|
36
|
+
:input => {},
|
37
|
+
:output => {}}
|
38
|
+
|
39
|
+
@current_entity = :data
|
40
|
+
block.call if block_given?
|
41
|
+
@current_entity = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def input(argument, properties)
|
45
|
+
raise "The only valid input name for a data query is 'query'" if argument != :query
|
46
|
+
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the interface for the data query
|
51
|
+
def dataquery_interface
|
52
|
+
@entities[:data] || {}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module MCollective
|
2
|
+
module DDL
|
3
|
+
# DDL for discovery plugins, a full example can be seen below
|
4
|
+
#
|
5
|
+
# metadata :name => "mc",
|
6
|
+
# :description => "MCollective Broadcast based discovery",
|
7
|
+
# :author => "R.I.Pienaar <rip@devco.net>",
|
8
|
+
# :license => "ASL 2.0",
|
9
|
+
# :version => "0.1",
|
10
|
+
# :url => "https://docs.puppetlabs.com/mcollective/",
|
11
|
+
# :timeout => 2
|
12
|
+
#
|
13
|
+
# discovery do
|
14
|
+
# capabilities [:classes, :facts, :identity, :agents, :compound]
|
15
|
+
# end
|
16
|
+
class DiscoveryDDL<Base
|
17
|
+
def discovery_interface
|
18
|
+
@entities[:discovery]
|
19
|
+
end
|
20
|
+
|
21
|
+
# records valid capabilities for discovery plugins
|
22
|
+
def capabilities(*caps)
|
23
|
+
caps = [caps].flatten
|
24
|
+
|
25
|
+
raise "Discovery plugin capabilities can't be empty" if caps.empty?
|
26
|
+
|
27
|
+
caps.each do |cap|
|
28
|
+
if [:classes, :facts, :identity, :agents, :compound].include?(cap)
|
29
|
+
@entities[:discovery][:capabilities] << cap
|
30
|
+
else
|
31
|
+
raise "%s is not a valid capability, valid capabilities are :classes, :facts, :identity, :agents and :compound" % cap
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Creates the definition for new discovery plugins
|
37
|
+
#
|
38
|
+
# discovery do
|
39
|
+
# capabilities [:classes, :facts, :identity, :agents, :compound]
|
40
|
+
# end
|
41
|
+
def discovery(&block)
|
42
|
+
raise "Discovery plugins can only have one definition" if @entities[:discovery]
|
43
|
+
|
44
|
+
@entities[:discovery] = {:capabilities => []}
|
45
|
+
|
46
|
+
@current_entity = :discovery
|
47
|
+
block.call if block_given?
|
48
|
+
@current_entity = nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
module MCollective
|
2
|
+
class Discovery
|
3
|
+
def initialize(client)
|
4
|
+
@known_methods = find_known_methods
|
5
|
+
@default_method = Config.instance.default_discovery_method
|
6
|
+
@client = client
|
7
|
+
end
|
8
|
+
|
9
|
+
def find_known_methods
|
10
|
+
PluginManager.find("discovery")
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_method?(method)
|
14
|
+
@known_methods.include?(method)
|
15
|
+
end
|
16
|
+
|
17
|
+
def force_direct_mode?
|
18
|
+
discovery_method != "mc"
|
19
|
+
end
|
20
|
+
|
21
|
+
def discovery_method
|
22
|
+
method = "mc"
|
23
|
+
|
24
|
+
if @client.options[:discovery_method]
|
25
|
+
method = @client.options[:discovery_method]
|
26
|
+
else
|
27
|
+
method = @default_method
|
28
|
+
end
|
29
|
+
|
30
|
+
raise "Unknown discovery method %s" % method unless has_method?(method)
|
31
|
+
|
32
|
+
unless method == "mc"
|
33
|
+
raise "Custom discovery methods require direct addressing mode" unless Config.instance.direct_addressing
|
34
|
+
end
|
35
|
+
|
36
|
+
return method
|
37
|
+
end
|
38
|
+
|
39
|
+
def discovery_class
|
40
|
+
method = discovery_method.capitalize
|
41
|
+
|
42
|
+
PluginManager.loadclass("MCollective::Discovery::#{method}") unless self.class.const_defined?(method)
|
43
|
+
|
44
|
+
self.class.const_get(method)
|
45
|
+
end
|
46
|
+
|
47
|
+
def ddl
|
48
|
+
@ddl ||= DDL.new(discovery_method, :discovery)
|
49
|
+
|
50
|
+
# if the discovery method got changed we might have an old DDL cached
|
51
|
+
# this will detect that and reread the correct DDL from disk
|
52
|
+
unless @ddl.meta[:name] == discovery_method
|
53
|
+
@ddl = DDL.new(discovery_method, :discovery)
|
54
|
+
end
|
55
|
+
|
56
|
+
return @ddl
|
57
|
+
end
|
58
|
+
|
59
|
+
# Agent filters are always present no matter what, so we cant raise an error if the capabilities
|
60
|
+
# suggest the discovery method cant do agents we just have to rely on the discovery plugin to not
|
61
|
+
# do stupid things in the presense of a agent filter
|
62
|
+
def check_capabilities(filter)
|
63
|
+
capabilities = ddl.discovery_interface[:capabilities]
|
64
|
+
|
65
|
+
unless capabilities.include?(:classes)
|
66
|
+
raise "Cannot use class filters while using the '%s' discovery method" % discovery_method unless filter["cf_class"].empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
unless capabilities.include?(:facts)
|
70
|
+
raise "Cannot use fact filters while using the '%s' discovery method" % discovery_method unless filter["fact"].empty?
|
71
|
+
end
|
72
|
+
|
73
|
+
unless capabilities.include?(:identity)
|
74
|
+
raise "Cannot use identity filters while using the '%s' discovery method" % discovery_method unless filter["identity"].empty?
|
75
|
+
end
|
76
|
+
|
77
|
+
unless capabilities.include?(:compound)
|
78
|
+
raise "Cannot use compound filters while using the '%s' discovery method" % discovery_method unless filter["compound"].empty?
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# checks if compound filters are used and then forces the 'mc' discovery plugin
|
83
|
+
def force_discovery_method_by_filter(filter)
|
84
|
+
unless discovery_method == "mc"
|
85
|
+
unless filter["compound"].empty?
|
86
|
+
Log.info "Switching to mc discovery method because compound filters are used"
|
87
|
+
@client.options[:discovery_method] = "mc"
|
88
|
+
|
89
|
+
return true
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
return false
|
94
|
+
end
|
95
|
+
|
96
|
+
# if a compound filter is specified and it has any function
|
97
|
+
# then we read the DDL for each of those plugins and sum up
|
98
|
+
# the timeout declared in the DDL
|
99
|
+
def timeout_for_compound_filter(compound_filter)
|
100
|
+
return 0 if compound_filter.nil? || compound_filter.empty?
|
101
|
+
|
102
|
+
timeout = 0
|
103
|
+
|
104
|
+
compound_filter.each do |filter|
|
105
|
+
filter.each do |statement|
|
106
|
+
if statement["fstatement"]
|
107
|
+
pluginname = Data.pluginname(statement["fstatement"]["name"])
|
108
|
+
ddl = DDL.new(pluginname, :data)
|
109
|
+
timeout += ddl.meta[:timeout]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
timeout
|
115
|
+
end
|
116
|
+
|
117
|
+
def discovery_timeout(timeout, filter)
|
118
|
+
timeout = ddl.meta[:timeout] unless timeout
|
119
|
+
|
120
|
+
unless (filter["compound"] && filter["compound"].empty?)
|
121
|
+
timeout + timeout_for_compound_filter(filter["compound"])
|
122
|
+
else
|
123
|
+
timeout
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def discover(filter, timeout, limit)
|
128
|
+
raise "Limit has to be an integer" unless limit.is_a?(Integer)
|
129
|
+
|
130
|
+
force_discovery_method_by_filter(filter)
|
131
|
+
|
132
|
+
check_capabilities(filter)
|
133
|
+
|
134
|
+
discovered = discovery_class.discover(filter, discovery_timeout(timeout, filter), limit, @client)
|
135
|
+
|
136
|
+
if limit > 0
|
137
|
+
return discovered[0,limit]
|
138
|
+
else
|
139
|
+
return discovered
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|