class Client
attr_accessor :timeout, :verbose, :filter, :config, :progress, :ttl, :reply_to
attr_reader :client, :stats, :ddl, :agent, :limit_targets, :limit_method, :output_format, :batch_size, :batch_sleep_time, :batch_mode
- attr_reader :discovery_options, :discovery_method, :limit_seed
+ attr_reader :discovery_options, :discovery_method, :default_discovery_method, :limit_seed
@@initial_options = nil
@output_format = initial_options[:output_format] || :console
@force_direct_request = false
@reply_to = initial_options[:reply_to]
- @discovery_method = initial_options[:discovery_method] || Config.instance.default_discovery_method
+ @discovery_method = initial_options[:discovery_method]
+ if !@discovery_method
+ @discovery_method = Config.instance.default_discovery_method
+ @default_discovery_method = true
+ else
+ @default_discovery_method = false
+ end
@discovery_options = initial_options[:discovery_options] || []
@force_display_mode = initial_options[:force_display_mode] || false
@collective = @client.collective
@ttl = initial_options[:ttl] || Config.instance.ttl
+ @publish_timeout = initial_options[:publish_timeout] || Config.instance.publish_timeout
+ @threaded = initial_options[:threaded] || Config.instance.threaded
# if we can find a DDL for the service override
# the timeout of the client so we always magically
# since that is the user supplied timeout either via initial options
# or via specifically setting it on the client.
def discovery_method=(method)
+ @default_discovery_method = false
@discovery_method = method
if @initial_options[:discovery_options]
# Sets the class filter
def class_filter(klass)
- @filter["cf_class"] << klass
+ @filter["cf_class"] = @filter["cf_class"] | [klass]
@filter["cf_class"].compact!
reset
end
if value.nil?
parsed = Util.parse_fact_string(fact)
- @filter["fact"] << parsed unless parsed == false
+ @filter["fact"] = @filter["fact"] | [parsed] unless parsed == false
else
parsed = Util.parse_fact_string("#{fact}#{operator}#{value}")
- @filter["fact"] << parsed unless parsed == false
+ @filter["fact"] = @filter["fact"] | [parsed] unless parsed == false
end
@filter["fact"].compact!
# Sets the agent filter
def agent_filter(agent)
- @filter["agent"] << agent
+ @filter["agent"] = @filter["agent"] | [agent]
@filter["agent"].compact!
reset
end
# Sets the identity filter
def identity_filter(identity)
- @filter["identity"] << identity
+ @filter["identity"] = @filter["identity"] | [identity]
@filter["identity"].compact!
reset
end
# Set a compound filter
def compound_filter(filter)
- @filter["compound"] << Matcher.create_compound_callstack(filter)
+ @filter["compound"] = @filter["compound"] | [Matcher.create_compound_callstack(filter)]
reset
end
@discovered_agents = hosts
@force_direct_request = true
- # if an identity filter is supplied and it is all strings no regex we can use that
- # as discovery data, technically the identity filter is then redundant if we are
- # in direct addressing mode and we could empty it out but this use case should
- # only really be for a few -I's on the CLI
- #
- # For safety we leave the filter in place for now, that way we can support this
- # enhancement also in broadcast mode.
- #
- # This is only needed for the 'mc' discovery method, other methods might change
- # the concept of identity to mean something else so we should pass the full
- # identity filter to them
- elsif options[:filter]["identity"].size > 0 && @discovery_method == "mc"
- regex_filters = options[:filter]["identity"].select{|i| i.match("^\/")}.size
-
- if regex_filters == 0
- @discovered_agents = options[:filter]["identity"].clone
- @force_direct_request = true if Config.instance.direct_addressing
- end
+ else
+ identity_filter_discovery_optimization
end
end
:discovery_method => @discovery_method,
:discovery_options => @discovery_options,
:force_display_mode => @force_display_mode,
- :config => @config}
+ :config => @config,
+ :publish_timeout => @publish_timeout,
+ :threaded => @threaded}
end
# Sets the collective we are communicating with
def fire_and_forget_request(action, args, filter=nil)
validate_request(action, args)
+ identity_filter_discovery_optimization
+
req = new_request(action.to_s, args)
filter = options[:filter] unless filter
message = Message.new(req, nil, {:agent => @agent, :type => :request, :collective => @collective, :filter => filter, :options => options})
message.reply_to = @reply_to if @reply_to
- return @client.sendreq(message, nil)
+ if @force_direct_request || @client.discoverer.force_direct_mode?
+ message.discovered_hosts = discover.clone
+ message.type = :direct_request
+ end
+
+ client.sendreq(message, nil)
+ end
+
+ # if an identity filter is supplied and it is all strings no regex we can use that
+ # as discovery data, technically the identity filter is then redundant if we are
+ # in direct addressing mode and we could empty it out but this use case should
+ # only really be for a few -I's on the CLI
+ #
+ # For safety we leave the filter in place for now, that way we can support this
+ # enhancement also in broadcast mode.
+ #
+ # This is only needed for the 'mc' discovery method, other methods might change
+ # the concept of identity to mean something else so we should pass the full
+ # identity filter to them
+ def identity_filter_discovery_optimization
+ if options[:filter]["identity"].size > 0 && @discovery_method == "mc"
+ regex_filters = options[:filter]["identity"].select{|i| i.match("^\/")}.size
+
+ if regex_filters == 0
+ @discovered_agents = options[:filter]["identity"].clone
+ @force_direct_request = true if Config.instance.direct_addressing
+ end
+ end
end
# Calls an agent in a way very similar to call_agent but it supports batching