4 @known_methods = find_known_methods
5 @default_method = Config.instance.default_discovery_method
10 PluginManager.find("discovery")
13 def has_method?(method)
14 @known_methods.include?(method)
17 def force_direct_mode?
18 discovery_method != "mc"
24 if @client.options[:discovery_method]
25 method = @client.options[:discovery_method]
27 method = @default_method
30 raise "Unknown discovery method %s" % method unless has_method?(method)
33 raise "Custom discovery methods require direct addressing mode" unless Config.instance.direct_addressing
40 method = discovery_method.capitalize
42 PluginManager.loadclass("MCollective::Discovery::#{method}") unless self.class.const_defined?(method)
44 self.class.const_get(method)
48 @ddl ||= DDL.new(discovery_method, :discovery)
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)
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]
65 unless capabilities.include?(:classes)
66 raise "Cannot use class filters while using the '%s' discovery method" % discovery_method unless filter["cf_class"].empty?
69 unless capabilities.include?(:facts)
70 raise "Cannot use fact filters while using the '%s' discovery method" % discovery_method unless filter["fact"].empty?
73 unless capabilities.include?(:identity)
74 raise "Cannot use identity filters while using the '%s' discovery method" % discovery_method unless filter["identity"].empty?
77 unless capabilities.include?(:compound)
78 raise "Cannot use compound filters while using the '%s' discovery method" % discovery_method unless filter["compound"].empty?
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"
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?
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]
117 def discovery_timeout(timeout, filter)
118 timeout = ddl.meta[:timeout] unless timeout
120 unless (filter["compound"] && filter["compound"].empty?)
121 timeout + timeout_for_compound_filter(filter["compound"])
127 def discover(filter, timeout, limit)
128 raise "Limit has to be an integer" unless limit.is_a?(Fixnum)
130 force_discovery_method_by_filter(filter)
132 check_capabilities(filter)
134 discovered = discovery_class.discover(filter, discovery_timeout(timeout, filter), limit, @client)
137 return discovered[0,limit]