bolt 2.42.0 → 2.44.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 +12 -12
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +6 -8
- data/lib/bolt/analytics.rb +3 -2
- data/lib/bolt/applicator.rb +11 -1
- data/lib/bolt/bolt_option_parser.rb +20 -13
- data/lib/bolt/catalog.rb +10 -29
- data/lib/bolt/cli.rb +22 -32
- data/lib/bolt/config.rb +84 -82
- data/lib/bolt/config/options.rb +68 -0
- data/lib/bolt/config/transport/options.rb +7 -0
- data/lib/bolt/config/transport/orch.rb +1 -0
- data/lib/bolt/executor.rb +15 -5
- data/lib/bolt/inventory.rb +1 -1
- data/lib/bolt/inventory/group.rb +7 -4
- data/lib/bolt/logger.rb +114 -10
- data/lib/bolt/module_installer.rb +4 -2
- data/lib/bolt/module_installer/resolver.rb +59 -14
- data/lib/bolt/module_installer/specs/forge_spec.rb +8 -2
- data/lib/bolt/module_installer/specs/git_spec.rb +17 -2
- data/lib/bolt/outputter/human.rb +8 -4
- data/lib/bolt/outputter/rainbow.rb +3 -3
- data/lib/bolt/pal.rb +93 -14
- data/lib/bolt/pal/yaml_plan.rb +8 -2
- data/lib/bolt/pal/yaml_plan/evaluator.rb +2 -2
- data/lib/bolt/pal/yaml_plan/transpiler.rb +1 -0
- data/lib/bolt/plugin.rb +2 -2
- data/lib/bolt/plugin/cache.rb +7 -7
- data/lib/bolt/plugin/module.rb +1 -1
- data/lib/bolt/plugin/puppet_connect_data.rb +35 -0
- data/lib/bolt/plugin/puppetdb.rb +1 -1
- data/lib/bolt/project.rb +56 -43
- data/lib/bolt/rerun.rb +1 -1
- data/lib/bolt/shell/bash.rb +1 -1
- data/lib/bolt/shell/bash/tmpdir.rb +4 -1
- data/lib/bolt/shell/powershell.rb +2 -2
- data/lib/bolt/task.rb +1 -1
- data/lib/bolt/transport/docker/connection.rb +2 -2
- data/lib/bolt/transport/local.rb +1 -1
- data/lib/bolt/transport/orch/connection.rb +1 -1
- data/lib/bolt/transport/ssh.rb +1 -2
- data/lib/bolt/transport/ssh/connection.rb +1 -1
- data/lib/bolt/validator.rb +2 -2
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/config.rb +1 -1
- data/lib/bolt_server/transport_app.rb +2 -1
- data/libexec/bolt_catalog +1 -1
- metadata +9 -8
@@ -13,14 +13,20 @@ module Bolt
|
|
13
13
|
class ForgeSpec
|
14
14
|
NAME_REGEX = %r{\A[a-zA-Z0-9]+[-/](?<name>[a-z][a-z0-9_]*)\z}.freeze
|
15
15
|
REQUIRED_KEYS = Set.new(%w[name]).freeze
|
16
|
-
KNOWN_KEYS = Set.new(%w[name version_requirement]).freeze
|
16
|
+
KNOWN_KEYS = Set.new(%w[name resolve version_requirement]).freeze
|
17
17
|
|
18
|
-
attr_reader :full_name, :name, :semantic_version, :type
|
18
|
+
attr_reader :full_name, :name, :resolve, :semantic_version, :type, :version_requirement
|
19
19
|
|
20
20
|
def initialize(init_hash)
|
21
|
+
@resolve = init_hash.key?('resolve') ? init_hash['resolve'] : true
|
21
22
|
@full_name, @name = parse_name(init_hash['name'])
|
22
23
|
@version_requirement, @semantic_version = parse_version_requirement(init_hash['version_requirement'])
|
23
24
|
@type = :forge
|
25
|
+
|
26
|
+
unless @resolve == true || @resolve == false
|
27
|
+
raise Bolt::ValidationError,
|
28
|
+
"Option 'resolve' for module spec #{@full_name} must be a Boolean"
|
29
|
+
end
|
24
30
|
end
|
25
31
|
|
26
32
|
def self.implements?(hash)
|
@@ -13,18 +13,31 @@ module Bolt
|
|
13
13
|
class GitSpec
|
14
14
|
NAME_REGEX = %r{\A(?:[a-zA-Z0-9]+[-/])?(?<name>[a-z][a-z0-9_]*)\z}.freeze
|
15
15
|
REQUIRED_KEYS = Set.new(%w[git ref]).freeze
|
16
|
+
KNOWN_KEYS = Set.new(%w[git name ref resolve]).freeze
|
16
17
|
|
17
|
-
attr_reader :git, :ref, :type
|
18
|
+
attr_reader :git, :ref, :resolve, :type
|
18
19
|
|
19
20
|
def initialize(init_hash)
|
21
|
+
@resolve = init_hash.key?('resolve') ? init_hash['resolve'] : true
|
20
22
|
@name = parse_name(init_hash['name'])
|
21
23
|
@git, @repo = parse_git(init_hash['git'])
|
22
24
|
@ref = init_hash['ref']
|
23
25
|
@type = :git
|
26
|
+
|
27
|
+
if @name.nil? && @resolve == false
|
28
|
+
raise Bolt::ValidationError,
|
29
|
+
"Missing name for Git module specification: #{@git}. Git module specifications "\
|
30
|
+
"must include a 'name' key when 'resolve' is false."
|
31
|
+
end
|
32
|
+
|
33
|
+
unless @resolve == true || @resolve == false
|
34
|
+
raise Bolt::ValidationError,
|
35
|
+
"Option 'resolve' for module spec #{@git} must be a Boolean"
|
36
|
+
end
|
24
37
|
end
|
25
38
|
|
26
39
|
def self.implements?(hash)
|
27
|
-
|
40
|
+
KNOWN_KEYS.superset?(hash.keys.to_set) && REQUIRED_KEYS.subset?(hash.keys.to_set)
|
28
41
|
end
|
29
42
|
|
30
43
|
# Parses the name into owner and name segments, and formats the full
|
@@ -47,6 +60,8 @@ module Bolt
|
|
47
60
|
# Gets the repo from the git URL.
|
48
61
|
#
|
49
62
|
private def parse_git(git)
|
63
|
+
return [git, nil] unless @resolve
|
64
|
+
|
50
65
|
repo = if git.start_with?('git@github.com:')
|
51
66
|
git.split('git@github.com:').last.split('.git').first
|
52
67
|
elsif git.start_with?('https://github.com')
|
data/lib/bolt/outputter/human.rb
CHANGED
@@ -32,8 +32,8 @@ module Bolt
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def start_spin
|
35
|
-
return unless @spin && @stream.isatty
|
36
|
-
@
|
35
|
+
return unless @spin && @stream.isatty && !@spinning
|
36
|
+
@spinning = true
|
37
37
|
@spin_thread = Thread.new do
|
38
38
|
loop do
|
39
39
|
sleep(0.1)
|
@@ -43,9 +43,9 @@ module Bolt
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def stop_spin
|
46
|
-
return unless @spin && @stream.isatty
|
46
|
+
return unless @spin && @stream.isatty && @spinning
|
47
|
+
@spinning = false
|
47
48
|
@spin_thread.terminate
|
48
|
-
@spin = false
|
49
49
|
@stream.print("\b")
|
50
50
|
end
|
51
51
|
|
@@ -81,6 +81,10 @@ module Bolt
|
|
81
81
|
print_plan_start(event)
|
82
82
|
when :plan_finish
|
83
83
|
print_plan_finish(event)
|
84
|
+
when :start_spin
|
85
|
+
start_spin
|
86
|
+
when :stop_spin
|
87
|
+
stop_spin
|
84
88
|
end
|
85
89
|
end
|
86
90
|
end
|
@@ -63,12 +63,12 @@ module Bolt
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def start_spin
|
66
|
-
return unless @spin && @stream.isatty
|
67
|
-
@
|
66
|
+
return unless @spin && @stream.isatty && !@spinning
|
67
|
+
@spinning = true
|
68
68
|
@spin_thread = Thread.new do
|
69
69
|
loop do
|
70
|
-
@stream.print(colorize(:rainbow, @pinwheel.rotate!.first + "\b"))
|
71
70
|
sleep(0.1)
|
71
|
+
@stream.print(colorize(:rainbow, @pinwheel.rotate!.first + "\b"))
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
data/lib/bolt/pal.rb
CHANGED
@@ -153,8 +153,10 @@ module Bolt
|
|
153
153
|
Dir.children(path).select { |name| Puppet::Module.is_module_directory?(name, path) }
|
154
154
|
end
|
155
155
|
if modules.include?(project.name)
|
156
|
-
Bolt::Logger.warn_once(
|
157
|
-
|
156
|
+
Bolt::Logger.warn_once(
|
157
|
+
"project_shadows_module",
|
158
|
+
"The project '#{project.name}' shadows an existing module of the same name"
|
159
|
+
)
|
158
160
|
end
|
159
161
|
end
|
160
162
|
|
@@ -357,19 +359,52 @@ module Bolt
|
|
357
359
|
Bolt::Task.from_task_signature(task)
|
358
360
|
end
|
359
361
|
|
362
|
+
def list_plans_with_cache(filter_content: false)
|
363
|
+
# Don't filter content yet, so that if users update their plan filters
|
364
|
+
# we don't need to refresh the cache
|
365
|
+
plan_names = list_plans(filter_content: false).map(&:first)
|
366
|
+
plan_cache = if @project
|
367
|
+
Bolt::Util.read_optional_json_file(@project.plan_cache_file, 'Plan cache file')
|
368
|
+
else
|
369
|
+
{}
|
370
|
+
end
|
371
|
+
updated = false
|
372
|
+
|
373
|
+
plan_list = plan_names.each_with_object([]) do |plan_name, list|
|
374
|
+
info = plan_cache[plan_name] || get_plan_info(plan_name, with_mtime: true)
|
375
|
+
|
376
|
+
# If the plan is a 'local' plan (in the project itself, or the
|
377
|
+
# modules/ directory) then verify it hasn't been updated since we
|
378
|
+
# cached it. If it has been updated, refresh the cache and use the
|
379
|
+
# new data.
|
380
|
+
if info['file'] &&
|
381
|
+
(File.mtime(info.dig('file', 'path')) <=> info.dig('file', 'mtime')) != 0
|
382
|
+
info = get_plan_info(plan_name, with_mtime: true)
|
383
|
+
updated = true
|
384
|
+
plan_cache[plan_name] = info
|
385
|
+
end
|
386
|
+
|
387
|
+
list << [plan_name] unless info['private']
|
388
|
+
end
|
389
|
+
|
390
|
+
File.write(@project.plan_cache_file, plan_cache.to_json) if updated
|
391
|
+
|
392
|
+
filter_content ? filter_content(plan_list, @project&.plans) : plan_list
|
393
|
+
end
|
394
|
+
|
360
395
|
def list_plans(filter_content: false)
|
361
396
|
in_bolt_compiler do |compiler|
|
362
397
|
errors = []
|
363
398
|
plans = compiler.list_plans(nil, errors).map { |plan| [plan.name] }.sort
|
364
399
|
errors.each do |error|
|
365
|
-
|
400
|
+
Bolt::Logger.warn("plan_load_error", error.details['original_error'])
|
366
401
|
end
|
367
402
|
|
368
403
|
filter_content ? filter_content(plans, @project&.plans) : plans
|
369
404
|
end
|
370
405
|
end
|
371
406
|
|
372
|
-
def get_plan_info(plan_name)
|
407
|
+
def get_plan_info(plan_name, with_mtime: false)
|
373
408
|
plan_sig = in_bolt_compiler do |compiler|
|
374
409
|
compiler.plan_signature(plan_name)
|
375
410
|
end
|
@@ -412,16 +447,28 @@ module Bolt
|
|
412
447
|
params[name]['default_value'] = defaults[name] if defaults.key?(name)
|
413
448
|
params[name]['description'] = param.text unless param.text.empty?
|
414
449
|
else
|
415
|
-
|
450
|
+
Bolt::Logger.warn(
|
451
|
+
"missing_plan_parameter",
|
452
|
+
"The documented parameter '#{name}' does not exist in plan signature"
|
453
|
+
)
|
416
454
|
end
|
417
455
|
end
|
418
456
|
|
419
|
-
|
420
|
-
|
457
|
+
privie = plan.tag(:private)&.text
|
458
|
+
unless privie.nil? || %w[true false].include?(privie.downcase)
|
459
|
+
msg = "Plan #{plan_name} key 'private' must be a boolean, received: #{privie}"
|
460
|
+
raise Bolt::Error.new(msg, 'bolt/invalid-plan')
|
461
|
+
end
|
462
|
+
|
463
|
+
pp_info = {
|
464
|
+
'name' => plan_name,
|
421
465
|
'description' => description,
|
422
|
-
'parameters'
|
423
|
-
'module'
|
466
|
+
'parameters' => parameters,
|
467
|
+
'module' => mod
|
424
468
|
}
|
469
|
+
pp_info.merge!({ 'private' => privie&.downcase == 'true' }) unless privie.nil?
|
470
|
+
pp_info.merge!(get_plan_mtime(plan.file)) if with_mtime
|
471
|
+
pp_info
|
425
472
|
|
426
473
|
# If it's a YAML plan, fall back to limited data
|
427
474
|
else
|
@@ -444,12 +491,32 @@ module Bolt
|
|
444
491
|
params[name]['default_value'] = param.value unless param.value.nil?
|
445
492
|
params[name]['description'] = param.description if param.description
|
446
493
|
end
|
447
|
-
|
448
|
-
|
494
|
+
|
495
|
+
yaml_info = {
|
496
|
+
'name' => plan_name,
|
449
497
|
'description' => plan.description,
|
450
|
-
'parameters'
|
451
|
-
'module'
|
498
|
+
'parameters' => parameters,
|
499
|
+
'module' => mod
|
452
500
|
}
|
501
|
+
yaml_info.merge!({ 'private' => plan.private }) unless plan.private.nil?
|
502
|
+
yaml_info.merge!(get_plan_mtime(yaml_path)) if with_mtime
|
503
|
+
yaml_info
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
def get_plan_mtime(path)
|
508
|
+
# If the plan is from the project modules/ directory, or is in the
|
509
|
+
# project itself, include the last mtime of the file so we can compare
|
510
|
+
# if the plan has been updated since it was cached.
|
511
|
+
if @project &&
|
512
|
+
File.exist?(path) &&
|
513
|
+
(path.include?(File.join(@project.path, 'modules')) ||
|
514
|
+
path.include?(@project.plans_path.to_s))
|
515
|
+
|
516
|
+
{ 'file' => { 'mtime' => File.mtime(path),
|
517
|
+
'path' => path } }
|
518
|
+
else
|
519
|
+
{}
|
453
520
|
end
|
454
521
|
end
|
455
522
|
|
@@ -490,16 +557,28 @@ module Bolt
|
|
490
557
|
end
|
491
558
|
end
|
492
559
|
|
493
|
-
def generate_types
|
560
|
+
def generate_types(cache: false)
|
494
561
|
require 'puppet/face/generate'
|
495
562
|
in_bolt_compiler do
|
496
563
|
generator = Puppet::Generate::Type
|
497
564
|
inputs = generator.find_inputs(:pcore)
|
498
565
|
FileUtils.mkdir_p(@resource_types)
|
566
|
+
cache_plan_info if @project && cache
|
499
567
|
generator.generate(inputs, @resource_types, true)
|
500
568
|
end
|
501
569
|
end
|
502
570
|
|
571
|
+
def cache_plan_info
|
572
|
+
# plan_name is an array here
|
573
|
+
plans_info = list_plans(filter_content: false).map do |plan_name,|
|
574
|
+
data = get_plan_info(plan_name, with_mtime: true)
|
575
|
+
{ plan_name => data }
|
576
|
+
end.reduce({}, :merge)
|
577
|
+
|
578
|
+
FileUtils.touch(@project.plan_cache_file)
|
579
|
+
File.write(@project.plan_cache_file, plans_info.to_json)
|
580
|
+
end
|
581
|
+
|
503
582
|
def run_task(task_name, targets, params, executor, inventory, description = nil)
|
504
583
|
in_task_compiler(executor, inventory) do |compiler|
|
505
584
|
params = params.merge('_bolt_api_call' => true, '_catch_errors' => true)
|
data/lib/bolt/pal/yaml_plan.rb
CHANGED
@@ -6,10 +6,10 @@ require 'bolt/pal/yaml_plan/step'
|
|
6
6
|
module Bolt
|
7
7
|
class PAL
|
8
8
|
class YamlPlan
|
9
|
-
PLAN_KEYS = Set['parameters', 'steps', 'return', 'version', 'description']
|
9
|
+
PLAN_KEYS = Set['parameters', 'private', 'steps', 'return', 'version', 'description']
|
10
10
|
VAR_NAME_PATTERN = /\A[a-z_][a-z0-9_]*\z/.freeze
|
11
11
|
|
12
|
-
attr_reader :name, :parameters, :steps, :return, :description
|
12
|
+
attr_reader :name, :parameters, :private, :steps, :return, :description
|
13
13
|
|
14
14
|
def initialize(name, plan)
|
15
15
|
# Top-level plan keys aren't allowed to be Puppet code, so force them
|
@@ -30,6 +30,12 @@ module Bolt
|
|
30
30
|
Parameter.new(param, definition)
|
31
31
|
end.freeze
|
32
32
|
|
33
|
+
@private = plan['private']
|
34
|
+
unless @private.nil? || @private.is_a?(TrueClass) || @private.is_a?(FalseClass)
|
35
|
+
msg = "Plan #{@name} key 'private' must be a boolean, received: #{@private.inspect}"
|
36
|
+
raise Bolt::Error.new(msg, "bolt/invalid-plan")
|
37
|
+
end
|
38
|
+
|
33
39
|
# Validate top level plan keys
|
34
40
|
top_level_keys = plan.keys.to_set
|
35
41
|
unless PLAN_KEYS.superset?(top_level_keys)
|
@@ -157,13 +157,13 @@ module Bolt
|
|
157
157
|
if plan.steps.any? { |step| step.body.key?('target') }
|
158
158
|
msg = "The 'target' parameter for YAML plan steps is deprecated and will be removed "\
|
159
159
|
"in a future version of Bolt. Use the 'targets' parameter instead."
|
160
|
-
Bolt::Logger.
|
160
|
+
Bolt::Logger.deprecate("yaml_plan_target", msg)
|
161
161
|
end
|
162
162
|
|
163
163
|
if plan.steps.any? { |step| step.body.key?('source') }
|
164
164
|
msg = "The 'source' parameter for YAML plan upload steps is deprecated and will be removed "\
|
165
165
|
"in a future version of Bolt. Use the 'upload' parameter instead."
|
166
|
-
Bolt::Logger.
|
166
|
+
Bolt::Logger.deprecate("yaml_plan_source", msg)
|
167
167
|
end
|
168
168
|
|
169
169
|
plan_result = closure_scope.with_local_scope(args_hash) do |scope|
|
@@ -30,6 +30,7 @@ module Bolt
|
|
30
30
|
plan_string = String.new('')
|
31
31
|
plan_string << "# #{plan_object.description}\n" if plan_object.description
|
32
32
|
plan_string << "# WARNING: This is an autogenerated plan. It may not behave as expected.\n"
|
33
|
+
plan_string << "# @private #{plan_object.private}\n" unless plan_object.private.nil?
|
33
34
|
plan_string << "#{param_descriptions}\n" unless param_descriptions.empty?
|
34
35
|
|
35
36
|
plan_string << "plan #{plan_object.name}("
|
data/lib/bolt/plugin.rb
CHANGED
@@ -139,7 +139,7 @@ module Bolt
|
|
139
139
|
plugins
|
140
140
|
end
|
141
141
|
|
142
|
-
RUBY_PLUGINS = %w[task prompt env_var puppetdb].freeze
|
142
|
+
RUBY_PLUGINS = %w[task prompt env_var puppetdb puppet_connect_data].freeze
|
143
143
|
BUILTIN_PLUGINS = %w[task terraform pkcs7 prompt vault aws_inventory puppetdb azure_inventory
|
144
144
|
yaml env_var gcloud_inventory].freeze
|
145
145
|
DEFAULT_PLUGIN_HOOKS = { 'puppet_library' => { 'plugin' => 'puppet_agent', 'stop_service' => true } }.freeze
|
@@ -297,7 +297,7 @@ module Bolt
|
|
297
297
|
def resolve_single_reference(reference)
|
298
298
|
plugin_cache = if cache?(reference)
|
299
299
|
cache = Bolt::Plugin::Cache.new(reference,
|
300
|
-
@config.project.
|
300
|
+
@config.project.plugin_cache_file,
|
301
301
|
@config.plugin_cache)
|
302
302
|
entry = cache.read_and_clean_cache
|
303
303
|
return entry unless entry.nil?
|
data/lib/bolt/plugin/cache.rb
CHANGED
@@ -7,11 +7,11 @@ require 'bolt/util'
|
|
7
7
|
module Bolt
|
8
8
|
class Plugin
|
9
9
|
class Cache
|
10
|
-
attr_reader :reference, :
|
10
|
+
attr_reader :reference, :plugin_cache_file, :default_config, :id
|
11
11
|
|
12
|
-
def initialize(reference,
|
12
|
+
def initialize(reference, plugin_cache_file, default_config)
|
13
13
|
@reference = reference
|
14
|
-
@
|
14
|
+
@plugin_cache_file = plugin_cache_file
|
15
15
|
@default_config = default_config
|
16
16
|
end
|
17
17
|
|
@@ -32,21 +32,21 @@ module Bolt
|
|
32
32
|
unmodified = false if expired
|
33
33
|
expired
|
34
34
|
end
|
35
|
-
File.write(
|
35
|
+
File.write(plugin_cache_file, cache.to_json) unless cache.empty? || unmodified
|
36
36
|
|
37
37
|
cache.dig(id, 'result')
|
38
38
|
end
|
39
39
|
|
40
40
|
private def cache
|
41
|
-
@cache ||= Bolt::Util.read_optional_json_file(@
|
41
|
+
@cache ||= Bolt::Util.read_optional_json_file(@plugin_cache_file, 'cache')
|
42
42
|
end
|
43
43
|
|
44
44
|
def write_cache(result)
|
45
45
|
cache.merge!({ id => { 'result' => result,
|
46
46
|
'mtime' => Time.now,
|
47
47
|
'ttl' => ttl } })
|
48
|
-
FileUtils.touch(
|
49
|
-
File.write(
|
48
|
+
FileUtils.touch(plugin_cache_file)
|
49
|
+
File.write(plugin_cache_file, cache.to_json)
|
50
50
|
end
|
51
51
|
|
52
52
|
def validate
|
data/lib/bolt/plugin/module.rb
CHANGED
@@ -187,7 +187,7 @@ module Bolt
|
|
187
187
|
if params.key?('private-key') || params.key?('public-key')
|
188
188
|
message = "pkcs7 keys 'private-key' and 'public-key' have been deprecated and will be "\
|
189
189
|
"removed in a future version of Bolt; use 'private_key' and 'public_key' instead."
|
190
|
-
Bolt::Logger.
|
190
|
+
Bolt::Logger.deprecate("pkcs7_params", message)
|
191
191
|
end
|
192
192
|
|
193
193
|
params['private_key'] = params.delete('private-key') if params.key?('private-key')
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Bolt
|
4
|
+
class Plugin
|
5
|
+
class PuppetConnectData
|
6
|
+
def initialize(context:, **_opts)
|
7
|
+
puppet_connect_data_yaml_path = File.join(context.boltdir, 'puppet_connect_data.yaml')
|
8
|
+
@data = Bolt::Util.read_optional_yaml_hash(
|
9
|
+
puppet_connect_data_yaml_path,
|
10
|
+
'puppet_connect_data.yaml'
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def name
|
15
|
+
'puppet_connect_data'
|
16
|
+
end
|
17
|
+
|
18
|
+
def hooks
|
19
|
+
%i[resolve_reference validate_resolve_reference]
|
20
|
+
end
|
21
|
+
|
22
|
+
def resolve_reference(opts)
|
23
|
+
key = opts['key']
|
24
|
+
@data[key]
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate_resolve_reference(opts)
|
28
|
+
unless opts['key']
|
29
|
+
raise Bolt::ValidationError,
|
30
|
+
"puppet_connect_data plugin requires that 'key' be specified"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/bolt/plugin/puppetdb.rb
CHANGED
@@ -31,7 +31,7 @@ module Bolt
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def warn_missing_fact(certname, fact)
|
34
|
-
|
34
|
+
Bolt::Logger.warn("puppetdb_missing_fact", "Could not find fact #{fact} for node #{certname}")
|
35
35
|
end
|
36
36
|
|
37
37
|
def fact_path(raw_fact)
|