choria-mcorpc-support 2.24.1 → 2.25.0

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.
@@ -8,18 +8,14 @@ mco plugin package [options] <directory>
8
8
  mco plugin info <directory>
9
9
  mco plugin doc <plugin>
10
10
  mco plugin doc <type/plugin>
11
- mco plugin generate agent <pluginname> [actions=val,val]
11
+ mco plugin generate client <ddl> <target>
12
+ mco plugin generate ddl <json_output> <ruby_output>
12
13
 
13
14
  info : Display plugin information including package details.
14
15
  package : Create all available plugin packages.
15
16
  doc : Display documentation for a specific plugin.
16
17
  END_OF_USAGE
17
18
 
18
- option :pluginname,
19
- :description => "Plugin name",
20
- :arguments => ["-n", "--name NAME"],
21
- :type => String
22
-
23
19
  option :postinstall,
24
20
  :description => "Post install script",
25
21
  :arguments => ["--postinstall POSTINSTALL"],
@@ -66,7 +62,7 @@ mco plugin package [options] <directory>
66
62
  :type => :array
67
63
 
68
64
  option :format,
69
- :description => "Package output format. Defaults to rpmpackage or debpackage",
65
+ :description => "Package output format. Defaults to forge",
70
66
  :arguments => ["--format OUTPUTFORMAT"],
71
67
  :type => String
72
68
 
@@ -80,41 +76,11 @@ mco plugin package [options] <directory>
80
76
  :arguments => ["--template HELPTEMPLATE"],
81
77
  :type => String
82
78
 
83
- option :description,
84
- :description => "Plugin description",
85
- :arguments => ["--description DESCRIPTION"],
86
- :type => String
87
-
88
- option :author,
89
- :description => "The author of the plugin",
90
- :arguments => ["--author AUTHOR"],
91
- :type => String
92
-
93
- option :license,
94
- :description => "The license under which the plugin is distributed",
95
- :arguments => ["--license LICENSE"],
96
- :type => String
97
-
98
79
  option :version,
99
80
  :description => "The version of the plugin",
100
81
  :arguments => ["--pluginversion VERSION"],
101
82
  :type => String
102
83
 
103
- option :url,
104
- :description => "Url at which information about the plugin can be found",
105
- :arguments => ["--url URL"],
106
- :type => String
107
-
108
- option :timeout,
109
- :description => "The plugin's timeout",
110
- :arguments => ["--timeout TIMEOUT"],
111
- :type => Integer
112
-
113
- option :actions,
114
- :description => "Actions to be generated for an Agent Plugin",
115
- :arguments => ["--actions [ACTIONS]"],
116
- :type => Array
117
-
118
84
  option :keep_artifacts,
119
85
  :description => "Don't remove artifacts after building packages",
120
86
  :arguments => ["--keep-artifacts"],
@@ -131,53 +97,12 @@ mco plugin package [options] <directory>
131
97
  configuration[:action] = ARGV.delete_at(0)
132
98
 
133
99
  configuration[:target] = ARGV.delete_at(0) || "."
134
-
135
- if configuration[:action] == "generate"
136
- unless ARGV[0] && ARGV[0].match(/(actions|outputs)=(.+)/i)
137
- if configuration[:pluginname] # rubocop:disable Metrics/BlockNesting
138
- ARGV.delete_at(0)
139
- else
140
- configuration[:pluginname] = ARGV.delete_at(0)
141
- end
142
- end
143
-
144
- ARGV.each do |argument|
145
- if argument.match(/(actions|outputs)=(.+)/i)
146
- configuration[$1.downcase.to_sym] = $2.split(",")
147
- else
148
- raise "Could not parse --arg '#{argument}'"
149
- end
150
- end
151
- end
152
100
  end
153
101
  end
154
102
 
155
- # Display info about plugin
156
- def info_command
157
- plugin = prepare_plugin
158
- packager = PluginPackager["#{configuration[:format].capitalize}Packager"]
159
- packager.new(plugin).package_information
160
- end
161
-
162
103
  # Generate a plugin skeleton
163
104
  def generate_command
164
- raise "undefined plugin type. cannot generate plugin. valid types are 'agent'" if configuration["target"] == "."
165
-
166
- unless configuration[:pluginname]
167
- puts "No plugin name specified. Using 'new_plugin'"
168
- configuration[:pluginname] = "new_plugin"
169
- end
170
-
171
- load_plugin_config_values
172
-
173
- case configuration[:target].downcase
174
- when "agent"
175
- Generators::AgentGenerator.new(configuration[:pluginname], configuration[:actions], configuration[:pluginname],
176
- configuration[:description], configuration[:author], configuration[:license],
177
- configuration[:version], configuration[:url], configuration[:timeout])
178
- else
179
- raise "invalid plugin type. cannot generate plugin '#{configuration[:target]}'"
180
- end
105
+ puts "CRITICAL: mco plugin generate is deprecated, please use 'choria plugin generate'"
181
106
  end
182
107
 
183
108
  # Package plugin
@@ -211,75 +136,10 @@ mco plugin package [options] <directory>
211
136
  end
212
137
 
213
138
  # Show application list and plugin help
214
- def doc_command # rubocop:disable Metrics/MethodLength
215
- known_plugin_types = [
216
- ["Agents", :agent],
217
- ["Aggregate", :aggregate],
218
- ["Connectors", :connector],
219
- ["Discovery Methods", :discovery],
220
- ["Validator Plugins", :validator]
221
- ]
222
-
223
- if configuration.include?(:target) && configuration[:target] != "."
224
- if configuration[:target] =~ /^(.+?)\/(.+)$/
225
- ddl = load_plugin_ddl($2.to_sym, $1)
226
- else
227
- found_plugin_type = nil
228
-
229
- known_plugin_types.each do |plugin_type|
230
- PluginManager.find(plugin_type[1], "ddl").each do |ddlf|
231
- pluginname = ddlf.gsub(/_#{plugin_type[1]}$/, "")
232
-
233
- abort "Duplicate plugin name found, please specify a full path like agent/rpcutil" if pluginname == configuration[:target] && found_plugin_type
234
-
235
- found_plugin_type = plugin_type[1] if pluginname == configuration[:target]
236
- end
237
- end
238
-
239
- abort "Could not find a plugin named '%s' in any supported plugin type" % configuration[:target] unless found_plugin_type
240
- ddl = load_plugin_ddl(configuration[:target], found_plugin_type)
241
- end
242
-
243
- if ddl
244
- puts ddl.help(configuration[:rpctemplate])
245
- else
246
- abort "Could not find a '%s' plugin named '%s'" % configuration[:target].split("/")
247
- end
248
-
249
- else
250
- puts "Please specify a plugin. Available plugins are:"
251
- puts
252
-
253
- load_errors = []
254
-
255
- known_plugin_types.each do |plugin_type|
256
- puts "%s:" % plugin_type[0]
257
-
258
- PluginManager.find(plugin_type[1], "ddl").each do |ddlf|
259
- begin
260
- help = DDL.new(ddlf, plugin_type[1], false)
139
+ def doc_command
140
+ puts "WARNING: mco plugin doc is deprecated, please use choria plugin doc"
261
141
 
262
- next unless help.client_activated?
263
-
264
- help.loadddlfile
265
- pluginname = ddlf.gsub(/_#{plugin_type[1]}$/, "")
266
- puts " %-25s %s" % [pluginname, help.meta[:description]]
267
- rescue => e
268
- load_errors << [plugin_type[1], ddlf, e]
269
- end
270
- end
271
-
272
- puts
273
- end
274
-
275
- unless load_errors.empty?
276
- puts "Plugin Load Errors:"
277
-
278
- load_errors.each do |e|
279
- puts " %-25s %s" % ["#{e[0]}/#{e[1]}", Util.colorize(:yellow, e[2])]
280
- end
281
- end
282
- end
142
+ exec("choria plugin doc %s" % [configuration[:target]])
283
143
  end
284
144
 
285
145
  # Creates the correct package plugin object.
@@ -341,18 +201,6 @@ mco plugin package [options] <directory>
341
201
  File.basename(plugintype[0])
342
202
  end
343
203
 
344
- # Load preset metadata values from config if they are present
345
- # This makes it possible to override metadata values in a local
346
- # client config file.
347
- #
348
- # Example : plugin.metadata.license = Apache 2
349
- def load_plugin_config_values
350
- config = Config.instance
351
- [:pluginname, :description, :author, :license, :version, :url, :timeout].each do |confoption|
352
- configuration[confoption] = config.pluginconf["metadata.#{confoption}"] unless configuration[confoption]
353
- end
354
- end
355
-
356
204
  def main
357
205
  abort "No action specified, please run 'mco help plugin' for help" unless configuration.include?(:action)
358
206
 
@@ -137,6 +137,8 @@ module MCollective
137
137
 
138
138
  raise('Identities can only match /\w\.\-/') unless @identity =~ /^[\w.\-]+$/
139
139
 
140
+ check_deprecations
141
+
140
142
  @configured = true
141
143
 
142
144
  libdirs.each do |dir|
@@ -254,5 +256,13 @@ module MCollective
254
256
  end
255
257
  end
256
258
  end
259
+
260
+ def check_deprecations
261
+ if @pluginconf["choria.use_srv_records"]
262
+ Log.warn("Configuration set 'choria.use_srv_records' which is deprecated in favor of 'choria.use_srv'.")
263
+ @pluginconf["choria.use_srv"] = @pluginconf["choria.use_srv_records"]
264
+ @pluginconf.delete("choria.use_srv_records")
265
+ end
266
+ end
257
267
  end
258
268
  end
@@ -10,6 +10,9 @@ module MCollective
10
10
 
11
11
  cmd = [binary_name, "discover", "-j", "--silent"]
12
12
 
13
+ config = client.options.fetch(:config)
14
+ cmd << "--config" << config if config
15
+
13
16
  cmd << "-T" << filter["collective"] if filter["collective"]
14
17
 
15
18
  filter.fetch("identity", []).each do |i|
@@ -53,6 +56,7 @@ module MCollective
53
56
 
54
57
  begin
55
58
  Timeout.timeout(timeout + 0.5) do
59
+ nodes.concat(JSON.parse(stdout.read))
56
60
  status = wait_thr.value
57
61
 
58
62
  raise("Choria discovery failed: %s" % stderr.read) unless status.exitstatus == 0
@@ -62,8 +66,6 @@ module MCollective
62
66
  Process.kill("KILL", wait_thr[:pid])
63
67
  raise("Choria failed to complete discovery within %d timeout" % timeout)
64
68
  end
65
-
66
- nodes.concat(JSON.parse(stdout.read))
67
69
  end
68
70
 
69
71
  nodes
@@ -96,9 +96,8 @@ module MCollective
96
96
  end
97
97
 
98
98
  @logger.start
99
- rescue Exception => e # rubocop:disable Lint/RescueException
99
+ rescue Exception # rubocop:disable Lint/RescueException
100
100
  @configured = false
101
- warn "Could not start logger: #{e.class} #{e}"
102
101
  end
103
102
 
104
103
  # figures out the filename that called us
@@ -157,19 +157,19 @@ module MCollective
157
157
 
158
158
  # Determines if SRV records should be used
159
159
  #
160
- # Setting choria.use_srv_records to anything other than t, true, yes or 1 will disable
160
+ # Setting choria.use_srv to anything other than t, true, yes or 1 will disable
161
161
  # SRV records
162
162
  #
163
163
  # @return [Boolean]
164
164
  def should_use_srv?
165
- ["t", "true", "yes", "1"].include?(get_option("choria.use_srv_records", "1").downcase)
165
+ ["t", "true", "yes", "1"].include?(get_option("choria.use_srv", "1").downcase)
166
166
  end
167
167
 
168
168
  # Query DNS for a series of records
169
169
  #
170
170
  # The given records will be passed through {#srv_records} to figure out the domain to query in.
171
171
  #
172
- # Querying of records can be bypassed by setting choria.use_srv_records to false
172
+ # Querying of records can be bypassed by setting choria.use_srv to false
173
173
  #
174
174
  # @yield [Hash] each record for modification by the caller
175
175
  # @param records [Array<String>] the records to query without their domain parts
@@ -634,21 +634,27 @@ module MCollective
634
634
 
635
635
  # The PuppetDB server to connect to
636
636
  #
637
- # Will consult _x-puppet-db._tcp.example.net then _x-puppet._tcp.example.net
638
- # then configurable using choria.puppetdb_host and choria.puppetdb_port, defaults
639
- # to puppet:8081
637
+ # Use choria.puppetdb_host if set, otherwise query
638
+ # _x-puppet-db._tcp.example.net then _x-puppet._tcp.example.net if SRV
639
+ # lookup is enabled, and fallback to puppet:8081 if nothing else worked.
640
640
  #
641
641
  # @return [Hash] with :target and :port
642
642
  def puppetdb_server
643
- d_host = get_option("choria.puppetdb_host", "puppet")
644
643
  d_port = get_option("choria.puppetdb_port", "8081")
645
644
 
645
+ answer = {
646
+ :target => get_option("choria.puppetdb_host", nil),
647
+ :port => d_port
648
+ }
649
+
650
+ return answer if answer[:target]
651
+
646
652
  answer = try_srv(["_x-puppet-db._tcp"], nil, nil)
647
653
  return answer if answer[:target]
648
654
 
649
655
  # In the case where we take _x-puppet._tcp SRV records we unfortunately have
650
656
  # to force the port else it uses the one from Puppet which will 404
651
- answer = try_srv(["_x-puppet._tcp"], d_host, d_port)
657
+ answer = try_srv(["_x-puppet._tcp"], "puppet", d_port)
652
658
  answer[:port] = d_port
653
659
 
654
660
  answer
@@ -65,7 +65,7 @@ module MCollective
65
65
  # AIO path to binaries like wrappers etc
66
66
  def aio_bin_path
67
67
  if Util.windows?
68
- 'C:\Program Files\Puppet Labs\Puppet\bin'
68
+ 'C:\Program Files\Puppet Labs\Puppet\puppet\bin'
69
69
  else
70
70
  "/opt/puppetlabs/puppet/bin"
71
71
  end
@@ -88,6 +88,13 @@ module MCollective
88
88
  end
89
89
  end
90
90
 
91
+ # Is this an AIO install?
92
+ #
93
+ # @return [Boolean]
94
+ def aio?
95
+ File.directory?(aio_bin_path)
96
+ end
97
+
91
98
  # Path to the task wrapper executable
92
99
  #
93
100
  # @return [String]
@@ -157,7 +164,7 @@ module MCollective
157
164
  # @return [String] path to the command
158
165
  def task_command(spooldir, task)
159
166
  file_spec = task["files"][0]
160
- file_name = File.join(spooldir, "files", file_spec["filename"])
167
+ file_name = File.join(spooldir, "files", task_module(task["task"]), "tasks", file_spec["filename"])
161
168
 
162
169
  command = platform_specific_command(file_name)
163
170
 
@@ -179,6 +186,8 @@ module MCollective
179
186
  "_choria_task_caller" => task_caller
180
187
  }
181
188
 
189
+ environment["PATH"] = "#{aio_bin_path}#{File::PATH_SEPARATOR}#{ENV['PATH']}" if aio?
190
+
182
191
  return environment unless task["input"]
183
192
  return environment unless ["both", "environment"].include?(task_input_method(task))
184
193
 
@@ -186,6 +195,7 @@ module MCollective
186
195
  environment["PT_%s" % k] = v.to_s
187
196
  end
188
197
 
198
+ environment["PT__task"] = task["task"]
189
199
  environment["PT__installdir"] = File.join(request_spooldir(task_id), "files")
190
200
 
191
201
  environment
@@ -220,7 +230,10 @@ module MCollective
220
230
  # @param task [Hash] task specification
221
231
  def populate_spooldir(spooldir, task)
222
232
  task["files"].each do |file|
223
- spool_filename = File.join(spooldir, "files", file["filename"])
233
+ filename = file["filename"]
234
+ filename = File.join(task_module(task["task"]), "tasks", filename) unless filename.index("/")
235
+
236
+ spool_filename = File.join(spooldir, "files", filename)
224
237
 
225
238
  FileUtils.mkdir_p(File.dirname(spool_filename), :mode => 0o0750)
226
239
  FileUtils.cp(task_file_name(file), spool_filename)
@@ -246,7 +259,7 @@ module MCollective
246
259
  # act on these tasks either by asking for their status or perhaps killing
247
260
  # them?
248
261
  #
249
- # @param command [Array<String>] command to run
262
+ # @param command [String] command to run
250
263
  # @param environment [Hash] environment to run with
251
264
  # @param stdin [String] stdin to send to the command
252
265
  # @param spooldir [String] path to the spool for this specific request
@@ -287,7 +300,7 @@ module MCollective
287
300
  Process.exec(environment, command, options)
288
301
  end
289
302
  else
290
- pid = Process.spawn(environment, command, options)
303
+ pid = Process.spawn(environment, [command, command], options)
291
304
  end
292
305
 
293
306
  sleep 0.1 until File.exist?(wrapper_stdout)
@@ -569,6 +582,15 @@ module MCollective
569
582
  parts
570
583
  end
571
584
 
585
+ # Return a task's module
586
+ #
587
+ # @param task [String]
588
+ # @return [String] the module name
589
+ # @raise [StandardError] for invalid task names
590
+ def task_module(task)
591
+ parse_task(task)[0]
592
+ end
593
+
572
594
  # Determines the cache path for a task file
573
595
  #
574
596
  # @param file [Hash] a file hash as per the task metadata
@@ -147,13 +147,11 @@ 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
157
  def self.config_paths_for_user