choria-mcorpc-support 2.20.3 → 2.20.4
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 +18 -19
- data/lib/mcollective/agent.rb +0 -1
- data/lib/mcollective/agents.rb +17 -18
- data/lib/mcollective/aggregate.rb +11 -11
- data/lib/mcollective/application.rb +30 -41
- data/lib/mcollective/applications.rb +13 -14
- data/lib/mcollective/cache.rb +1 -1
- data/lib/mcollective/client.rb +25 -25
- data/lib/mcollective/config.rb +114 -120
- data/lib/mcollective/data.rb +9 -9
- data/lib/mcollective/ddl.rb +1 -1
- data/lib/mcollective/discovery.rb +13 -13
- data/lib/mcollective/exceptions.rb +17 -17
- data/lib/mcollective/facts.rb +2 -2
- data/lib/mcollective/log.rb +7 -9
- data/lib/mcollective/matcher.rb +28 -32
- data/lib/mcollective/message.rb +31 -29
- data/lib/mcollective/monkey_patches.rb +92 -83
- data/lib/mcollective/optionparser.rb +23 -23
- data/lib/mcollective/pluginmanager.rb +8 -11
- data/lib/mcollective/pluginpackager.rb +13 -17
- data/lib/mcollective/rpc.rb +16 -18
- data/lib/mcollective/runnerstats.rb +10 -6
- data/lib/mcollective/shell.rb +30 -33
- data/lib/mcollective/ssl.rb +9 -12
- data/lib/mcollective/util.rb +160 -135
- data/lib/mcollective/validator.rb +18 -20
- metadata +4 -4
@@ -1,128 +1,139 @@
|
|
1
1
|
# start_with? was introduced in 1.8.7, we need to support
|
2
2
|
# 1.8.5 and 1.8.6
|
3
3
|
class String
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
unless method_defined?("start_with?")
|
5
|
+
def start_with?(str)
|
6
|
+
self[0..(str.length - 1)] == str
|
7
|
+
end
|
8
|
+
end
|
7
9
|
end
|
8
10
|
|
9
11
|
# Make arrays of Symbols sortable
|
10
12
|
class Symbol
|
11
13
|
include Comparable
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
unless method_defined?("<=>")
|
16
|
+
def <=>(other)
|
17
|
+
to_s <=> other.to_s
|
18
|
+
end
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
# This provides an alias for RbConfig to Config for versions of Ruby older then
|
19
23
|
# # version 1.8.5. This allows us to use RbConfig in place of the older Config in
|
20
24
|
# # our code and still be compatible with at least Ruby 1.8.1.
|
21
25
|
# require 'rbconfig'
|
22
|
-
unless defined? ::RbConfig
|
23
|
-
::RbConfig = ::Config
|
24
|
-
end
|
26
|
+
::RbConfig = ::Config unless defined? ::RbConfig
|
25
27
|
|
26
28
|
# a method # that walks an array in groups, pass a block to
|
27
29
|
# call the block on each sub array
|
28
30
|
class Array
|
29
|
-
|
30
|
-
|
31
|
+
unless method_defined?(:in_groups_of)
|
32
|
+
def in_groups_of(chunk_size, padded_with=nil, &block)
|
33
|
+
arr = clone
|
31
34
|
|
32
|
-
|
33
|
-
|
35
|
+
# how many to add
|
36
|
+
padding = chunk_size - (arr.size % chunk_size)
|
34
37
|
|
35
|
-
|
36
|
-
|
38
|
+
# pad at the end
|
39
|
+
arr.concat([padded_with] * padding) unless padding == chunk_size
|
37
40
|
|
38
|
-
|
39
|
-
|
41
|
+
# how many chunks we'll make
|
42
|
+
count = arr.size / chunk_size
|
40
43
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
# make that many arrays
|
45
|
+
result = []
|
46
|
+
count.times {|s| result << arr[s * chunk_size, chunk_size]}
|
44
47
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
+
if block_given?
|
49
|
+
result.each_with_index do |a, i|
|
50
|
+
case block.arity
|
48
51
|
when 1
|
49
52
|
yield(a)
|
50
53
|
when 2
|
51
54
|
yield(a, (i == result.size - 1))
|
52
55
|
else
|
53
56
|
raise "Expected 1 or 2 arguments, got #{block.arity}"
|
57
|
+
end
|
54
58
|
end
|
59
|
+
else
|
60
|
+
result
|
55
61
|
end
|
56
|
-
else
|
57
|
-
result
|
58
62
|
end
|
59
|
-
end
|
63
|
+
end
|
60
64
|
end
|
61
65
|
|
62
66
|
class String
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
67
|
+
unless method_defined?(:bytes)
|
68
|
+
def bytes(&block)
|
69
|
+
# This should not be necessary, really ...
|
70
|
+
require "enumerator"
|
71
|
+
return to_enum(:each_byte) unless block_given?
|
72
|
+
each_byte(&block)
|
73
|
+
end
|
74
|
+
end
|
69
75
|
end
|
70
76
|
|
71
77
|
class Dir
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
|
91
|
-
path << "-#{n}" if n
|
92
|
-
path << suffix
|
93
|
-
Dir.mkdir(path, 0700)
|
94
|
-
rescue Errno::EEXIST
|
95
|
-
n ||= 0
|
96
|
-
n += 1
|
97
|
-
retry
|
98
|
-
end
|
99
|
-
|
100
|
-
if block_given?
|
78
|
+
unless method_defined?(:mktmpdir)
|
79
|
+
def self.mktmpdir(prefix_suffix=nil, tmpdir=nil)
|
80
|
+
case prefix_suffix
|
81
|
+
when nil
|
82
|
+
prefix = "d"
|
83
|
+
suffix = ""
|
84
|
+
when String
|
85
|
+
prefix = prefix_suffix
|
86
|
+
suffix = ""
|
87
|
+
when Array
|
88
|
+
prefix = prefix_suffix[0]
|
89
|
+
suffix = prefix_suffix[1]
|
90
|
+
else
|
91
|
+
raise ArgumentError, "unexpected prefix_suffix: #{prefix_suffix.inspect}"
|
92
|
+
end
|
93
|
+
tmpdir ||= Dir.tmpdir
|
94
|
+
t = Time.now.strftime("%Y%m%d")
|
95
|
+
n = nil
|
101
96
|
begin
|
102
|
-
|
103
|
-
|
104
|
-
|
97
|
+
path = "#{tmpdir}/#{prefix}#{t}-#{$$}-#{rand(0x100000000).to_s(36)}"
|
98
|
+
path << "-#{n}" if n
|
99
|
+
path << suffix
|
100
|
+
Dir.mkdir(path, 0o700)
|
101
|
+
rescue Errno::EEXIST
|
102
|
+
n ||= 0
|
103
|
+
n += 1
|
104
|
+
retry
|
105
|
+
end
|
106
|
+
|
107
|
+
if block_given?
|
108
|
+
begin
|
109
|
+
yield path
|
110
|
+
ensure
|
111
|
+
FileUtils.remove_entry_secure path
|
112
|
+
end
|
113
|
+
else
|
114
|
+
path
|
105
115
|
end
|
106
|
-
else
|
107
|
-
path
|
108
116
|
end
|
109
|
-
end
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
117
|
+
end
|
118
|
+
|
119
|
+
unless method_defined?(:tmpdir)
|
120
|
+
def self.tmpdir
|
121
|
+
tmp = "."
|
122
|
+
[ENV["TMPDIR"], ENV["TMP"], ENV["TEMP"], "/tmp"].each do |dir|
|
123
|
+
if dir && (stat = File.stat(dir)) && stat.directory? && stat.writable?
|
124
|
+
tmp = dir
|
125
|
+
break
|
126
|
+
end rescue nil
|
127
|
+
end
|
128
|
+
|
129
|
+
File.expand_path(tmp)
|
118
130
|
end
|
119
|
-
|
120
|
-
end unless method_defined?(:tmpdir)
|
131
|
+
end
|
121
132
|
end
|
122
133
|
|
123
134
|
# Reject all SSLv2 ciphers and all SSLv2 or SSLv3 handshakes by default
|
124
|
-
require
|
125
|
-
class OpenSSL::SSL::SSLContext
|
135
|
+
require "openssl"
|
136
|
+
class OpenSSL::SSL::SSLContext # rubocop:disable Style/ClassAndModuleChildren
|
126
137
|
if DEFAULT_PARAMS[:options]
|
127
138
|
DEFAULT_PARAMS[:options] |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
|
128
139
|
else
|
@@ -134,9 +145,7 @@ class OpenSSL::SSL::SSLContext
|
|
134
145
|
DEFAULT_PARAMS[:options] |= OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS
|
135
146
|
end
|
136
147
|
|
137
|
-
if DEFAULT_PARAMS[:ciphers]
|
138
|
-
DEFAULT_PARAMS[:ciphers] << ':!SSLv2'
|
139
|
-
end
|
148
|
+
DEFAULT_PARAMS[:ciphers] << ":!SSLv2" if DEFAULT_PARAMS[:ciphers]
|
140
149
|
|
141
150
|
alias __mcollective_original_initialize initialize
|
142
151
|
private :__mcollective_original_initialize
|
@@ -145,7 +154,7 @@ class OpenSSL::SSL::SSLContext
|
|
145
154
|
__mcollective_original_initialize(*args)
|
146
155
|
params = {
|
147
156
|
:options => DEFAULT_PARAMS[:options],
|
148
|
-
:ciphers => DEFAULT_PARAMS[:ciphers]
|
157
|
+
:ciphers => DEFAULT_PARAMS[:ciphers]
|
149
158
|
}
|
150
159
|
set_params(params)
|
151
160
|
end
|
@@ -17,7 +17,7 @@ module MCollective
|
|
17
17
|
# Starts a parser in verbose mode that does not show the common options:
|
18
18
|
#
|
19
19
|
# oparser = MCollective::Optionparser.new({:verbose => true}, "filter", "common")
|
20
|
-
def initialize(defaults
|
20
|
+
def initialize(defaults={}, include_sections=nil, exclude_sections=nil)
|
21
21
|
@parser = ::OptionParser.new
|
22
22
|
|
23
23
|
@include = [include_sections].flatten
|
@@ -56,7 +56,7 @@ module MCollective
|
|
56
56
|
next if @exclude.include?(i)
|
57
57
|
|
58
58
|
options_name = "add_#{i}_options"
|
59
|
-
send(options_name)
|
59
|
+
send(options_name) if respond_to?(options_name)
|
60
60
|
end
|
61
61
|
|
62
62
|
@parser.environment("MCOLLECTIVE_EXTRA_OPTS")
|
@@ -74,7 +74,7 @@ module MCollective
|
|
74
74
|
@parser.separator ""
|
75
75
|
@parser.separator "Host Filters"
|
76
76
|
|
77
|
-
@parser.on(
|
77
|
+
@parser.on("-W", "--with FILTER", "Combined classes and facts filter") do |f|
|
78
78
|
f.split(" ").each do |filter|
|
79
79
|
begin
|
80
80
|
fact_parsed = parse_fact(filter)
|
@@ -85,40 +85,40 @@ module MCollective
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
@parser.on(
|
88
|
+
@parser.on("-S", "--select FILTER", "Compound filter combining facts and classes") do |f|
|
89
89
|
@options[:filter]["compound"] << Matcher.create_compound_callstack(f)
|
90
90
|
end
|
91
91
|
|
92
|
-
@parser.on(
|
92
|
+
@parser.on("-F", "--wf", "--with-fact fact=val", "Match hosts with a certain fact") do |f|
|
93
93
|
fact_parsed = parse_fact(f)
|
94
94
|
|
95
95
|
@options[:filter]["fact"] << fact_parsed if fact_parsed
|
96
96
|
end
|
97
97
|
|
98
|
-
@parser.on(
|
98
|
+
@parser.on("-C", "--wc", "--with-class CLASS", "Match hosts with a certain config management class") do |f|
|
99
99
|
@options[:filter]["cf_class"] << f
|
100
100
|
end
|
101
101
|
|
102
|
-
@parser.on(
|
102
|
+
@parser.on("-A", "--wa", "--with-agent AGENT", "Match hosts with a certain agent") do |a|
|
103
103
|
@options[:filter]["agent"] << a
|
104
104
|
end
|
105
105
|
|
106
|
-
@parser.on(
|
106
|
+
@parser.on("-I", "--wi", "--with-identity IDENT", "Match hosts with a certain configured identity") do |a|
|
107
107
|
@options[:filter]["identity"] << a
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
111
|
# These options should always be present
|
112
112
|
def add_required_options
|
113
|
-
@parser.on(
|
113
|
+
@parser.on("-c", "--config FILE", "Load configuration from file rather than default") do |f|
|
114
114
|
@options[:config] = f
|
115
115
|
end
|
116
116
|
|
117
|
-
@parser.on(
|
117
|
+
@parser.on("-v", "--verbose", "Be verbose") do |v|
|
118
118
|
@options[:verbose] = v
|
119
119
|
end
|
120
120
|
|
121
|
-
@parser.on(
|
121
|
+
@parser.on("-h", "--help", "Display this screen") do
|
122
122
|
puts @parser
|
123
123
|
exit! 1
|
124
124
|
end
|
@@ -129,41 +129,41 @@ module MCollective
|
|
129
129
|
@parser.separator ""
|
130
130
|
@parser.separator "Common Options"
|
131
131
|
|
132
|
-
@parser.on(
|
132
|
+
@parser.on("-T", "--target COLLECTIVE", "Target messages to a specific sub collective") do |f|
|
133
133
|
@options[:collective] = f
|
134
134
|
end
|
135
135
|
|
136
|
-
@parser.on(
|
136
|
+
@parser.on("--dt", "--discovery-timeout SECONDS", Integer, "Timeout for doing discovery") do |t|
|
137
137
|
@options[:disctimeout] = t
|
138
138
|
end
|
139
139
|
|
140
|
-
@parser.on(
|
140
|
+
@parser.on("-t", "--timeout SECONDS", Integer, "Timeout for calling remote agents") do |t|
|
141
141
|
@options[:timeout] = t
|
142
142
|
end
|
143
143
|
|
144
|
-
@parser.on(
|
144
|
+
@parser.on("-q", "--quiet", "Do not be verbose") do |_v|
|
145
145
|
@options[:verbose] = false
|
146
146
|
end
|
147
147
|
|
148
|
-
@parser.on(
|
148
|
+
@parser.on("--ttl TTL", "Set the message validity period") do |v|
|
149
149
|
@options[:ttl] = v.to_i
|
150
150
|
end
|
151
151
|
|
152
|
-
@parser.on(
|
152
|
+
@parser.on("--reply-to TARGET", "Set a custom target for replies") do |v|
|
153
153
|
@options[:reply_to] = v
|
154
154
|
end
|
155
155
|
|
156
|
-
@parser.on(
|
156
|
+
@parser.on("--dm", "--disc-method METHOD", "Which discovery method to use") do |v|
|
157
157
|
raise "Discovery method is already set by a competing option" if @options[:discovery_method] && @options[:discovery_method] != v
|
158
158
|
@options[:discovery_method] = v
|
159
159
|
end
|
160
160
|
|
161
|
-
@parser.on(
|
161
|
+
@parser.on("--do", "--disc-option OPTION", "Options to pass to the discovery method") do |a|
|
162
162
|
@options[:discovery_options] << a
|
163
163
|
end
|
164
164
|
|
165
165
|
@parser.on("--nodes FILE", "List of nodes to address") do |v|
|
166
|
-
raise "Cannot mix --disc-method, --disc-option and --nodes" if @options[:discovery_method] ||
|
166
|
+
raise "Cannot mix --disc-method, --disc-option and --nodes" if @options[:discovery_method] || !@options[:discovery_options].empty?
|
167
167
|
raise "Cannot read the discovery file #{v}" unless File.readable?(v)
|
168
168
|
|
169
169
|
@options[:discovery_method] = "flatfile"
|
@@ -174,11 +174,11 @@ module MCollective
|
|
174
174
|
@options[:publish_timeout] = pt
|
175
175
|
end
|
176
176
|
|
177
|
-
@parser.on("--threaded", "Start publishing requests and receiving responses in threaded mode.") do |
|
177
|
+
@parser.on("--threaded", "Start publishing requests and receiving responses in threaded mode.") do |_v|
|
178
178
|
@options[:threaded] = true
|
179
179
|
end
|
180
180
|
|
181
|
-
@parser.on("--sort", "Sort the output of an RPC call before processing.") do |
|
181
|
+
@parser.on("--sort", "Sort the output of an RPC call before processing.") do |_v|
|
182
182
|
@options[:sort] = true
|
183
183
|
end
|
184
184
|
|
@@ -188,10 +188,10 @@ module MCollective
|
|
188
188
|
end
|
189
189
|
|
190
190
|
private
|
191
|
+
|
191
192
|
# Parse a fact filter string like foo=bar into the tuple hash thats needed
|
192
193
|
def parse_fact(fact)
|
193
194
|
Util.parse_fact_string(fact)
|
194
195
|
end
|
195
|
-
|
196
196
|
end
|
197
197
|
end
|
@@ -36,7 +36,6 @@ module MCollective
|
|
36
36
|
|
37
37
|
raise("Plugin #{type} already loaded") if @plugins.include?(type)
|
38
38
|
|
39
|
-
|
40
39
|
# If we get a string then store 'nil' as the instance, signalling that we'll
|
41
40
|
# create the class later on demand.
|
42
41
|
if klass.is_a?(String)
|
@@ -76,7 +75,7 @@ module MCollective
|
|
76
75
|
|
77
76
|
if @plugins[plugin][:single]
|
78
77
|
# Create an instance of the class if one hasn't been done before
|
79
|
-
if @plugins[plugin][:instance]
|
78
|
+
if @plugins[plugin][:instance].nil?
|
80
79
|
Log.debug("Returning new plugin #{plugin} with class #{klass}")
|
81
80
|
@plugins[plugin][:instance] = create_instance(klass)
|
82
81
|
else
|
@@ -92,11 +91,9 @@ module MCollective
|
|
92
91
|
|
93
92
|
# use eval to create an instance of a class
|
94
93
|
def self.create_instance(klass)
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
raise("Could not create instance of plugin #{klass}: #{e}")
|
99
|
-
end
|
94
|
+
eval("#{klass}.new") # rubocop:disable Security/Eval
|
95
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
96
|
+
raise("Could not create instance of plugin #{klass}: #{e}")
|
100
97
|
end
|
101
98
|
|
102
99
|
# Finds plugins in all configured libdirs
|
@@ -114,7 +111,7 @@ module MCollective
|
|
114
111
|
# Will return the same list but only of files with extension .ddl
|
115
112
|
# in the agent subdirectory
|
116
113
|
def self.find(type, extension="rb")
|
117
|
-
extension = ".#{extension}" unless extension
|
114
|
+
extension = ".#{extension}" unless extension =~ /^\./
|
118
115
|
|
119
116
|
plugins = []
|
120
117
|
|
@@ -146,14 +143,14 @@ module MCollective
|
|
146
143
|
#
|
147
144
|
# This will load only plugins matching /puppet/
|
148
145
|
def self.find_and_load(type, extension="rb")
|
149
|
-
extension = ".#{extension}" unless extension
|
146
|
+
extension = ".#{extension}" unless extension =~ /^\./
|
150
147
|
|
151
148
|
klasses = find(type, extension).map do |plugin|
|
152
149
|
if block_given?
|
153
150
|
next unless yield(plugin)
|
154
151
|
end
|
155
152
|
|
156
|
-
"%s::%s::%s" % [
|
153
|
+
"%s::%s::%s" % ["MCollective", type.capitalize, plugin.capitalize]
|
157
154
|
end.compact
|
158
155
|
|
159
156
|
klasses.sort.uniq.each {|klass| loadclass(klass, true)}
|
@@ -167,7 +164,7 @@ module MCollective
|
|
167
164
|
Log.debug("Loading #{klass} from #{fname}")
|
168
165
|
|
169
166
|
load fname
|
170
|
-
rescue Exception => e
|
167
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
171
168
|
Log.error("Failed to load #{klass}: #{e}")
|
172
169
|
raise unless squash_failures
|
173
170
|
end
|