choria-mcorpc-support 2.23.1 → 2.24.2

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.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/lib/mcollective.rb +3 -2
  3. data/lib/mcollective/agent/choria_util.ddl +206 -107
  4. data/lib/mcollective/agent/choria_util.json +101 -1
  5. data/lib/mcollective/agent/rpcutil.json +2 -3
  6. data/lib/mcollective/agent/scout.json +107 -135
  7. data/lib/mcollective/application/facts.rb +2 -67
  8. data/lib/mcollective/application/find.rb +1 -1
  9. data/lib/mcollective/application/plugin.rb +2 -15
  10. data/lib/mcollective/client.rb +1 -1
  11. data/lib/mcollective/config.rb +135 -103
  12. data/lib/mcollective/ddl.rb +0 -1
  13. data/lib/mcollective/discovery.rb +11 -63
  14. data/lib/mcollective/discovery/broadcast.ddl +11 -0
  15. data/lib/mcollective/discovery/choria.ddl +6 -4
  16. data/lib/mcollective/discovery/delegate.ddl +13 -0
  17. data/lib/mcollective/discovery/delegate.rb +73 -0
  18. data/lib/mcollective/discovery/external.ddl +13 -0
  19. data/lib/mcollective/discovery/file.ddl +13 -0
  20. data/lib/mcollective/discovery/flatfile.ddl +7 -5
  21. data/lib/mcollective/discovery/inventory.ddl +13 -0
  22. data/lib/mcollective/discovery/mc.ddl +3 -3
  23. data/lib/mcollective/generators.rb +0 -1
  24. data/lib/mcollective/optionparser.rb +1 -1
  25. data/lib/mcollective/pluginpackager/forge_packager.rb +1 -1
  26. data/lib/mcollective/rpc/client.rb +4 -2
  27. data/lib/mcollective/util.rb +25 -35
  28. data/lib/mcollective/util/tasks_support.rb +15 -2
  29. metadata +9 -23
  30. data/lib/mcollective/data.rb +0 -96
  31. data/lib/mcollective/data/agent_data.ddl +0 -22
  32. data/lib/mcollective/data/agent_data.rb +0 -17
  33. data/lib/mcollective/data/base.rb +0 -68
  34. data/lib/mcollective/data/bolt_task_data.ddl +0 -90
  35. data/lib/mcollective/data/bolt_task_data.rb +0 -32
  36. data/lib/mcollective/data/collective_data.ddl +0 -20
  37. data/lib/mcollective/data/collective_data.rb +0 -9
  38. data/lib/mcollective/data/fact_data.ddl +0 -28
  39. data/lib/mcollective/data/fact_data.rb +0 -55
  40. data/lib/mcollective/data/fstat_data.ddl +0 -89
  41. data/lib/mcollective/data/fstat_data.rb +0 -54
  42. data/lib/mcollective/data/result.rb +0 -50
  43. data/lib/mcollective/ddl/dataddl.rb +0 -56
  44. data/lib/mcollective/discovery/choria.rb +0 -223
  45. data/lib/mcollective/discovery/flatfile.rb +0 -47
  46. data/lib/mcollective/discovery/stdin.ddl +0 -11
  47. data/lib/mcollective/discovery/stdin.rb +0 -67
  48. data/lib/mcollective/generators/data_generator.rb +0 -50
  49. data/lib/mcollective/generators/templates/data_input_snippet.erb +0 -7
@@ -0,0 +1,73 @@
1
+ module MCollective
2
+ class Discovery
3
+ class Delegate
4
+ def self.binary_name
5
+ "choria"
6
+ end
7
+
8
+ def self.discover(filter, timeout, limit, client)
9
+ raise("Cannot find the choria binary in your path") unless Util.command_in_path?("choria")
10
+
11
+ cmd = [binary_name, "discover", "-j", "--silent"]
12
+
13
+ cmd << "-T" << filter["collective"] if filter["collective"]
14
+
15
+ filter.fetch("identity", []).each do |i|
16
+ cmd << "-I" << i
17
+ end
18
+
19
+ filter.fetch("cf_class", []).each do |c|
20
+ cmd << "-C" << c
21
+ end
22
+
23
+ filter.fetch("fact", []).each do |f|
24
+ cmd << "-F" << "%s%s%s" % [f[:fact], f[:operator], f[:value]]
25
+ end
26
+
27
+ filter.fetch("agent", []).each do |a|
28
+ cmd << "-A" << a
29
+ end
30
+
31
+ filter.fetch("compound", []).each do |c|
32
+ next unless c.is_a?(Array)
33
+
34
+ cmd << "-S" << c.first["expr"]
35
+ end
36
+
37
+ client.options.fetch(:discovery_options, []).each do |opt|
38
+ cmd << "--do" << opt
39
+ end
40
+
41
+ cmd << "--dm" << (client.options.fetch(:discovery_method, "broadcast") rescue "broadcast")
42
+
43
+ run_discover(cmd, timeout)
44
+ end
45
+
46
+ def self.run_discover(cmd, timeout)
47
+ nodes = []
48
+
49
+ Log.debug("Executing choria for discovery using: %s" % cmd.join(" "))
50
+
51
+ Open3.popen3(ENV, *cmd) do |stdin, stdout, stderr, wait_thr|
52
+ stdin.close
53
+
54
+ begin
55
+ Timeout.timeout(timeout + 0.5) do
56
+ status = wait_thr.value
57
+
58
+ raise("Choria discovery failed: %s" % stderr.read) unless status.exitstatus == 0
59
+ end
60
+ rescue Timeout::Error
61
+ Log.warn("Timeout waiting for Choria to perform discovery")
62
+ Process.kill("KILL", wait_thr[:pid])
63
+ raise("Choria failed to complete discovery within %d timeout" % timeout)
64
+ end
65
+
66
+ nodes.concat(JSON.parse(stdout.read))
67
+ end
68
+
69
+ nodes
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,13 @@
1
+ metadata :name => "external",
2
+ :description => "External executable based discovery",
3
+ :author => "R.I.Pienaar <rip@devco.net>",
4
+ :license => "Apache-2.0",
5
+ :version => "0.1",
6
+ :url => "https://choria.io/",
7
+ :timeout => 2
8
+
9
+ discovery do
10
+ capabilities [:classes, :facts, :identity, :agents, :compound]
11
+ end
12
+
13
+
@@ -0,0 +1,13 @@
1
+ metadata :name => "file",
2
+ :description => "Discovers from JSON, YAML and Text files",
3
+ :author => "R.I.Pienaar <rip@devco.net>",
4
+ :license => "Apache-2.0",
5
+ :version => "0.1",
6
+ :url => "https://choria.io/",
7
+ :timeout => 2
8
+
9
+ discovery do
10
+ capabilities [:identity]
11
+ end
12
+
13
+
@@ -1,11 +1,13 @@
1
1
  metadata :name => "flatfile",
2
- :description => "Flatfile based discovery for node identities",
2
+ :description => "Discovers from JSON, YAML and Text files",
3
3
  :author => "R.I.Pienaar <rip@devco.net>",
4
- :license => "ASL 2.0",
4
+ :license => "Apache-2.0",
5
5
  :version => "0.1",
6
- :url => "https://docs.puppetlabs.com/mcollective/",
7
- :timeout => 0
6
+ :url => "https://choria.io/",
7
+ :timeout => 2
8
8
 
9
9
  discovery do
10
- capabilities :identity
10
+ capabilities [:identity]
11
11
  end
12
+
13
+
@@ -0,0 +1,13 @@
1
+ metadata :name => "delegate",
2
+ :description => "Choria CLI based delegated discovery",
3
+ :author => "R.I.Pienaar <rip@devco.net>",
4
+ :license => "Apache 2.0",
5
+ :version => "0.1",
6
+ :url => "https://choria.io/",
7
+ :timeout => 2
8
+
9
+ discovery do
10
+ capabilities [:classes, :facts, :identity, :agents, :compound]
11
+ end
12
+
13
+
@@ -1,9 +1,9 @@
1
1
  metadata :name => "mc",
2
- :description => "MCollective Broadcast based discovery",
2
+ :description => "Choria Broadcast based discovery",
3
3
  :author => "R.I.Pienaar <rip@devco.net>",
4
- :license => "ASL 2.0",
4
+ :license => "Apache-2.0",
5
5
  :version => "0.1",
6
- :url => "https://docs.puppetlabs.com/mcollective/",
6
+ :url => "https://choria.io",
7
7
  :timeout => 2
8
8
 
9
9
  discovery do
@@ -1,7 +1,6 @@
1
1
  module MCollective
2
2
  module Generators
3
3
  require "mcollective/generators/base"
4
- require "mcollective/generators/data_generator"
5
4
  require "mcollective/generators/agent_generator"
6
5
  end
7
6
  end
@@ -168,7 +168,7 @@ module MCollective
168
168
  raise "Cannot read the discovery file #{v}" unless File.readable?(v)
169
169
 
170
170
  @options[:discovery_method] = "flatfile"
171
- @options[:discovery_options] << v
171
+ @options[:discovery_options] << "file=%s" % v
172
172
  end
173
173
 
174
174
  @parser.on("--publish_timeout TIMEOUT", Integer, "Timeout for publishing requests to remote agents.") do |pt|
@@ -191,7 +191,7 @@ module MCollective
191
191
  end
192
192
 
193
193
  def render_template(infile, outfile)
194
- erb = ERB.new(File.read(infile), 0, "%")
194
+ erb = ERB.new(File.read(infile), 0, "-")
195
195
  File.open(outfile, "w") do |f|
196
196
  f.puts erb.result(binding)
197
197
  end
@@ -533,6 +533,8 @@ module MCollective
533
533
 
534
534
  # All else fails we do it the hard way using a traditional broadcast
535
535
  unless @discovered_agents
536
+ raise("Invalid discovery method %s" % discovery_method) unless @client.discoverer.find_known_methods.include?(discovery_method)
537
+
536
538
  @stats.time_discovery :start
537
539
 
538
540
  @client.options = options
@@ -548,9 +550,9 @@ module MCollective
548
550
  actual_timeout = @client.discoverer.discovery_timeout(discovery_timeout, options[:filter])
549
551
 
550
552
  if actual_timeout > 0
551
- @stderr.print("Discovering hosts using the %s method for %d second(s) .... " % [@client.discoverer.discovery_method, actual_timeout])
553
+ @stderr.print("Discovering hosts using the %s method for %d second(s) .... " % [discovery_method, actual_timeout])
552
554
  else
553
- @stderr.print("Discovering hosts using the %s method .... " % [@client.discoverer.discovery_method])
555
+ @stderr.print("Discovering hosts using the %s method .... " % discovery_method)
554
556
  end
555
557
  end
556
558
 
@@ -147,28 +147,30 @@ module MCollective
147
147
 
148
148
  # Returns the PuppetLabs mcollective path for windows
149
149
  def self.windows_prefix
150
- require "win32/dir"
151
- File.join(Dir::COMMON_APPDATA, "PuppetLabs", "choria")
150
+ File.join(ENV["ALLUSERSPROFILE"], "PuppetLabs", "choria")
152
151
  end
153
152
 
154
153
  def self.choria_windows_prefix
155
- require "win32/dir"
156
- File.join(Dir::COMMON_APPDATA, "ChoriaIO", "choria")
154
+ File.join(ENV["ALLUSERSPROFILE"], "choria")
157
155
  end
158
156
 
159
- def self.mcollective_config_paths_for_user
157
+ def self.config_paths_for_user
160
158
  config_paths = []
161
159
 
162
- begin
163
- # File.expand_path will raise if HOME isn't set, catch it
164
- user_path = File.expand_path("~/.mcollective")
165
- config_paths << user_path
166
- rescue Exception # rubocop:disable Lint/RescueException, Lint/SuppressedException
160
+ ["~/.choriarc", "~/.mcollective"].each do |f|
161
+ begin
162
+ # File.expand_path will raise if HOME isn't set, catch it
163
+ config_paths << File.expand_path(f)
164
+ rescue ArgumentError # rubocop:disable Lint/SuppressedException
165
+ end
167
166
  end
168
167
 
169
168
  if windows?
169
+ config_paths << File.join(choria_windows_prefix, "etc", "client.conf")
170
170
  config_paths << File.join(windows_prefix, "etc", "client.cfg")
171
171
  else
172
+ config_paths << "/etc/choria/client.conf"
173
+ config_paths << "/usr/local/etc/choria/client.conf"
172
174
  config_paths << "/etc/puppetlabs/mcollective/client.cfg"
173
175
  config_paths << "/etc/mcollective/client.cfg"
174
176
  config_paths << "/usr/local/etc/mcollective/client.cfg"
@@ -177,42 +179,30 @@ module MCollective
177
179
  config_paths
178
180
  end
179
181
 
180
- def self.choria_config_paths_for_user
181
- config_paths = []
182
-
183
- begin
184
- # File.expand_path will raise if HOME isn't set, catch it
185
- user_path = File.expand_path("~/.choriarc")
186
- config_paths << user_path
187
- rescue Exception # rubocop:disable Lint/RescueException, Lint/SuppressedException
188
- end
189
-
190
- if windows?
191
- config_paths << File.join(choria_windows_prefix, "etc", "client.conf")
192
- else
193
- config_paths << "/etc/choria/client.conf"
194
- config_paths << "/usr/local/etc/choria/client.conf"
195
- end
196
-
197
- config_paths
198
- end
199
-
200
182
  # Picks the default user config file, priorities are first Choria ones then old MCollective ones
201
183
  #
202
184
  # In roughly this order, first to exist is used:
203
185
  #
204
186
  # - ~/.choriarc
205
- # - APPData/ChoriaIO/choria/etc/client.conf on windows
206
- # - /etc/choria/client.conf then
207
- # - /usr/local/etc/choria/client.conf on unix
208
187
  # - ~/.mcollective
209
- # - APPData/PuppetLabs/mcollective/etc/client.cfg on windows
188
+ #
189
+ # On Unix:
190
+ #
191
+ # - /etc/choria/client.conf
192
+ # - /usr/local/etc/choria/client.conf
210
193
  # - /etc/puppetlabs/mcollective/client.cfg
211
194
  # - /etc/mcollective/client.cfg
212
195
  # - /usr/local/etc/mcollective/client.cfg
196
+ #
197
+ # On Windows:
198
+ #
199
+ # - APPData/ChoriaIO/choria/etc/client.conf on windows
200
+ # - APPData/PuppetLabs/mcollective/etc/client.cfg on windows
213
201
  def self.config_file_for_user
214
- config_paths = choria_config_paths_for_user + mcollective_config_paths_for_user
202
+ config_paths = config_paths_for_user
203
+
215
204
  found = config_paths.find_index { |file| File.readable?(file) } || 0
205
+
216
206
  config_paths[found]
217
207
  end
218
208
 
@@ -157,7 +157,7 @@ module MCollective
157
157
  # @return [String] path to the command
158
158
  def task_command(spooldir, task)
159
159
  file_spec = task["files"][0]
160
- file_name = File.join(spooldir, "files", file_spec["filename"])
160
+ file_name = File.join(spooldir, "files", task_module(task["task"]), "tasks", file_spec["filename"])
161
161
 
162
162
  command = platform_specific_command(file_name)
163
163
 
@@ -220,7 +220,10 @@ module MCollective
220
220
  # @param task [Hash] task specification
221
221
  def populate_spooldir(spooldir, task)
222
222
  task["files"].each do |file|
223
- spool_filename = File.join(spooldir, "files", file["filename"])
223
+ filename = file["filename"]
224
+ filename = File.join(task_module(task["task"]), "tasks", filename) unless filename.index("/")
225
+
226
+ spool_filename = File.join(spooldir, "files", filename)
224
227
 
225
228
  FileUtils.mkdir_p(File.dirname(spool_filename), :mode => 0o0750)
226
229
  FileUtils.cp(task_file_name(file), spool_filename)
@@ -283,6 +286,7 @@ module MCollective
283
286
  if pid.nil?
284
287
  Process.gid = Process.egid = u.gid
285
288
  Process.uid = Process.euid = u.uid
289
+ ENV.delete_if { |name| name !~ /^LC_/ }
286
290
  Process.exec(environment, command, options)
287
291
  end
288
292
  else
@@ -568,6 +572,15 @@ module MCollective
568
572
  parts
569
573
  end
570
574
 
575
+ # Return a task's module
576
+ #
577
+ # @param task [String]
578
+ # @return [String] the module name
579
+ # @raise [StandardError] for invalid task names
580
+ def task_module(task)
581
+ parse_task(task)[0]
582
+ end
583
+
571
584
  # Determines the cache path for a task file
572
585
  #
573
586
  # @param file [Hash] a file hash as per the task metadata
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: choria-mcorpc-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.23.1
4
+ version: 2.24.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - R.I.Pienaar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-12 00:00:00.000000000 Z
11
+ date: 2021-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: systemu
@@ -98,34 +98,22 @@ files:
98
98
  - lib/mcollective/connector/base.rb
99
99
  - lib/mcollective/connector/nats.ddl
100
100
  - lib/mcollective/connector/nats.rb
101
- - lib/mcollective/data.rb
102
- - lib/mcollective/data/agent_data.ddl
103
- - lib/mcollective/data/agent_data.rb
104
- - lib/mcollective/data/base.rb
105
- - lib/mcollective/data/bolt_task_data.ddl
106
- - lib/mcollective/data/bolt_task_data.rb
107
- - lib/mcollective/data/collective_data.ddl
108
- - lib/mcollective/data/collective_data.rb
109
- - lib/mcollective/data/fact_data.ddl
110
- - lib/mcollective/data/fact_data.rb
111
- - lib/mcollective/data/fstat_data.ddl
112
- - lib/mcollective/data/fstat_data.rb
113
- - lib/mcollective/data/result.rb
114
101
  - lib/mcollective/ddl.rb
115
102
  - lib/mcollective/ddl/agentddl.rb
116
103
  - lib/mcollective/ddl/base.rb
117
- - lib/mcollective/ddl/dataddl.rb
118
104
  - lib/mcollective/ddl/discoveryddl.rb
119
105
  - lib/mcollective/ddl/validatorddl.rb
120
106
  - lib/mcollective/discovery.rb
107
+ - lib/mcollective/discovery/broadcast.ddl
121
108
  - lib/mcollective/discovery/choria.ddl
122
- - lib/mcollective/discovery/choria.rb
109
+ - lib/mcollective/discovery/delegate.ddl
110
+ - lib/mcollective/discovery/delegate.rb
111
+ - lib/mcollective/discovery/external.ddl
112
+ - lib/mcollective/discovery/file.ddl
123
113
  - lib/mcollective/discovery/flatfile.ddl
124
- - lib/mcollective/discovery/flatfile.rb
114
+ - lib/mcollective/discovery/inventory.ddl
125
115
  - lib/mcollective/discovery/mc.ddl
126
116
  - lib/mcollective/discovery/mc.rb
127
- - lib/mcollective/discovery/stdin.ddl
128
- - lib/mcollective/discovery/stdin.rb
129
117
  - lib/mcollective/exceptions.rb
130
118
  - lib/mcollective/facts.rb
131
119
  - lib/mcollective/facts/base.rb
@@ -133,9 +121,7 @@ files:
133
121
  - lib/mcollective/generators.rb
134
122
  - lib/mcollective/generators/agent_generator.rb
135
123
  - lib/mcollective/generators/base.rb
136
- - lib/mcollective/generators/data_generator.rb
137
124
  - lib/mcollective/generators/templates/action_snippet.erb
138
- - lib/mcollective/generators/templates/data_input_snippet.erb
139
125
  - lib/mcollective/generators/templates/ddl.erb
140
126
  - lib/mcollective/generators/templates/plugin.erb
141
127
  - lib/mcollective/log.rb
@@ -255,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
255
241
  version: '0'
256
242
  requirements: []
257
243
  rubyforge_project:
258
- rubygems_version: 2.6.13
244
+ rubygems_version: 2.7.6.2
259
245
  signing_key:
260
246
  specification_version: 4
261
247
  summary: Support libraries the Choria Server
@@ -1,96 +0,0 @@
1
- module MCollective
2
- module Data
3
- require "mcollective/data/base"
4
- require "mcollective/data/result"
5
-
6
- def self.load_data_sources
7
- PluginManager.find_and_load("data")
8
-
9
- PluginManager.grep(/_data$/).each do |plugin|
10
- begin
11
- unless PluginManager[plugin].class.activate?
12
- Log.debug("Disabling data plugin %s due to plugin activation policy" % plugin)
13
- PluginManager.delete(plugin)
14
- end
15
- rescue Exception => e # rubocop:disable Lint/RescueException
16
- Log.debug("Disabling data plugin %s due to exception %s: %s" % [plugin, e.class, e])
17
- PluginManager.delete(plugin)
18
- end
19
- end
20
- end
21
-
22
- def self.pluginname(plugin)
23
- plugin.to_s =~ /_data$/i ? plugin.to_s.downcase : "%s_data" % plugin.to_s.downcase
24
- end
25
-
26
- def self.[](plugin)
27
- PluginManager[pluginname(plugin)]
28
- end
29
-
30
- # Data.package("httpd").architecture
31
- def self.method_missing(method, *args)
32
- super unless PluginManager.include?(pluginname(method))
33
-
34
- PluginManager[pluginname(method)].lookup(args.first)
35
- end
36
-
37
- def self.respond_to_missing?(method, *)
38
- PluginManager.include?(pluginname(method)) || super
39
- end
40
-
41
- def self.ddl(plugin)
42
- DDL.new(pluginname(plugin), :data)
43
- end
44
-
45
- def self.ddl_validate(ddl, argument)
46
- name = ddl.meta[:name]
47
- query = ddl.entities[:data]
48
-
49
- raise DDLValidationError, "No dataquery has been defined in the DDL for data plugin #{name}" unless query
50
-
51
- input = query.fetch(:input, {})
52
- output = query.fetch(:output, {})
53
-
54
- raise DDLValidationError, "No output has been defined in the DDL for data plugin #{name}" if output.keys.empty?
55
-
56
- if input[:query]
57
- return true if argument.nil? && input[:query][:optional]
58
-
59
- ddl.validate_input_argument(input, :query, argument)
60
- else
61
- raise("No data plugin argument was declared in the %s DDL but an input was supplied" % name) if argument
62
-
63
- true
64
- end
65
- end
66
-
67
- def self.ddl_has_output?(ddl, output)
68
- ddl.entities[:data][:output].include?(output.to_sym) rescue false
69
- end
70
-
71
- # For an input where the DDL requests a boolean or some number
72
- # this will convert the input to the right type where possible
73
- # else just returns the origin input unedited
74
- #
75
- # if anything here goes wrong just return the input value
76
- # this is not really the end of the world or anything since
77
- # all that will happen is that DDL validation will fail and
78
- # the user will get an error, no need to be too defensive here
79
- def self.ddl_transform_input(ddl, input)
80
- begin
81
- type = ddl.entities[:data][:input][:query][:type]
82
-
83
- case type
84
- when :boolean
85
- return DDL.string_to_boolean(input)
86
-
87
- when :number, :integer, :float
88
- return DDL.string_to_number(input)
89
- end
90
- rescue # rubocop:disable Lint/SuppressedException
91
- end
92
-
93
- input
94
- end
95
- end
96
- end