choria-mcorpc-support 2.20.8 → 2.23.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/mcollective.rb +1 -1
- data/lib/mcollective/agent/bolt_tasks.ddl +235 -0
- data/lib/mcollective/agent/bolt_tasks.json +347 -0
- data/lib/mcollective/agent/bolt_tasks.rb +176 -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 +7 -3
- 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 +249 -0
- data/lib/mcollective/application/completion.rb +6 -6
- data/lib/mcollective/application/describe_filter.rb +20 -20
- data/lib/mcollective/application/facts.rb +19 -11
- data/lib/mcollective/application/federation.rb +239 -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 +3 -77
- 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 +416 -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 +11 -14
- data/lib/mcollective/discovery.rb +12 -26
- 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/matcher.rb +14 -14
- data/lib/mcollective/matcher/parser.rb +31 -41
- data/lib/mcollective/matcher/scanner.rb +69 -74
- data/lib/mcollective/message.rb +10 -17
- data/lib/mcollective/monkey_patches.rb +2 -4
- data/lib/mcollective/optionparser.rb +1 -0
- data/lib/mcollective/pluginmanager.rb +3 -5
- data/lib/mcollective/pluginpackager.rb +1 -3
- data/lib/mcollective/pluginpackager/agent_definition.rb +10 -11
- 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 +29 -36
- 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 +1103 -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 +733 -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 +8 -3
- 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
- data/lib/mcollective/validator/typecheck_validator.rb +4 -0
- metadata +67 -4
@@ -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"] | [Matcher.create_compound_callstack(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
|
825
|
+
if 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
|