choria-mcorpc-support 2.21.1 → 2.23.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 +4 -4
- data/lib/mcollective.rb +1 -2
- data/lib/mcollective/agent/bolt_tasks.ddl +253 -0
- data/lib/mcollective/agent/bolt_tasks.json +365 -0
- data/lib/mcollective/agent/bolt_tasks.rb +178 -0
- data/lib/mcollective/agent/choria_util.ddl +152 -0
- data/lib/mcollective/agent/choria_util.json +244 -0
- data/lib/mcollective/agent/rpcutil.ddl +8 -4
- data/lib/mcollective/agent/rpcutil.json +333 -0
- data/lib/mcollective/agent/scout.ddl +169 -0
- data/lib/mcollective/agent/scout.json +224 -0
- data/lib/mcollective/agents.rb +7 -6
- data/lib/mcollective/aggregate.rb +4 -4
- data/lib/mcollective/aggregate/average.rb +2 -2
- data/lib/mcollective/aggregate/base.rb +2 -2
- data/lib/mcollective/aggregate/result.rb +3 -3
- data/lib/mcollective/aggregate/result/collection_result.rb +2 -2
- data/lib/mcollective/aggregate/result/numeric_result.rb +2 -2
- data/lib/mcollective/aggregate/sum.rb +2 -2
- data/lib/mcollective/aggregate/summary.rb +3 -4
- data/lib/mcollective/application.rb +57 -21
- data/lib/mcollective/application/choria.rb +189 -0
- data/lib/mcollective/application/completion.rb +6 -6
- data/lib/mcollective/application/facts.rb +11 -11
- data/lib/mcollective/application/federation.rb +237 -0
- data/lib/mcollective/application/find.rb +4 -4
- data/lib/mcollective/application/help.rb +3 -3
- data/lib/mcollective/application/inventory.rb +3 -341
- data/lib/mcollective/application/ping.rb +5 -51
- data/lib/mcollective/application/playbook.rb +207 -0
- data/lib/mcollective/application/plugin.rb +106 -106
- data/lib/mcollective/application/rpc.rb +3 -108
- data/lib/mcollective/application/tasks.rb +425 -0
- data/lib/mcollective/applications.rb +11 -10
- data/lib/mcollective/audit/choria.rb +33 -0
- data/lib/mcollective/cache.rb +2 -4
- data/lib/mcollective/client.rb +11 -10
- data/lib/mcollective/config.rb +21 -34
- data/lib/mcollective/connector/base.rb +2 -1
- data/lib/mcollective/connector/nats.ddl +9 -0
- data/lib/mcollective/connector/nats.rb +450 -0
- data/lib/mcollective/data.rb +8 -3
- data/lib/mcollective/data/agent_data.rb +1 -1
- data/lib/mcollective/data/base.rb +6 -5
- data/lib/mcollective/data/bolt_task_data.ddl +90 -0
- data/lib/mcollective/data/bolt_task_data.rb +32 -0
- data/lib/mcollective/data/collective_data.rb +1 -1
- data/lib/mcollective/data/fact_data.rb +6 -6
- data/lib/mcollective/data/fstat_data.rb +2 -4
- data/lib/mcollective/data/result.rb +7 -2
- data/lib/mcollective/ddl/agentddl.rb +5 -17
- data/lib/mcollective/ddl/base.rb +10 -13
- data/lib/mcollective/discovery.rb +24 -39
- data/lib/mcollective/discovery/choria.ddl +11 -0
- data/lib/mcollective/discovery/choria.rb +223 -0
- data/lib/mcollective/discovery/flatfile.rb +7 -8
- data/lib/mcollective/discovery/mc.rb +2 -2
- data/lib/mcollective/discovery/stdin.rb +17 -18
- data/lib/mcollective/exceptions.rb +13 -0
- data/lib/mcollective/facts/base.rb +9 -9
- data/lib/mcollective/facts/yaml_facts.rb +12 -12
- data/lib/mcollective/generators.rb +3 -3
- data/lib/mcollective/generators/agent_generator.rb +3 -4
- data/lib/mcollective/generators/base.rb +14 -15
- data/lib/mcollective/generators/data_generator.rb +5 -6
- data/lib/mcollective/log.rb +2 -2
- data/lib/mcollective/logger/base.rb +3 -2
- data/lib/mcollective/logger/console_logger.rb +10 -10
- data/lib/mcollective/logger/file_logger.rb +7 -7
- data/lib/mcollective/logger/syslog_logger.rb +11 -15
- data/lib/mcollective/message.rb +8 -39
- data/lib/mcollective/monkey_patches.rb +2 -4
- data/lib/mcollective/optionparser.rb +2 -1
- data/lib/mcollective/pluginmanager.rb +3 -5
- data/lib/mcollective/pluginpackager.rb +1 -3
- data/lib/mcollective/pluginpackager/agent_definition.rb +3 -8
- data/lib/mcollective/pluginpackager/forge_packager.rb +7 -9
- data/lib/mcollective/pluginpackager/standard_definition.rb +1 -2
- data/lib/mcollective/registration/base.rb +18 -16
- data/lib/mcollective/rpc.rb +2 -4
- data/lib/mcollective/rpc/actionrunner.rb +16 -18
- data/lib/mcollective/rpc/agent.rb +26 -43
- data/lib/mcollective/rpc/audit.rb +1 -0
- data/lib/mcollective/rpc/client.rb +67 -85
- data/lib/mcollective/rpc/helpers.rb +55 -62
- data/lib/mcollective/rpc/progress.rb +2 -2
- data/lib/mcollective/rpc/reply.rb +17 -19
- data/lib/mcollective/rpc/request.rb +7 -5
- data/lib/mcollective/rpc/result.rb +6 -8
- data/lib/mcollective/rpc/stats.rb +49 -58
- data/lib/mcollective/security/base.rb +13 -56
- data/lib/mcollective/security/choria.rb +765 -0
- data/lib/mcollective/shell.rb +9 -4
- data/lib/mcollective/signer/base.rb +28 -0
- data/lib/mcollective/signer/choria.rb +185 -0
- data/lib/mcollective/ssl.rb +8 -6
- data/lib/mcollective/util.rb +58 -55
- data/lib/mcollective/util/bolt_support.rb +176 -0
- data/lib/mcollective/util/bolt_support/plan_runner.rb +167 -0
- data/lib/mcollective/util/bolt_support/task_result.rb +94 -0
- data/lib/mcollective/util/bolt_support/task_results.rb +128 -0
- data/lib/mcollective/util/choria.rb +946 -0
- data/lib/mcollective/util/indifferent_hash.rb +12 -0
- data/lib/mcollective/util/natswrapper.rb +242 -0
- data/lib/mcollective/util/playbook.rb +435 -0
- data/lib/mcollective/util/playbook/data_stores.rb +201 -0
- data/lib/mcollective/util/playbook/data_stores/base.rb +99 -0
- data/lib/mcollective/util/playbook/data_stores/consul_data_store.rb +88 -0
- data/lib/mcollective/util/playbook/data_stores/environment_data_store.rb +33 -0
- data/lib/mcollective/util/playbook/data_stores/etcd_data_store.rb +42 -0
- data/lib/mcollective/util/playbook/data_stores/file_data_store.rb +106 -0
- data/lib/mcollective/util/playbook/data_stores/shell_data_store.rb +103 -0
- data/lib/mcollective/util/playbook/inputs.rb +265 -0
- data/lib/mcollective/util/playbook/nodes.rb +207 -0
- data/lib/mcollective/util/playbook/nodes/mcollective_nodes.rb +86 -0
- data/lib/mcollective/util/playbook/nodes/pql_nodes.rb +40 -0
- data/lib/mcollective/util/playbook/nodes/shell_nodes.rb +55 -0
- data/lib/mcollective/util/playbook/nodes/terraform_nodes.rb +65 -0
- data/lib/mcollective/util/playbook/nodes/yaml_nodes.rb +47 -0
- data/lib/mcollective/util/playbook/playbook_logger.rb +47 -0
- data/lib/mcollective/util/playbook/puppet_logger.rb +51 -0
- data/lib/mcollective/util/playbook/report.rb +152 -0
- data/lib/mcollective/util/playbook/task_result.rb +55 -0
- data/lib/mcollective/util/playbook/tasks.rb +196 -0
- data/lib/mcollective/util/playbook/tasks/base.rb +45 -0
- data/lib/mcollective/util/playbook/tasks/graphite_event_task.rb +64 -0
- data/lib/mcollective/util/playbook/tasks/mcollective_task.rb +356 -0
- data/lib/mcollective/util/playbook/tasks/shell_task.rb +93 -0
- data/lib/mcollective/util/playbook/tasks/slack_task.rb +105 -0
- data/lib/mcollective/util/playbook/tasks/webhook_task.rb +136 -0
- data/lib/mcollective/util/playbook/template_util.rb +98 -0
- data/lib/mcollective/util/playbook/uses.rb +169 -0
- data/lib/mcollective/util/tasks_support.rb +751 -0
- data/lib/mcollective/util/tasks_support/cli.rb +260 -0
- data/lib/mcollective/util/tasks_support/default_formatter.rb +138 -0
- data/lib/mcollective/util/tasks_support/json_formatter.rb +108 -0
- data/lib/mcollective/validator.rb +6 -1
- data/lib/mcollective/validator/bolt_task_name_validator.ddl +7 -0
- data/lib/mcollective/validator/bolt_task_name_validator.rb +11 -0
- data/lib/mcollective/validator/length_validator.rb +1 -3
- metadata +65 -6
- data/lib/mcollective/application/describe_filter.rb +0 -87
- data/lib/mcollective/matcher.rb +0 -220
- data/lib/mcollective/matcher/parser.rb +0 -128
- data/lib/mcollective/matcher/scanner.rb +0 -241
|
@@ -4,10 +4,10 @@ module MCollective
|
|
|
4
4
|
# and just brings in a lot of convention and standard approached.
|
|
5
5
|
class Client
|
|
6
6
|
attr_accessor :timeout, :verbose, :filter, :config, :progress, :ttl, :reply_to
|
|
7
|
-
attr_reader :client, :stats, :ddl, :agent, :limit_targets, :limit_method, :output_format, :batch_size, :batch_sleep_time, :batch_mode
|
|
8
|
-
|
|
7
|
+
attr_reader :client, :stats, :ddl, :agent, :limit_targets, :limit_method, :output_format, :batch_size, :batch_sleep_time, :batch_mode, :discovery_options,
|
|
8
|
+
:discovery_method, :default_discovery_method, :limit_seed
|
|
9
9
|
|
|
10
|
-
@@initial_options = nil
|
|
10
|
+
@@initial_options = nil # rubocop:disable Style/ClassVars
|
|
11
11
|
|
|
12
12
|
# Creates a stub for a remote agent, you can pass in an options array in the flags
|
|
13
13
|
# which will then be used else it will just create a default options array with
|
|
@@ -17,7 +17,7 @@ module MCollective
|
|
|
17
17
|
#
|
|
18
18
|
# You typically would not call this directly you'd use MCollective::RPC#rpcclient instead
|
|
19
19
|
# which is a wrapper around this that can be used as a Mixin
|
|
20
|
-
def initialize(agent, flags
|
|
20
|
+
def initialize(agent, flags={}) # rubocop:disable Metrics/MethodLength
|
|
21
21
|
if flags.include?(:options)
|
|
22
22
|
initial_options = flags[:options]
|
|
23
23
|
|
|
@@ -25,22 +25,20 @@ module MCollective
|
|
|
25
25
|
initial_options = Marshal.load(@@initial_options)
|
|
26
26
|
|
|
27
27
|
else
|
|
28
|
-
oparser = MCollective::Optionparser.new({
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
oparser = MCollective::Optionparser.new({:verbose => false,
|
|
29
|
+
:progress_bar => true,
|
|
30
|
+
:mcollective_limit_targets => false,
|
|
31
|
+
:batch_size => nil,
|
|
32
|
+
:batch_sleep_time => 1},
|
|
33
33
|
"filter")
|
|
34
34
|
|
|
35
35
|
initial_options = oparser.parse do |parser, opts|
|
|
36
|
-
if block_given?
|
|
37
|
-
yield(parser, opts)
|
|
38
|
-
end
|
|
36
|
+
yield(parser, opts) if block_given?
|
|
39
37
|
|
|
40
38
|
Helpers.add_simplerpc_options(parser, opts)
|
|
41
39
|
end
|
|
42
40
|
|
|
43
|
-
@@initial_options = Marshal.dump(initial_options)
|
|
41
|
+
@@initial_options = Marshal.dump(initial_options) # rubocop:disable Style/ClassVars
|
|
44
42
|
end
|
|
45
43
|
|
|
46
44
|
@initial_options = initial_options
|
|
@@ -109,21 +107,21 @@ module MCollective
|
|
|
109
107
|
if initial_options[:stderr]
|
|
110
108
|
@stderr = initial_options[:stderr]
|
|
111
109
|
else
|
|
112
|
-
@stderr =
|
|
110
|
+
@stderr = $stderr
|
|
113
111
|
@stderr.sync = true
|
|
114
112
|
end
|
|
115
113
|
|
|
116
114
|
if initial_options[:stdout]
|
|
117
115
|
@stdout = initial_options[:stdout]
|
|
118
116
|
else
|
|
119
|
-
@stdout =
|
|
117
|
+
@stdout = $stdout
|
|
120
118
|
@stdout.sync = true
|
|
121
119
|
end
|
|
122
120
|
|
|
123
121
|
if initial_options[:stdin]
|
|
124
122
|
@stdin = initial_options[:stdin]
|
|
125
123
|
else
|
|
126
|
-
@stdin =
|
|
124
|
+
@stdin = $stdin
|
|
127
125
|
end
|
|
128
126
|
end
|
|
129
127
|
|
|
@@ -159,12 +157,12 @@ module MCollective
|
|
|
159
157
|
def new_request(action, data)
|
|
160
158
|
callerid = PluginManager["security_plugin"].callerid
|
|
161
159
|
|
|
162
|
-
raise
|
|
160
|
+
raise "callerid received from security plugin is not valid" unless PluginManager["security_plugin"].valid_callerid?(callerid)
|
|
163
161
|
|
|
164
|
-
{:agent
|
|
162
|
+
{:agent => @agent,
|
|
165
163
|
:action => action,
|
|
166
164
|
:caller => callerid,
|
|
167
|
-
:data
|
|
165
|
+
:data => data}
|
|
168
166
|
end
|
|
169
167
|
|
|
170
168
|
# For the provided arguments and action the input arguments get
|
|
@@ -238,7 +236,7 @@ module MCollective
|
|
|
238
236
|
#
|
|
239
237
|
# This will do everything exactly as normal but communicate to only 5
|
|
240
238
|
# agents at a time
|
|
241
|
-
def method_missing(method_name, *args, &block)
|
|
239
|
+
def method_missing(method_name, *args, &block) # rubocop:disable Style/MissingRespondToMissing
|
|
242
240
|
# set args to an empty hash if nothings given
|
|
243
241
|
args = args[0]
|
|
244
242
|
args = {} if args.nil?
|
|
@@ -256,7 +254,6 @@ module MCollective
|
|
|
256
254
|
|
|
257
255
|
# if a global batch size is set just use that else set it
|
|
258
256
|
# in the case that it was passed as an argument
|
|
259
|
-
batch_mode = args.include?(:batch_size) || @batch_mode
|
|
260
257
|
batch_size = args.delete(:batch_size) || @batch_size
|
|
261
258
|
batch_sleep_time = args.delete(:batch_sleep_time) || @batch_sleep_time
|
|
262
259
|
|
|
@@ -308,7 +305,7 @@ module MCollective
|
|
|
308
305
|
# hash as a filter, this will force that request to be a directly addressed
|
|
309
306
|
# request which technically does not need filters. If you try to use this
|
|
310
307
|
# mode with direct addressing disabled an exception will be raise
|
|
311
|
-
def custom_request(action, args, expected_agents, filter
|
|
308
|
+
def custom_request(action, args, expected_agents, filter={}, &block)
|
|
312
309
|
validate_request(action, args)
|
|
313
310
|
|
|
314
311
|
if filter == {} && !Config.instance.direct_addressing
|
|
@@ -324,9 +321,7 @@ module MCollective
|
|
|
324
321
|
# we could just use the merge method but I want to be sure
|
|
325
322
|
# we dont merge in stuff that isnt actually valid
|
|
326
323
|
["identity", "fact", "agent", "cf_class", "compound"].each do |ftype|
|
|
327
|
-
if filter.include?(ftype)
|
|
328
|
-
custom_filter[ftype] = [filter[ftype], custom_filter[ftype]].flatten
|
|
329
|
-
end
|
|
324
|
+
custom_filter[ftype] = [filter[ftype], custom_filter[ftype]].flatten if filter.include?(ftype)
|
|
330
325
|
end
|
|
331
326
|
|
|
332
327
|
# ensure that all filters at least restrict the call to the agent we're a proxy for
|
|
@@ -341,9 +336,7 @@ module MCollective
|
|
|
341
336
|
# If a specific reply-to was set then from the client perspective this should
|
|
342
337
|
# be a fire and forget request too since no response will ever reach us - it
|
|
343
338
|
# will go to the reply-to destination
|
|
344
|
-
if args[:process_results] == false || @reply_to
|
|
345
|
-
return fire_and_forget_request(action, args, custom_filter)
|
|
346
|
-
end
|
|
339
|
+
return fire_and_forget_request(action, args, custom_filter) if args[:process_results] == false || @reply_to
|
|
347
340
|
|
|
348
341
|
# Now do a call pretty much exactly like in method_missing except with our own
|
|
349
342
|
# options and discovery magic
|
|
@@ -358,7 +351,8 @@ module MCollective
|
|
|
358
351
|
|
|
359
352
|
def discovery_timeout
|
|
360
353
|
return @discovery_timeout if @discovery_timeout
|
|
361
|
-
|
|
354
|
+
|
|
355
|
+
@client.discoverer.ddl.meta[:timeout]
|
|
362
356
|
end
|
|
363
357
|
|
|
364
358
|
def discovery_timeout=(timeout)
|
|
@@ -423,12 +417,11 @@ module MCollective
|
|
|
423
417
|
|
|
424
418
|
if value.nil?
|
|
425
419
|
parsed = Util.parse_fact_string(fact)
|
|
426
|
-
@filter["fact"] = @filter["fact"] | [parsed] unless parsed == false
|
|
427
420
|
else
|
|
428
421
|
parsed = Util.parse_fact_string("#{fact}#{operator}#{value}")
|
|
429
|
-
@filter["fact"] = @filter["fact"] | [parsed] unless parsed == false
|
|
430
422
|
end
|
|
431
423
|
|
|
424
|
+
@filter["fact"] = @filter["fact"] | [parsed] unless parsed == false
|
|
432
425
|
@filter["fact"].compact!
|
|
433
426
|
reset
|
|
434
427
|
end
|
|
@@ -449,7 +442,7 @@ module MCollective
|
|
|
449
442
|
|
|
450
443
|
# Set a compound filter
|
|
451
444
|
def compound_filter(filter)
|
|
452
|
-
@filter["compound"] = @filter["compound"] |
|
|
445
|
+
@filter["compound"] = @filter["compound"] | [[{"expr" => filter}]]
|
|
453
446
|
reset
|
|
454
447
|
end
|
|
455
448
|
|
|
@@ -477,9 +470,9 @@ module MCollective
|
|
|
477
470
|
#
|
|
478
471
|
# Then we override discovery to try to grok the data on STDIN
|
|
479
472
|
def detect_and_set_stdin_discovery
|
|
480
|
-
if
|
|
481
|
-
self.discovery_method =
|
|
482
|
-
self.discovery_options =
|
|
473
|
+
if default_discovery_method && !@stdin.tty? && !@stdin.eof?
|
|
474
|
+
self.discovery_method = "stdin"
|
|
475
|
+
self.discovery_options = "auto"
|
|
483
476
|
end
|
|
484
477
|
end
|
|
485
478
|
|
|
@@ -499,7 +492,7 @@ module MCollective
|
|
|
499
492
|
#
|
|
500
493
|
# Use reset to force a new discovery
|
|
501
494
|
def discover(flags={})
|
|
502
|
-
flags.
|
|
495
|
+
flags.each_key do |key|
|
|
503
496
|
raise "Unknown option #{key} passed to discover" unless [:verbose, :hosts, :nodes, :json].include?(key)
|
|
504
497
|
end
|
|
505
498
|
|
|
@@ -565,8 +558,8 @@ module MCollective
|
|
|
565
558
|
# and if we're configured to use the first found hosts as the
|
|
566
559
|
# limit method then pass in the limit thus minimizing the amount
|
|
567
560
|
# of work we do in the discover phase and speeding it up significantly
|
|
568
|
-
filter = @filter.merge({
|
|
569
|
-
if @limit_method == :first
|
|
561
|
+
filter = @filter.merge({"collective" => @collective})
|
|
562
|
+
if (@limit_method == :first) && @limit_targets.is_a?(Integer)
|
|
570
563
|
@discovered_agents = @client.discover(filter, discovery_timeout, @limit_targets)
|
|
571
564
|
else
|
|
572
565
|
@discovered_agents = @client.discover(filter, discovery_timeout)
|
|
@@ -604,10 +597,10 @@ module MCollective
|
|
|
604
597
|
end
|
|
605
598
|
|
|
606
599
|
# Sets the collective we are communicating with
|
|
607
|
-
def collective=(
|
|
608
|
-
raise "Unknown collective #{
|
|
600
|
+
def collective=(collective)
|
|
601
|
+
raise "Unknown collective #{collective}" unless Config.instance.collectives.include?(collective)
|
|
609
602
|
|
|
610
|
-
@collective =
|
|
603
|
+
@collective = collective
|
|
611
604
|
@client.options = options
|
|
612
605
|
reset
|
|
613
606
|
end
|
|
@@ -616,7 +609,7 @@ module MCollective
|
|
|
616
609
|
# used to restrict how many nodes we'll target
|
|
617
610
|
# Limit targets can be reset by passing nil or false
|
|
618
611
|
def limit_targets=(limit)
|
|
619
|
-
|
|
612
|
+
unless limit
|
|
620
613
|
@limit_targets = nil
|
|
621
614
|
return
|
|
622
615
|
end
|
|
@@ -646,9 +639,7 @@ module MCollective
|
|
|
646
639
|
|
|
647
640
|
# Sets the batch size, if the size is set to 0 that will disable batch mode
|
|
648
641
|
def batch_size=(limit)
|
|
649
|
-
unless Config.instance.direct_addressing
|
|
650
|
-
raise "Can only set batch size if direct addressing is supported"
|
|
651
|
-
end
|
|
642
|
+
raise "Can only set batch size if direct addressing is supported" unless Config.instance.direct_addressing
|
|
652
643
|
|
|
653
644
|
validate_batch_size(limit)
|
|
654
645
|
|
|
@@ -721,21 +712,20 @@ module MCollective
|
|
|
721
712
|
return nil unless ddl
|
|
722
713
|
return nil unless ddl.action_interface(action).keys.include?(:aggregate)
|
|
723
714
|
|
|
724
|
-
|
|
725
|
-
|
|
715
|
+
Aggregate.new(ddl.action_interface(action))
|
|
726
716
|
rescue => e
|
|
727
717
|
Log.error("Failed to load aggregate functions, calculating summaries disabled: %s: %s (%s)" % [e.backtrace.first, e.to_s, e.class])
|
|
728
|
-
|
|
718
|
+
nil
|
|
729
719
|
end
|
|
730
720
|
|
|
731
721
|
def aggregate_reply(reply, aggregate)
|
|
732
722
|
return nil unless aggregate
|
|
733
723
|
|
|
734
724
|
aggregate.call_functions(reply)
|
|
735
|
-
|
|
736
|
-
rescue Exception => e
|
|
725
|
+
aggregate
|
|
726
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
737
727
|
Log.error("Failed to calculate aggregate summaries for reply from %s, calculating summaries disabled: %s: %s (%s)" % [reply[:senderid], e.backtrace.first, e.to_s, e.class])
|
|
738
|
-
|
|
728
|
+
nil
|
|
739
729
|
end
|
|
740
730
|
|
|
741
731
|
def rpc_result_from_reply(agent, action, reply)
|
|
@@ -763,7 +753,7 @@ module MCollective
|
|
|
763
753
|
|
|
764
754
|
req = new_request(action.to_s, args)
|
|
765
755
|
|
|
766
|
-
filter
|
|
756
|
+
filter ||= options[:filter]
|
|
767
757
|
|
|
768
758
|
message = Message.new(req, nil, {:agent => @agent, :type => :request, :collective => @collective, :filter => filter, :options => options})
|
|
769
759
|
message.reply_to = @reply_to if @reply_to
|
|
@@ -788,8 +778,8 @@ module MCollective
|
|
|
788
778
|
# the concept of identity to mean something else so we should pass the full
|
|
789
779
|
# identity filter to them
|
|
790
780
|
def identity_filter_discovery_optimization
|
|
791
|
-
if options[:filter]["identity"].
|
|
792
|
-
regex_filters = options[:filter]["identity"].select{|i| i.match("^\/")}.size
|
|
781
|
+
if !options[:filter]["identity"].empty? && @discovery_method == "mc"
|
|
782
|
+
regex_filters = options[:filter]["identity"].select {|i| i.match("^\/")}.size
|
|
793
783
|
|
|
794
784
|
if regex_filters == 0
|
|
795
785
|
@discovered_agents = options[:filter]["identity"].clone
|
|
@@ -805,9 +795,10 @@ module MCollective
|
|
|
805
795
|
# from normal call_agent.
|
|
806
796
|
#
|
|
807
797
|
# This is used by method_missing and works only with direct addressing mode
|
|
808
|
-
def call_agent_batched(action, args, opts, batch_size, sleep_time, &block)
|
|
798
|
+
def call_agent_batched(action, args, opts, batch_size, sleep_time, &block) # rubocop:disable Metrics/MethodLength
|
|
809
799
|
raise "Batched requests requires direct addressing" unless Config.instance.direct_addressing
|
|
810
800
|
raise "Cannot bypass result processing for batched requests" if args[:process_results] == false
|
|
801
|
+
|
|
811
802
|
validate_batch_size(batch_size)
|
|
812
803
|
|
|
813
804
|
sleep_time = Float(sleep_time)
|
|
@@ -820,7 +811,7 @@ module MCollective
|
|
|
820
811
|
results = []
|
|
821
812
|
respcount = 0
|
|
822
813
|
|
|
823
|
-
if discovered.
|
|
814
|
+
if !discovered.empty?
|
|
824
815
|
req = new_request(action.to_s, args)
|
|
825
816
|
|
|
826
817
|
aggregate = load_aggregate_functions(action, @ddl)
|
|
@@ -831,7 +822,7 @@ module MCollective
|
|
|
831
822
|
@stdout.print twirl.twirl(respcount, discovered.size)
|
|
832
823
|
end
|
|
833
824
|
|
|
834
|
-
if (batch_size =~ /^(\d+)%$/
|
|
825
|
+
if batch_size.is_a?(String) && batch_size =~ /^(\d+)%$/
|
|
835
826
|
# determine batch_size as a percentage of the discovered array's size
|
|
836
827
|
batch_size = (discovered.size / 100.0 * Integer($1)).ceil
|
|
837
828
|
else
|
|
@@ -869,9 +860,7 @@ module MCollective
|
|
|
869
860
|
end
|
|
870
861
|
end
|
|
871
862
|
|
|
872
|
-
if @initial_options[:sort]
|
|
873
|
-
results.sort!
|
|
874
|
-
end
|
|
863
|
+
results.sort! if @initial_options[:sort]
|
|
875
864
|
|
|
876
865
|
@stats.noresponsefrom.concat @client.stats[:noresponsefrom]
|
|
877
866
|
@stats.unexpectedresponsefrom.concat @client.stats[:unexpectedresponsefrom]
|
|
@@ -881,9 +870,7 @@ module MCollective
|
|
|
881
870
|
@stats.discoverytime += @client.stats[:discoverytime]
|
|
882
871
|
|
|
883
872
|
processed_nodes += hosts.length
|
|
884
|
-
if
|
|
885
|
-
sleep sleep_time
|
|
886
|
-
end
|
|
873
|
+
sleep sleep_time if discovered.length > processed_nodes
|
|
887
874
|
end
|
|
888
875
|
|
|
889
876
|
@stats.aggregate_summary = aggregate.summarize if aggregate
|
|
@@ -899,9 +886,9 @@ module MCollective
|
|
|
899
886
|
@stdout.print("\n") if @progress
|
|
900
887
|
|
|
901
888
|
if block_given?
|
|
902
|
-
|
|
889
|
+
stats
|
|
903
890
|
else
|
|
904
|
-
|
|
891
|
+
[results].flatten
|
|
905
892
|
end
|
|
906
893
|
end
|
|
907
894
|
|
|
@@ -942,7 +929,7 @@ module MCollective
|
|
|
942
929
|
results = []
|
|
943
930
|
respcount = 0
|
|
944
931
|
|
|
945
|
-
if discovered.
|
|
932
|
+
if !discovered.empty?
|
|
946
933
|
message.type = :direct_request if @force_direct_request
|
|
947
934
|
|
|
948
935
|
if @progress && !block_given?
|
|
@@ -967,9 +954,7 @@ module MCollective
|
|
|
967
954
|
end
|
|
968
955
|
end
|
|
969
956
|
|
|
970
|
-
if @initial_options[:sort]
|
|
971
|
-
results.sort!
|
|
972
|
-
end
|
|
957
|
+
results.sort! if @initial_options[:sort]
|
|
973
958
|
|
|
974
959
|
@stats.aggregate_summary = aggregate.summarize if aggregate
|
|
975
960
|
@stats.aggregate_failures = aggregate.failed if aggregate
|
|
@@ -985,9 +970,9 @@ module MCollective
|
|
|
985
970
|
@stdout.print("\n\n") if @progress
|
|
986
971
|
|
|
987
972
|
if block_given?
|
|
988
|
-
|
|
973
|
+
stats
|
|
989
974
|
else
|
|
990
|
-
|
|
975
|
+
[results].flatten
|
|
991
976
|
end
|
|
992
977
|
end
|
|
993
978
|
|
|
@@ -1025,25 +1010,23 @@ module MCollective
|
|
|
1025
1010
|
@stats.time_block_execution :start
|
|
1026
1011
|
|
|
1027
1012
|
case block.arity
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1013
|
+
when 1
|
|
1014
|
+
block.call(resp)
|
|
1015
|
+
when 2
|
|
1016
|
+
block.call(resp, result)
|
|
1032
1017
|
end
|
|
1033
1018
|
|
|
1034
1019
|
@stats.time_block_execution :end
|
|
1035
1020
|
|
|
1036
|
-
|
|
1021
|
+
aggregate
|
|
1037
1022
|
end
|
|
1038
1023
|
|
|
1039
1024
|
private
|
|
1040
1025
|
|
|
1041
1026
|
def determine_batch_mode(batch_size)
|
|
1042
|
-
if
|
|
1043
|
-
return true
|
|
1044
|
-
end
|
|
1027
|
+
return true if batch_size != 0 && batch_size != "0"
|
|
1045
1028
|
|
|
1046
|
-
|
|
1029
|
+
false
|
|
1047
1030
|
end
|
|
1048
1031
|
|
|
1049
1032
|
# Validate the bach_size based on the following criteria
|
|
@@ -1051,12 +1034,11 @@ module MCollective
|
|
|
1051
1034
|
# batch_size is a string of digits
|
|
1052
1035
|
# batch_size is of type Integer
|
|
1053
1036
|
def validate_batch_size(batch_size)
|
|
1054
|
-
|
|
1037
|
+
case batch_size
|
|
1038
|
+
when Integer
|
|
1055
1039
|
return
|
|
1056
|
-
|
|
1057
|
-
if (
|
|
1058
|
-
return
|
|
1059
|
-
end
|
|
1040
|
+
when String
|
|
1041
|
+
return if (batch_size =~ /^(\d+)%$/ && Integer($1) != 0) || batch_size =~ /^(\d+)$/
|
|
1060
1042
|
end
|
|
1061
1043
|
|
|
1062
1044
|
raise("batch_size must be an integer or match a percentage string (e.g. '24%'")
|
|
@@ -26,9 +26,7 @@ module MCollective
|
|
|
26
26
|
hosts.map do |host|
|
|
27
27
|
raise "JSON host list is not an array of Hashes" unless host.is_a?(Hash)
|
|
28
28
|
|
|
29
|
-
unless host.include?("sender") || host.include?("certname")
|
|
30
|
-
raise "JSON host list does not have senders in it"
|
|
31
|
-
end
|
|
29
|
+
raise "JSON host list does not have senders in it" unless host.include?("sender") || host.include?("certname")
|
|
32
30
|
|
|
33
31
|
host["sender"] || host["certname"]
|
|
34
32
|
end.uniq
|
|
@@ -39,6 +37,7 @@ module MCollective
|
|
|
39
37
|
def self.extract_hosts_from_array(hosts)
|
|
40
38
|
[hosts].flatten.map do |host|
|
|
41
39
|
raise "#{host} should be a string" unless host.is_a?(String)
|
|
40
|
+
|
|
42
41
|
host.chomp
|
|
43
42
|
end
|
|
44
43
|
end
|
|
@@ -61,7 +60,7 @@ module MCollective
|
|
|
61
60
|
# If you've asked it to flatten the result it will not print sender
|
|
62
61
|
# hostnames, it will just print the result as if it's one huge result,
|
|
63
62
|
# handy for things like showing a combined mailq.
|
|
64
|
-
def self.rpcresults(result, flags
|
|
63
|
+
def self.rpcresults(result, flags={})
|
|
65
64
|
flags = {:verbose => false, :flatten => false, :format => :console, :force_display_mode => false}.merge(flags)
|
|
66
65
|
|
|
67
66
|
result_text = ""
|
|
@@ -70,55 +69,49 @@ module MCollective
|
|
|
70
69
|
# if running in verbose mode, just use the old style print
|
|
71
70
|
# no need for all the DDL helpers obfuscating the result
|
|
72
71
|
if flags[:format] == :json
|
|
73
|
-
if
|
|
72
|
+
if $stdout.tty?
|
|
74
73
|
result_text = JSON.pretty_generate(result)
|
|
75
74
|
else
|
|
76
75
|
result_text = result.to_json
|
|
77
76
|
end
|
|
77
|
+
elsif flags[:verbose]
|
|
78
|
+
result_text = old_rpcresults(result, flags)
|
|
78
79
|
else
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
[result].flatten.each do |r|
|
|
83
|
-
begin
|
|
84
|
-
ddl ||= DDL.new(r.agent).action_interface(r.action.to_s)
|
|
80
|
+
[result].flatten.each do |r|
|
|
81
|
+
begin
|
|
82
|
+
ddl ||= DDL.new(r.agent).action_interface(r.action.to_s)
|
|
85
83
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
84
|
+
sender = r[:sender]
|
|
85
|
+
status = r[:statuscode]
|
|
86
|
+
message = r[:statusmsg]
|
|
87
|
+
result = r[:data]
|
|
90
88
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
if flags[:force_display_mode]
|
|
90
|
+
display = flags[:force_display_mode]
|
|
91
|
+
else
|
|
92
|
+
display = ddl[:display]
|
|
93
|
+
end
|
|
96
94
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
result_text << text_for_result(sender, status, message, result, ddl)
|
|
102
|
-
end
|
|
95
|
+
# appand the results only according to what the DDL says
|
|
96
|
+
case display
|
|
97
|
+
when :ok
|
|
98
|
+
result_text << text_for_result(sender, status, message, result, ddl) if status == 0
|
|
103
99
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
result_text << text_for_result(sender, status, message, result, ddl)
|
|
107
|
-
end
|
|
100
|
+
when :failed
|
|
101
|
+
result_text << text_for_result(sender, status, message, result, ddl) if status > 0
|
|
108
102
|
|
|
109
|
-
|
|
110
|
-
|
|
103
|
+
when :always
|
|
104
|
+
result_text << text_for_result(sender, status, message, result, ddl)
|
|
111
105
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
106
|
+
when :flatten
|
|
107
|
+
Log.warn("The display option :flatten is being deprecated and will be removed in the next minor release")
|
|
108
|
+
result_text << text_for_flattened_result(status, result)
|
|
115
109
|
|
|
116
|
-
end
|
|
117
|
-
rescue Exception => e
|
|
118
|
-
# no DDL so just do the old style print unchanged for
|
|
119
|
-
# backward compat
|
|
120
|
-
result_text = old_rpcresults(result, flags)
|
|
121
110
|
end
|
|
111
|
+
rescue Exception # rubocop:disable Lint/RescueException
|
|
112
|
+
# no DDL so just do the old style print unchanged for
|
|
113
|
+
# backward compat
|
|
114
|
+
result_text = old_rpcresults(result, flags)
|
|
122
115
|
end
|
|
123
116
|
end
|
|
124
117
|
end
|
|
@@ -151,7 +144,7 @@ module MCollective
|
|
|
151
144
|
end
|
|
152
145
|
end
|
|
153
146
|
|
|
154
|
-
result.keys.
|
|
147
|
+
result.keys.sort.each do |k|
|
|
155
148
|
# get all the output fields nicely lined up with a
|
|
156
149
|
# 3 space front padding
|
|
157
150
|
begin
|
|
@@ -169,6 +162,7 @@ module MCollective
|
|
|
169
162
|
if [String, Numeric].include?(result[k].class)
|
|
170
163
|
lines = result[k].to_s.split("\n")
|
|
171
164
|
|
|
165
|
+
# rubocop:disable Metrics/BlockNesting
|
|
172
166
|
if lines.empty?
|
|
173
167
|
result_text << "\n"
|
|
174
168
|
else
|
|
@@ -178,6 +172,7 @@ module MCollective
|
|
|
178
172
|
result_text << "#{padtxt}#{line}\n"
|
|
179
173
|
end
|
|
180
174
|
end
|
|
175
|
+
# rubocop:enable Metrics/BlockNesting
|
|
181
176
|
else
|
|
182
177
|
padding = " " * (lengths.max + 5)
|
|
183
178
|
result_text << " " << result[k].pretty_inspect.split("\n").join("\n" << padding) << "\n"
|
|
@@ -188,7 +183,7 @@ module MCollective
|
|
|
188
183
|
# data by default since the DDL will supply all the defaults
|
|
189
184
|
# it just doesnt look right
|
|
190
185
|
else
|
|
191
|
-
result_text << "\n\t
|
|
186
|
+
result_text << "\n\t#{result.pretty_inspect.split("\n").join("\n\t")}"
|
|
192
187
|
end
|
|
193
188
|
end
|
|
194
189
|
|
|
@@ -201,16 +196,16 @@ module MCollective
|
|
|
201
196
|
result_text = ""
|
|
202
197
|
|
|
203
198
|
if status <= 1
|
|
204
|
-
|
|
205
|
-
result_text << result.pretty_inspect
|
|
206
|
-
else
|
|
199
|
+
if result.is_a?(String)
|
|
207
200
|
result_text << result
|
|
201
|
+
else
|
|
202
|
+
result_text << result.pretty_inspect
|
|
208
203
|
end
|
|
209
204
|
end
|
|
210
205
|
end
|
|
211
206
|
|
|
212
207
|
# Backward compatible display block for results without a DDL
|
|
213
|
-
def self.old_rpcresults(result, flags
|
|
208
|
+
def self.old_rpcresults(result, flags={})
|
|
214
209
|
result_text = ""
|
|
215
210
|
|
|
216
211
|
if flags[:flatten]
|
|
@@ -218,10 +213,10 @@ module MCollective
|
|
|
218
213
|
if r[:statuscode] <= 1
|
|
219
214
|
data = r[:data]
|
|
220
215
|
|
|
221
|
-
|
|
222
|
-
result_text << data.pretty_inspect
|
|
223
|
-
else
|
|
216
|
+
if data.is_a?(String)
|
|
224
217
|
result_text << data
|
|
218
|
+
else
|
|
219
|
+
result_text << data.pretty_inspect
|
|
225
220
|
end
|
|
226
221
|
else
|
|
227
222
|
result_text << r.pretty_inspect
|
|
@@ -250,9 +245,7 @@ module MCollective
|
|
|
250
245
|
result_text << " #{r[:statusmsg]}"
|
|
251
246
|
end
|
|
252
247
|
else
|
|
253
|
-
unless r[:statuscode] == 0
|
|
254
|
-
result_text << "%-40s %s\n" % [r[:sender], Util.colorize(:red, r[:statusmsg])]
|
|
255
|
-
end
|
|
248
|
+
result_text << "%-40s %s\n" % [r[:sender], Util.colorize(:red, r[:statusmsg])] unless r[:statuscode] == 0
|
|
256
249
|
end
|
|
257
250
|
end
|
|
258
251
|
end
|
|
@@ -266,32 +259,32 @@ module MCollective
|
|
|
266
259
|
parser.separator "RPC Options"
|
|
267
260
|
|
|
268
261
|
# add SimpleRPC specific options to all clients that use our library
|
|
269
|
-
parser.on(
|
|
262
|
+
parser.on("--np", "--no-progress", "Do not show the progress bar") do |_v|
|
|
270
263
|
options[:progress_bar] = false
|
|
271
264
|
end
|
|
272
265
|
|
|
273
|
-
parser.on(
|
|
266
|
+
parser.on("--one", "-1", "Send request to only one discovered nodes") do |_v|
|
|
274
267
|
options[:mcollective_limit_targets] = 1
|
|
275
268
|
end
|
|
276
269
|
|
|
277
|
-
parser.on(
|
|
270
|
+
parser.on("--batch SIZE", "Do requests in batches") do |v|
|
|
278
271
|
# validate batch string. Is it x% where x > 0 or is it an integer
|
|
279
|
-
if (
|
|
272
|
+
if (v =~ /^(\d+)%$/ && Integer($1) != 0) || v =~ /^(\d+)$/
|
|
280
273
|
options[:batch_size] = v
|
|
281
274
|
else
|
|
282
|
-
raise
|
|
275
|
+
raise ::OptionParser::InvalidArgument, v
|
|
283
276
|
end
|
|
284
277
|
end
|
|
285
278
|
|
|
286
|
-
parser.on(
|
|
279
|
+
parser.on("--batch-sleep SECONDS", Float, "Sleep time between batches") do |v|
|
|
287
280
|
options[:batch_sleep_time] = v
|
|
288
281
|
end
|
|
289
282
|
|
|
290
|
-
parser.on(
|
|
283
|
+
parser.on("--limit-seed NUMBER", Integer, "Seed value for deterministic random batching") do |v|
|
|
291
284
|
options[:limit_seed] = v
|
|
292
285
|
end
|
|
293
286
|
|
|
294
|
-
parser.on(
|
|
287
|
+
parser.on("--limit-nodes COUNT", "--ln", "--limit", "Send request to only a subset of nodes, can be a percentage") do |v|
|
|
295
288
|
raise "Invalid limit specified: #{v} valid limits are /^\d+%*$/" unless v =~ /^\d+%*$/
|
|
296
289
|
|
|
297
290
|
if v =~ /^\d+$/
|
|
@@ -301,12 +294,12 @@ module MCollective
|
|
|
301
294
|
end
|
|
302
295
|
end
|
|
303
296
|
|
|
304
|
-
parser.on(
|
|
297
|
+
parser.on("--json", "-j", "Produce JSON output") do |_v|
|
|
305
298
|
options[:progress_bar] = false
|
|
306
299
|
options[:output_format] = :json
|
|
307
300
|
end
|
|
308
301
|
|
|
309
|
-
parser.on(
|
|
302
|
+
parser.on("--display MODE", "Influence how results are displayed. One of ok, all or failed") do |v|
|
|
310
303
|
if v == "all"
|
|
311
304
|
options[:force_display_mode] = :always
|
|
312
305
|
else
|