bolt 3.5.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Puppetfile +3 -3
- data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +26 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/containerresult.rb +27 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +43 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +29 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +34 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +55 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +66 -0
- data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +5 -1
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +5 -1
- data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +1 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +2 -0
- data/bolt-modules/file/lib/puppet/functions/file/exists.rb +9 -3
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +6 -2
- data/bolt-modules/file/lib/puppet/functions/file/readable.rb +8 -3
- data/guides/guide.txt +17 -0
- data/guides/links.txt +13 -0
- data/guides/targets.txt +29 -0
- data/guides/transports.txt +23 -0
- data/lib/bolt/analytics.rb +4 -8
- data/lib/bolt/applicator.rb +1 -1
- data/lib/bolt/bolt_option_parser.rb +351 -225
- data/lib/bolt/catalog.rb +2 -1
- data/lib/bolt/cli.rb +122 -55
- data/lib/bolt/config.rb +11 -7
- data/lib/bolt/config/options.rb +41 -9
- data/lib/bolt/config/transport/podman.rb +33 -0
- data/lib/bolt/executor.rb +15 -11
- data/lib/bolt/inventory.rb +5 -4
- data/lib/bolt/inventory/inventory.rb +3 -2
- data/lib/bolt/module_installer/specs/git_spec.rb +10 -6
- data/lib/bolt/outputter/human.rb +194 -79
- data/lib/bolt/outputter/json.rb +10 -4
- data/lib/bolt/pal.rb +45 -0
- data/lib/bolt/pal/yaml_plan/step.rb +4 -2
- data/lib/bolt/plan_creator.rb +2 -2
- data/lib/bolt/plugin.rb +13 -11
- data/lib/bolt/puppetdb/client.rb +54 -0
- data/lib/bolt/result.rb +5 -0
- data/lib/bolt/shell/bash.rb +23 -10
- data/lib/bolt/transport/docker.rb +1 -1
- data/lib/bolt/transport/docker/connection.rb +10 -6
- data/lib/bolt/transport/podman.rb +19 -0
- data/lib/bolt/transport/podman/connection.rb +98 -0
- data/lib/bolt/transport/ssh/connection.rb +3 -6
- data/lib/bolt/util.rb +71 -0
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/transport_app.rb +3 -0
- data/lib/bolt_spec/plans/mock_executor.rb +2 -1
- metadata +10 -2
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bolt/error'
|
4
|
+
require 'bolt/config/transport/base'
|
5
|
+
|
6
|
+
module Bolt
|
7
|
+
class Config
|
8
|
+
module Transport
|
9
|
+
class Podman < Base
|
10
|
+
OPTIONS = %w[
|
11
|
+
cleanup
|
12
|
+
host
|
13
|
+
interpreters
|
14
|
+
shell-command
|
15
|
+
tmpdir
|
16
|
+
tty
|
17
|
+
].freeze
|
18
|
+
|
19
|
+
DEFAULTS = {
|
20
|
+
'cleanup' => true
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
private def validate
|
24
|
+
super
|
25
|
+
|
26
|
+
if @config['interpreters']
|
27
|
+
@config['interpreters'] = normalize_interpreters(@config['interpreters'])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/bolt/executor.rb
CHANGED
@@ -12,34 +12,37 @@ require 'bolt/config'
|
|
12
12
|
require 'bolt/result_set'
|
13
13
|
require 'bolt/puppetdb'
|
14
14
|
# Load transports
|
15
|
-
require 'bolt/transport/
|
16
|
-
require 'bolt/transport/winrm'
|
17
|
-
require 'bolt/transport/orch'
|
15
|
+
require 'bolt/transport/docker'
|
18
16
|
require 'bolt/transport/local'
|
19
17
|
require 'bolt/transport/lxd'
|
20
|
-
require 'bolt/transport/
|
18
|
+
require 'bolt/transport/orch'
|
19
|
+
require 'bolt/transport/podman'
|
21
20
|
require 'bolt/transport/remote'
|
21
|
+
require 'bolt/transport/ssh'
|
22
|
+
require 'bolt/transport/winrm'
|
22
23
|
require 'bolt/yarn'
|
23
24
|
|
24
25
|
module Bolt
|
25
26
|
TRANSPORTS = {
|
26
|
-
|
27
|
-
winrm: Bolt::Transport::WinRM,
|
28
|
-
pcp: Bolt::Transport::Orch,
|
27
|
+
docker: Bolt::Transport::Docker,
|
29
28
|
local: Bolt::Transport::Local,
|
30
29
|
lxd: Bolt::Transport::LXD,
|
31
|
-
|
32
|
-
|
30
|
+
pcp: Bolt::Transport::Orch,
|
31
|
+
podman: Bolt::Transport::Podman,
|
32
|
+
remote: Bolt::Transport::Remote,
|
33
|
+
ssh: Bolt::Transport::SSH,
|
34
|
+
winrm: Bolt::Transport::WinRM
|
33
35
|
}.freeze
|
34
36
|
|
35
37
|
class Executor
|
36
|
-
attr_reader :noop, :transports, :in_parallel
|
38
|
+
attr_reader :noop, :transports, :in_parallel, :future
|
37
39
|
attr_accessor :run_as
|
38
40
|
|
39
41
|
def initialize(concurrency = 1,
|
40
42
|
analytics = Bolt::Analytics::NoopClient.new,
|
41
43
|
noop = false,
|
42
|
-
modified_concurrency = false
|
44
|
+
modified_concurrency = false,
|
45
|
+
future = {})
|
43
46
|
# lazy-load expensive gem code
|
44
47
|
require 'concurrent'
|
45
48
|
@analytics = analytics
|
@@ -64,6 +67,7 @@ module Bolt
|
|
64
67
|
@noop = noop
|
65
68
|
@run_as = nil
|
66
69
|
@in_parallel = false
|
70
|
+
@future = future
|
67
71
|
@pool = if concurrency > 0
|
68
72
|
Concurrent::ThreadPoolExecutor.new(name: 'exec', max_threads: concurrency)
|
69
73
|
else
|
data/lib/bolt/inventory.rb
CHANGED
@@ -86,6 +86,7 @@ module Bolt
|
|
86
86
|
if config.default_inventoryfile.exist?
|
87
87
|
logger.debug("Loaded inventory from #{config.default_inventoryfile}")
|
88
88
|
else
|
89
|
+
source = nil
|
89
90
|
logger.debug("Tried to load inventory from #{config.default_inventoryfile}, but the file does not exist")
|
90
91
|
end
|
91
92
|
end
|
@@ -100,17 +101,17 @@ module Bolt
|
|
100
101
|
validator.warnings.each { |warning| Bolt::Logger.warn(warning[:id], warning[:msg]) }
|
101
102
|
end
|
102
103
|
|
103
|
-
inventory = create_version(data, config.transport, config.transports, plugins)
|
104
|
+
inventory = create_version(data, config.transport, config.transports, plugins, source)
|
104
105
|
inventory.validate
|
105
106
|
inventory
|
106
107
|
end
|
107
108
|
|
108
|
-
def self.create_version(data, transport, transports, plugins)
|
109
|
+
def self.create_version(data, transport, transports, plugins, source = nil)
|
109
110
|
version = (data || {}).delete('version') { 2 }
|
110
111
|
|
111
112
|
case version
|
112
113
|
when 2
|
113
|
-
Bolt::Inventory::Inventory.new(data, transport, transports, plugins)
|
114
|
+
Bolt::Inventory::Inventory.new(data, transport, transports, plugins, source)
|
114
115
|
else
|
115
116
|
raise ValidationError.new("Unsupported version #{version} specified in inventory", nil)
|
116
117
|
end
|
@@ -120,7 +121,7 @@ module Bolt
|
|
120
121
|
config = Bolt::Config.default
|
121
122
|
plugins = Bolt::Plugin.setup(config, nil)
|
122
123
|
|
123
|
-
create_version({}, config.transport, config.transports, plugins)
|
124
|
+
create_version({}, config.transport, config.transports, plugins, nil)
|
124
125
|
end
|
125
126
|
end
|
126
127
|
end
|
@@ -6,7 +6,7 @@ require 'bolt/inventory/target'
|
|
6
6
|
module Bolt
|
7
7
|
class Inventory
|
8
8
|
class Inventory
|
9
|
-
attr_reader :
|
9
|
+
attr_reader :config, :plugins, :source, :targets, :transport
|
10
10
|
|
11
11
|
class WildcardError < Bolt::Error
|
12
12
|
def initialize(target)
|
@@ -15,7 +15,7 @@ module Bolt
|
|
15
15
|
end
|
16
16
|
|
17
17
|
# TODO: Pass transport config instead of config object
|
18
|
-
def initialize(data, transport, transports, plugins)
|
18
|
+
def initialize(data, transport, transports, plugins, source = nil)
|
19
19
|
@logger = Bolt::Logger.logger(self)
|
20
20
|
@data = data || {}
|
21
21
|
@transport = transport
|
@@ -24,6 +24,7 @@ module Bolt
|
|
24
24
|
@groups = Group.new(@data, plugins, all_group: true)
|
25
25
|
@group_lookup = {}
|
26
26
|
@targets = {}
|
27
|
+
@source = source
|
27
28
|
|
28
29
|
@groups.resolve_string_targets(@groups.target_aliases, @groups.all_targets)
|
29
30
|
|
@@ -67,8 +67,7 @@ module Bolt
|
|
67
67
|
elsif git.start_with?('https://github.com')
|
68
68
|
git.split('https://github.com/').last.split('.git').first
|
69
69
|
else
|
70
|
-
raise Bolt::ValidationError,
|
71
|
-
"Invalid git source: #{git}. Only GitHub modules are supported."
|
70
|
+
raise Bolt::ValidationError, invalid_git_msg(git)
|
72
71
|
end
|
73
72
|
|
74
73
|
[git, repo]
|
@@ -89,6 +88,14 @@ module Bolt
|
|
89
88
|
}
|
90
89
|
end
|
91
90
|
|
91
|
+
# Returns an error message that the provided repo is not a git repo or
|
92
|
+
# is private.
|
93
|
+
#
|
94
|
+
private def invalid_git_msg(repo_name)
|
95
|
+
"#{repo_name} is not a public GitHub repository. See https://pup.pt/no-resolve "\
|
96
|
+
"for information on how to install this module."
|
97
|
+
end
|
98
|
+
|
92
99
|
# Returns a PuppetfileResolver::Model::GitModule object for resolving.
|
93
100
|
#
|
94
101
|
def to_resolver_module
|
@@ -157,10 +164,7 @@ module Bolt
|
|
157
164
|
|
158
165
|
raise Bolt::Error.new(message, 'bolt/github-api-rate-limit-error')
|
159
166
|
when Net::HTTPNotFound
|
160
|
-
raise Bolt::Error.new(
|
161
|
-
"#{git} is not a git repository.",
|
162
|
-
"bolt/missing-git-repository-error"
|
163
|
-
)
|
167
|
+
raise Bolt::Error.new(invalid_git_msg(git), "bolt/missing-git-repository-error")
|
164
168
|
else
|
165
169
|
raise Bolt::Error.new(
|
166
170
|
"Ref #{ref} at #{git} is not a commit, tag, or branch.",
|
data/lib/bolt/outputter/human.rb
CHANGED
@@ -6,6 +6,7 @@ module Bolt
|
|
6
6
|
class Outputter
|
7
7
|
class Human < Bolt::Outputter
|
8
8
|
COLORS = {
|
9
|
+
dim: "2", # Dim, the other color of the rainbow
|
9
10
|
red: "31",
|
10
11
|
green: "32",
|
11
12
|
yellow: "33",
|
@@ -173,12 +174,16 @@ module Bolt
|
|
173
174
|
@stream.puts(remove_trail(indent(2, result.message)))
|
174
175
|
end
|
175
176
|
|
176
|
-
|
177
|
-
|
177
|
+
case result.action
|
178
|
+
when 'command', 'script'
|
178
179
|
safe_value = result.safe_value
|
179
180
|
@stream.puts(indent(2, safe_value['merged_output'])) unless safe_value['merged_output'].strip.empty?
|
180
|
-
|
181
|
-
@stream.puts(indent(2,
|
181
|
+
when 'lookup'
|
182
|
+
@stream.puts(indent(2, result['value']))
|
183
|
+
else
|
184
|
+
if result.generic_value.any?
|
185
|
+
@stream.puts(indent(2, ::JSON.pretty_generate(result.generic_value)))
|
186
|
+
end
|
182
187
|
end
|
183
188
|
end
|
184
189
|
end
|
@@ -292,7 +297,7 @@ module Bolt
|
|
292
297
|
end
|
293
298
|
|
294
299
|
def print_tasks(tasks, modulepath)
|
295
|
-
command = Bolt::Util.powershell? ? 'Get-BoltTask -
|
300
|
+
command = Bolt::Util.powershell? ? 'Get-BoltTask -Name <TASK NAME>' : 'bolt task show <TASK NAME>'
|
296
301
|
|
297
302
|
tasks = tasks.map do |name, description|
|
298
303
|
description = truncate(description, 72)
|
@@ -313,78 +318,115 @@ module Bolt
|
|
313
318
|
|
314
319
|
# @param [Hash] task A hash representing the task
|
315
320
|
def print_task_info(task)
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
+
params = (task.parameters || []).sort
|
322
|
+
|
323
|
+
info = +''
|
324
|
+
|
325
|
+
# Add task name and description
|
326
|
+
info << colorize(:cyan, "#{task.name}\n")
|
327
|
+
info << if task.description
|
328
|
+
indent(2, task.description.chomp)
|
321
329
|
else
|
322
|
-
|
330
|
+
indent(2, 'No description')
|
323
331
|
end
|
332
|
+
info << "\n\n"
|
324
333
|
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
334
|
+
# Build usage string
|
335
|
+
usage = +''
|
336
|
+
usage << if Bolt::Util.powershell?
|
337
|
+
"Invoke-BoltTask -Name #{task.name} -Targets <targets>"
|
338
|
+
else
|
339
|
+
"bolt task run #{task.name} --targets <targets>"
|
340
|
+
end
|
341
|
+
usage << (Bolt::Util.powershell? ? ' [-Noop]' : ' [--noop]') if task.supports_noop
|
342
|
+
params.each do |name, data|
|
343
|
+
usage << if data['type']&.start_with?('Optional')
|
344
|
+
" [#{name}=<value>]"
|
331
345
|
else
|
332
|
-
" #{
|
346
|
+
" #{name}=<value>"
|
333
347
|
end
|
334
348
|
end
|
335
349
|
|
336
|
-
|
337
|
-
|
350
|
+
# Add usage
|
351
|
+
info << colorize(:cyan, "Usage\n")
|
352
|
+
info << indent(2, wrap(usage))
|
353
|
+
info << "\n"
|
354
|
+
|
355
|
+
# Add parameters, if any
|
356
|
+
if params.any?
|
357
|
+
info << colorize(:cyan, "Parameters\n")
|
358
|
+
params.each do |name, data|
|
359
|
+
info << indent(2, "#{colorize(:yellow, name)} #{colorize(:dim, data['type'] || 'Any')}\n")
|
360
|
+
info << indent(4, "#{wrap(data['description']).chomp}\n") if data['description']
|
361
|
+
info << indent(4, "Default: #{data['default'].inspect}\n") if data.key?('default')
|
362
|
+
info << "\n"
|
363
|
+
end
|
338
364
|
end
|
339
365
|
|
340
|
-
|
341
|
-
task_info << " - #{task.description}" if task.description
|
342
|
-
task_info << "\n\n"
|
343
|
-
task_info << "USAGE:\n#{usage}\n\n"
|
344
|
-
task_info << "PARAMETERS:\n#{pretty_params}\n" unless pretty_params.empty?
|
345
|
-
task_info << "MODULE:\n"
|
346
|
-
|
366
|
+
# Add module location
|
347
367
|
path = task.files.first['path'].chomp("/tasks/#{task.files.first['name']}")
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
368
|
+
info << colorize(:cyan, "Module\n")
|
369
|
+
info << if path.start_with?(Bolt::Config::Modulepath::MODULES_PATH)
|
370
|
+
indent(2, 'built-in module')
|
371
|
+
else
|
372
|
+
indent(2, path)
|
373
|
+
end
|
374
|
+
|
375
|
+
@stream.puts info
|
354
376
|
end
|
355
377
|
|
356
378
|
# @param [Hash] plan A hash representing the plan
|
357
379
|
def print_plan_info(plan)
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
380
|
+
params = plan['parameters'].sort
|
381
|
+
|
382
|
+
info = +''
|
383
|
+
|
384
|
+
# Add plan name and description
|
385
|
+
info << colorize(:cyan, "#{plan['name']}\n")
|
386
|
+
info << if plan['description']
|
387
|
+
indent(2, plan['description'].chomp)
|
363
388
|
else
|
364
|
-
|
389
|
+
indent(2, 'No description')
|
365
390
|
end
|
391
|
+
info << "\n\n"
|
366
392
|
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
393
|
+
# Build the usage string
|
394
|
+
usage = +''
|
395
|
+
usage << if Bolt::Util.powershell?
|
396
|
+
"Invoke-BoltPlan -Name #{plan['name']}"
|
397
|
+
else
|
398
|
+
"bolt plan run #{plan['name']}"
|
399
|
+
end
|
400
|
+
params.each do |name, data|
|
401
|
+
usage << (data.include?('default_value') ? " [#{name}=<value>]" : " #{name}=<value>")
|
372
402
|
end
|
373
403
|
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
plan_info << "PARAMETERS:\n#{pretty_params}\n" unless plan['parameters'].empty?
|
379
|
-
plan_info << "MODULE:\n"
|
404
|
+
# Add usage
|
405
|
+
info << colorize(:cyan, "Usage\n")
|
406
|
+
info << indent(2, wrap(usage))
|
407
|
+
info << "\n"
|
380
408
|
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
409
|
+
# Add parameters, if any
|
410
|
+
if params.any?
|
411
|
+
info << colorize(:cyan, "Parameters\n")
|
412
|
+
|
413
|
+
params.each do |name, data|
|
414
|
+
info << indent(2, "#{colorize(:yellow, name)} #{colorize(:dim, data['type'])}\n")
|
415
|
+
info << indent(4, "#{wrap(data['description']).chomp}\n") if data['description']
|
416
|
+
info << indent(4, "Default: #{data['default_value']}\n") unless data['default_value'].nil?
|
417
|
+
info << "\n"
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
# Add module location
|
422
|
+
info << colorize(:cyan, "Module\n")
|
423
|
+
info << if plan['module'].start_with?(Bolt::Config::Modulepath::MODULES_PATH)
|
424
|
+
indent(2, 'built-in module')
|
425
|
+
else
|
426
|
+
indent(2, plan['module'])
|
427
|
+
end
|
428
|
+
|
429
|
+
@stream.puts info
|
388
430
|
end
|
389
431
|
|
390
432
|
def print_plans(plans, modulepath)
|
@@ -445,42 +487,115 @@ module Bolt
|
|
445
487
|
end
|
446
488
|
end
|
447
489
|
|
448
|
-
def print_targets(target_list,
|
490
|
+
def print_targets(target_list, inventory_source, default_inventory, target_flag)
|
449
491
|
adhoc = colorize(:yellow, "(Not found in inventory file)")
|
450
492
|
|
451
493
|
targets = []
|
452
494
|
targets += target_list[:inventory].map { |target| [target.name, nil] }
|
453
495
|
targets += target_list[:adhoc].map { |target| [target.name, adhoc] }
|
454
496
|
|
455
|
-
|
456
|
-
@stream.puts format_table(targets, 0, 2)
|
457
|
-
@stream.puts
|
458
|
-
end
|
497
|
+
info = +''
|
459
498
|
|
460
|
-
|
461
|
-
|
462
|
-
|
499
|
+
# Add target list
|
500
|
+
info << colorize(:cyan, "Targets\n")
|
501
|
+
info << if targets.any?
|
502
|
+
format_table(targets, 2, 2).to_s
|
503
|
+
else
|
504
|
+
indent(2, 'No targets')
|
505
|
+
end
|
506
|
+
info << "\n\n"
|
507
|
+
|
508
|
+
info << format_inventory_source(inventory_source, default_inventory)
|
509
|
+
info << format_target_summary(target_list[:inventory].count, target_list[:adhoc].count, target_flag, false)
|
510
|
+
|
511
|
+
@stream.puts info
|
512
|
+
end
|
513
|
+
|
514
|
+
def print_target_info(target_list, inventory_source, default_inventory, target_flag)
|
515
|
+
adhoc_targets = target_list[:adhoc].map(&:name).to_set
|
516
|
+
inventory_targets = target_list[:inventory].map(&:name).to_set
|
517
|
+
targets = target_list.values.flatten.sort_by(&:name)
|
518
|
+
|
519
|
+
info = +''
|
520
|
+
|
521
|
+
if targets.any?
|
522
|
+
adhoc = colorize(:yellow, " (Not found in inventory file)")
|
523
|
+
|
524
|
+
targets.each do |target|
|
525
|
+
info << colorize(:cyan, target.name)
|
526
|
+
info << adhoc if adhoc_targets.include?(target.name)
|
527
|
+
info << "\n"
|
528
|
+
info << indent(2, target.detail.to_yaml.lines.drop(1).join)
|
529
|
+
info << "\n"
|
530
|
+
end
|
463
531
|
else
|
464
|
-
|
532
|
+
info << colorize(:cyan, "Targets\n")
|
533
|
+
info << indent(2, "No targets\n\n")
|
465
534
|
end
|
466
535
|
|
467
|
-
|
468
|
-
|
469
|
-
|
536
|
+
info << format_inventory_source(inventory_source, default_inventory)
|
537
|
+
info << format_target_summary(inventory_targets.count, adhoc_targets.count, target_flag, true)
|
538
|
+
|
539
|
+
@stream.puts info
|
470
540
|
end
|
471
541
|
|
472
|
-
def
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
542
|
+
private def format_inventory_source(inventory_source, default_inventory)
|
543
|
+
info = +''
|
544
|
+
|
545
|
+
# Add inventory file source
|
546
|
+
info << colorize(:cyan, "Inventory source\n")
|
547
|
+
info << if inventory_source
|
548
|
+
indent(2, "#{inventory_source}\n")
|
549
|
+
else
|
550
|
+
indent(2, wrap("Tried to load inventory from #{default_inventory}, but the file does not exist\n"))
|
551
|
+
end
|
552
|
+
info << "\n"
|
478
553
|
end
|
479
554
|
|
480
|
-
def
|
481
|
-
|
482
|
-
|
483
|
-
|
555
|
+
private def format_target_summary(inventory_count, adhoc_count, target_flag, detail_flag)
|
556
|
+
info = +''
|
557
|
+
|
558
|
+
# Add target count summary
|
559
|
+
count = "#{inventory_count + adhoc_count} total, "\
|
560
|
+
"#{inventory_count} from inventory, "\
|
561
|
+
"#{adhoc_count} adhoc"
|
562
|
+
info << colorize(:cyan, "Target count\n")
|
563
|
+
info << indent(2, count)
|
564
|
+
|
565
|
+
# Add filtering information
|
566
|
+
unless target_flag && detail_flag
|
567
|
+
info << colorize(:cyan, "\n\nAdditional information\n")
|
568
|
+
|
569
|
+
unless target_flag
|
570
|
+
opt = Bolt::Util.windows? ? "'-Targets', '-Query', or '-Rerun'" : "'--targets', '--query', or '--rerun'"
|
571
|
+
info << indent(2, "Use the #{opt} option to view specific targets\n")
|
572
|
+
end
|
573
|
+
|
574
|
+
unless detail_flag
|
575
|
+
opt = Bolt::Util.windows? ? '-Detail' : '--detail'
|
576
|
+
info << indent(2, "Use the '#{opt}' option to view target configuration and data")
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
info
|
581
|
+
end
|
582
|
+
|
583
|
+
def print_groups(groups, inventory_source, default_inventory)
|
584
|
+
info = +''
|
585
|
+
|
586
|
+
# Add group list
|
587
|
+
info << colorize(:cyan, "Groups\n")
|
588
|
+
info << indent(2, groups.join("\n"))
|
589
|
+
info << "\n\n"
|
590
|
+
|
591
|
+
# Add inventory file source
|
592
|
+
info << format_inventory_source(inventory_source, default_inventory)
|
593
|
+
|
594
|
+
# Add group count summary
|
595
|
+
info << colorize(:cyan, "Group count\n")
|
596
|
+
info << indent(2, "#{groups.count} total")
|
597
|
+
|
598
|
+
@stream.puts info
|
484
599
|
end
|
485
600
|
|
486
601
|
# @param [Bolt::ResultSet] apply_result A ResultSet object representing the result of a `bolt apply`
|