choria-mcorpc-support 2.23.0 → 2.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 240757ac597e3d2cfe78d338c925b62b7e9ae384
4
- data.tar.gz: d67ed99f4a98219aa82f9b193c3eafc6a7ed0668
3
+ metadata.gz: 88cacd67cd1dd9b6289e5b896b920d3467e3a220
4
+ data.tar.gz: a7cf2dccf0ae9133abd81866296784fb6791b0e0
5
5
  SHA512:
6
- metadata.gz: d513a4149861bd15a98250139e282b0681465d58f6a1e6503dd8b7e0323f22f7c9c5c80a4f502a52dca8322d9349946ccef538c219bf899144f988a731262144
7
- data.tar.gz: eb5b2c1a2127999d93b49ae248e2f19ae95e30163c5b209eeb70c74ba2c5b6f10d6851172eb7656922e536c83f164d707526914bde8f5cc1303dfd2b62be1656
6
+ metadata.gz: 368859ec015b8605af21238d7c6d93aa4472c728948d61dcf07095a7728509f4fcdafb2d5867aef0b941a09572ce7ad43ec4ce54a91cde8e6de26fc48a888b9c
7
+ data.tar.gz: d1ce8dbd24f8f1a24163e4e5c69d9514d98372885bf14b6f3efd59b824c842d5ed2efee50df7551eec577e0dd15cfc7da36f66f732b6fd35ab74ca7f30f8d9cc
@@ -40,7 +40,6 @@ module MCollective
40
40
  require "mcollective/facts"
41
41
  require "mcollective/logger"
42
42
  require "mcollective/log"
43
- require "mcollective/matcher"
44
43
  require "mcollective/message"
45
44
  require "mcollective/optionparser"
46
45
  require "mcollective/generators"
@@ -54,7 +53,7 @@ module MCollective
54
53
  require "mcollective/util"
55
54
  require "mcollective/validator"
56
55
 
57
- VERSION = "2.23.0".freeze
56
+ VERSION = "2.23.1".freeze
58
57
 
59
58
  def self.version
60
59
  VERSION
@@ -77,6 +77,15 @@ action "run_and_wait", :description => "Runs a Puppet Task that was previously d
77
77
  :default => "{}",
78
78
  :maxlength => 102400
79
79
 
80
+ input :run_as,
81
+ :prompt => "Run As",
82
+ :description => "User to run the task as",
83
+ :type => :string,
84
+ :validation => ".+",
85
+ :optional => true,
86
+ :default => nil,
87
+ :maxlength => 32
88
+
80
89
  output :task_id,
81
90
  :description => "The ID the task was created with",
82
91
  :display_as => "Task ID",
@@ -165,6 +174,15 @@ action "run_no_wait", :description => "Runs a Puppet Task that was previously do
165
174
  :default => "{}",
166
175
  :maxlength => 102400
167
176
 
177
+ input :run_as,
178
+ :prompt => "Run As",
179
+ :description => "User to run the task as",
180
+ :type => :string,
181
+ :validation => ".+",
182
+ :optional => true,
183
+ :default => nil,
184
+ :maxlength => 32
185
+
168
186
  output :task_id,
169
187
  :description => "The ID the task was created with",
170
188
  :display_as => "Task ID",
@@ -101,6 +101,15 @@
101
101
  "optional": false,
102
102
  "validation": "^.+$",
103
103
  "maxlength": 102400
104
+ },
105
+ "run_as": {
106
+ "prompt": "Run As",
107
+ "description": "User to run the task as",
108
+ "type": "string",
109
+ "default": null,
110
+ "optional": true,
111
+ "validation": ".+",
112
+ "maxlength": 32
104
113
  }
105
114
  },
106
115
  "output": {
@@ -233,6 +242,15 @@
233
242
  "optional": true,
234
243
  "validation": "^.+$",
235
244
  "maxlength": 102400
245
+ },
246
+ "run_as": {
247
+ "prompt": "Run As",
248
+ "description": "User to run the task as",
249
+ "type": "string",
250
+ "default": null,
251
+ "optional": true,
252
+ "validation": ".+",
253
+ "maxlength": 32
236
254
  }
237
255
  },
238
256
  "output": {
@@ -37,7 +37,8 @@ module MCollective
37
37
  "task" => request[:task],
38
38
  "input_method" => request[:input_method],
39
39
  "input" => request[:input],
40
- "files" => JSON.parse(request[:files])
40
+ "files" => JSON.parse(request[:files]),
41
+ "run_as" => request[:run_as]
41
42
  }
42
43
 
43
44
  unless tasks.cached?(task["files"])
@@ -77,7 +78,8 @@ module MCollective
77
78
  "task" => request[:task],
78
79
  "input_method" => request[:input_method],
79
80
  "input" => request[:input],
80
- "files" => JSON.parse(request[:files])
81
+ "files" => JSON.parse(request[:files]),
82
+ "run_as" => request[:run_as]
81
83
  }
82
84
 
83
85
  status = tasks.run_task_command(reply[:task_id], task, false, request.caller)
@@ -65,9 +65,9 @@ action "get_fact", :description => "Retrieve a single fact from the fact store"
65
65
  :prompt => "The name of the fact",
66
66
  :description => "The fact to retrieve",
67
67
  :type => :string,
68
- :validation => '^[\w\-\.]+$',
68
+ :validation => '.+',
69
69
  :optional => false,
70
- :maxlength => 256
70
+ :maxlength => 512
71
71
 
72
72
  output :fact,
73
73
  :description => "The name of the fact being returned",
@@ -216,8 +216,8 @@
216
216
  "type": "string",
217
217
  "default": null,
218
218
  "optional": false,
219
- "validation": "^[\\w\\-\\.]+$",
220
- "maxlength": 256
219
+ "validation": ".+",
220
+ "maxlength": 512
221
221
  }
222
222
  },
223
223
  "output": {
@@ -8,37 +8,18 @@ module MCollective
8
8
 
9
9
  The ACTION can be one of the following:
10
10
 
11
- request_cert - requests a certificate from the Puppet CA
12
11
  show_config - shows the active configuration parameters
13
12
 
14
- The environment is chosen using --environment and the concurrent
15
- runs may be limited using --batch.
16
-
17
- The batching works a bit different than typical, it will only batch
18
- based on a sorted list of certificate names, this means the batches
19
- will always run in predictable order.
20
13
  USAGE
21
14
 
22
15
  exclude_argument_sections "common", "filter", "rpc"
23
16
 
24
- option :ca,
25
- :arguments => ["--ca SERVER"],
26
- :description => "Address of your Puppet CA",
27
- :type => String
28
-
29
- option :certname,
30
- :arguments => ["--certname CERTNAME"],
31
- :description => "Override the default certificate name",
32
- :type => String
33
-
34
17
  def post_option_parser(configuration)
35
18
  if ARGV.length >= 1
36
19
  configuration[:command] = ARGV.shift
37
20
  else
38
21
  abort("Please specify a command, valid commands are: %s" % valid_commands.join(", "))
39
22
  end
40
-
41
- ENV["MCOLLECTIVE_CERTNAME"] = configuration[:certname] if configuration[:certname]
42
23
  end
43
24
 
44
25
  # Validates the configuration
@@ -48,10 +29,6 @@ module MCollective
48
29
  Util.loadclass("MCollective::Util::Choria")
49
30
 
50
31
  abort("Unknown command %s, valid commands are: %s" % [configuration[:command], valid_commands.join(", ")]) unless valid_commands.include?(configuration[:command])
51
-
52
- if !choria.has_client_public_cert? && !["request_cert", "show_config"].include?(configuration[:command])
53
- abort("A certificate is needed from the Puppet CA for `%s`, please use the `request_cert` command" % choria.certname)
54
- end
55
32
  end
56
33
 
57
34
  def main
@@ -66,45 +43,8 @@ module MCollective
66
43
  #
67
44
  # @return [void]
68
45
  def request_cert_command
69
- disconnect
70
-
71
- raise(Util::Choria::UserError, "Cannot only request certificates in Puppet security mode") unless choria.puppet_security?
72
-
73
- raise(Util::Choria::UserError, "Already have a certificate '%s', cannot request a new one" % choria.client_public_cert) if choria.has_client_public_cert?
74
-
75
- choria.ca = configuration[:ca] if configuration[:ca]
76
-
77
- certname = choria.client_public_cert
78
-
79
- choria.make_ssl_dirs
80
- choria.fetch_ca
81
-
82
- if choria.waiting_for_cert?
83
- puts("Certificate %s has already been requested, attempting to retrieve it" % certname)
84
- else
85
- puts("Requesting certificate for '%s'" % certname)
86
- choria.request_cert
87
- end
88
-
89
- puts("Waiting up to 240 seconds for it to be signed")
90
- puts
91
-
92
- puts("Key fingerprint: %s" % choria.csr_fingerprint)
93
- puts
94
-
95
- 24.times do |time|
96
- print "Attempting to download certificate %s: %d / 24\r" % [certname, time]
97
-
98
- break if choria.attempt_fetch_cert
99
-
100
- sleep 10
101
- end
102
-
103
- unless choria.has_client_public_cert?
104
- raise(Util::Choria::UserError, "Could not fetch the certificate after 240 seconds, please ensure it gets signed and rerun this command")
105
- end
106
-
107
- puts("Certificate %s has been stored in %s" % [certname, choria.ssl_dir])
46
+ puts("Please use 'choria enroll' to enroll in the security subsystem")
47
+ raise(Util::Choria::Abort, "1")
108
48
  end
109
49
 
110
50
  def show_config_command # rubocop:disable Metrics/MethodLength
@@ -174,7 +114,7 @@ module MCollective
174
114
  if valid_ssl
175
115
  puts " Valid SSL Setup: %s" % [Util.colorize(:green, "yes")]
176
116
  else
177
- puts " Valid SSL Setup: %s try running 'mco choria request_cert'" % [Util.colorize(:red, "no")]
117
+ puts " Valid SSL Setup: %s try running 'choria enroll'" % [Util.colorize(:red, "no")]
178
118
  end
179
119
 
180
120
  puts " Security Provider: %s" % [choria.security_provider]
@@ -217,9 +217,7 @@ The ACTION can be one of the following:
217
217
 
218
218
  abort("Unknown command %s, valid commands are: %s" % [configuration[:command], valid_commands.join(", ")]) unless valid_commands.include?(configuration[:command])
219
219
 
220
- if !choria.has_client_public_cert? && !["request_cert", "show_config"].include?(configuration[:command])
221
- abort("A certificate is needed from the Puppet CA for `%s`, please use the `request_cert` command" % choria.certname)
222
- end
220
+ abort("A certificate is needed from the Puppet CA for `%s`, please use the `choria enroll` command" % choria.certname) unless choria.has_client_public_cert?
223
221
  end
224
222
 
225
223
  def main
@@ -1,8 +1,36 @@
1
1
  module MCollective
2
2
  class Application::Ping < Application # rubocop:disable Style/ClassAndModuleChildren
3
- description "Ping all nodes"
3
+ description "Low level network connectivity test"
4
4
 
5
- external(:command => "choria", :args => ["ping"])
6
- external_help(:command => "choria", :args => ["ping", "--help"])
5
+ def main
6
+ # If the user did not override the default timeout include the discovery timeout
7
+ if options[:timeout] == 5
8
+ discovery_timeout = options[:disctimeout] || Config.instance.discovery_timeout || 0
9
+ options[:timeout] = options[:timeout] + discovery_timeout
10
+ end
11
+ client = MCollective::Client.new(options)
12
+
13
+ start = Time.now.to_f
14
+ times = []
15
+
16
+ client.req("ping", "discovery") do |resp|
17
+ times << (Time.now.to_f - start) * 1000
18
+
19
+ puts "%-40s time=%.2f ms" % [resp[:senderid], times.last]
20
+ end
21
+
22
+ puts("\n\n---- ping statistics ----")
23
+
24
+ if !times.empty?
25
+ sum = times.inject(0) {|acc, i| acc + i}
26
+ avg = sum / times.length.to_f
27
+
28
+ puts "%d replies max: %.2f min: %.2f avg: %.2f" % [times.size, times.max, times.min, avg]
29
+ else
30
+ puts("No responses received")
31
+ end
32
+
33
+ halt client.stats
34
+ end
7
35
  end
8
36
  end
@@ -148,6 +148,13 @@ Examples:
148
148
  :required => false,
149
149
  :default => 1,
150
150
  :type => Integer
151
+
152
+ self.class.option :__run_as,
153
+ :arguments => ["--run-as USERNAME"],
154
+ :description => "Run task as user USERNAME",
155
+ :required => false,
156
+ :default => nil,
157
+ :type => String
151
158
  end
152
159
 
153
160
  def say(msg="")
@@ -180,6 +187,8 @@ Examples:
180
187
  :files => meta["files"].to_json
181
188
  }
182
189
 
190
+ request[:run_as] = configuration[:__run_as] if configuration[:__run_as]
191
+
183
192
  request[:input] = input.to_json if input
184
193
 
185
194
  if configuration[:__background]
@@ -85,19 +85,18 @@ module MCollective
85
85
  def timeout_for_compound_filter(compound_filter)
86
86
  return 0 if compound_filter.nil? || compound_filter.empty?
87
87
 
88
- timeout = 0
89
-
90
- compound_filter.each do |filter|
91
- filter.each do |statement|
92
- next unless statement["fstatement"]
93
-
94
- pluginname = Data.pluginname(statement["fstatement"]["name"])
95
- ddl = DDL.new(pluginname, :data)
96
- timeout += ddl.meta[:timeout]
97
- end
98
- end
99
-
100
- timeout
88
+ # disabled while bringing in new compound filters
89
+ # compound_filter.each do |filter|
90
+ # filter.each do |statement|
91
+ # next unless statement["fstatement"]
92
+ #
93
+ # pluginname = Data.pluginname(statement["fstatement"]["name"])
94
+ # ddl = DDL.new(pluginname, :data)
95
+ # timeout += ddl.meta[:timeout]
96
+ # end
97
+ # end
98
+
99
+ 0
101
100
  end
102
101
 
103
102
  def discovery_timeout(timeout, filter)
@@ -148,8 +148,6 @@ module MCollective
148
148
  @requestid = request.payload[:requestid]
149
149
  @payload = PluginManager["security_plugin"].encodereply(agent, payload, requestid, request.payload[:callerid])
150
150
  when :request, :direct_request
151
- validate_compound_filter(@filter["compound"]) unless @filter["compound"].empty?
152
-
153
151
  @requestid ||= create_reqid
154
152
  @payload = PluginManager["security_plugin"].encoderequest(Config.instance.identity, payload, requestid, filter, agent, collective, ttl)
155
153
  else
@@ -157,28 +155,6 @@ module MCollective
157
155
  end
158
156
  end
159
157
 
160
- def validate_compound_filter(compound_filter)
161
- compound_filter.each do |filter|
162
- filter.each do |statement|
163
- next unless statement["fstatement"]
164
-
165
- functionname = statement["fstatement"]["name"]
166
- pluginname = Data.pluginname(functionname)
167
- value = statement["fstatement"]["value"]
168
-
169
- ddl = DDL.new(pluginname, :data)
170
-
171
- # parses numbers and booleans entered as strings into proper
172
- # types of data so that DDL validation will pass
173
- statement["fstatement"]["params"] = Data.ddl_transform_input(ddl, statement["fstatement"]["params"])
174
-
175
- Data.ddl_validate(ddl, statement["fstatement"]["params"])
176
-
177
- raise(DDLValidationError, "Data plugin '%s()' does not return a '%s' value" % [functionname, value]) unless value && Data.ddl_has_output?(ddl, value)
178
- end
179
- end
180
- end
181
-
182
158
  def decode!
183
159
  raise "Cannot decode message type #{type}" unless [:request, :reply].include?(type)
184
160
 
@@ -86,7 +86,7 @@ module MCollective
86
86
  end
87
87
 
88
88
  @parser.on("-S", "--select FILTER", "Compound filter combining facts and classes") do |f|
89
- @options[:filter]["compound"] << Matcher.create_compound_callstack(f)
89
+ @options[:filter]["compound"] << [{"expr" => f}]
90
90
  end
91
91
 
92
92
  @parser.on("-F", "--wf", "--with-fact fact=val", "Match hosts with a certain fact") do |f|
@@ -442,7 +442,7 @@ module MCollective
442
442
 
443
443
  # Set a compound filter
444
444
  def compound_filter(filter)
445
- @filter["compound"] = @filter["compound"] | [Matcher.create_compound_callstack(filter)]
445
+ @filter["compound"] = @filter["compound"] | [[{"expr" => filter}]]
446
446
  reset
447
447
  end
448
448
 
@@ -822,7 +822,7 @@ module MCollective
822
822
  @stdout.print twirl.twirl(respcount, discovered.size)
823
823
  end
824
824
 
825
- if batch_size =~ /^(\d+)%$/
825
+ if batch_size.is_a?(String) && batch_size =~ /^(\d+)%$/
826
826
  # determine batch_size as a percentage of the discovered array's size
827
827
  batch_size = (discovered.size / 100.0 * Integer($1)).ceil
828
828
  else
@@ -72,43 +72,7 @@ module MCollective
72
72
  end
73
73
 
74
74
  when "compound"
75
- filter[key].each do |compound|
76
- result = false
77
- truth_values = []
78
-
79
- begin
80
- compound.each do |expression|
81
- case expression.keys.first
82
- when "statement"
83
- truth_values << Matcher.eval_compound_statement(expression).to_s
84
- when "fstatement"
85
- truth_values << Matcher.eval_compound_fstatement(expression.values.first)
86
- when "and"
87
- truth_values << "&&"
88
- when "or"
89
- truth_values << "||"
90
- when "("
91
- truth_values << "("
92
- when ")"
93
- truth_values << ")"
94
- when "not"
95
- truth_values << "!"
96
- end
97
- end
98
-
99
- result = eval(truth_values.join(" ")) # rubocop:disable Security/Eval
100
- rescue DDLValidationError
101
- result = false
102
- end
103
-
104
- if result
105
- Log.debug("Passing based on class and fact composition")
106
- passed += 1
107
- else
108
- Log.debug("Failing based on class and fact composition")
109
- failed += 1
110
- end
111
- end
75
+ # removed while rebuilding compound filters, this whole method is probably unused now
112
76
 
113
77
  when "agent"
114
78
  filter[key].each do |f|