bolt 2.42.0 → 2.44.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 +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)
         |