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.
@@ -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