bolt 3.14.1 → 3.17.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 +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +137 -104
- data/guides/debugging.yaml +27 -0
- data/guides/inventory.yaml +23 -0
- data/guides/links.yaml +12 -0
- data/guides/logging.yaml +17 -0
- data/guides/module.yaml +18 -0
- data/guides/modulepath.yaml +24 -0
- data/guides/project.yaml +21 -0
- data/guides/targets.yaml +28 -0
- data/guides/transports.yaml +22 -0
- data/lib/bolt/analytics.rb +2 -19
- data/lib/bolt/application.rb +634 -0
- data/lib/bolt/bolt_option_parser.rb +28 -4
- data/lib/bolt/cli.rb +592 -788
- data/lib/bolt/fiber_executor.rb +7 -3
- data/lib/bolt/inventory/inventory.rb +68 -39
- data/lib/bolt/inventory.rb +2 -9
- data/lib/bolt/module_installer/puppetfile.rb +24 -10
- data/lib/bolt/outputter/human.rb +83 -32
- data/lib/bolt/outputter/json.rb +63 -38
- data/lib/bolt/pal/yaml_plan/transpiler.rb +1 -1
- data/lib/bolt/pal.rb +31 -11
- data/lib/bolt/plan_creator.rb +84 -25
- data/lib/bolt/plan_future.rb +11 -6
- data/lib/bolt/plan_result.rb +1 -1
- data/lib/bolt/plugin/task.rb +1 -1
- data/lib/bolt/plugin.rb +11 -17
- data/lib/bolt/project.rb +0 -7
- data/lib/bolt/result_set.rb +2 -1
- data/lib/bolt/transport/local/connection.rb +17 -1
- data/lib/bolt/transport/orch/connection.rb +13 -1
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/file_cache.rb +12 -0
- data/lib/bolt_server/schemas/action-apply.json +32 -0
- data/lib/bolt_server/schemas/action-apply_prep.json +19 -0
- data/lib/bolt_server/transport_app.rb +113 -24
- data/lib/bolt_spec/bolt_context.rb +1 -1
- data/lib/bolt_spec/run.rb +1 -1
- metadata +14 -3
- data/lib/bolt/secret.rb +0 -37
    
        data/lib/bolt/outputter/json.rb
    CHANGED
    
    | @@ -49,7 +49,11 @@ module Bolt | |
| 49 49 | 
             
                  alias print_module_list print_table
         | 
| 50 50 | 
             
                  alias print_module_info print_table
         | 
| 51 51 |  | 
| 52 | 
            -
                   | 
| 52 | 
            +
                  # Print information about a task.
         | 
| 53 | 
            +
                  #
         | 
| 54 | 
            +
                  # @param task [Bolt::Task] The task information.
         | 
| 55 | 
            +
                  #
         | 
| 56 | 
            +
                  def print_task_info(task:)
         | 
| 53 57 | 
             
                    path = task.files.first['path'].chomp("/tasks/#{task.files.first['name']}")
         | 
| 54 58 | 
             
                    module_dir = if path.start_with?(Bolt::Config::Modulepath::MODULES_PATH)
         | 
| 55 59 | 
             
                                   "built-in module"
         | 
| @@ -59,11 +63,16 @@ module Bolt | |
| 59 63 | 
             
                    @stream.puts task.to_h.merge(module_dir: module_dir).to_json
         | 
| 60 64 | 
             
                  end
         | 
| 61 65 |  | 
| 62 | 
            -
                   | 
| 63 | 
            -
             | 
| 66 | 
            +
                  # List available tasks.
         | 
| 67 | 
            +
                  #
         | 
| 68 | 
            +
                  # @param tasks [Array] A list of task names and descriptions.
         | 
| 69 | 
            +
                  # @param modulepath [Array] The modulepath.
         | 
| 70 | 
            +
                  #
         | 
| 71 | 
            +
                  def print_tasks(**kwargs)
         | 
| 72 | 
            +
                    print_table(**kwargs)
         | 
| 64 73 | 
             
                  end
         | 
| 65 74 |  | 
| 66 | 
            -
                  def print_plugin_list(plugins | 
| 75 | 
            +
                  def print_plugin_list(plugins:, modulepath:)
         | 
| 67 76 | 
             
                    plugins.delete(:validate_resolve_reference)
         | 
| 68 77 | 
             
                    print_table('plugins' => plugins, 'modulepath' => modulepath)
         | 
| 69 78 | 
             
                  end
         | 
| @@ -78,11 +87,15 @@ module Bolt | |
| 78 87 | 
             
                    @stream.puts plan.to_json
         | 
| 79 88 | 
             
                  end
         | 
| 80 89 |  | 
| 81 | 
            -
                  def print_plans( | 
| 82 | 
            -
                    print_table( | 
| 90 | 
            +
                  def print_plans(**kwargs)
         | 
| 91 | 
            +
                    print_table(**kwargs)
         | 
| 83 92 | 
             
                  end
         | 
| 84 93 |  | 
| 85 | 
            -
                  def  | 
| 94 | 
            +
                  def print_new_plan(**kwargs)
         | 
| 95 | 
            +
                    print_table(**kwargs)
         | 
| 96 | 
            +
                  end
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                  def print_apply_result(apply_result)
         | 
| 86 99 | 
             
                    @stream.puts apply_result.to_json
         | 
| 87 100 | 
             
                  end
         | 
| 88 101 |  | 
| @@ -95,10 +108,19 @@ module Bolt | |
| 95 108 | 
             
                    @stream.puts result_set.to_json
         | 
| 96 109 | 
             
                  end
         | 
| 97 110 |  | 
| 98 | 
            -
                   | 
| 99 | 
            -
             | 
| 111 | 
            +
                  # Print available guide topics.
         | 
| 112 | 
            +
                  #
         | 
| 113 | 
            +
                  # @param topics [Array] The available topics.
         | 
| 114 | 
            +
                  #
         | 
| 115 | 
            +
                  def print_topics(**kwargs)
         | 
| 116 | 
            +
                    print_table(kwargs)
         | 
| 100 117 | 
             
                  end
         | 
| 101 118 |  | 
| 119 | 
            +
                  # Print the guide for the specified topic.
         | 
| 120 | 
            +
                  #
         | 
| 121 | 
            +
                  # @param guide [String] The guide.
         | 
| 122 | 
            +
                  # @param topic [String] The topic.
         | 
| 123 | 
            +
                  #
         | 
| 102 124 | 
             
                  def print_guide(**kwargs)
         | 
| 103 125 | 
             
                    @stream.puts(kwargs.to_json)
         | 
| 104 126 | 
             
                  end
         | 
| @@ -113,35 +135,38 @@ module Bolt | |
| 113 135 | 
             
                                   moduledir: moduledir.to_s }.to_json)
         | 
| 114 136 | 
             
                  end
         | 
| 115 137 |  | 
| 116 | 
            -
                   | 
| 117 | 
            -
             | 
| 118 | 
            -
             | 
| 119 | 
            -
             | 
| 120 | 
            -
             | 
| 121 | 
            -
             | 
| 122 | 
            -
             | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
             | 
| 126 | 
            -
             | 
| 127 | 
            -
             | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 130 | 
            -
                   | 
| 131 | 
            -
             | 
| 132 | 
            -
                   | 
| 133 | 
            -
             | 
| 134 | 
            -
             | 
| 135 | 
            -
             | 
| 136 | 
            -
             | 
| 137 | 
            -
             | 
| 138 | 
            -
                    )
         | 
| 139 | 
            -
                  end
         | 
| 140 | 
            -
             | 
| 141 | 
            -
                   | 
| 142 | 
            -
             | 
| 143 | 
            -
             | 
| 144 | 
            -
             | 
| 138 | 
            +
                  # Print target names and where they came from.
         | 
| 139 | 
            +
                  #
         | 
| 140 | 
            +
                  # @param adhoc [Hash] Adhoc targets provided on the command line.
         | 
| 141 | 
            +
                  # @param inventory [Hash] Targets provided from the inventory.
         | 
| 142 | 
            +
                  # @param targets [Array] All targets.
         | 
| 143 | 
            +
                  # @param count [Integer] Number of targets.
         | 
| 144 | 
            +
                  #
         | 
| 145 | 
            +
                  def print_targets(adhoc:, inventory:, targets:, count:, **_kwargs)
         | 
| 146 | 
            +
                    adhoc[:targets]     = adhoc[:targets].map { |t| t['name'] }
         | 
| 147 | 
            +
                    inventory[:targets] = inventory[:targets].map { |t| t['name'] }
         | 
| 148 | 
            +
                    targets             = targets.map { |t| t['name'] }
         | 
| 149 | 
            +
                    @stream.puts({ adhoc: adhoc, inventory: inventory, targets: targets, count: count }.to_json)
         | 
| 150 | 
            +
                  end
         | 
| 151 | 
            +
             | 
| 152 | 
            +
                  # Print target names and where they came from.
         | 
| 153 | 
            +
                  #
         | 
| 154 | 
            +
                  # @param adhoc [Hash] Adhoc targets provided on the command line.
         | 
| 155 | 
            +
                  # @param inventory [Hash] Targets provided from the inventory.
         | 
| 156 | 
            +
                  # @param targets [Array] All targets.
         | 
| 157 | 
            +
                  # @param count [Integer] Number of targets.
         | 
| 158 | 
            +
                  #
         | 
| 159 | 
            +
                  def print_target_info(adhoc:, inventory:, targets:, count:, **_kwargs)
         | 
| 160 | 
            +
                    @stream.puts({ adhoc: adhoc, inventory: inventory, targets: targets, count: count }.to_json)
         | 
| 161 | 
            +
                  end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                  # Print inventory group information.
         | 
| 164 | 
            +
                  #
         | 
| 165 | 
            +
                  # @param count [Integer] Number of groups in the inventory.
         | 
| 166 | 
            +
                  # @param groups [Array] Names of groups in the inventory.
         | 
| 167 | 
            +
                  #
         | 
| 168 | 
            +
                  def print_groups(count:, groups:, **_kwargs)
         | 
| 169 | 
            +
                    @stream.puts({ count: count, groups: groups }.to_json)
         | 
| 145 170 | 
             
                  end
         | 
| 146 171 |  | 
| 147 172 | 
             
                  def fatal_error(err)
         | 
| @@ -30,7 +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 might not behave as expected.\n"
         | 
| 33 | 
            -
                      plan_string << "# @ | 
| 33 | 
            +
                      plan_string << "# @api #{plan_object.private ? 'private' : 'public'}\n" unless plan_object.private.nil?
         | 
| 34 34 | 
             
                      plan_string << "#{param_descriptions}\n" unless param_descriptions.empty?
         | 
| 35 35 |  | 
| 36 36 | 
             
                      plan_string << "plan #{plan_object.name}("
         | 
    
        data/lib/bolt/pal.rb
    CHANGED
    
    | @@ -447,7 +447,7 @@ module Bolt | |
| 447 447 | 
             
                # @param mtime [String] The last time the file was modified.
         | 
| 448 448 | 
             
                #
         | 
| 449 449 | 
             
                private def file_modified?(path, mtime)
         | 
| 450 | 
            -
                  path && !(File.exist?(path) && File.mtime(path).to_s == mtime)
         | 
| 450 | 
            +
                  path && !(File.exist?(path) && File.mtime(path).to_s == mtime.to_s)
         | 
| 451 451 | 
             
                end
         | 
| 452 452 |  | 
| 453 453 | 
             
                def list_plans(filter_content: false)
         | 
| @@ -512,19 +512,14 @@ module Bolt | |
| 512 512 | 
             
                      end
         | 
| 513 513 | 
             
                    end
         | 
| 514 514 |  | 
| 515 | 
            -
                    privie = plan.tag(:private)&.text
         | 
| 516 | 
            -
                    unless privie.nil? || %w[true false].include?(privie.downcase)
         | 
| 517 | 
            -
                      msg = "Plan #{plan_name} key 'private' must be a boolean, received: #{privie}"
         | 
| 518 | 
            -
                      raise Bolt::Error.new(msg, 'bolt/invalid-plan')
         | 
| 519 | 
            -
                    end
         | 
| 520 | 
            -
             | 
| 521 515 | 
             
                    pp_info = {
         | 
| 522 516 | 
             
                      'name'        => plan_name,
         | 
| 523 517 | 
             
                      'description' => description,
         | 
| 524 518 | 
             
                      'parameters'  => parameters,
         | 
| 525 | 
            -
                      'module'      => mod
         | 
| 519 | 
            +
                      'module'      => mod,
         | 
| 520 | 
            +
                      'private'     => private_plan?(plan)
         | 
| 526 521 | 
             
                    }
         | 
| 527 | 
            -
             | 
| 522 | 
            +
             | 
| 528 523 | 
             
                    pp_info.merge!(get_plan_mtime(plan.file)) if with_mtime
         | 
| 529 524 | 
             
                    pp_info
         | 
| 530 525 |  | 
| @@ -554,14 +549,39 @@ module Bolt | |
| 554 549 | 
             
                      'name'        => plan_name,
         | 
| 555 550 | 
             
                      'description' => plan.description,
         | 
| 556 551 | 
             
                      'parameters'  => parameters,
         | 
| 557 | 
            -
                      'module'      => mod
         | 
| 552 | 
            +
                      'module'      => mod,
         | 
| 553 | 
            +
                      'private'     => !!plan.private
         | 
| 558 554 | 
             
                    }
         | 
| 559 | 
            -
             | 
| 555 | 
            +
             | 
| 560 556 | 
             
                    yaml_info.merge!(get_plan_mtime(yaml_path)) if with_mtime
         | 
| 561 557 | 
             
                    yaml_info
         | 
| 562 558 | 
             
                  end
         | 
| 563 559 | 
             
                end
         | 
| 564 560 |  | 
| 561 | 
            +
                # Returns true if the plan is private, false otherwise.
         | 
| 562 | 
            +
                #
         | 
| 563 | 
            +
                # @param plan [PuppetStrings::Yard::CodeObjects::Plan] The puppet-strings plan documentation.
         | 
| 564 | 
            +
                # @return [Boolean]
         | 
| 565 | 
            +
                #
         | 
| 566 | 
            +
                private def private_plan?(plan)
         | 
| 567 | 
            +
                  if plan.tag(:private)
         | 
| 568 | 
            +
                    value     = plan.tag(:private).text
         | 
| 569 | 
            +
                    api_value = value.downcase == 'true' ? 'private' : 'public'
         | 
| 570 | 
            +
             | 
| 571 | 
            +
                    Bolt::Logger.deprecate(
         | 
| 572 | 
            +
                      'plan_private_tag',
         | 
| 573 | 
            +
                      "Tag '@private #{value}' in plan '#{plan.name}' is deprecated, use '@api #{api_value}' instead"
         | 
| 574 | 
            +
                    )
         | 
| 575 | 
            +
             | 
| 576 | 
            +
                    unless %w[true false].include?(plan.tag(:private).text.downcase)
         | 
| 577 | 
            +
                      msg = "Value for '@private' tag in plan '#{plan.name}' must be a boolean, received: #{value}"
         | 
| 578 | 
            +
                      raise Bolt::Error.new(msg, 'bolt/invalid-plan')
         | 
| 579 | 
            +
                    end
         | 
| 580 | 
            +
                  end
         | 
| 581 | 
            +
             | 
| 582 | 
            +
                  plan.tag(:api).text == 'private' || plan.tag(:private)&.text&.downcase == 'true'
         | 
| 583 | 
            +
                end
         | 
| 584 | 
            +
             | 
| 565 585 | 
             
                def get_plan_mtime(path)
         | 
| 566 586 | 
             
                  # If the plan is from the project modules/ directory, or is in the
         | 
| 567 587 | 
             
                  # project itself, include the last mtime of the file so we can compare
         | 
    
        data/lib/bolt/plan_creator.rb
    CHANGED
    
    | @@ -7,7 +7,7 @@ require 'bolt/util' | |
| 7 7 |  | 
| 8 8 | 
             
            module Bolt
         | 
| 9 9 | 
             
              module PlanCreator
         | 
| 10 | 
            -
                def self. | 
| 10 | 
            +
                def self.validate_plan_name(project, plan_name)
         | 
| 11 11 | 
             
                  if project.name.nil?
         | 
| 12 12 | 
             
                    raise Bolt::Error.new(
         | 
| 13 13 | 
             
                      "Project directory '#{project.path}' is not a named project. Unable to create "\
         | 
| @@ -51,7 +51,15 @@ module Bolt | |
| 51 51 | 
             
                  end
         | 
| 52 52 | 
             
                end
         | 
| 53 53 |  | 
| 54 | 
            -
                 | 
| 54 | 
            +
                # Create a new plan from the plan templates based on which language the
         | 
| 55 | 
            +
                # user configured, and whether the plan wraps a script.
         | 
| 56 | 
            +
                #
         | 
| 57 | 
            +
                # @param plans_path [string] The path to the new plan
         | 
| 58 | 
            +
                # @param plan_name [string] The name of the new plan
         | 
| 59 | 
            +
                # @param is_puppet [boolean] Whether to create a Puppet language plan
         | 
| 60 | 
            +
                # @param script [string] A reference to a script for the new plan to run
         | 
| 61 | 
            +
                #
         | 
| 62 | 
            +
                def self.create_plan(plans_path, plan_name, is_puppet: false, script: nil)
         | 
| 55 63 | 
             
                  _, name_segments, basename = segment_plan_name(plan_name)
         | 
| 56 64 | 
             
                  dir_path = plans_path.join(*name_segments)
         | 
| 57 65 |  | 
| @@ -66,8 +74,15 @@ module Bolt | |
| 66 74 |  | 
| 67 75 | 
             
                  type = is_puppet ? 'pp' : 'yaml'
         | 
| 68 76 | 
             
                  plan_path = dir_path + "#{basename}.#{type}"
         | 
| 69 | 
            -
                  plan_template = is_puppet  | 
| 70 | 
            -
             | 
| 77 | 
            +
                  plan_template = if is_puppet && script
         | 
| 78 | 
            +
                                    puppet_script_plan(plan_name, script)
         | 
| 79 | 
            +
                                  elsif is_puppet
         | 
| 80 | 
            +
                                    puppet_plan(plan_name)
         | 
| 81 | 
            +
                                  elsif script
         | 
| 82 | 
            +
                                    yaml_script_plan(script)
         | 
| 83 | 
            +
                                  else
         | 
| 84 | 
            +
                                    yaml_plan(plan_name)
         | 
| 85 | 
            +
                                  end
         | 
| 71 86 | 
             
                  begin
         | 
| 72 87 | 
             
                    File.write(plan_path, plan_template)
         | 
| 73 88 | 
             
                  rescue Errno::EACCES => e
         | 
| @@ -77,25 +92,7 @@ module Bolt | |
| 77 92 | 
             
                    )
         | 
| 78 93 | 
             
                  end
         | 
| 79 94 |  | 
| 80 | 
            -
                   | 
| 81 | 
            -
                    show_command = 'Get-BoltPlan -Name '
         | 
| 82 | 
            -
                    run_command  = 'Invoke-BoltPlan -Name '
         | 
| 83 | 
            -
                  else
         | 
| 84 | 
            -
                    show_command = 'bolt plan show'
         | 
| 85 | 
            -
                    run_command  = 'bolt plan run'
         | 
| 86 | 
            -
                  end
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                  output = <<~OUTPUT
         | 
| 89 | 
            -
                    Created plan '#{plan_name}' at '#{plan_path}'
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                    Show this plan with:
         | 
| 92 | 
            -
                        #{show_command} #{plan_name}
         | 
| 93 | 
            -
                    Run this plan with:
         | 
| 94 | 
            -
                        #{run_command} #{plan_name}
         | 
| 95 | 
            -
                  OUTPUT
         | 
| 96 | 
            -
             | 
| 97 | 
            -
                  outputter.print_message(output)
         | 
| 98 | 
            -
                  0
         | 
| 95 | 
            +
                  { name: plan_name, path: plan_path }
         | 
| 99 96 | 
             
                end
         | 
| 100 97 |  | 
| 101 98 | 
             
                def self.segment_plan_name(plan_name)
         | 
| @@ -108,7 +105,11 @@ module Bolt | |
| 108 105 | 
             
                  [prefix, name_segments, basename]
         | 
| 109 106 | 
             
                end
         | 
| 110 107 |  | 
| 111 | 
            -
                 | 
| 108 | 
            +
                # Template for a new simple YAML plan.
         | 
| 109 | 
            +
                #
         | 
| 110 | 
            +
                # @param plan_name [string] The name of the new plan
         | 
| 111 | 
            +
                #
         | 
| 112 | 
            +
                private_class_method def self.yaml_plan(plan_name)
         | 
| 112 113 | 
             
                  <<~YAML
         | 
| 113 114 | 
             
                    # This is the structure of a simple plan. To learn more about writing
         | 
| 114 115 | 
             
                    # YAML plans, see the documentation: http://pup.pt/bolt-yaml-plans
         | 
| @@ -137,7 +138,42 @@ module Bolt | |
| 137 138 | 
             
                  YAML
         | 
| 138 139 | 
             
                end
         | 
| 139 140 |  | 
| 140 | 
            -
                 | 
| 141 | 
            +
                # Template for a new YAML plan that runs a script.
         | 
| 142 | 
            +
                #
         | 
| 143 | 
            +
                # @param script [string] A reference to the script to run.
         | 
| 144 | 
            +
                #
         | 
| 145 | 
            +
                private_class_method def self.yaml_script_plan(script)
         | 
| 146 | 
            +
                  <<~YAML
         | 
| 147 | 
            +
                    # This is the structure of a simple plan. To learn more about writing
         | 
| 148 | 
            +
                    # YAML plans, see the documentation: http://pup.pt/bolt-yaml-plans
         | 
| 149 | 
            +
                    
         | 
| 150 | 
            +
                    # The description sets the description of the plan that will appear
         | 
| 151 | 
            +
                    # in 'bolt plan show' output.
         | 
| 152 | 
            +
                    description: A plan created with bolt plan new
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                    # The parameters key defines the parameters that can be passed to
         | 
| 155 | 
            +
                    # the plan.
         | 
| 156 | 
            +
                    parameters:
         | 
| 157 | 
            +
                      targets:
         | 
| 158 | 
            +
                        type: TargetSpec
         | 
| 159 | 
            +
                        description: A list of targets to run actions on
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                    # The steps key defines the actions the plan will take in order.
         | 
| 162 | 
            +
                    steps:
         | 
| 163 | 
            +
                      - name: run_script
         | 
| 164 | 
            +
                        script: #{script}
         | 
| 165 | 
            +
                        targets: $targets
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                    # The return key sets the return value of the plan.
         | 
| 168 | 
            +
                    return: $run_script
         | 
| 169 | 
            +
                  YAML
         | 
| 170 | 
            +
                end
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                # Template for a new simple Puppet plan.
         | 
| 173 | 
            +
                #
         | 
| 174 | 
            +
                # @param plan_name [string] The name of the new plan
         | 
| 175 | 
            +
                #
         | 
| 176 | 
            +
                private_class_method def self.puppet_plan(plan_name)
         | 
| 141 177 | 
             
                  <<~PUPPET
         | 
| 142 178 | 
             
                    # This is the structure of a simple plan. To learn more about writing
         | 
| 143 179 | 
             
                    # Puppet plans, see the documentation: http://pup.pt/bolt-puppet-plans
         | 
| @@ -156,5 +192,28 @@ module Bolt | |
| 156 192 | 
             
                    }
         | 
| 157 193 | 
             
                  PUPPET
         | 
| 158 194 | 
             
                end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
                # Template for a new Puppet plan that only runs a script.
         | 
| 197 | 
            +
                #
         | 
| 198 | 
            +
                # @param plan_name [string] The name of the new plan
         | 
| 199 | 
            +
                # @param script [string] A reference to the script to run
         | 
| 200 | 
            +
                #
         | 
| 201 | 
            +
                private_class_method def self.puppet_script_plan(plan_name, script)
         | 
| 202 | 
            +
                  <<~PUPPET
         | 
| 203 | 
            +
                    # This is the structure of a simple plan. To learn more about writing
         | 
| 204 | 
            +
                    # Puppet plans, see the documentation: http://pup.pt/bolt-puppet-plans
         | 
| 205 | 
            +
             | 
| 206 | 
            +
                    # The summary sets the description of the plan that will appear
         | 
| 207 | 
            +
                    # in 'bolt plan show' output. Bolt uses puppet-strings to parse the
         | 
| 208 | 
            +
                    # summary and parameters from the plan.
         | 
| 209 | 
            +
                    # @summary A plan created with bolt plan new.
         | 
| 210 | 
            +
                    # @param targets The targets to run on.
         | 
| 211 | 
            +
                    plan #{plan_name} (
         | 
| 212 | 
            +
                      TargetSpec $targets
         | 
| 213 | 
            +
                    ) {
         | 
| 214 | 
            +
                      return run_script('#{script}', $targets)
         | 
| 215 | 
            +
                    }
         | 
| 216 | 
            +
                  PUPPET
         | 
| 217 | 
            +
                end
         | 
| 159 218 | 
             
              end
         | 
| 160 219 | 
             
            end
         | 
    
        data/lib/bolt/plan_future.rb
    CHANGED
    
    | @@ -4,14 +4,19 @@ require 'fiber' | |
| 4 4 |  | 
| 5 5 | 
             
            module Bolt
         | 
| 6 6 | 
             
              class PlanFuture
         | 
| 7 | 
            -
                attr_reader :fiber, :id
         | 
| 7 | 
            +
                attr_reader :fiber, :id, :scope
         | 
| 8 8 | 
             
                attr_accessor :value, :plan_stack
         | 
| 9 9 |  | 
| 10 | 
            -
                def initialize(fiber, id, plan_id:, name: nil)
         | 
| 11 | 
            -
                  @fiber | 
| 12 | 
            -
                  @id | 
| 13 | 
            -
                  @name | 
| 14 | 
            -
                  @value | 
| 10 | 
            +
                def initialize(fiber, id, plan_id:, name: nil, scope: nil)
         | 
| 11 | 
            +
                  @fiber = fiber
         | 
| 12 | 
            +
                  @id    = id
         | 
| 13 | 
            +
                  @name  = name
         | 
| 14 | 
            +
                  @value = nil
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  # Default to Puppet's current global_scope, otherwise things will
         | 
| 17 | 
            +
                  # blow up when the Fiber Executor tries to override the global_scope.
         | 
| 18 | 
            +
                  @scope = scope || Puppet.lookup(:global_scope) { nil }
         | 
| 19 | 
            +
             | 
| 15 20 | 
             
                  # The plan invocation ID when the Future is created may be
         | 
| 16 21 | 
             
                  # different from the plan ID of the Future when we switch to it if a new
         | 
| 17 22 | 
             
                  # plan was run inside the Future, so keep track of the plans that a
         | 
    
        data/lib/bolt/plan_result.rb
    CHANGED
    
    
    
        data/lib/bolt/plugin/task.rb
    CHANGED
    
    | @@ -59,7 +59,7 @@ module Bolt | |
| 59 59 | 
             
                    run_opts = {}
         | 
| 60 60 | 
             
                    run_opts[:run_as] = opts['_run_as'] if opts['_run_as']
         | 
| 61 61 | 
             
                    begin
         | 
| 62 | 
            -
                      task =  | 
| 62 | 
            +
                      task = @context.get_validated_task(opts['task'], params)
         | 
| 63 63 | 
             
                    rescue Bolt::Error => e
         | 
| 64 64 | 
             
                      raise Bolt::Plugin::PluginError::ExecutionError.new(e.message, name, 'puppet_library')
         | 
| 65 65 | 
             
                    end
         | 
    
        data/lib/bolt/plugin.rb
    CHANGED
    
    | @@ -127,29 +127,15 @@ module Bolt | |
| 127 127 | 
             
                  end
         | 
| 128 128 | 
             
                end
         | 
| 129 129 |  | 
| 130 | 
            -
                def self.setup(config, pal, analytics = Bolt::Analytics::NoopClient.new, **opts)
         | 
| 131 | 
            -
                  plugins = new(config, pal, analytics, **opts)
         | 
| 132 | 
            -
             | 
| 133 | 
            -
                  config.plugins.each_key do |plugin|
         | 
| 134 | 
            -
                    plugins.by_name(plugin)
         | 
| 135 | 
            -
                  end
         | 
| 136 | 
            -
             | 
| 137 | 
            -
                  plugins.plugin_hooks.merge!(plugins.resolve_references(config.plugin_hooks))
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                  plugins
         | 
| 140 | 
            -
                end
         | 
| 141 | 
            -
             | 
| 142 130 | 
             
                RUBY_PLUGINS = %w[task prompt env_var puppetdb puppet_connect_data].freeze
         | 
| 143 131 | 
             
                BUILTIN_PLUGINS = %w[task terraform pkcs7 prompt vault aws_inventory puppetdb azure_inventory
         | 
| 144 132 | 
             
                                     yaml env_var gcloud_inventory].freeze
         | 
| 145 133 | 
             
                DEFAULT_PLUGIN_HOOKS = { 'puppet_library' => { 'plugin' => 'puppet_agent', 'stop_service' => true } }.freeze
         | 
| 146 134 |  | 
| 147 135 | 
             
                attr_reader :pal, :plugin_context
         | 
| 148 | 
            -
                 | 
| 136 | 
            +
                attr_writer :plugin_hooks
         | 
| 149 137 |  | 
| 150 | 
            -
                 | 
| 151 | 
            -
             | 
| 152 | 
            -
                def initialize(config, pal, analytics, load_plugins: true)
         | 
| 138 | 
            +
                def initialize(config, pal, analytics = Bolt::Analytics::NoopClient.new, load_plugins: true)
         | 
| 153 139 | 
             
                  @config = config
         | 
| 154 140 | 
             
                  @analytics = analytics
         | 
| 155 141 | 
             
                  @plugin_context = PluginContext.new(config, pal, self)
         | 
| @@ -166,7 +152,15 @@ module Bolt | |
| 166 152 | 
             
                    raise Bolt::Error.new(msg, 'bolt/plugin-error')
         | 
| 167 153 | 
             
                  end
         | 
| 168 154 | 
             
                  @unresolved_plugin_configs['puppetdb'] = config.puppetdb if config.puppetdb
         | 
| 169 | 
            -
             | 
| 155 | 
            +
                end
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                # Returns a map of configured plugin hooks. Any unresolved plugin references
         | 
| 158 | 
            +
                # are resolved.
         | 
| 159 | 
            +
                #
         | 
| 160 | 
            +
                # @return [Hash[String, Hash]]
         | 
| 161 | 
            +
                #
         | 
| 162 | 
            +
                def plugin_hooks
         | 
| 163 | 
            +
                  @plugin_hooks ||= DEFAULT_PLUGIN_HOOKS.merge(resolve_references(@config.plugin_hooks))
         | 
| 170 164 | 
             
                end
         | 
| 171 165 |  | 
| 172 166 | 
             
                def modules
         |