bolt 2.19.0 → 2.24.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.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
 - data/Puppetfile +3 -1
 - data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +123 -0
 - data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +6 -0
 - data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +12 -6
 - data/bolt-modules/dir/lib/puppet/functions/dir/children.rb +35 -0
 - data/bolt-modules/out/lib/puppet/functions/out/message.rb +1 -1
 - data/exe/bolt +1 -0
 - data/guides/inventory.txt +19 -0
 - data/guides/project.txt +22 -0
 - data/lib/bolt/analytics.rb +5 -5
 - data/lib/bolt/applicator.rb +4 -3
 - data/lib/bolt/bolt_option_parser.rb +100 -27
 - data/lib/bolt/catalog.rb +12 -3
 - data/lib/bolt/cli.rb +356 -156
 - data/lib/bolt/config.rb +2 -2
 - data/lib/bolt/config/options.rb +18 -4
 - data/lib/bolt/executor.rb +30 -7
 - data/lib/bolt/inventory/group.rb +6 -5
 - data/lib/bolt/inventory/inventory.rb +4 -3
 - data/lib/bolt/logger.rb +3 -4
 - data/lib/bolt/module.rb +2 -1
 - data/lib/bolt/outputter.rb +56 -0
 - data/lib/bolt/outputter/human.rb +10 -9
 - data/lib/bolt/outputter/json.rb +11 -4
 - data/lib/bolt/outputter/logger.rb +2 -2
 - data/lib/bolt/outputter/rainbow.rb +18 -2
 - data/lib/bolt/pal.rb +13 -11
 - data/lib/bolt/pal/yaml_plan/evaluator.rb +22 -1
 - data/lib/bolt/pal/yaml_plan/step.rb +24 -2
 - data/lib/bolt/pal/yaml_plan/step/download.rb +38 -0
 - data/lib/bolt/pal/yaml_plan/step/message.rb +30 -0
 - data/lib/bolt/pal/yaml_plan/step/upload.rb +3 -3
 - data/lib/bolt/pal/yaml_plan/transpiler.rb +11 -3
 - data/lib/bolt/plugin/prompt.rb +3 -3
 - data/lib/bolt/plugin/puppetdb.rb +3 -2
 - data/lib/bolt/project.rb +7 -4
 - data/lib/bolt/project_migrate.rb +138 -0
 - data/lib/bolt/puppetdb/client.rb +2 -0
 - data/lib/bolt/puppetdb/config.rb +16 -0
 - data/lib/bolt/result.rb +7 -0
 - data/lib/bolt/shell/bash.rb +31 -11
 - data/lib/bolt/shell/powershell.rb +10 -4
 - data/lib/bolt/transport/base.rb +24 -0
 - data/lib/bolt/transport/docker.rb +8 -0
 - data/lib/bolt/transport/docker/connection.rb +28 -10
 - data/lib/bolt/transport/local/connection.rb +15 -2
 - data/lib/bolt/transport/orch.rb +15 -3
 - data/lib/bolt/transport/simple.rb +6 -0
 - data/lib/bolt/transport/ssh/connection.rb +13 -5
 - data/lib/bolt/transport/ssh/exec_connection.rb +24 -3
 - data/lib/bolt/transport/winrm/connection.rb +125 -15
 - data/lib/bolt/util.rb +27 -12
 - data/lib/bolt/util/puppet_log_level.rb +4 -3
 - data/lib/bolt/version.rb +1 -1
 - data/lib/bolt_server/base_config.rb +1 -1
 - data/lib/bolt_server/pe/pal.rb +1 -1
 - data/lib/bolt_server/transport_app.rb +79 -2
 - data/lib/bolt_spec/bolt_context.rb +7 -2
 - data/lib/bolt_spec/plans.rb +16 -3
 - data/lib/bolt_spec/plans/action_stubs.rb +3 -2
 - data/lib/bolt_spec/plans/action_stubs/download_stub.rb +66 -0
 - data/lib/bolt_spec/plans/mock_executor.rb +14 -1
 - data/lib/bolt_spec/run.rb +22 -0
 - data/libexec/apply_catalog.rb +2 -2
 - data/libexec/bolt_catalog +4 -3
 - data/libexec/custom_facts.rb +1 -1
 - data/libexec/query_resources.rb +1 -1
 - data/modules/secure_env_vars/plans/init.pp +20 -0
 - metadata +11 -2
 
    
        data/lib/bolt/config.rb
    CHANGED
    
    | 
         @@ -204,7 +204,7 @@ module Bolt 
     | 
|
| 
       204 
204 
     | 
    
         
             
                    'compile-concurrency' => Etc.nprocessors,
         
     | 
| 
       205 
205 
     | 
    
         
             
                    'concurrency'         => default_concurrency,
         
     | 
| 
       206 
206 
     | 
    
         
             
                    'format'              => 'human',
         
     | 
| 
       207 
     | 
    
         
            -
                    'log'                 => { 'console' => {} },
         
     | 
| 
      
 207 
     | 
    
         
            +
                    'log'                 => { 'console' => {}, 'bolt-debug.log' => { 'level' => 'debug', 'append' => false } },
         
     | 
| 
       208 
208 
     | 
    
         
             
                    'plugin_hooks'        => {},
         
     | 
| 
       209 
209 
     | 
    
         
             
                    'plugins'             => {},
         
     | 
| 
       210 
210 
     | 
    
         
             
                    'puppetdb'            => {},
         
     | 
| 
         @@ -499,7 +499,7 @@ module Bolt 
     | 
|
| 
       499 
499 
     | 
    
         
             
                end
         
     | 
| 
       500 
500 
     | 
    
         | 
| 
       501 
501 
     | 
    
         
             
                def matching_paths(paths)
         
     | 
| 
       502 
     | 
    
         
            -
                   
     | 
| 
      
 502 
     | 
    
         
            +
                  Array(paths).map { |p| Dir.glob([p, casefold(p)]) }.flatten.uniq.reject { |p| Array(paths).include?(p) }
         
     | 
| 
       503 
503 
     | 
    
         
             
                end
         
     | 
| 
       504 
504 
     | 
    
         | 
| 
       505 
505 
     | 
    
         
             
                private def casefold(path)
         
     | 
    
        data/lib/bolt/config/options.rb
    CHANGED
    
    | 
         @@ -186,8 +186,8 @@ module Bolt 
     | 
|
| 
       186 
186 
     | 
    
         
             
                            "level" => {
         
     | 
| 
       187 
187 
     | 
    
         
             
                              description: "The type of information to log.",
         
     | 
| 
       188 
188 
     | 
    
         
             
                              type: String,
         
     | 
| 
       189 
     | 
    
         
            -
                              enum: %w[debug error info  
     | 
| 
       190 
     | 
    
         
            -
                              _default: "warn 
     | 
| 
      
 189 
     | 
    
         
            +
                              enum: %w[trace debug error info warn fatal any],
         
     | 
| 
      
 190 
     | 
    
         
            +
                              _default: "warn"
         
     | 
| 
       191 
191 
     | 
    
         
             
                            }
         
     | 
| 
       192 
192 
     | 
    
         
             
                          }
         
     | 
| 
       193 
193 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -204,8 +204,8 @@ module Bolt 
     | 
|
| 
       204 
204 
     | 
    
         
             
                          "level" => {
         
     | 
| 
       205 
205 
     | 
    
         
             
                            description: "The type of information to log.",
         
     | 
| 
       206 
206 
     | 
    
         
             
                            type: String,
         
     | 
| 
       207 
     | 
    
         
            -
                            enum: %w[debug error info  
     | 
| 
       208 
     | 
    
         
            -
                            _default: "warn 
     | 
| 
      
 207 
     | 
    
         
            +
                            enum: %w[trace debug error info warn fatal any],
         
     | 
| 
      
 208 
     | 
    
         
            +
                            _default: "warn"
         
     | 
| 
       209 
209 
     | 
    
         
             
                          }
         
     | 
| 
       210 
210 
     | 
    
         
             
                        }
         
     | 
| 
       211 
211 
     | 
    
         
             
                      },
         
     | 
| 
         @@ -275,11 +275,25 @@ module Bolt 
     | 
|
| 
       275 
275 
     | 
    
         
             
                          type: String,
         
     | 
| 
       276 
276 
     | 
    
         
             
                          _example: "/etc/puppetlabs/puppet/ssl/certs/my-host.example.com.pem"
         
     | 
| 
       277 
277 
     | 
    
         
             
                        },
         
     | 
| 
      
 278 
     | 
    
         
            +
                        "connect_timeout" => {
         
     | 
| 
      
 279 
     | 
    
         
            +
                          description: "How long to wait in seconds when establishing connections with PuppetDB.",
         
     | 
| 
      
 280 
     | 
    
         
            +
                          type: Integer,
         
     | 
| 
      
 281 
     | 
    
         
            +
                          minimum: 1,
         
     | 
| 
      
 282 
     | 
    
         
            +
                          _default: 60,
         
     | 
| 
      
 283 
     | 
    
         
            +
                          _example: 120
         
     | 
| 
      
 284 
     | 
    
         
            +
                        },
         
     | 
| 
       278 
285 
     | 
    
         
             
                        "key" => {
         
     | 
| 
       279 
286 
     | 
    
         
             
                          description: "The private key for the certificate.",
         
     | 
| 
       280 
287 
     | 
    
         
             
                          type: String,
         
     | 
| 
       281 
288 
     | 
    
         
             
                          _example: "/etc/puppetlabs/puppet/ssl/private_keys/my-host.example.com.pem"
         
     | 
| 
       282 
289 
     | 
    
         
             
                        },
         
     | 
| 
      
 290 
     | 
    
         
            +
                        "read_timeout" => {
         
     | 
| 
      
 291 
     | 
    
         
            +
                          description: "How long to wait in seconds for a response from PuppetDB.",
         
     | 
| 
      
 292 
     | 
    
         
            +
                          type: Integer,
         
     | 
| 
      
 293 
     | 
    
         
            +
                          minimum: 1,
         
     | 
| 
      
 294 
     | 
    
         
            +
                          _default: 60,
         
     | 
| 
      
 295 
     | 
    
         
            +
                          _example: 120
         
     | 
| 
      
 296 
     | 
    
         
            +
                        },
         
     | 
| 
       283 
297 
     | 
    
         
             
                        "server_urls" => {
         
     | 
| 
       284 
298 
     | 
    
         
             
                          description: "An array containing the PuppetDB host to connect to. Include the protocol `https` "\
         
     | 
| 
       285 
299 
     | 
    
         
             
                                       "and the port, which is usually `8081`. For example, "\
         
     | 
    
        data/lib/bolt/executor.rb
    CHANGED
    
    | 
         @@ -56,11 +56,12 @@ module Bolt 
     | 
|
| 
       56 
56 
     | 
    
         
             
                  @reported_transports = Set.new
         
     | 
| 
       57 
57 
     | 
    
         
             
                  @subscribers = {}
         
     | 
| 
       58 
58 
     | 
    
         
             
                  @publisher = Concurrent::SingleThreadExecutor.new
         
     | 
| 
      
 59 
     | 
    
         
            +
                  @publisher.post { Thread.current[:name] = 'event-publisher' }
         
     | 
| 
       59 
60 
     | 
    
         | 
| 
       60 
61 
     | 
    
         
             
                  @noop = noop
         
     | 
| 
       61 
62 
     | 
    
         
             
                  @run_as = nil
         
     | 
| 
       62 
63 
     | 
    
         
             
                  @pool = if concurrency > 0
         
     | 
| 
       63 
     | 
    
         
            -
                            Concurrent::ThreadPoolExecutor.new(max_threads: concurrency)
         
     | 
| 
      
 64 
     | 
    
         
            +
                            Concurrent::ThreadPoolExecutor.new(name: 'exec', max_threads: concurrency)
         
     | 
| 
       64 
65 
     | 
    
         
             
                          else
         
     | 
| 
       65 
66 
     | 
    
         
             
                            Concurrent.global_immediate_executor
         
     | 
| 
       66 
67 
     | 
    
         
             
                          end
         
     | 
| 
         @@ -125,6 +126,7 @@ module Bolt 
     | 
|
| 
       125 
126 
     | 
    
         
             
                      # Pass this argument through to avoid retaining a reference to a
         
     | 
| 
       126 
127 
     | 
    
         
             
                      # local variable that will change on the next iteration of the loop.
         
     | 
| 
       127 
128 
     | 
    
         
             
                      @pool.post(batch_promises) do |result_promises|
         
     | 
| 
      
 129 
     | 
    
         
            +
                        Thread.current[:name] ||= Thread.current.name
         
     | 
| 
       128 
130 
     | 
    
         
             
                        results = yield transport, batch
         
     | 
| 
       129 
131 
     | 
    
         
             
                        Array(results).each do |result|
         
     | 
| 
       130 
132 
     | 
    
         
             
                          result_promises[result.target].set(result)
         
     | 
| 
         @@ -241,7 +243,7 @@ module Bolt 
     | 
|
| 
       241 
243 
     | 
    
         | 
| 
       242 
244 
     | 
    
         
             
                  @analytics&.event('Plan', 'yaml', plan_steps: steps, return_type: return_type)
         
     | 
| 
       243 
245 
     | 
    
         
             
                rescue StandardError => e
         
     | 
| 
       244 
     | 
    
         
            -
                  @logger. 
     | 
| 
      
 246 
     | 
    
         
            +
                  @logger.trace { "Failed to submit analytics event: #{e.message}" }
         
     | 
| 
       245 
247 
     | 
    
         
             
                end
         
     | 
| 
       246 
248 
     | 
    
         | 
| 
       247 
249 
     | 
    
         
             
                def with_node_logging(description, batch)
         
     | 
| 
         @@ -320,6 +322,27 @@ module Bolt 
     | 
|
| 
       320 
322 
     | 
    
         
             
                  end
         
     | 
| 
       321 
323 
     | 
    
         
             
                end
         
     | 
| 
       322 
324 
     | 
    
         | 
| 
      
 325 
     | 
    
         
            +
                def download_file(targets, source, destination, options = {})
         
     | 
| 
      
 326 
     | 
    
         
            +
                  description = options.fetch(:description, "file download from #{source} to #{destination}")
         
     | 
| 
      
 327 
     | 
    
         
            +
             
     | 
| 
      
 328 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 329 
     | 
    
         
            +
                    FileUtils.mkdir_p(destination)
         
     | 
| 
      
 330 
     | 
    
         
            +
                  rescue Errno::EEXIST => e
         
     | 
| 
      
 331 
     | 
    
         
            +
                    message = "#{e.message}; unable to create destination directory #{destination}"
         
     | 
| 
      
 332 
     | 
    
         
            +
                    raise Bolt::Error.new(message, 'bolt/file-exist-error')
         
     | 
| 
      
 333 
     | 
    
         
            +
                  end
         
     | 
| 
      
 334 
     | 
    
         
            +
             
     | 
| 
      
 335 
     | 
    
         
            +
                  log_action(description, targets) do
         
     | 
| 
      
 336 
     | 
    
         
            +
                    options[:run_as] = run_as if run_as && !options.key?(:run_as)
         
     | 
| 
      
 337 
     | 
    
         
            +
             
     | 
| 
      
 338 
     | 
    
         
            +
                    batch_execute(targets) do |transport, batch|
         
     | 
| 
      
 339 
     | 
    
         
            +
                      with_node_logging("Downloading file #{source} to #{destination}", batch) do
         
     | 
| 
      
 340 
     | 
    
         
            +
                        transport.batch_download(batch, source, destination, options, &method(:publish_event))
         
     | 
| 
      
 341 
     | 
    
         
            +
                      end
         
     | 
| 
      
 342 
     | 
    
         
            +
                    end
         
     | 
| 
      
 343 
     | 
    
         
            +
                  end
         
     | 
| 
      
 344 
     | 
    
         
            +
                end
         
     | 
| 
      
 345 
     | 
    
         
            +
             
     | 
| 
       323 
346 
     | 
    
         
             
                def run_plan(scope, plan, params)
         
     | 
| 
       324 
347 
     | 
    
         
             
                  plan.call_by_name_with_scope(scope, params, true)
         
     | 
| 
       325 
348 
     | 
    
         
             
                end
         
     | 
| 
         @@ -360,19 +383,19 @@ module Bolt 
     | 
|
| 
       360 
383 
     | 
    
         
             
                end
         
     | 
| 
       361 
384 
     | 
    
         | 
| 
       362 
385 
     | 
    
         
             
                def prompt(prompt, options)
         
     | 
| 
       363 
     | 
    
         
            -
                  unless  
     | 
| 
      
 386 
     | 
    
         
            +
                  unless $stdin.tty?
         
     | 
| 
       364 
387 
     | 
    
         
             
                    raise Bolt::Error.new('STDIN is not a tty, unable to prompt', 'bolt/no-tty-error')
         
     | 
| 
       365 
388 
     | 
    
         
             
                  end
         
     | 
| 
       366 
389 
     | 
    
         | 
| 
       367 
     | 
    
         
            -
                   
     | 
| 
      
 390 
     | 
    
         
            +
                  $stderr.print("#{prompt}: ")
         
     | 
| 
       368 
391 
     | 
    
         | 
| 
       369 
392 
     | 
    
         
             
                  value = if options[:sensitive]
         
     | 
| 
       370 
     | 
    
         
            -
                             
     | 
| 
      
 393 
     | 
    
         
            +
                            $stdin.noecho(&:gets).to_s.chomp
         
     | 
| 
       371 
394 
     | 
    
         
             
                          else
         
     | 
| 
       372 
     | 
    
         
            -
                             
     | 
| 
      
 395 
     | 
    
         
            +
                            $stdin.gets.to_s.chomp
         
     | 
| 
       373 
396 
     | 
    
         
             
                          end
         
     | 
| 
       374 
397 
     | 
    
         | 
| 
       375 
     | 
    
         
            -
                   
     | 
| 
      
 398 
     | 
    
         
            +
                  $stderr.puts if options[:sensitive]
         
     | 
| 
       376 
399 
     | 
    
         | 
| 
       377 
400 
     | 
    
         
             
                  value
         
     | 
| 
       378 
401 
     | 
    
         
             
                end
         
     | 
    
        data/lib/bolt/inventory/group.rb
    CHANGED
    
    | 
         @@ -50,10 +50,11 @@ module Bolt 
     | 
|
| 
       50 
50 
     | 
    
         
             
                      # or it could be a name/alias of a target defined in another group.
         
     | 
| 
       51 
51 
     | 
    
         
             
                      # We can't tell the difference until all groups have been resolved,
         
     | 
| 
       52 
52 
     | 
    
         
             
                      # so we store the string on its own here and process it later.
         
     | 
| 
       53 
     | 
    
         
            -
                       
     | 
| 
      
 53 
     | 
    
         
            +
                      case target
         
     | 
| 
      
 54 
     | 
    
         
            +
                      when String
         
     | 
| 
       54 
55 
     | 
    
         
             
                        @string_targets << target
         
     | 
| 
       55 
56 
     | 
    
         
             
                      # Handle plugins at this level so that lookups cannot trigger recursive lookups
         
     | 
| 
       56 
     | 
    
         
            -
                       
     | 
| 
      
 57 
     | 
    
         
            +
                      when Hash
         
     | 
| 
       57 
58 
     | 
    
         
             
                        add_target_definition(target)
         
     | 
| 
       58 
59 
     | 
    
         
             
                      else
         
     | 
| 
       59 
60 
     | 
    
         
             
                        raise ValidationError.new("Target entry must be a String or Hash, not #{target.class}", @name)
         
     | 
| 
         @@ -118,7 +119,7 @@ module Bolt 
     | 
|
| 
       118 
119 
     | 
    
         
             
                    end
         
     | 
| 
       119 
120 
     | 
    
         | 
| 
       120 
121 
     | 
    
         
             
                    if contains_target?(t_name)
         
     | 
| 
       121 
     | 
    
         
            -
                      @logger. 
     | 
| 
      
 122 
     | 
    
         
            +
                      @logger.debug("Ignoring duplicate target in #{@name}: #{target}")
         
     | 
| 
       122 
123 
     | 
    
         
             
                      return
         
     | 
| 
       123 
124 
     | 
    
         
             
                    end
         
     | 
| 
       124 
125 
     | 
    
         | 
| 
         @@ -199,14 +200,14 @@ module Bolt 
     | 
|
| 
       199 
200 
     | 
    
         
             
                      # If this is an alias for an existing target, then add it to this group
         
     | 
| 
       200 
201 
     | 
    
         
             
                      elsif (canonical_name = aliases[string_target])
         
     | 
| 
       201 
202 
     | 
    
         
             
                        if contains_target?(canonical_name)
         
     | 
| 
       202 
     | 
    
         
            -
                          @logger. 
     | 
| 
      
 203 
     | 
    
         
            +
                          @logger.debug("Ignoring duplicate target in #{@name}: #{canonical_name}")
         
     | 
| 
       203 
204 
     | 
    
         
             
                        else
         
     | 
| 
       204 
205 
     | 
    
         
             
                          @unresolved_targets[canonical_name] = { 'name' => canonical_name }
         
     | 
| 
       205 
206 
     | 
    
         
             
                        end
         
     | 
| 
       206 
207 
     | 
    
         
             
                      # If it's not the name or alias of an existing target, then make a
         
     | 
| 
       207 
208 
     | 
    
         
             
                      # new target using the string as the URI
         
     | 
| 
       208 
209 
     | 
    
         
             
                      elsif contains_target?(string_target)
         
     | 
| 
       209 
     | 
    
         
            -
                        @logger. 
     | 
| 
      
 210 
     | 
    
         
            +
                        @logger.debug("Ignoring duplicate target in #{@name}: #{string_target}")
         
     | 
| 
       210 
211 
     | 
    
         
             
                      else
         
     | 
| 
       211 
212 
     | 
    
         
             
                        @unresolved_targets[string_target] = { 'uri' => string_target }
         
     | 
| 
       212 
213 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -109,11 +109,12 @@ module Bolt 
     | 
|
| 
       109 
109 
     | 
    
         
             
                  private :resolve_name
         
     | 
| 
       110 
110 
     | 
    
         | 
| 
       111 
111 
     | 
    
         
             
                  def expand_targets(targets)
         
     | 
| 
       112 
     | 
    
         
            -
                     
     | 
| 
      
 112 
     | 
    
         
            +
                    case targets
         
     | 
| 
      
 113 
     | 
    
         
            +
                    when Bolt::Target
         
     | 
| 
       113 
114 
     | 
    
         
             
                      targets
         
     | 
| 
       114 
     | 
    
         
            -
                     
     | 
| 
      
 115 
     | 
    
         
            +
                    when Array
         
     | 
| 
       115 
116 
     | 
    
         
             
                      targets.map { |tish| expand_targets(tish) }
         
     | 
| 
       116 
     | 
    
         
            -
                     
     | 
| 
      
 117 
     | 
    
         
            +
                    when String
         
     | 
| 
       117 
118 
     | 
    
         
             
                      # Expand a comma-separated list
         
     | 
| 
       118 
119 
     | 
    
         
             
                      targets.split(/[[:space:],]+/).reject(&:empty?).map do |name|
         
     | 
| 
       119 
120 
     | 
    
         
             
                        ts = resolve_name(name)
         
     | 
    
        data/lib/bolt/logger.rb
    CHANGED
    
    | 
         @@ -14,13 +14,12 @@ module Bolt 
     | 
|
| 
       14 
14 
     | 
    
         
             
                  # redefs, so skip it if it's already been initialized
         
     | 
| 
       15 
15 
     | 
    
         
             
                  return if Logging.initialized?
         
     | 
| 
       16 
16 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
                  Logging.init :debug, :info, :notice, :warn, :error, :fatal, :any
         
     | 
| 
      
 17 
     | 
    
         
            +
                  Logging.init :trace, :debug, :info, :notice, :warn, :error, :fatal, :any
         
     | 
| 
       18 
18 
     | 
    
         
             
                  @mutex = Mutex.new
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
                  Logging.color_scheme(
         
     | 
| 
       21 
21 
     | 
    
         
             
                    'bolt',
         
     | 
| 
       22 
22 
     | 
    
         
             
                    lines: {
         
     | 
| 
       23 
     | 
    
         
            -
                      notice: :green,
         
     | 
| 
       24 
23 
     | 
    
         
             
                      warn: :yellow,
         
     | 
| 
       25 
24 
     | 
    
         
             
                      error: :red,
         
     | 
| 
       26 
25 
     | 
    
         
             
                      fatal: %i[white on_red]
         
     | 
| 
         @@ -81,7 +80,7 @@ module Bolt 
     | 
|
| 
       81 
80 
     | 
    
         | 
| 
       82 
81 
     | 
    
         
             
                def self.default_layout
         
     | 
| 
       83 
82 
     | 
    
         
             
                  Logging.layouts.pattern(
         
     | 
| 
       84 
     | 
    
         
            -
                    pattern: '%d %-6l %c 
     | 
| 
      
 83 
     | 
    
         
            +
                    pattern: '%d %-6l [%T] [%c] %m\n',
         
     | 
| 
       85 
84 
     | 
    
         
             
                    date_pattern: '%Y-%m-%dT%H:%M:%S.%6N'
         
     | 
| 
       86 
85 
     | 
    
         
             
                  )
         
     | 
| 
       87 
86 
     | 
    
         
             
                end
         
     | 
| 
         @@ -91,7 +90,7 @@ module Bolt 
     | 
|
| 
       91 
90 
     | 
    
         
             
                end
         
     | 
| 
       92 
91 
     | 
    
         | 
| 
       93 
92 
     | 
    
         
             
                def self.default_file_level
         
     | 
| 
       94 
     | 
    
         
            -
                  : 
     | 
| 
      
 93 
     | 
    
         
            +
                  :warn
         
     | 
| 
       95 
94 
     | 
    
         
             
                end
         
     | 
| 
       96 
95 
     | 
    
         | 
| 
       97 
96 
     | 
    
         
             
                # Explicitly check the log level names instead of the log level number, as levels
         
     | 
    
        data/lib/bolt/module.rb
    CHANGED
    
    | 
         @@ -3,7 +3,8 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            # Is this Bolt::Pobs::Module?
         
     | 
| 
       4 
4 
     | 
    
         
             
            module Bolt
         
     | 
| 
       5 
5 
     | 
    
         
             
              class Module
         
     | 
| 
       6 
     | 
    
         
            -
                 
     | 
| 
      
 6 
     | 
    
         
            +
                CONTENT_NAME_REGEX = /\A[a-z][a-z0-9_]*(::[a-z][a-z0-9_]*)*\z/.freeze
         
     | 
| 
      
 7 
     | 
    
         
            +
                MODULE_NAME_REGEX  = /\A[a-z][a-z0-9_]*\z/.freeze
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
                def self.discover(modulepath)
         
     | 
| 
       9 
10 
     | 
    
         
             
                  modulepath.each_with_object({}) do |path, mods|
         
     | 
    
        data/lib/bolt/outputter.rb
    CHANGED
    
    | 
         @@ -21,6 +21,62 @@ module Bolt 
     | 
|
| 
       21 
21 
     | 
    
         
             
                  @trace = trace
         
     | 
| 
       22 
22 
     | 
    
         
             
                  @stream = stream
         
     | 
| 
       23 
23 
     | 
    
         
             
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def indent(indent, string)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  indent = ' ' * indent
         
     | 
| 
      
 27 
     | 
    
         
            +
                  string.gsub(/^/, indent.to_s)
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                def print_message_event(event)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  print_message(stringify(event[:message]))
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def print_message
         
     | 
| 
      
 35 
     | 
    
         
            +
                  raise NotImplementedError, "print_message() must be implemented by the outputter class"
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                def stringify(message)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  formatted = format_message(message)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  if formatted.is_a?(Hash) || formatted.is_a?(Array)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    ::JSON.pretty_generate(formatted)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  else
         
     | 
| 
      
 43 
     | 
    
         
            +
                    formatted
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                def format_message(message)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  case message
         
     | 
| 
      
 49 
     | 
    
         
            +
                  when Array
         
     | 
| 
      
 50 
     | 
    
         
            +
                    message.map { |item| format_message(item) }
         
     | 
| 
      
 51 
     | 
    
         
            +
                  when Bolt::ApplyResult
         
     | 
| 
      
 52 
     | 
    
         
            +
                    format_apply_result(message)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  when Bolt::Result, Bolt::ResultSet
         
     | 
| 
      
 54 
     | 
    
         
            +
                    # This is equivalent to to_s, but formattable
         
     | 
| 
      
 55 
     | 
    
         
            +
                    message.to_data
         
     | 
| 
      
 56 
     | 
    
         
            +
                  when Bolt::RunFailure
         
     | 
| 
      
 57 
     | 
    
         
            +
                    formatted_resultset = message.result_set.to_data
         
     | 
| 
      
 58 
     | 
    
         
            +
                    message.to_h.merge('result_set' => formatted_resultset)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  when Hash
         
     | 
| 
      
 60 
     | 
    
         
            +
                    message.each_with_object({}) do |(k, v), h|
         
     | 
| 
      
 61 
     | 
    
         
            +
                      h[format_message(k)] = format_message(v)
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  when Integer, Float, NilClass
         
     | 
| 
      
 64 
     | 
    
         
            +
                    message
         
     | 
| 
      
 65 
     | 
    
         
            +
                  else
         
     | 
| 
      
 66 
     | 
    
         
            +
                    message.to_s
         
     | 
| 
      
 67 
     | 
    
         
            +
                  end
         
     | 
| 
      
 68 
     | 
    
         
            +
                end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                def format_apply_result(result)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  logs = result.resource_logs&.map do |log|
         
     | 
| 
      
 72 
     | 
    
         
            +
                    # Omit low-level info/debug messages
         
     | 
| 
      
 73 
     | 
    
         
            +
                    next if %w[info debug].include?(log['level'])
         
     | 
| 
      
 74 
     | 
    
         
            +
                    indent(2, format_log(log))
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                  hash = result.to_data
         
     | 
| 
      
 77 
     | 
    
         
            +
                  hash['logs'] = logs unless logs.empty?
         
     | 
| 
      
 78 
     | 
    
         
            +
                  hash
         
     | 
| 
      
 79 
     | 
    
         
            +
                end
         
     | 
| 
       24 
80 
     | 
    
         
             
              end
         
     | 
| 
       25 
81 
     | 
    
         
             
            end
         
     | 
| 
       26 
82 
     | 
    
         | 
    
        data/lib/bolt/outputter/human.rb
    CHANGED
    
    | 
         @@ -27,11 +27,6 @@ module Bolt 
     | 
|
| 
       27 
27 
     | 
    
         
             
                    end
         
     | 
| 
       28 
28 
     | 
    
         
             
                  end
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                  def indent(indent, string)
         
     | 
| 
       31 
     | 
    
         
            -
                    indent = ' ' * indent
         
     | 
| 
       32 
     | 
    
         
            -
                    string.gsub(/^/, indent.to_s)
         
     | 
| 
       33 
     | 
    
         
            -
                  end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
30 
     | 
    
         
             
                  def remove_trail(string)
         
     | 
| 
       36 
31 
     | 
    
         
             
                    string.sub(/\s\z/, '')
         
     | 
| 
       37 
32 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -291,6 +286,16 @@ module Bolt 
     | 
|
| 
       291 
286 
     | 
    
         
             
                                    "details and parameters for a specific plan.")
         
     | 
| 
       292 
287 
     | 
    
         
             
                  end
         
     | 
| 
       293 
288 
     | 
    
         | 
| 
      
 289 
     | 
    
         
            +
                  def print_topics(topics)
         
     | 
| 
      
 290 
     | 
    
         
            +
                    print_message("Available topics are:")
         
     | 
| 
      
 291 
     | 
    
         
            +
                    print_message(topics.join("\n"))
         
     | 
| 
      
 292 
     | 
    
         
            +
                    print_message("\nUse `bolt guide <topic>` to view a specific guide.")
         
     | 
| 
      
 293 
     | 
    
         
            +
                  end
         
     | 
| 
      
 294 
     | 
    
         
            +
             
     | 
| 
      
 295 
     | 
    
         
            +
                  def print_guide(guide, _topic)
         
     | 
| 
      
 296 
     | 
    
         
            +
                    @stream.puts(guide)
         
     | 
| 
      
 297 
     | 
    
         
            +
                  end
         
     | 
| 
      
 298 
     | 
    
         
            +
             
     | 
| 
       294 
299 
     | 
    
         
             
                  def print_module_list(module_list)
         
     | 
| 
       295 
300 
     | 
    
         
             
                    module_list.each do |path, modules|
         
     | 
| 
       296 
301 
     | 
    
         
             
                      if (mod = modules.find { |m| m[:internal_module_group] })
         
     | 
| 
         @@ -372,10 +377,6 @@ module Bolt 
     | 
|
| 
       372 
377 
     | 
    
         
             
                    end
         
     | 
| 
       373 
378 
     | 
    
         
             
                  end
         
     | 
| 
       374 
379 
     | 
    
         | 
| 
       375 
     | 
    
         
            -
                  def print_message_event(event)
         
     | 
| 
       376 
     | 
    
         
            -
                    print_message(event[:message])
         
     | 
| 
       377 
     | 
    
         
            -
                  end
         
     | 
| 
       378 
     | 
    
         
            -
             
     | 
| 
       379 
380 
     | 
    
         
             
                  def fatal_error(err)
         
     | 
| 
       380 
381 
     | 
    
         
             
                    @stream.puts(colorize(:red, err.message))
         
     | 
| 
       381 
382 
     | 
    
         
             
                    if err.is_a? Bolt::RunFailure
         
     | 
    
        data/lib/bolt/outputter/json.rb
    CHANGED
    
    | 
         @@ -83,6 +83,17 @@ module Bolt 
     | 
|
| 
       83 
83 
     | 
    
         
             
                    @stream.puts result.to_json
         
     | 
| 
       84 
84 
     | 
    
         
             
                  end
         
     | 
| 
       85 
85 
     | 
    
         | 
| 
      
 86 
     | 
    
         
            +
                  def print_topics(topics)
         
     | 
| 
      
 87 
     | 
    
         
            +
                    print_table('topics' => topics)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  def print_guide(guide, topic)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    @stream.puts({
         
     | 
| 
      
 92 
     | 
    
         
            +
                      'topic' => topic,
         
     | 
| 
      
 93 
     | 
    
         
            +
                      'guide' => guide
         
     | 
| 
      
 94 
     | 
    
         
            +
                    }.to_json)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
       86 
97 
     | 
    
         
             
                  def print_puppetfile_result(success, puppetfile, moduledir)
         
     | 
| 
       87 
98 
     | 
    
         
             
                    @stream.puts({ "success": success,
         
     | 
| 
       88 
99 
     | 
    
         
             
                                   "puppetfile": puppetfile,
         
     | 
| 
         @@ -121,10 +132,6 @@ module Bolt 
     | 
|
| 
       121 
132 
     | 
    
         
             
                    @stream.puts '}' if @object_open
         
     | 
| 
       122 
133 
     | 
    
         
             
                  end
         
     | 
| 
       123 
134 
     | 
    
         | 
| 
       124 
     | 
    
         
            -
                  def print_message_event(event)
         
     | 
| 
       125 
     | 
    
         
            -
                    print_message(event[:message])
         
     | 
| 
       126 
     | 
    
         
            -
                  end
         
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
135 
     | 
    
         
             
                  def print_message(message)
         
     | 
| 
       129 
136 
     | 
    
         
             
                    $stderr.puts(message)
         
     | 
| 
       130 
137 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -40,13 +40,13 @@ module Bolt 
     | 
|
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
                  def log_plan_start(event)
         
     | 
| 
       42 
42 
     | 
    
         
             
                    plan = event[:plan]
         
     | 
| 
       43 
     | 
    
         
            -
                    @logger. 
     | 
| 
      
 43 
     | 
    
         
            +
                    @logger.info("Starting: plan #{plan}")
         
     | 
| 
       44 
44 
     | 
    
         
             
                  end
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
                  def log_plan_finish(event)
         
     | 
| 
       47 
47 
     | 
    
         
             
                    plan = event[:plan]
         
     | 
| 
       48 
48 
     | 
    
         
             
                    duration = event[:duration]
         
     | 
| 
       49 
     | 
    
         
            -
                    @logger. 
     | 
| 
      
 49 
     | 
    
         
            +
                    @logger.info("Finished: plan #{plan} in #{duration.round(2)} sec")
         
     | 
| 
       50 
50 
     | 
    
         
             
                  end
         
     | 
| 
       51 
51 
     | 
    
         
             
                end
         
     | 
| 
       52 
52 
     | 
    
         
             
              end
         
     | 
| 
         @@ -39,9 +39,10 @@ module Bolt 
     | 
|
| 
       39 
39 
     | 
    
         
             
                        a = string.chars.map do |c|
         
     | 
| 
       40 
40 
     | 
    
         
             
                          case @state
         
     | 
| 
       41 
41 
     | 
    
         
             
                          when :normal
         
     | 
| 
       42 
     | 
    
         
            -
                             
     | 
| 
      
 42 
     | 
    
         
            +
                            case c
         
     | 
| 
      
 43 
     | 
    
         
            +
                            when "\e"
         
     | 
| 
       43 
44 
     | 
    
         
             
                              @state = :ansi
         
     | 
| 
       44 
     | 
    
         
            -
                             
     | 
| 
      
 45 
     | 
    
         
            +
                            when "\n"
         
     | 
| 
       45 
46 
     | 
    
         
             
                              @line_color += 1
         
     | 
| 
       46 
47 
     | 
    
         
             
                              @color = @line_color
         
     | 
| 
       47 
48 
     | 
    
         
             
                              c
         
     | 
| 
         @@ -85,6 +86,21 @@ module Bolt 
     | 
|
| 
       85 
86 
     | 
    
         
             
                    total_msg << " in #{duration_to_string(elapsed_time)}" unless elapsed_time.nil?
         
     | 
| 
       86 
87 
     | 
    
         
             
                    @stream.puts colorize(:rainbow, total_msg)
         
     | 
| 
       87 
88 
     | 
    
         
             
                  end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                  def print_guide(guide, _topic)
         
     | 
| 
      
 91 
     | 
    
         
            +
                    @stream.puts colorize(:rainbow, guide)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  def print_topics(topics)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    content  = String.new("Available topics are:\n")
         
     | 
| 
      
 96 
     | 
    
         
            +
                    content += topics.join("\n")
         
     | 
| 
      
 97 
     | 
    
         
            +
                    content += "\n\nUse `bolt guide <topic>` to view a specific guide."
         
     | 
| 
      
 98 
     | 
    
         
            +
                    @stream.puts colorize(:rainbow, content)
         
     | 
| 
      
 99 
     | 
    
         
            +
                  end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                  def print_message(message)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    @stream.puts colorize(:rainbow, message)
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
       88 
104 
     | 
    
         
             
                end
         
     | 
| 
       89 
105 
     | 
    
         
             
              end
         
     | 
| 
       90 
106 
     | 
    
         
             
            end
         
     | 
    
        data/lib/bolt/pal.rb
    CHANGED
    
    | 
         @@ -48,7 +48,7 @@ module Bolt 
     | 
|
| 
       48 
48 
     | 
    
         
             
                  end
         
     | 
| 
       49 
49 
     | 
    
         
             
                end
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                attr_reader :modulepath
         
     | 
| 
      
 51 
     | 
    
         
            +
                attr_reader :modulepath, :user_modulepath
         
     | 
| 
       52 
52 
     | 
    
         | 
| 
       53 
53 
     | 
    
         
             
                def initialize(modulepath, hiera_config, resource_types, max_compiles = Etc.nprocessors,
         
     | 
| 
       54 
54 
     | 
    
         
             
                               trusted_external = nil, apply_settings = {}, project = nil)
         
     | 
| 
         @@ -56,7 +56,7 @@ module Bolt 
     | 
|
| 
       56 
56 
     | 
    
         
             
                  # is safe and in practice only happens in tests
         
     | 
| 
       57 
57 
     | 
    
         
             
                  self.class.load_puppet
         
     | 
| 
       58 
58 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
                  @ 
     | 
| 
      
 59 
     | 
    
         
            +
                  @user_modulepath = modulepath
         
     | 
| 
       60 
60 
     | 
    
         
             
                  @modulepath = [BOLTLIB_PATH, *modulepath, MODULES_PATH]
         
     | 
| 
       61 
61 
     | 
    
         
             
                  @hiera_config = hiera_config
         
     | 
| 
       62 
62 
     | 
    
         
             
                  @trusted_external = trusted_external
         
     | 
| 
         @@ -67,7 +67,7 @@ module Bolt 
     | 
|
| 
       67 
67 
     | 
    
         | 
| 
       68 
68 
     | 
    
         
             
                  @logger = Logging.logger[self]
         
     | 
| 
       69 
69 
     | 
    
         
             
                  if modulepath && !modulepath.empty?
         
     | 
| 
       70 
     | 
    
         
            -
                    @logger. 
     | 
| 
      
 70 
     | 
    
         
            +
                    @logger.debug("Loading modules from #{@modulepath.join(File::PATH_SEPARATOR)}")
         
     | 
| 
       71 
71 
     | 
    
         
             
                  end
         
     | 
| 
       72 
72 
     | 
    
         | 
| 
       73 
73 
     | 
    
         
             
                  @loaded = false
         
     | 
| 
         @@ -150,7 +150,12 @@ module Bolt 
     | 
|
| 
       150 
150 
     | 
    
         
             
                  r = Puppet::Pal.in_tmp_environment('bolt', modulepath: @modulepath, facts: {}) do |pal|
         
     | 
| 
       151 
151 
     | 
    
         
             
                    # Only load the project if it a) exists, b) has a name it can be loaded with
         
     | 
| 
       152 
152 
     | 
    
         
             
                    bolt_project = @project if @project&.name
         
     | 
| 
      
 153 
     | 
    
         
            +
                    # Puppet currently won't receive the project unless it is a named project. Since
         
     | 
| 
      
 154 
     | 
    
         
            +
                    # the download_file plan function needs access to the project path, add it to the
         
     | 
| 
      
 155 
     | 
    
         
            +
                    # context.
         
     | 
| 
      
 156 
     | 
    
         
            +
                    bolt_project_data = @project
         
     | 
| 
       153 
157 
     | 
    
         
             
                    Puppet.override(bolt_project: bolt_project,
         
     | 
| 
      
 158 
     | 
    
         
            +
                                    bolt_project_data: bolt_project_data,
         
     | 
| 
       154 
159 
     | 
    
         
             
                                    yaml_plan_instantiator: Bolt::PAL::YamlPlan::Loader) do
         
     | 
| 
       155 
160 
     | 
    
         
             
                      pal.with_script_compiler do |compiler|
         
     | 
| 
       156 
161 
     | 
    
         
             
                        alias_types(compiler)
         
     | 
| 
         @@ -203,7 +208,7 @@ module Bolt 
     | 
|
| 
       203 
208 
     | 
    
         
             
                      # Skip syncing built-in plugins, since we vendor some Puppet 6
         
     | 
| 
       204 
209 
     | 
    
         
             
                      # versions of "core" types, which are already present on the agent,
         
     | 
| 
       205 
210 
     | 
    
         
             
                      # but may cause issues on Puppet 5 agents.
         
     | 
| 
       206 
     | 
    
         
            -
                      @ 
     | 
| 
      
 211 
     | 
    
         
            +
                      @user_modulepath,
         
     | 
| 
       207 
212 
     | 
    
         
             
                      @project,
         
     | 
| 
       208 
213 
     | 
    
         
             
                      pdb_client,
         
     | 
| 
       209 
214 
     | 
    
         
             
                      @hiera_config,
         
     | 
| 
         @@ -273,15 +278,12 @@ module Bolt 
     | 
|
| 
       273 
278 
     | 
    
         
             
                  end
         
     | 
| 
       274 
279 
     | 
    
         
             
                end
         
     | 
| 
       275 
280 
     | 
    
         | 
| 
       276 
     | 
    
         
            -
                def list_modulepath
         
     | 
| 
       277 
     | 
    
         
            -
                  @modulepath - [BOLTLIB_PATH, MODULES_PATH]
         
     | 
| 
       278 
     | 
    
         
            -
                end
         
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
       280 
281 
     | 
    
         
             
                def parse_params(type, object_name, params)
         
     | 
| 
       281 
282 
     | 
    
         
             
                  in_bolt_compiler do |compiler|
         
     | 
| 
       282 
     | 
    
         
            -
                     
     | 
| 
      
 283 
     | 
    
         
            +
                    case type
         
     | 
| 
      
 284 
     | 
    
         
            +
                    when 'task'
         
     | 
| 
       283 
285 
     | 
    
         
             
                      param_spec = compiler.task_signature(object_name)&.task_hash&.dig('parameters')
         
     | 
| 
       284 
     | 
    
         
            -
                     
     | 
| 
      
 286 
     | 
    
         
            +
                    when 'plan'
         
     | 
| 
       285 
287 
     | 
    
         
             
                      plan = compiler.plan_signature(object_name)
         
     | 
| 
       286 
288 
     | 
    
         
             
                      param_spec = plan.params_type.elements&.each_with_object({}) { |t, h| h[t.name] = t.value_type } if plan
         
     | 
| 
       287 
289 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -407,7 +409,7 @@ module Bolt 
     | 
|
| 
       407 
409 
     | 
    
         
             
                                 end
         
     | 
| 
       408 
410 
     | 
    
         
             
                      params[name] = { 'type' => type_str }
         
     | 
| 
       409 
411 
     | 
    
         
             
                      params[name]['sensitive'] = param.type_expr.instance_of?(Puppet::Pops::Types::PSensitiveType)
         
     | 
| 
       410 
     | 
    
         
            -
                      params[name]['default_value'] = param.value
         
     | 
| 
      
 412 
     | 
    
         
            +
                      params[name]['default_value'] = param.value unless param.value.nil?
         
     | 
| 
       411 
413 
     | 
    
         
             
                      params[name]['description'] = param.description if param.description
         
     | 
| 
       412 
414 
     | 
    
         
             
                    end
         
     | 
| 
       413 
415 
     | 
    
         
             
                    {
         
     |