File: //proc/thread-self/root/opt/puppetlabs/puppet/lib/ruby/vendor_ruby/mcollective/discovery.rb
module MCollective
class Discovery
def initialize(client)
@known_methods = find_known_methods
@default_method = Config.instance.default_discovery_method
@client = client
end
def find_known_methods
PluginManager.find("discovery")
end
def has_method?(method)
@known_methods.include?(method)
end
def force_direct_mode?
discovery_method != "mc"
end
def discovery_method
method = "mc"
if @client.options[:discovery_method]
method = @client.options[:discovery_method]
else
method = @default_method
end
raise "Unknown discovery method %s" % method unless has_method?(method)
unless method == "mc"
raise "Custom discovery methods require direct addressing mode" unless Config.instance.direct_addressing
end
return method
end
def discovery_class
method = discovery_method.capitalize
PluginManager.loadclass("MCollective::Discovery::#{method}") unless self.class.const_defined?(method)
self.class.const_get(method)
end
def ddl
@ddl ||= DDL.new(discovery_method, :discovery)
# if the discovery method got changed we might have an old DDL cached
# this will detect that and reread the correct DDL from disk
unless @ddl.meta[:name] == discovery_method
@ddl = DDL.new(discovery_method, :discovery)
end
return @ddl
end
# Agent filters are always present no matter what, so we cant raise an error if the capabilities
# suggest the discovery method cant do agents we just have to rely on the discovery plugin to not
# do stupid things in the presense of a agent filter
def check_capabilities(filter)
capabilities = ddl.discovery_interface[:capabilities]
unless capabilities.include?(:classes)
raise "Cannot use class filters while using the '%s' discovery method" % discovery_method unless filter["cf_class"].empty?
end
unless capabilities.include?(:facts)
raise "Cannot use fact filters while using the '%s' discovery method" % discovery_method unless filter["fact"].empty?
end
unless capabilities.include?(:identity)
raise "Cannot use identity filters while using the '%s' discovery method" % discovery_method unless filter["identity"].empty?
end
unless capabilities.include?(:compound)
raise "Cannot use compound filters while using the '%s' discovery method" % discovery_method unless filter["compound"].empty?
end
end
# checks if compound filters are used and then forces the 'mc' discovery plugin
def force_discovery_method_by_filter(filter)
unless discovery_method == "mc"
unless filter["compound"].empty?
Log.info "Switching to mc discovery method because compound filters are used"
@client.options[:discovery_method] = "mc"
return true
end
end
return false
end
# if a compound filter is specified and it has any function
# then we read the DDL for each of those plugins and sum up
# the timeout declared in the DDL
def timeout_for_compound_filter(compound_filter)
return 0 if compound_filter.nil? || compound_filter.empty?
timeout = 0
compound_filter.each do |filter|
filter.each do |statement|
if statement["fstatement"]
pluginname = Data.pluginname(statement["fstatement"]["name"])
ddl = DDL.new(pluginname, :data)
timeout += ddl.meta[:timeout]
end
end
end
timeout
end
def discovery_timeout(timeout, filter)
timeout = ddl.meta[:timeout] unless timeout
unless (filter["compound"] && filter["compound"].empty?)
timeout + timeout_for_compound_filter(filter["compound"])
else
timeout
end
end
def discover(filter, timeout, limit)
raise "Limit has to be an integer" unless limit.is_a?(Integer)
force_discovery_method_by_filter(filter)
check_capabilities(filter)
discovered = discovery_class.discover(filter, discovery_timeout(timeout, filter), limit, @client)
if limit > 0
return discovered[0,limit]
else
return discovered
end
end
end
end