choria-mcorpc-support 2.23.1 → 2.24.2

Sign up to get free protection for your applications and to get access to all the features.
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