choria-mcorpc-support 2.20.3 → 2.20.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,7 +10,7 @@ module MCollective
10
10
  end
11
11
 
12
12
  def self.[](klass)
13
- const_get("#{klass}")
13
+ const_get(klass.to_s)
14
14
  end
15
15
 
16
16
  # Fetch and return metadata from plugin DDL
@@ -19,12 +19,12 @@ module MCollective
19
19
 
20
20
  begin
21
21
  ddl_file = File.read(Dir.glob(File.join(path, type, "*.ddl")).first)
22
- rescue Exception
22
+ rescue Exception # rubocop:disable Lint/RescueException
23
23
  raise "failed to load ddl file in plugin directory : #{File.join(path, type)}"
24
24
  end
25
25
  ddl.instance_eval ddl_file
26
26
 
27
- return ddl.meta, ddl.requirements[:mcollective]
27
+ [ddl.meta, ddl.requirements[:mcollective]]
28
28
  end
29
29
 
30
30
  # Checks if a directory is present and not empty
@@ -34,19 +34,19 @@ module MCollective
34
34
 
35
35
  # Quietly calls a block if verbose parameter is false
36
36
  def self.execute_verbosely(verbose, &block)
37
- unless verbose
37
+ if verbose
38
+ block.call
39
+ else
38
40
  old_stdout = $stdout.clone
39
41
  $stdout.reopen(File.new("/dev/null", "w"))
40
42
  begin
41
43
  block.call
42
- rescue Exception => e
44
+ rescue Exception # rubocop:disable Lint/RescueException
43
45
  $stdout.reopen old_stdout
44
- raise e
46
+ raise
45
47
  ensure
46
48
  $stdout.reopen old_stdout
47
49
  end
48
- else
49
- block.call
50
50
  end
51
51
  end
52
52
 
@@ -54,15 +54,13 @@ module MCollective
54
54
  def self.command_available?(build_tool)
55
55
  ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
56
56
  builder = File.join(path, build_tool)
57
- if File.exists?(builder)
58
- return true
59
- end
57
+ return true if File.exist?(builder)
60
58
  end
61
59
  false
62
60
  end
63
61
 
64
62
  def self.safe_system(*args)
65
- raise(RuntimeError, "Failed: #{args.join(' ')}") unless system *args
63
+ raise("Failed: #{args.join(' ')}") unless system(*args)
66
64
  end
67
65
 
68
66
  # Filter out platform specific dependencies
@@ -77,22 +75,20 @@ module MCollective
77
75
  if prefix == $1
78
76
  dependency[:name] = $2
79
77
  dependency
80
- else
81
- nil
82
78
  end
83
79
  else
84
80
  dependency
85
81
  end
86
- end.reject{ |dependency| dependency == nil }
82
+ end.reject(&:nil?)
87
83
  end
88
84
 
89
85
  # Return the path to a plugin's core directories
90
86
  def self.get_plugin_path(target)
91
- if (File.exists?(File.join(target, "lib", "mcollective")))
87
+ if File.exist?(File.join(target, "lib", "mcollective"))
92
88
  return File.join(target, "lib", "mcollective")
93
89
  end
94
90
 
95
- return target
91
+ target
96
92
  end
97
93
  end
98
94
  end
@@ -1,4 +1,4 @@
1
- require 'pp'
1
+ require "pp"
2
2
 
3
3
  module MCollective
4
4
  # Toolset to create a standard interface of client and agent using
@@ -21,15 +21,13 @@ module MCollective
21
21
  def rpcoptions
22
22
  oparser = MCollective::Optionparser.new({:verbose => false, :progress_bar => true}, "filter")
23
23
 
24
- options = oparser.parse do |parser, options|
25
- if block_given?
26
- yield(parser, options)
27
- end
24
+ options = oparser.parse do |parser, opts|
25
+ yield(parser, opts) if block_given?
28
26
 
29
- Helpers.add_simplerpc_options(parser, options)
27
+ Helpers.add_simplerpc_options(parser, opts)
30
28
  end
31
29
 
32
- return options
30
+ options
33
31
  end
34
32
 
35
33
  # Wrapper to create clients, supposed to be used as
@@ -57,7 +55,7 @@ module MCollective
57
55
  # :exit_on_failure is true by default, and causes the application to
58
56
  # exit if there is a failure constructing the RPC client. Set this flag
59
57
  # to false to cause an Exception to be raised instead.
60
- def rpcclient(agent, flags = {})
58
+ def rpcclient(agent, flags={})
61
59
  configfile = flags[:configfile] || Util.config_file_for_user
62
60
  options = flags[:options] || nil
63
61
 
@@ -71,12 +69,12 @@ module MCollective
71
69
  begin
72
70
  if options
73
71
  rpc = Client.new(agent, :configfile => options[:config], :options => options)
74
- @options = rpc.options
75
72
  else
76
73
  rpc = Client.new(agent, :configfile => configfile)
77
- @options = rpc.options
78
74
  end
79
- rescue Exception => e
75
+
76
+ @options = rpc.options
77
+ rescue Exception => e # rubocop:disable Lint/RescueException:
80
78
  if exit_on_failure
81
79
  puts("Could not create RPC client: #{e}")
82
80
  exit!
@@ -97,7 +95,7 @@ module MCollective
97
95
  # printrpcstats can easily get access to it without
98
96
  # users having to pass it around in params.
99
97
  def self.stats(stats)
100
- @@stats = stats
98
+ @@stats = stats # rubocop:disable Style/ClassVars
101
99
  end
102
100
 
103
101
  # means for other classes to drop discovered hosts into this module
@@ -105,7 +103,7 @@ module MCollective
105
103
  # printrpcstats can easily get access to it without
106
104
  # users having to pass it around in params.
107
105
  def self.discovered(discovered)
108
- @@discovered = discovered
106
+ @@discovered = discovered # rubocop:disable Style/ClassVars
109
107
  end
110
108
 
111
109
  # Prints stats, requires stats to be saved from elsewhere
@@ -125,7 +123,7 @@ module MCollective
125
123
 
126
124
  flags = {:summarize => false, :caption => "rpc stats"}.merge(flags)
127
125
 
128
- verbose = @options[:verbose] rescue verbose = false
126
+ verbose = !!@options[:verbose]
129
127
 
130
128
  begin
131
129
  stats = @@stats
@@ -143,17 +141,17 @@ module MCollective
143
141
  # that produce an error will be printed
144
142
  #
145
143
  # To get details of each result run with the -v command line option.
146
- def printrpc(result, flags = {})
147
- verbose = @options[:verbose] rescue verbose = false
144
+ def printrpc(result, flags={})
145
+ verbose = !!@options[:verbose]
148
146
  verbose = flags[:verbose] || verbose
149
147
  flatten = flags[:flatten] || false
150
148
  format = @options[:output_format]
151
149
  forced_mode = @options[:force_display_mode] || false
152
150
 
153
- result_text = Helpers.rpcresults(result, {:verbose => verbose, :flatten => flatten, :format => format, :force_display_mode => forced_mode})
151
+ result_text = Helpers.rpcresults(result, :verbose => verbose, :flatten => flatten, :format => format, :force_display_mode => forced_mode)
154
152
 
155
153
  if result.is_a?(Array) && format == :console
156
- puts "\n%s\n" % [ result_text ]
154
+ puts "\n%s\n" % [result_text]
157
155
  else
158
156
  # when we get just one result to print dont pad them all with
159
157
  # blank spaces etc, just print the individual result with no
@@ -60,27 +60,31 @@ module MCollective
60
60
 
61
61
  # Returns a hash with all stats
62
62
  def to_hash
63
- stats = {:validated => @validated,
63
+ stats = {
64
+ :validated => @validated,
64
65
  :unvalidated => @unvalidated,
65
66
  :passed => @passed,
66
67
  :filtered => @filtered,
67
68
  :starttime => @starttime,
68
69
  :total => @total,
69
70
  :ttlexpired => @ttlexpired,
70
- :replies => @replies}
71
+ :replies => @replies
72
+ }
71
73
 
72
- reply = {:stats => stats,
74
+ reply = {
75
+ :stats => stats,
73
76
  :threads => [],
74
77
  :pid => Process.pid,
75
- :times => {} }
78
+ :times => {}
79
+ }
76
80
 
77
- ::Process.times.each_pair{|k,v|
81
+ ::Process.times.each_pair {|k, v|
78
82
  k = k.to_sym
79
83
  reply[:times][k] = v
80
84
  }
81
85
 
82
86
  Thread.list.each do |t|
83
- reply[:threads] << "#{t.inspect}"
87
+ reply[:threads] << t.inspect.to_s
84
88
  end
85
89
 
86
90
  reply[:agents] = Agents.agentlist
@@ -36,33 +36,33 @@ module MCollective
36
36
 
37
37
  options.each do |opt, val|
38
38
  case opt.to_s
39
- when "stdout"
40
- raise "stdout should support <<" unless val.respond_to?("<<")
41
- @stdout = val
39
+ when "stdout"
40
+ raise "stdout should support <<" unless val.respond_to?("<<")
41
+ @stdout = val
42
42
 
43
- when "stderr"
44
- raise "stderr should support <<" unless val.respond_to?("<<")
45
- @stderr = val
43
+ when "stderr"
44
+ raise "stderr should support <<" unless val.respond_to?("<<")
45
+ @stderr = val
46
46
 
47
- when "stdin"
48
- raise "stdin should be a String" unless val.is_a?(String)
49
- @stdin = val
47
+ when "stdin"
48
+ raise "stdin should be a String" unless val.is_a?(String)
49
+ @stdin = val
50
50
 
51
- when "cwd"
52
- raise "Directory #{val} does not exist" unless File.directory?(val)
53
- @cwd = val
51
+ when "cwd"
52
+ raise "Directory #{val} does not exist" unless File.directory?(val)
53
+ @cwd = val
54
54
 
55
- when "environment"
56
- if val.nil?
57
- @environment = {}
58
- else
59
- @environment.merge!(val.dup)
60
- @environment = @environment.delete_if { |k,v| v.nil? }
61
- end
55
+ when "environment"
56
+ if val.nil?
57
+ @environment = {}
58
+ else
59
+ @environment.merge!(val.dup)
60
+ @environment = @environment.delete_if { |_k, v| v.nil? }
61
+ end
62
62
 
63
- when "timeout"
64
- raise "timeout should be a positive integer or the symbol :on_thread_exit symbol" unless val.eql?(:on_thread_exit) || ( val.is_a?(Integer) && val>0 )
65
- @timeout = val
63
+ when "timeout"
64
+ raise "timeout should be a positive integer or the symbol :on_thread_exit symbol" unless val.eql?(:on_thread_exit) || (val.is_a?(Integer) && val > 0)
65
+ @timeout = val
66
66
  end
67
67
  end
68
68
  end
@@ -76,7 +76,6 @@ module MCollective
76
76
 
77
77
  opts["stdin"] = @stdin if @stdin
78
78
 
79
-
80
79
  thread = Thread.current
81
80
  # Start a double fork and exec with systemu which implies a guard thread.
82
81
  # If a valid timeout is configured the guard thread will terminate the
@@ -90,32 +89,30 @@ module MCollective
90
89
  sleep timeout
91
90
  else
92
91
  # sleep while the agent thread is still alive
93
- while(thread.alive?)
94
- sleep 0.1
95
- end
92
+ sleep 0.1 while thread.alive?
96
93
  end
97
94
 
98
95
  # if the process is still running
99
- if (Process.kill(0, cid))
96
+ if Process.kill(0, cid)
100
97
  # and a timeout was specified
101
98
  if timeout
102
99
  if Util.windows?
103
- Process.kill('KILL', cid)
100
+ Process.kill("KILL", cid)
104
101
  else
105
102
  # Kill the process
106
- Process.kill('TERM', cid)
103
+ Process.kill("TERM", cid)
107
104
  sleep 2
108
- Process.kill('KILL', cid) if (Process.kill(0, cid))
105
+ Process.kill("KILL", cid) if Process.kill(0, cid) # rubocop:disable Metrics/BlockNesting
109
106
  end
110
107
  end
111
108
  # only wait if the parent thread is dead
112
109
  Process.waitpid(cid) unless thread.alive?
113
110
  end
114
- rescue SystemExit
115
- rescue Errno::ESRCH
111
+ rescue SystemExit # rubocop:disable Lint/HandleExceptions
112
+ rescue Errno::ESRCH # rubocop:disable Lint/HandleExceptions
116
113
  rescue Errno::ECHILD
117
114
  Log.warn("Could not reap process '#{cid}'.")
118
- rescue Exception => e
115
+ rescue Exception => e # rubocop:disable Lint/RescueException
119
116
  Log.info("Unexpected exception received while waiting for child process: #{e.class}: #{e}")
120
117
  end
121
118
  end
@@ -1,6 +1,6 @@
1
- require 'openssl'
2
- require 'base64'
3
- require 'digest/sha1'
1
+ require "openssl"
2
+ require "base64"
3
+ require "digest/sha1"
4
4
 
5
5
  module MCollective
6
6
  # A class that assists in encrypting and decrypting data using a
@@ -161,7 +161,7 @@ module MCollective
161
161
  cipher.decrypt
162
162
  cipher.key = key
163
163
  cipher.pkcs5_keyivgen(key)
164
- decrypted_data = cipher.update(crypt_string) + cipher.final
164
+ cipher.update(crypt_string) + cipher.final
165
165
  end
166
166
 
167
167
  # Signs a string using the private key
@@ -195,9 +195,7 @@ module MCollective
195
195
  def self.base64_decode(string)
196
196
  # The Base 64 character set is A-Z a-z 0-9 + / =
197
197
  # Also allow for whitespace, but raise if we get anything else
198
- if string !~ /^[A-Za-z0-9+\/=\s]+$/
199
- raise ArgumentError, 'invalid base64'
200
- end
198
+ raise(ArgumentError, "invalid base64") if string !~ /^[A-Za-z0-9+\/=\s]+$/
201
199
  Base64.decode64(string)
202
200
  end
203
201
 
@@ -216,9 +214,9 @@ module MCollective
216
214
  # https://github.com/kwilczynski/puppet-functions/blob/master/lib/puppet/parser/functions/uuid.rb
217
215
  #
218
216
  def self.uuid(string=nil)
219
- string ||= OpenSSL::Random.random_bytes(16).unpack('H*').shift
217
+ string ||= OpenSSL::Random.random_bytes(16).unpack("H*").shift
220
218
 
221
- uuid_name_space_dns = [0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8].map {|b| b.chr}.join
219
+ uuid_name_space_dns = [0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8].map(&:chr).join
222
220
 
223
221
  sha1 = Digest::SHA1.new
224
222
  sha1.update(uuid_name_space_dns)
@@ -236,10 +234,10 @@ module MCollective
236
234
  bytes[8] |= 0x80
237
235
 
238
236
  bytes = [4, 2, 2, 2, 6].collect do |i|
239
- bytes.slice!(0, i).pack('C*').unpack('H*')
237
+ bytes.slice!(0, i).pack("C*").unpack("H*")
240
238
  end
241
239
 
242
- bytes.join('-')
240
+ bytes.join("-")
243
241
  end
244
242
 
245
243
  # Reads either a :public or :private key from disk, uses an
@@ -280,6 +278,5 @@ module MCollective
280
278
  raise "Can only load :public or :private keys"
281
279
  end
282
280
  end
283
-
284
281
  end
285
282
  end
@@ -6,10 +6,10 @@ module MCollective
6
6
  # If the passed name starts with a / it's assumed to be regex
7
7
  # and will use regex to match
8
8
  def self.has_agent?(agent)
9
- agent = Regexp.new(agent.gsub("\/", "")) if agent.match("^/")
9
+ agent = Regexp.new(agent.gsub("\/", "")) if agent.start_with?("/")
10
10
 
11
11
  if agent.is_a?(Regexp)
12
- if Agents.agentlist.grep(agent).size > 0
12
+ if !Agents.agentlist.grep(agent).empty?
13
13
  return true
14
14
  else
15
15
  return false
@@ -17,8 +17,6 @@ module MCollective
17
17
  else
18
18
  return Agents.agentlist.include?(agent)
19
19
  end
20
-
21
- false
22
20
  end
23
21
 
24
22
  # On windows ^c can't interrupt the VM if its blocking on
@@ -36,7 +34,7 @@ module MCollective
36
34
  # If the passed name starts with a / it's assumed to be regex
37
35
  # and will use regex to match
38
36
  def self.has_cf_class?(klass)
39
- klass = Regexp.new(klass.gsub("\/", "")) if klass.match("^/")
37
+ klass = Regexp.new(klass.gsub("\/", "")) if klass.start_with?("/")
40
38
  cfile = Config.instance.classesfile
41
39
 
42
40
  Log.debug("Looking for configuration management classes in #{cfile}")
@@ -45,11 +43,11 @@ module MCollective
45
43
  File.readlines(cfile).each do |k|
46
44
  if klass.is_a?(Regexp)
47
45
  return true if k.chomp.match(klass)
48
- else
49
- return true if k.chomp == klass
46
+ elsif k.chomp == klass
47
+ return true
50
48
  end
51
49
  end
52
- rescue Exception => e
50
+ rescue Exception => e # rubocop:disable Lint/RescueException
53
51
  Log.warn("Parsing classes file '#{cfile}' failed: #{e.class}: #{e}")
54
52
  end
55
53
 
@@ -67,7 +65,6 @@ module MCollective
67
65
  # If the passed value starts with a / it's assumed to be regex
68
66
  # and will use regex to match
69
67
  def self.has_fact?(fact, value, operator)
70
-
71
68
  Log.debug("Comparing #{fact} #{operator} #{value}")
72
69
  Log.debug("where :fact = '#{fact}', :operator = '#{operator}', :value = '#{value}'")
73
70
 
@@ -86,30 +83,28 @@ module MCollective
86
83
  end
87
84
 
88
85
  def self.test_fact_value(fact, value, operator)
89
- if operator == '=~'
86
+ if operator == "=~"
90
87
  # to maintain backward compat we send the value
91
88
  # as /.../ which is what 1.0.x needed. this strips
92
89
  # off the /'s which is what we need here
93
- if value =~ /^\/(.+)\/$/
94
- value = $1
95
- end
90
+ value = $1 if value =~ /^\/(.+)\/$/
96
91
 
97
92
  return true if fact.match(Regexp.new(value))
98
93
 
99
94
  elsif operator == "=="
100
95
  return true if fact == value
101
96
 
102
- elsif ['<=', '>=', '<', '>', '!='].include?(operator)
97
+ elsif ["<=", ">=", "<", ">", "!="].include?(operator)
103
98
  # Yuk - need to type cast, but to_i and to_f are overzealous
104
99
  if value =~ /^[0-9]+$/ && fact =~ /^[0-9]+$/
105
- fact = Integer(fact)
106
- value = Integer(value)
100
+ fact = Integer(fact) # rubocop:disable Lint/UselessAssignment
101
+ value = Integer(value) # rubocop:disable Lint/UselessAssignment
107
102
  elsif value =~ /^[0-9]+.[0-9]+$/ && fact =~ /^[0-9]+.[0-9]+$/
108
- fact = Float(fact)
109
- value = Float(value)
103
+ fact = Float(fact) # rubocop:disable Lint/UselessAssignment
104
+ value = Float(value) # rubocop:disable Lint/UselessAssignment
110
105
  end
111
106
 
112
- return true if eval("fact #{operator} value")
107
+ return true if eval("fact #{operator} value") # rubocop:disable Security/Eval
113
108
  end
114
109
 
115
110
  false
@@ -121,12 +116,12 @@ module MCollective
121
116
  # If the passed name starts with a / it's assumed to be regex
122
117
  # and will use regex to match
123
118
  def self.has_identity?(identity)
124
- identity = Regexp.new(identity.gsub("\/", "")) if identity.match("^/")
119
+ identity = Regexp.new(identity.gsub("\/", "")) if identity.start_with?("/")
125
120
 
126
121
  if identity.is_a?(Regexp)
127
122
  return Config.instance.identity.match(identity)
128
- else
129
- return true if Config.instance.identity == identity
123
+ elsif Config.instance.identity == identity
124
+ return true
130
125
  end
131
126
 
132
127
  false
@@ -139,56 +134,94 @@ module MCollective
139
134
 
140
135
  # Creates an empty filter
141
136
  def self.empty_filter
142
- {"fact" => [],
143
- "cf_class" => [],
144
- "agent" => [],
145
- "identity" => [],
146
- "compound" => []}
137
+ {
138
+ "fact" => [],
139
+ "cf_class" => [],
140
+ "agent" => [],
141
+ "identity" => [],
142
+ "compound" => []
143
+ }
147
144
  end
148
145
 
149
146
  # Returns the PuppetLabs mcollective path for windows
150
147
  def self.windows_prefix
151
- require 'win32/dir'
152
- prefix = File.join(Dir::COMMON_APPDATA, "PuppetLabs", "mcollective")
148
+ require "win32/dir"
149
+ File.join(Dir::COMMON_APPDATA, "PuppetLabs", "mcollective")
153
150
  end
154
151
 
155
- # Picks a config file defaults to ~/.mcollective
156
- # else /etc/mcollective/client.cfg
157
- def self.config_file_for_user
158
- # the set of acceptable config files
152
+ def self.choria_windows_prefix
153
+ require "win32/dir"
154
+ File.join(Dir::COMMON_APPDATA, "ChoriaIO", "choria")
155
+ end
156
+
157
+ def self.mcollective_config_paths_for_user
159
158
  config_paths = []
160
159
 
161
- # user dotfile
162
160
  begin
163
161
  # File.expand_path will raise if HOME isn't set, catch it
164
162
  user_path = File.expand_path("~/.mcollective")
165
163
  config_paths << user_path
166
- rescue Exception
164
+ rescue Exception # rubocop:disable Lint/RescueException, Lint/HandleExceptions
167
165
  end
168
166
 
169
- # standard locations
170
- if self.windows?
171
- config_paths << File.join(self.windows_prefix, 'etc', 'client.cfg')
167
+ if windows?
168
+ config_paths << File.join(windows_prefix, "etc", "client.cfg")
172
169
  else
173
- config_paths << '/etc/puppetlabs/mcollective/client.cfg'
174
- config_paths << '/etc/mcollective/client.cfg'
170
+ config_paths << "/etc/puppetlabs/mcollective/client.cfg"
171
+ config_paths << "/etc/mcollective/client.cfg"
175
172
  end
176
173
 
177
- # use the first readable config file, or if none are the first listed
174
+ config_paths
175
+ end
176
+
177
+ def self.choria_config_paths_for_user
178
+ config_paths = []
179
+
180
+ begin
181
+ # File.expand_path will raise if HOME isn't set, catch it
182
+ user_path = File.expand_path("~/.choriarc")
183
+ config_paths << user_path
184
+ rescue Exception # rubocop:disable Lint/RescueException, Lint/HandleExceptions
185
+ end
186
+
187
+ if windows?
188
+ config_paths << File.join(choria_windows_prefix, "etc", "client.conf")
189
+ else
190
+ config_paths << "/etc/choria/client.conf"
191
+ end
192
+
193
+ config_paths
194
+ end
195
+
196
+ # Picks the default user config file, pririties are first Choria ones then old MCollective ones
197
+ #
198
+ # In roughly this order, first to exist is used:
199
+ #
200
+ # - ~/.choriarc
201
+ # - APPData/ChoriaIO/choria/etc/client.conf on windows
202
+ # - /etc/choria/client.conf on unix
203
+ # - ~/.mcollective
204
+ # - APPData/PuppetLabs/mcollective/etc/client.cfg on windows
205
+ # - /etc/puppetlabs/mcollective/client.cfg
206
+ # - /etc/mcollective/client.cfg
207
+ def self.config_file_for_user
208
+ config_paths = choria_config_paths_for_user + mcollective_config_paths_for_user
178
209
  found = config_paths.find_index { |file| File.readable?(file) } || 0
179
- return config_paths[found]
210
+ config_paths[found]
180
211
  end
181
212
 
182
213
  # Creates a standard options hash
183
214
  def self.default_options
184
- {:verbose => false,
185
- :disctimeout => nil,
186
- :timeout => 5,
187
- :config => config_file_for_user,
188
- :collective => nil,
189
- :discovery_method => nil,
190
- :discovery_options => Config.instance.default_discovery_options,
191
- :filter => empty_filter}
215
+ {
216
+ :verbose => false,
217
+ :disctimeout => nil,
218
+ :timeout => 5,
219
+ :config => config_file_for_user,
220
+ :collective => nil,
221
+ :discovery_method => nil,
222
+ :discovery_options => Config.instance.default_discovery_options,
223
+ :filter => empty_filter
224
+ }
192
225
  end
193
226
 
194
227
  def self.make_subscriptions(agent, type, collective=nil)
@@ -237,15 +270,15 @@ module MCollective
237
270
  # Parse a fact filter string like foo=bar into the tuple hash thats needed
238
271
  def self.parse_fact_string(fact)
239
272
  if fact =~ /^([^ ]+?)[ ]*=>[ ]*(.+)/
240
- return {:fact => $1, :value => $2, :operator => '>=' }
273
+ {:fact => $1, :value => $2, :operator => ">="}
241
274
  elsif fact =~ /^([^ ]+?)[ ]*=<[ ]*(.+)/
242
- return {:fact => $1, :value => $2, :operator => '<=' }
275
+ {:fact => $1, :value => $2, :operator => "<="}
243
276
  elsif fact =~ /^([^ ]+?)[ ]*(<=|>=|<|>|!=|==|=~)[ ]*(.+)/
244
- return {:fact => $1, :value => $3, :operator => $2 }
277
+ {:fact => $1, :value => $3, :operator => $2}
245
278
  elsif fact =~ /^(.+?)[ ]*=[ ]*\/(.+)\/$/
246
- return {:fact => $1, :value => "/#{$2}/", :operator => '=~' }
279
+ {:fact => $1, :value => "/#{$2}/", :operator => "=~"}
247
280
  elsif fact =~ /^([^= ]+?)[ ]*=[ ]*(.+)/
248
- return {:fact => $1, :value => $2, :operator => '==' }
281
+ {:fact => $1, :value => $2, :operator => "=="}
249
282
  else
250
283
  raise "Could not parse fact #{fact} it does not appear to be in a valid format"
251
284
  end
@@ -267,11 +300,11 @@ module MCollective
267
300
  # combo is regarded as line continuation and simply ignored.
268
301
  str.gsub!(/\n/, "'\n'")
269
302
 
270
- return str
303
+ str
271
304
  end
272
305
 
273
306
  def self.windows?
274
- !!(RbConfig::CONFIG['host_os'] =~ /mswin|win32|dos|mingw|cygwin/i)
307
+ !!(RbConfig::CONFIG["host_os"] =~ /mswin|win32|dos|mingw|cygwin/i)
275
308
  end
276
309
 
277
310
  # Return color codes, if the config color= option is false
@@ -279,12 +312,14 @@ module MCollective
279
312
  def self.color(code)
280
313
  colorize = Config.instance.color
281
314
 
282
- colors = {:red => "",
283
- :green => "",
284
- :yellow => "",
285
- :cyan => "",
286
- :bold => "",
287
- :reset => ""}
315
+ colors = {
316
+ :red => "",
317
+ :green => "",
318
+ :yellow => "",
319
+ :cyan => "",
320
+ :bold => "",
321
+ :reset => ""
322
+ }
288
323
 
289
324
  if colorize
290
325
  return colors[code] || ""
@@ -295,7 +330,7 @@ module MCollective
295
330
 
296
331
  # Helper to return a string in specific color
297
332
  def self.colorize(code, msg)
298
- "%s%s%s" % [ color(code), msg, color(:reset) ]
333
+ "%s%s%s" % [color(code), msg, color(:reset)]
299
334
  end
300
335
 
301
336
  # Returns the current ruby version as per RUBY_VERSION, mostly
@@ -316,7 +351,7 @@ module MCollective
316
351
  # The terminal size is detected by default, but custom line widths can
317
352
  # passed. All strings will also be left aligned with 5 whitespace characters
318
353
  # by default.
319
- def self.align_text(text, console_cols = nil, preamble = 5)
354
+ def self.align_text(text, console_cols=nil, preamble=5)
320
355
  unless console_cols
321
356
  console_cols = terminal_dimensions[0]
322
357
 
@@ -334,40 +369,36 @@ module MCollective
334
369
  console_cols = 80 if console_cols <= 0
335
370
 
336
371
  text = text.split("\n")
337
- piece = ''
372
+ piece = ""
338
373
  whitespace = 0
339
374
 
340
375
  text.each_with_index do |line, i|
341
376
  whitespace = 0
342
377
 
343
- while whitespace < line.length && line[whitespace].chr == ' '
378
+ while whitespace < line.length && line[whitespace].chr == " "
344
379
  whitespace += 1
345
380
  end
346
381
 
347
382
  # If the current line is empty, indent it so that a snippet
348
383
  # from the previous line is aligned correctly.
349
- if line == ""
350
- line = (" " * whitespace)
351
- end
384
+ line = (" " * whitespace) if line == ""
352
385
 
353
386
  # If text was snipped from the previous line, prepend it to the
354
387
  # current line after any current indentation.
355
- if piece != ''
388
+ if piece != ""
356
389
  # Reset whitespaces to 0 if there are more whitespaces than there are
357
390
  # console columns
358
391
  whitespace = 0 if whitespace >= console_cols
359
392
 
360
393
  # If the current line is empty and being prepended to, create a new
361
394
  # empty line in the text so that formatting is preserved.
362
- if text[i + 1] && line == (" " * whitespace)
363
- text.insert(i + 1, "")
364
- end
395
+ text.insert(i + 1, "") if text[i + 1] && line == (" " * whitespace)
365
396
 
366
397
  # Add the snipped text to the current line
367
398
  line.insert(whitespace, "#{piece} ")
368
399
  end
369
400
 
370
- piece = ''
401
+ piece = ""
371
402
 
372
403
  # Compare the line length to the allowed line length.
373
404
  # If it exceeds it, snip the offending text from the line
@@ -375,9 +406,7 @@ module MCollective
375
406
  if line.length > (console_cols + preamble)
376
407
  reverse = console_cols
377
408
 
378
- while line[reverse].chr != ' '
379
- reverse -= 1
380
- end
409
+ reverse -= 1 while line[reverse].chr != " "
381
410
 
382
411
  piece = line.slice!(reverse, (line.length - 1)).lstrip
383
412
  end
@@ -385,13 +414,13 @@ module MCollective
385
414
  # If a snippet exists when all the columns in the text have been
386
415
  # updated, create a new line and append the snippet to it, using
387
416
  # the same left alignment as the last line in the text.
388
- if piece != '' && text[i+1].nil?
389
- text[i+1] = "#{' ' * (whitespace)}#{piece}"
390
- piece = ''
417
+ if piece != "" && text[i + 1].nil?
418
+ text[i + 1] = "#{' ' * whitespace}#{piece}"
419
+ piece = ""
391
420
  end
392
421
 
393
422
  # Add the preamble to the line and add it to the text
394
- line = ((' ' * preamble) + line)
423
+ line = ((" " * preamble) + line)
395
424
  text[i] = line
396
425
  end
397
426
 
@@ -402,7 +431,7 @@ module MCollective
402
431
  #
403
432
  # Returns [0, 0] if it can't figure it out or if you're
404
433
  # not running on a tty
405
- def self.terminal_dimensions(stdout = STDOUT, environment = ENV)
434
+ def self.terminal_dimensions(stdout=STDOUT, environment=ENV)
406
435
  return [0, 0] unless stdout.tty?
407
436
 
408
437
  return [80, 40] if Util.windows?
@@ -413,8 +442,8 @@ module MCollective
413
442
  elsif environment["TERM"] && command_in_path?("tput")
414
443
  return [`tput cols`.to_i, `tput lines`.to_i]
415
444
 
416
- elsif command_in_path?('stty')
417
- return `stty size`.scan(/\d+/).map {|s| s.to_i }
445
+ elsif command_in_path?("stty")
446
+ return `stty size`.scan(/\d+/).map(&:to_i)
418
447
  else
419
448
  return [0, 0]
420
449
  end
@@ -444,28 +473,26 @@ module MCollective
444
473
  ax = version_a.scan(vre)
445
474
  bx = version_b.scan(vre)
446
475
 
447
- while (ax.length>0 && bx.length>0)
476
+ while !ax.empty? && !bx.empty?
448
477
  a = ax.shift
449
478
  b = bx.shift
450
479
 
451
- if( a == b ) then next
452
- elsif (a == '-' && b == '-') then next
453
- elsif (a == '-') then return -1
454
- elsif (b == '-') then return 1
455
- elsif (a == '.' && b == '.') then next
456
- elsif (a == '.' ) then return -1
457
- elsif (b == '.' ) then return 1
458
- elsif (a =~ /^\d+$/ && b =~ /^\d+$/) then
459
- if( a =~ /^0/ or b =~ /^0/ ) then
460
- return a.to_s.upcase <=> b.to_s.upcase
461
- end
480
+ if a == b then next
481
+ elsif a == "-" && b == "-" then next
482
+ elsif a == "-" then return -1
483
+ elsif b == "-" then return 1
484
+ elsif a == "." && b == "." then next
485
+ elsif a == "." then return -1
486
+ elsif b == "." then return 1
487
+ elsif a =~ /^\d+$/ && b =~ /^\d+$/
488
+ return a.to_s.upcase <=> b.to_s.upcase if a =~ /^0/ || b =~ /^0/
462
489
  return a.to_i <=> b.to_i
463
490
  else
464
491
  return a.upcase <=> b.upcase
465
492
  end
466
493
  end
467
494
 
468
- version_a <=> version_b;
495
+ version_a <=> version_b
469
496
  end
470
497
 
471
498
  # we should really use Pathname#absolute? but it's not in all the
@@ -486,7 +513,7 @@ module MCollective
486
513
  def self.str_to_bool(val)
487
514
  clean_val = val.to_s.strip
488
515
  if clean_val =~ /^(1|yes|true|y|t)$/i
489
- return true
516
+ return true
490
517
  elsif clean_val =~ /^(0|no|false|n|f)$/i
491
518
  return false
492
519
  else
@@ -498,10 +525,10 @@ module MCollective
498
525
  def self.templatepath(template_file)
499
526
  config_dir = File.dirname(Config.instance.configfile)
500
527
  template_path = File.join(config_dir, template_file)
501
- return template_path if File.exists?(template_path)
528
+ return template_path if File.exist?(template_path)
502
529
 
503
530
  template_path = File.join("/etc/mcollective", template_file)
504
- return template_path
531
+ template_path
505
532
  end
506
533
 
507
534
  # subscribe to the direct addressing queue
@@ -511,68 +538,66 @@ module MCollective
511
538
 
512
539
  # Get field size for printing
513
540
  def self.field_size(elements, min_size=40)
514
- max_length = elements.max_by { |e| e.length }.length
541
+ max_length = elements.max_by(&:length).length
515
542
  max_length > min_size ? max_length : min_size
516
543
  end
517
544
 
518
545
  # Calculate number of fields for printing
519
546
  def self.field_number(field_size, max_size=90)
520
- number = (max_size/field_size).to_i
521
- (number == 0) ? 1 : number
547
+ number = (max_size / field_size).to_i
548
+ number == 0 ? 1 : number
522
549
  end
523
-
524
- def self.get_hidden_input_on_windows()
525
- require 'Win32API'
550
+
551
+ def self.get_hidden_input_on_windows # rubocop:disable Naming/AccessorMethodName
552
+ require "Win32API"
553
+
526
554
  # Hook into getch from crtdll. Keep reading all keys till return
527
555
  # or newline is hit.
528
556
  # If key is backspace or delete, then delete the character and update
529
557
  # the buffer.
530
- input = ''
531
- while char = Win32API.new("crtdll", "_getch", [ ], "I").Call do
532
- break if char == 10 || char == 13 # return or newline
533
- if char == 127 || char == 8 # backspace and delete
534
- if input.length > 0
535
- input.slice!(-1, 1)
536
- end
558
+ input = ""
559
+
560
+ while char = Win32API.new("crtdll", "_getch", [], "I").Call
561
+ break if [10, 13].include?(char) # return or newline
562
+ if [127, 8].include?(char) # backspace and delete
563
+ input.slice!(-1, 1) unless input.empty?
537
564
  else
538
565
  input << char.chr
539
566
  end
540
567
  end
541
- char = ''
568
+
542
569
  input
543
570
  end
544
571
 
545
- def self.get_hidden_input_on_unix()
572
+ def self.get_hidden_input_on_unix # rubocop:disable Naming/AccessorMethodName
546
573
  unless $stdin.tty?
547
- raise 'Could not hook to stdin to hide input. If using SSH, try using -t flag while connecting to server.'
574
+ raise "Could not hook to stdin to hide input. If using SSH, try using -t flag while connecting to server."
548
575
  end
549
- unless system 'stty -echo -icanon'
550
- raise 'Could not hide input using stty command.'
576
+ unless system "stty -echo -icanon"
577
+ raise "Could not hide input using stty command."
551
578
  end
552
579
  input = $stdin.gets
553
- ensure
554
- unless system 'stty echo icanon'
555
- raise 'Could not enable echoing of input. Try executing `stty echo icanon` to debug.'
556
- end
580
+ ensure
581
+ unless system "stty echo icanon"
582
+ raise "Could not enable echoing of input. Try executing `stty echo icanon` to debug."
583
+ end
557
584
  input
558
585
  end
559
586
 
560
- def self.get_hidden_input(message='Please enter data: ')
561
- unless message.nil?
562
- print message
563
- end
564
- if versioncmp(ruby_version, '1.9.3') >= 0
565
- require 'io/console'
587
+ def self.get_hidden_input(message="Please enter data: ")
588
+ print message unless message.nil?
589
+
590
+ if versioncmp(ruby_version, "1.9.3") >= 0
591
+ require "io/console"
566
592
  input = $stdin.noecho(&:gets)
593
+ elsif windows? # Use hacks to get hidden input on Ruby <1.9.3
594
+ input = get_hidden_input_on_windows
567
595
  else
568
- # Use hacks to get hidden input on Ruby <1.9.3
569
- if self.windows?
570
- input = self.get_hidden_input_on_windows()
571
- else
572
- input = self.get_hidden_input_on_unix()
573
- end
596
+ input = get_hidden_input_on_unix
574
597
  end
598
+
575
599
  input.chomp! if input
600
+
576
601
  input
577
602
  end
578
603
  end