bolt 2.26.0 → 2.31.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 +13 -12
 - data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +2 -2
 - data/lib/bolt/analytics.rb +4 -0
 - data/lib/bolt/applicator.rb +19 -18
 - data/lib/bolt/bolt_option_parser.rb +112 -22
 - data/lib/bolt/catalog.rb +1 -1
 - data/lib/bolt/cli.rb +210 -174
 - data/lib/bolt/config.rb +22 -2
 - data/lib/bolt/config/modulepath.rb +30 -0
 - data/lib/bolt/config/options.rb +30 -0
 - data/lib/bolt/config/transport/options.rb +1 -1
 - data/lib/bolt/executor.rb +1 -1
 - data/lib/bolt/inventory.rb +11 -10
 - data/lib/bolt/logger.rb +26 -19
 - data/lib/bolt/module_installer.rb +242 -0
 - data/lib/bolt/outputter.rb +4 -0
 - data/lib/bolt/outputter/human.rb +77 -17
 - data/lib/bolt/outputter/json.rb +21 -6
 - data/lib/bolt/outputter/logger.rb +2 -2
 - data/lib/bolt/pal.rb +46 -25
 - data/lib/bolt/plugin.rb +1 -1
 - data/lib/bolt/plugin/module.rb +1 -1
 - data/lib/bolt/project.rb +62 -12
 - data/lib/bolt/project_migrator.rb +80 -0
 - data/lib/bolt/project_migrator/base.rb +39 -0
 - data/lib/bolt/project_migrator/config.rb +67 -0
 - data/lib/bolt/project_migrator/inventory.rb +67 -0
 - data/lib/bolt/project_migrator/modules.rb +198 -0
 - data/lib/bolt/puppetfile.rb +149 -0
 - data/lib/bolt/puppetfile/installer.rb +43 -0
 - data/lib/bolt/puppetfile/module.rb +93 -0
 - data/lib/bolt/rerun.rb +1 -1
 - data/lib/bolt/result.rb +15 -0
 - data/lib/bolt/shell/bash.rb +4 -3
 - data/lib/bolt/transport/base.rb +4 -4
 - data/lib/bolt/transport/ssh/connection.rb +1 -1
 - data/lib/bolt/util.rb +51 -10
 - data/lib/bolt/version.rb +1 -1
 - data/lib/bolt_server/acl.rb +2 -2
 - data/lib/bolt_server/base_config.rb +3 -3
 - data/lib/bolt_server/config.rb +1 -1
 - data/lib/bolt_server/file_cache.rb +11 -11
 - data/lib/bolt_server/transport_app.rb +206 -27
 - data/lib/bolt_spec/bolt_context.rb +8 -6
 - data/lib/bolt_spec/plans.rb +1 -1
 - data/lib/bolt_spec/plans/mock_executor.rb +1 -1
 - data/lib/bolt_spec/run.rb +1 -1
 - metadata +14 -6
 - data/lib/bolt/project_migrate.rb +0 -138
 - data/lib/bolt_server/pe/pal.rb +0 -67
 
    
        data/lib/bolt/version.rb
    CHANGED
    
    
    
        data/lib/bolt_server/acl.rb
    CHANGED
    
    
| 
         @@ -7,7 +7,7 @@ module BoltServer 
     | 
|
| 
       7 
7 
     | 
    
         
             
              class BaseConfig
         
     | 
| 
       8 
8 
     | 
    
         
             
                def config_keys
         
     | 
| 
       9 
9 
     | 
    
         
             
                  %w[host port ssl-cert ssl-key ssl-ca-cert
         
     | 
| 
       10 
     | 
    
         
            -
                     ssl-cipher-suites loglevel logfile  
     | 
| 
      
 10 
     | 
    
         
            +
                     ssl-cipher-suites loglevel logfile allowlist projects-dir]
         
     | 
| 
       11 
11 
     | 
    
         
             
                end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
                def env_keys
         
     | 
| 
         @@ -98,8 +98,8 @@ module BoltServer 
     | 
|
| 
       98 
98 
     | 
    
         
             
                    raise Bolt::ValidationError, "Configured 'ssl-cipher-suites' must be an array of cipher suite names"
         
     | 
| 
       99 
99 
     | 
    
         
             
                  end
         
     | 
| 
       100 
100 
     | 
    
         | 
| 
       101 
     | 
    
         
            -
                  unless @data[' 
     | 
| 
       102 
     | 
    
         
            -
                    raise Bolt::ValidationError, "Configured ' 
     | 
| 
      
 101 
     | 
    
         
            +
                  unless @data['allowlist'].nil? || @data['allowlist'].is_a?(Array)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    raise Bolt::ValidationError, "Configured 'allowlist' must be an array of names"
         
     | 
| 
       103 
103 
     | 
    
         
             
                  end
         
     | 
| 
       104 
104 
     | 
    
         
             
                end
         
     | 
| 
       105 
105 
     | 
    
         | 
    
        data/lib/bolt_server/config.rb
    CHANGED
    
    | 
         @@ -7,7 +7,7 @@ require 'bolt/error' 
     | 
|
| 
       7 
7 
     | 
    
         
             
            module BoltServer
         
     | 
| 
       8 
8 
     | 
    
         
             
              class Config < BoltServer::BaseConfig
         
     | 
| 
       9 
9 
     | 
    
         
             
                def config_keys
         
     | 
| 
       10 
     | 
    
         
            -
                  super + %w[concurrency cache-dir file-server-conn-timeout file-server-uri]
         
     | 
| 
      
 10 
     | 
    
         
            +
                  super + %w[concurrency cache-dir file-server-conn-timeout file-server-uri projects-dir]
         
     | 
| 
       11 
11 
     | 
    
         
             
                end
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
                def env_keys
         
     | 
| 
         @@ -64,17 +64,17 @@ module BoltServer 
     | 
|
| 
       64 
64 
     | 
    
         | 
| 
       65 
65 
     | 
    
         
             
                def client
         
     | 
| 
       66 
66 
     | 
    
         
             
                  @client ||= begin
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
             
     | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
       71 
     | 
    
         
            -
             
     | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
      
 67 
     | 
    
         
            +
                    uri = URI(@config['file-server-uri'])
         
     | 
| 
      
 68 
     | 
    
         
            +
                    https = Net::HTTP.new(uri.host, uri.port)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    https.use_ssl = true
         
     | 
| 
      
 70 
     | 
    
         
            +
                    https.ssl_version = :TLSv1_2
         
     | 
| 
      
 71 
     | 
    
         
            +
                    https.ca_file = @config['ssl-ca-cert']
         
     | 
| 
      
 72 
     | 
    
         
            +
                    https.cert = OpenSSL::X509::Certificate.new(ssl_cert)
         
     | 
| 
      
 73 
     | 
    
         
            +
                    https.key = OpenSSL::PKey::RSA.new(ssl_key)
         
     | 
| 
      
 74 
     | 
    
         
            +
                    https.verify_mode = OpenSSL::SSL::VERIFY_PEER
         
     | 
| 
      
 75 
     | 
    
         
            +
                    https.open_timeout = @config['file-server-conn-timeout']
         
     | 
| 
      
 76 
     | 
    
         
            +
                    https
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
       78 
78 
     | 
    
         
             
                end
         
     | 
| 
       79 
79 
     | 
    
         | 
| 
       80 
80 
     | 
    
         
             
                def request_file(path, params, file)
         
     | 
| 
         @@ -5,6 +5,7 @@ require 'addressable/uri' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            require 'bolt'
         
     | 
| 
       6 
6 
     | 
    
         
             
            require 'bolt/error'
         
     | 
| 
       7 
7 
     | 
    
         
             
            require 'bolt/inventory'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require 'bolt/project'
         
     | 
| 
       8 
9 
     | 
    
         
             
            require 'bolt/target'
         
     | 
| 
       9 
10 
     | 
    
         
             
            require 'bolt_server/file_cache'
         
     | 
| 
       10 
11 
     | 
    
         
             
            require 'bolt/task/puppet_server'
         
     | 
| 
         @@ -13,7 +14,9 @@ require 'json-schema' 
     | 
|
| 
       13 
14 
     | 
    
         | 
| 
       14 
15 
     | 
    
         
             
            # These are only needed for the `/plans` endpoint.
         
     | 
| 
       15 
16 
     | 
    
         
             
            require 'puppet'
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            # Needed by the `/project_file_metadatas` endpoint
         
     | 
| 
      
 19 
     | 
    
         
            +
            require 'puppet/file_serving/fileset'
         
     | 
| 
       17 
20 
     | 
    
         | 
| 
       18 
21 
     | 
    
         
             
            module BoltServer
         
     | 
| 
       19 
22 
     | 
    
         
             
              class TransportApp < Sinatra::Base
         
     | 
| 
         @@ -34,6 +37,17 @@ module BoltServer 
     | 
|
| 
       34 
37 
     | 
    
         
             
                  transport-winrm
         
     | 
| 
       35 
38 
     | 
    
         
             
                ].freeze
         
     | 
| 
       36 
39 
     | 
    
         | 
| 
      
 40 
     | 
    
         
            +
                # PE_BOLTLIB_PATH is intended to function exactly like the BOLTLIB_PATH used
         
     | 
| 
      
 41 
     | 
    
         
            +
                # in Bolt::PAL. Paths and variable names are similar to what exists in
         
     | 
| 
      
 42 
     | 
    
         
            +
                # Bolt::PAL, but with a 'PE' prefix.
         
     | 
| 
      
 43 
     | 
    
         
            +
                PE_BOLTLIB_PATH = '/opt/puppetlabs/server/apps/bolt-server/pe-bolt-modules'
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                # For now at least, we maintain an entirely separate codedir from
         
     | 
| 
      
 46 
     | 
    
         
            +
                # puppetserver by default, so that filesync can work properly. If filesync
         
     | 
| 
      
 47 
     | 
    
         
            +
                # is not used, this can instead match the usual puppetserver codedir.
         
     | 
| 
      
 48 
     | 
    
         
            +
                # See the `orchestrator.bolt.codedir` tk config setting.
         
     | 
| 
      
 49 
     | 
    
         
            +
                DEFAULT_BOLT_CODEDIR = '/opt/puppetlabs/server/data/orchestration-services/code'
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
       37 
51 
     | 
    
         
             
                def initialize(config)
         
     | 
| 
       38 
52 
     | 
    
         
             
                  @config = config
         
     | 
| 
       39 
53 
     | 
    
         
             
                  @schemas = Hash[REQUEST_SCHEMAS.map do |basename|
         
     | 
| 
         @@ -190,21 +204,82 @@ module BoltServer 
     | 
|
| 
       190 
204 
     | 
    
         
             
                  [@executor.run_script(target, file_location, body['arguments'])]
         
     | 
| 
       191 
205 
     | 
    
         
             
                end
         
     | 
| 
       192 
206 
     | 
    
         | 
| 
       193 
     | 
    
         
            -
                 
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
             
     | 
| 
       202 
     | 
    
         
            -
             
     | 
| 
       203 
     | 
    
         
            -
             
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
                       
     | 
| 
      
 207 
     | 
    
         
            +
                # This function is nearly identical to Bolt::Pal's `with_puppet_settings` with the
         
     | 
| 
      
 208 
     | 
    
         
            +
                # one difference that we set the codedir to point to actual code, rather than the
         
     | 
| 
      
 209 
     | 
    
         
            +
                # tmpdir. We only use this funtion inside the Modulepath initializer so that Puppet
         
     | 
| 
      
 210 
     | 
    
         
            +
                # is correctly configured to pull environment configuration correctly. If we don't
         
     | 
| 
      
 211 
     | 
    
         
            +
                # set codedir in this way: when we try to load and interpolate the modulepath it
         
     | 
| 
      
 212 
     | 
    
         
            +
                # won't correctly load.
         
     | 
| 
      
 213 
     | 
    
         
            +
                #
         
     | 
| 
      
 214 
     | 
    
         
            +
                # WARNING: THIS FUNCTION SHOULD ONLY BE CALLED INSIDE A SYNCHRONIZED PAL MUTEX
         
     | 
| 
      
 215 
     | 
    
         
            +
                def with_pe_pal_init_settings(codedir, environmentpath, basemodulepath)
         
     | 
| 
      
 216 
     | 
    
         
            +
                  Dir.mktmpdir('pe-bolt') do |dir|
         
     | 
| 
      
 217 
     | 
    
         
            +
                    cli = []
         
     | 
| 
      
 218 
     | 
    
         
            +
                    Puppet::Settings::REQUIRED_APP_SETTINGS.each do |setting|
         
     | 
| 
      
 219 
     | 
    
         
            +
                      dir = setting == :codedir ? codedir : dir
         
     | 
| 
      
 220 
     | 
    
         
            +
                      cli << "--#{setting}" << dir
         
     | 
| 
       207 
221 
     | 
    
         
             
                    end
         
     | 
| 
      
 222 
     | 
    
         
            +
                    cli << "--environmentpath" << environmentpath
         
     | 
| 
      
 223 
     | 
    
         
            +
                    cli << "--basemodulepath" << basemodulepath
         
     | 
| 
      
 224 
     | 
    
         
            +
                    Puppet.settings.send(:clear_everything_for_tests)
         
     | 
| 
      
 225 
     | 
    
         
            +
                    Puppet.initialize_settings(cli)
         
     | 
| 
      
 226 
     | 
    
         
            +
                    yield
         
     | 
| 
      
 227 
     | 
    
         
            +
                  end
         
     | 
| 
      
 228 
     | 
    
         
            +
                end
         
     | 
| 
      
 229 
     | 
    
         
            +
             
     | 
| 
      
 230 
     | 
    
         
            +
                # Use puppet to identify the modulepath from an environment.
         
     | 
| 
      
 231 
     | 
    
         
            +
                #
         
     | 
| 
      
 232 
     | 
    
         
            +
                # WARNING: THIS FUNCTION SHOULD ONLY BE CALLED INSIDE A SYNCHRONIZED PAL MUTEX
         
     | 
| 
      
 233 
     | 
    
         
            +
                def modulepath_from_environment(environment_name)
         
     | 
| 
      
 234 
     | 
    
         
            +
                  codedir = DEFAULT_BOLT_CODEDIR
         
     | 
| 
      
 235 
     | 
    
         
            +
                  environmentpath = "#{codedir}/environments"
         
     | 
| 
      
 236 
     | 
    
         
            +
                  basemodulepath = "#{codedir}/modules:/opt/puppetlabs/puppet/modules"
         
     | 
| 
      
 237 
     | 
    
         
            +
                  modulepath_dirs = nil
         
     | 
| 
      
 238 
     | 
    
         
            +
                  with_pe_pal_init_settings(codedir, environmentpath, basemodulepath) do
         
     | 
| 
      
 239 
     | 
    
         
            +
                    environment = Puppet.lookup(:environments).get!(environment_name)
         
     | 
| 
      
 240 
     | 
    
         
            +
                    modulepath_dirs = environment.modulepath
         
     | 
| 
      
 241 
     | 
    
         
            +
                  end
         
     | 
| 
      
 242 
     | 
    
         
            +
                  modulepath_dirs
         
     | 
| 
      
 243 
     | 
    
         
            +
                end
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                def in_pe_pal_env(environment)
         
     | 
| 
      
 246 
     | 
    
         
            +
                  return [400, '`environment` is a required argument'] if environment.nil?
         
     | 
| 
      
 247 
     | 
    
         
            +
                  @pal_mutex.synchronize do
         
     | 
| 
      
 248 
     | 
    
         
            +
                    modulepath_obj = Bolt::Config::Modulepath.new(
         
     | 
| 
      
 249 
     | 
    
         
            +
                      modulepath_from_environment(environment),
         
     | 
| 
      
 250 
     | 
    
         
            +
                      boltlib_path: [PE_BOLTLIB_PATH, Bolt::Config::Modulepath::BOLTLIB_PATH]
         
     | 
| 
      
 251 
     | 
    
         
            +
                    )
         
     | 
| 
      
 252 
     | 
    
         
            +
                    pal = Bolt::PAL.new(modulepath_obj, nil, nil)
         
     | 
| 
      
 253 
     | 
    
         
            +
                    yield pal
         
     | 
| 
      
 254 
     | 
    
         
            +
                  rescue Puppet::Environments::EnvironmentNotFound
         
     | 
| 
      
 255 
     | 
    
         
            +
                    [400, {
         
     | 
| 
      
 256 
     | 
    
         
            +
                      "class" => 'bolt/unknown-environment',
         
     | 
| 
      
 257 
     | 
    
         
            +
                      "message" => "Environment #{environment} not found"
         
     | 
| 
      
 258 
     | 
    
         
            +
                    }.to_json]
         
     | 
| 
      
 259 
     | 
    
         
            +
                  rescue Bolt::Error => e
         
     | 
| 
      
 260 
     | 
    
         
            +
                    [400, e.to_json]
         
     | 
| 
      
 261 
     | 
    
         
            +
                  end
         
     | 
| 
      
 262 
     | 
    
         
            +
                end
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                def in_bolt_project(bolt_project)
         
     | 
| 
      
 265 
     | 
    
         
            +
                  return [400, '`project_ref` is a required argument'] if bolt_project.nil?
         
     | 
| 
      
 266 
     | 
    
         
            +
                  project_dir = File.join(@config['projects-dir'], bolt_project)
         
     | 
| 
      
 267 
     | 
    
         
            +
                  return [400, "`project_ref`: #{project_dir} does not exist"] unless Dir.exist?(project_dir)
         
     | 
| 
      
 268 
     | 
    
         
            +
                  @pal_mutex.synchronize do
         
     | 
| 
      
 269 
     | 
    
         
            +
                    project = Bolt::Project.create_project(project_dir)
         
     | 
| 
      
 270 
     | 
    
         
            +
                    bolt_config = Bolt::Config.from_project(project, { log: { 'bolt-debug.log' => 'disable' } })
         
     | 
| 
      
 271 
     | 
    
         
            +
                    modulepath_object = Bolt::Config::Modulepath.new(
         
     | 
| 
      
 272 
     | 
    
         
            +
                      bolt_config.modulepath,
         
     | 
| 
      
 273 
     | 
    
         
            +
                      boltlib_path: [PE_BOLTLIB_PATH, Bolt::Config::Modulepath::BOLTLIB_PATH]
         
     | 
| 
      
 274 
     | 
    
         
            +
                    )
         
     | 
| 
      
 275 
     | 
    
         
            +
                    pal = Bolt::PAL.new(modulepath_object, nil, nil, nil, nil, nil, bolt_config.project)
         
     | 
| 
      
 276 
     | 
    
         
            +
                    context = {
         
     | 
| 
      
 277 
     | 
    
         
            +
                      pal: pal,
         
     | 
| 
      
 278 
     | 
    
         
            +
                      config: bolt_config
         
     | 
| 
      
 279 
     | 
    
         
            +
                    }
         
     | 
| 
      
 280 
     | 
    
         
            +
                    yield context
         
     | 
| 
      
 281 
     | 
    
         
            +
                  rescue Bolt::Error => e
         
     | 
| 
      
 282 
     | 
    
         
            +
                    [400, e.to_json]
         
     | 
| 
       208 
283 
     | 
    
         
             
                  end
         
     | 
| 
       209 
284 
     | 
    
         
             
                end
         
     | 
| 
       210 
285 
     | 
    
         | 
| 
         @@ -221,14 +296,12 @@ module BoltServer 
     | 
|
| 
       221 
296 
     | 
    
         
             
                  plan_info
         
     | 
| 
       222 
297 
     | 
    
         
             
                end
         
     | 
| 
       223 
298 
     | 
    
         | 
| 
       224 
     | 
    
         
            -
                def build_puppetserver_uri(file_identifier, module_name,  
     | 
| 
      
 299 
     | 
    
         
            +
                def build_puppetserver_uri(file_identifier, module_name, parameters)
         
     | 
| 
       225 
300 
     | 
    
         
             
                  segments = file_identifier.split('/', 3)
         
     | 
| 
       226 
301 
     | 
    
         
             
                  if segments.size == 1
         
     | 
| 
       227 
302 
     | 
    
         
             
                    {
         
     | 
| 
       228 
303 
     | 
    
         
             
                      'path' => "/puppet/v3/file_content/tasks/#{module_name}/#{file_identifier}",
         
     | 
| 
       229 
     | 
    
         
            -
                      'params' =>  
     | 
| 
       230 
     | 
    
         
            -
                        'environment' => environment
         
     | 
| 
       231 
     | 
    
         
            -
                      }
         
     | 
| 
      
 304 
     | 
    
         
            +
                      'params' => parameters
         
     | 
| 
       232 
305 
     | 
    
         
             
                    }
         
     | 
| 
       233 
306 
     | 
    
         
             
                  else
         
     | 
| 
       234 
307 
     | 
    
         
             
                    module_segment, mount_segment, name_segment = *segments
         
     | 
| 
         @@ -241,14 +314,12 @@ module BoltServer 
     | 
|
| 
       241 
314 
     | 
    
         
             
                                when 'lib'
         
     | 
| 
       242 
315 
     | 
    
         
             
                                  "/puppet/v3/file_content/plugins/#{name_segment}"
         
     | 
| 
       243 
316 
     | 
    
         
             
                                end,
         
     | 
| 
       244 
     | 
    
         
            -
                      'params' =>  
     | 
| 
       245 
     | 
    
         
            -
                        'environment' => environment
         
     | 
| 
       246 
     | 
    
         
            -
                      }
         
     | 
| 
      
 317 
     | 
    
         
            +
                      'params' => parameters
         
     | 
| 
       247 
318 
     | 
    
         
             
                    }
         
     | 
| 
       248 
319 
     | 
    
         
             
                  end
         
     | 
| 
       249 
320 
     | 
    
         
             
                end
         
     | 
| 
       250 
321 
     | 
    
         | 
| 
       251 
     | 
    
         
            -
                def pe_task_info(pal, module_name, task_name,  
     | 
| 
      
 322 
     | 
    
         
            +
                def pe_task_info(pal, module_name, task_name, parameters)
         
     | 
| 
       252 
323 
     | 
    
         
             
                  # Handle case where task name is simply module name with special `init` task
         
     | 
| 
       253 
324 
     | 
    
         
             
                  task_name = if task_name == 'init' || task_name.nil?
         
     | 
| 
       254 
325 
     | 
    
         
             
                                module_name
         
     | 
| 
         @@ -261,7 +332,7 @@ module BoltServer 
     | 
|
| 
       261 
332 
     | 
    
         
             
                      'filename' => file_hash['name'],
         
     | 
| 
       262 
333 
     | 
    
         
             
                      'sha256' => Digest::SHA256.hexdigest(File.read(file_hash['path'])),
         
     | 
| 
       263 
334 
     | 
    
         
             
                      'size_bytes' => File.size(file_hash['path']),
         
     | 
| 
       264 
     | 
    
         
            -
                      'uri' => build_puppetserver_uri(file_hash['name'], module_name,  
     | 
| 
      
 335 
     | 
    
         
            +
                      'uri' => build_puppetserver_uri(file_hash['name'], module_name, parameters)
         
     | 
| 
       265 
336 
     | 
    
         
             
                    }
         
     | 
| 
       266 
337 
     | 
    
         
             
                  end
         
     | 
| 
       267 
338 
     | 
    
         
             
                  {
         
     | 
| 
         @@ -271,6 +342,38 @@ module BoltServer 
     | 
|
| 
       271 
342 
     | 
    
         
             
                  }
         
     | 
| 
       272 
343 
     | 
    
         
             
                end
         
     | 
| 
       273 
344 
     | 
    
         | 
| 
      
 345 
     | 
    
         
            +
                def allowed_helper(metadata, allowlist)
         
     | 
| 
      
 346 
     | 
    
         
            +
                  allowed = allowlist.nil? || allowlist.include?(metadata['name']) ? true : false
         
     | 
| 
      
 347 
     | 
    
         
            +
                  metadata.merge({ 'allowed' => allowed })
         
     | 
| 
      
 348 
     | 
    
         
            +
                end
         
     | 
| 
      
 349 
     | 
    
         
            +
             
     | 
| 
      
 350 
     | 
    
         
            +
                def task_list(pal)
         
     | 
| 
      
 351 
     | 
    
         
            +
                  tasks = pal.list_tasks
         
     | 
| 
      
 352 
     | 
    
         
            +
                  tasks.map { |task_name, _description| { 'name' => task_name } }
         
     | 
| 
      
 353 
     | 
    
         
            +
                end
         
     | 
| 
      
 354 
     | 
    
         
            +
             
     | 
| 
      
 355 
     | 
    
         
            +
                def plan_list(pal)
         
     | 
| 
      
 356 
     | 
    
         
            +
                  plans = pal.list_plans.flatten
         
     | 
| 
      
 357 
     | 
    
         
            +
                  plans.map { |plan_name| { 'name' => plan_name } }
         
     | 
| 
      
 358 
     | 
    
         
            +
                end
         
     | 
| 
      
 359 
     | 
    
         
            +
             
     | 
| 
      
 360 
     | 
    
         
            +
                def file_metadatas(pal, module_name, file)
         
     | 
| 
      
 361 
     | 
    
         
            +
                  pal.in_bolt_compiler do
         
     | 
| 
      
 362 
     | 
    
         
            +
                    mod = Puppet.lookup(:current_environment).module(module_name)
         
     | 
| 
      
 363 
     | 
    
         
            +
                    raise ArgumentError, "`module_name`: #{module_name} does not exist" unless mod
         
     | 
| 
      
 364 
     | 
    
         
            +
                    abs_file_path = mod.file(file)
         
     | 
| 
      
 365 
     | 
    
         
            +
                    raise ArgumentError, "`file`: #{file} does not exist inside the module's 'files' directory" unless abs_file_path
         
     | 
| 
      
 366 
     | 
    
         
            +
                    fileset = Puppet::FileServing::Fileset.new(abs_file_path, 'recurse' => 'yes')
         
     | 
| 
      
 367 
     | 
    
         
            +
                    Puppet::FileServing::Fileset.merge(fileset).collect do |relative_file_path, base_path|
         
     | 
| 
      
 368 
     | 
    
         
            +
                      metadata = Puppet::FileServing::Metadata.new(base_path, relative_path: relative_file_path)
         
     | 
| 
      
 369 
     | 
    
         
            +
                      metadata.checksum_type = 'sha256'
         
     | 
| 
      
 370 
     | 
    
         
            +
                      metadata.links = 'follow'
         
     | 
| 
      
 371 
     | 
    
         
            +
                      metadata.collect
         
     | 
| 
      
 372 
     | 
    
         
            +
                      metadata.to_data_hash
         
     | 
| 
      
 373 
     | 
    
         
            +
                    end
         
     | 
| 
      
 374 
     | 
    
         
            +
                  end
         
     | 
| 
      
 375 
     | 
    
         
            +
                end
         
     | 
| 
      
 376 
     | 
    
         
            +
             
     | 
| 
       274 
377 
     | 
    
         
             
                get '/' do
         
     | 
| 
       275 
378 
     | 
    
         
             
                  200
         
     | 
| 
       276 
379 
     | 
    
         
             
                end
         
     | 
| 
         @@ -401,12 +504,40 @@ module BoltServer 
     | 
|
| 
       401 
504 
     | 
    
         
             
                  end
         
     | 
| 
       402 
505 
     | 
    
         
             
                end
         
     | 
| 
       403 
506 
     | 
    
         | 
| 
      
 507 
     | 
    
         
            +
                # Fetches the metadata for a single plan
         
     | 
| 
      
 508 
     | 
    
         
            +
                #
         
     | 
| 
      
 509 
     | 
    
         
            +
                # @param project_ref [String] the project to fetch the plan from
         
     | 
| 
      
 510 
     | 
    
         
            +
                get '/project_plans/:module_name/:plan_name' do
         
     | 
| 
      
 511 
     | 
    
         
            +
                  in_bolt_project(params['project_ref']) do |context|
         
     | 
| 
      
 512 
     | 
    
         
            +
                    plan_info = pe_plan_info(context[:pal], params[:module_name], params[:plan_name])
         
     | 
| 
      
 513 
     | 
    
         
            +
                    plan_info = allowed_helper(plan_info, context[:config].project.plans)
         
     | 
| 
      
 514 
     | 
    
         
            +
                    [200, plan_info.to_json]
         
     | 
| 
      
 515 
     | 
    
         
            +
                  end
         
     | 
| 
      
 516 
     | 
    
         
            +
                end
         
     | 
| 
      
 517 
     | 
    
         
            +
             
     | 
| 
       404 
518 
     | 
    
         
             
                # Fetches the metadata for a single task
         
     | 
| 
       405 
519 
     | 
    
         
             
                #
         
     | 
| 
       406 
520 
     | 
    
         
             
                # @param environment [String] the environment to fetch the task from
         
     | 
| 
       407 
521 
     | 
    
         
             
                get '/tasks/:module_name/:task_name' do
         
     | 
| 
       408 
522 
     | 
    
         
             
                  in_pe_pal_env(params['environment']) do |pal|
         
     | 
| 
       409 
     | 
    
         
            -
                     
     | 
| 
      
 523 
     | 
    
         
            +
                    ps_parameters = {
         
     | 
| 
      
 524 
     | 
    
         
            +
                      'environment' => params['environment']
         
     | 
| 
      
 525 
     | 
    
         
            +
                    }
         
     | 
| 
      
 526 
     | 
    
         
            +
                    task_info = pe_task_info(pal, params[:module_name], params[:task_name], ps_parameters)
         
     | 
| 
      
 527 
     | 
    
         
            +
                    [200, task_info.to_json]
         
     | 
| 
      
 528 
     | 
    
         
            +
                  end
         
     | 
| 
      
 529 
     | 
    
         
            +
                end
         
     | 
| 
      
 530 
     | 
    
         
            +
             
     | 
| 
      
 531 
     | 
    
         
            +
                # Fetches the metadata for a single task
         
     | 
| 
      
 532 
     | 
    
         
            +
                #
         
     | 
| 
      
 533 
     | 
    
         
            +
                # @param bolt_project_ref [String] the reference to the bolt-project directory to load task metadata from
         
     | 
| 
      
 534 
     | 
    
         
            +
                get '/project_tasks/:module_name/:task_name' do
         
     | 
| 
      
 535 
     | 
    
         
            +
                  in_bolt_project(params['project_ref']) do |context|
         
     | 
| 
      
 536 
     | 
    
         
            +
                    ps_parameters = {
         
     | 
| 
      
 537 
     | 
    
         
            +
                      'project' => params['project_ref']
         
     | 
| 
      
 538 
     | 
    
         
            +
                    }
         
     | 
| 
      
 539 
     | 
    
         
            +
                    task_info = pe_task_info(context[:pal], params[:module_name], params[:task_name], ps_parameters)
         
     | 
| 
      
 540 
     | 
    
         
            +
                    task_info = allowed_helper(task_info, context[:config].project.tasks)
         
     | 
| 
       410 
541 
     | 
    
         
             
                    [200, task_info.to_json]
         
     | 
| 
       411 
542 
     | 
    
         
             
                  end
         
     | 
| 
       412 
543 
     | 
    
         
             
                end
         
     | 
| 
         @@ -435,13 +566,30 @@ module BoltServer 
     | 
|
| 
       435 
566 
     | 
    
         
             
                  end
         
     | 
| 
       436 
567 
     | 
    
         
             
                end
         
     | 
| 
       437 
568 
     | 
    
         | 
| 
      
 569 
     | 
    
         
            +
                # Fetches the list of plans for a project
         
     | 
| 
      
 570 
     | 
    
         
            +
                #
         
     | 
| 
      
 571 
     | 
    
         
            +
                # @param project_ref [String] the project to fetch the list of plans from
         
     | 
| 
      
 572 
     | 
    
         
            +
                get '/project_plans' do
         
     | 
| 
      
 573 
     | 
    
         
            +
                  in_bolt_project(params['project_ref']) do |context|
         
     | 
| 
      
 574 
     | 
    
         
            +
                    plans_response = plan_list(context[:pal])
         
     | 
| 
      
 575 
     | 
    
         
            +
             
     | 
| 
      
 576 
     | 
    
         
            +
                    # Dig in context for the allowlist of plans from project object
         
     | 
| 
      
 577 
     | 
    
         
            +
                    plans_response.map! { |metadata| allowed_helper(metadata, context[:config].project.plans) }
         
     | 
| 
      
 578 
     | 
    
         
            +
             
     | 
| 
      
 579 
     | 
    
         
            +
                    # We structure this array of plans to be an array of hashes so that it matches the structure
         
     | 
| 
      
 580 
     | 
    
         
            +
                    # returned by the puppetserver API that serves data like this. Structuring the output this way
         
     | 
| 
      
 581 
     | 
    
         
            +
                    # makes switching between puppetserver and bolt-server easier, which makes changes to switch
         
     | 
| 
      
 582 
     | 
    
         
            +
                    # to bolt-server smaller/simpler.
         
     | 
| 
      
 583 
     | 
    
         
            +
                    [200, plans_response.to_json]
         
     | 
| 
      
 584 
     | 
    
         
            +
                  end
         
     | 
| 
      
 585 
     | 
    
         
            +
                end
         
     | 
| 
      
 586 
     | 
    
         
            +
             
     | 
| 
       438 
587 
     | 
    
         
             
                # Fetches the list of tasks for an environment
         
     | 
| 
       439 
588 
     | 
    
         
             
                #
         
     | 
| 
       440 
589 
     | 
    
         
             
                # @param environment [String] the environment to fetch the list of tasks from
         
     | 
| 
       441 
590 
     | 
    
         
             
                get '/tasks' do
         
     | 
| 
       442 
591 
     | 
    
         
             
                  in_pe_pal_env(params['environment']) do |pal|
         
     | 
| 
       443 
     | 
    
         
            -
                     
     | 
| 
       444 
     | 
    
         
            -
                    tasks_response = tasks.map { |task_name, _description| { 'name' => task_name } }.to_json
         
     | 
| 
      
 592 
     | 
    
         
            +
                    tasks_response = task_list(pal).to_json
         
     | 
| 
       445 
593 
     | 
    
         | 
| 
       446 
594 
     | 
    
         
             
                    # We structure this array of tasks to be an array of hashes so that it matches the structure
         
     | 
| 
       447 
595 
     | 
    
         
             
                    # returned by the puppetserver API that serves data like this. Structuring the output this way
         
     | 
| 
         @@ -451,6 +599,37 @@ module BoltServer 
     | 
|
| 
       451 
599 
     | 
    
         
             
                  end
         
     | 
| 
       452 
600 
     | 
    
         
             
                end
         
     | 
| 
       453 
601 
     | 
    
         | 
| 
      
 602 
     | 
    
         
            +
                # Fetches the list of tasks for a bolt-project
         
     | 
| 
      
 603 
     | 
    
         
            +
                #
         
     | 
| 
      
 604 
     | 
    
         
            +
                # @param project_ref [String] the project to fetch the list of tasks from
         
     | 
| 
      
 605 
     | 
    
         
            +
                get '/project_tasks' do
         
     | 
| 
      
 606 
     | 
    
         
            +
                  in_bolt_project(params['project_ref']) do |context|
         
     | 
| 
      
 607 
     | 
    
         
            +
                    tasks_response = task_list(context[:pal])
         
     | 
| 
      
 608 
     | 
    
         
            +
             
     | 
| 
      
 609 
     | 
    
         
            +
                    # Dig in context for the allowlist of tasks from project object
         
     | 
| 
      
 610 
     | 
    
         
            +
                    tasks_response.map! { |metadata| allowed_helper(metadata, context[:config].project.tasks) }
         
     | 
| 
      
 611 
     | 
    
         
            +
             
     | 
| 
      
 612 
     | 
    
         
            +
                    # We structure this array of tasks to be an array of hashes so that it matches the structure
         
     | 
| 
      
 613 
     | 
    
         
            +
                    # returned by the puppetserver API that serves data like this. Structuring the output this way
         
     | 
| 
      
 614 
     | 
    
         
            +
                    # makes switching between puppetserver and bolt-server easier, which makes changes to switch
         
     | 
| 
      
 615 
     | 
    
         
            +
                    # to bolt-server smaller/simpler.
         
     | 
| 
      
 616 
     | 
    
         
            +
                    [200, tasks_response.to_json]
         
     | 
| 
      
 617 
     | 
    
         
            +
                  end
         
     | 
| 
      
 618 
     | 
    
         
            +
                end
         
     | 
| 
      
 619 
     | 
    
         
            +
             
     | 
| 
      
 620 
     | 
    
         
            +
                # Implements puppetserver's file_metadatas endpoint for projects.
         
     | 
| 
      
 621 
     | 
    
         
            +
                #
         
     | 
| 
      
 622 
     | 
    
         
            +
                # @param project_ref [String] the project_ref to fetch the file metadatas from
         
     | 
| 
      
 623 
     | 
    
         
            +
                get '/project_file_metadatas/:module_name/*' do
         
     | 
| 
      
 624 
     | 
    
         
            +
                  in_bolt_project(params['project_ref']) do |context|
         
     | 
| 
      
 625 
     | 
    
         
            +
                    file = params[:splat].first
         
     | 
| 
      
 626 
     | 
    
         
            +
                    metadatas = file_metadatas(context[:pal], params[:module_name], file)
         
     | 
| 
      
 627 
     | 
    
         
            +
                    [200, metadatas.to_json]
         
     | 
| 
      
 628 
     | 
    
         
            +
                  end
         
     | 
| 
      
 629 
     | 
    
         
            +
                rescue ArgumentError => e
         
     | 
| 
      
 630 
     | 
    
         
            +
                  [400, e.message]
         
     | 
| 
      
 631 
     | 
    
         
            +
                end
         
     | 
| 
      
 632 
     | 
    
         
            +
             
     | 
| 
       454 
633 
     | 
    
         
             
                error 404 do
         
     | 
| 
       455 
634 
     | 
    
         
             
                  err = Bolt::Error.new("Could not find route #{request.path}",
         
     | 
| 
       456 
635 
     | 
    
         
             
                                        'boltserver/not-found')
         
     | 
| 
         @@ -105,7 +105,7 @@ module BoltSpec 
     | 
|
| 
       105 
105 
     | 
    
         | 
| 
       106 
106 
     | 
    
         
             
                  # Set the things
         
     | 
| 
       107 
107 
     | 
    
         
             
                  Puppet[:tasks] = true
         
     | 
| 
       108 
     | 
    
         
            -
                  RSpec.configuration.module_path = [modulepath, Bolt:: 
     | 
| 
      
 108 
     | 
    
         
            +
                  RSpec.configuration.module_path = [modulepath, Bolt::Config::Modulepath::BOLTLIB_PATH].join(File::PATH_SEPARATOR)
         
     | 
| 
       109 
109 
     | 
    
         
             
                  opts = {
         
     | 
| 
       110 
110 
     | 
    
         
             
                    bolt_executor: executor,
         
     | 
| 
       111 
111 
     | 
    
         
             
                    bolt_inventory: inventory,
         
     | 
| 
         @@ -142,10 +142,10 @@ module BoltSpec 
     | 
|
| 
       142 
142 
     | 
    
         
             
                # Override in your tests
         
     | 
| 
       143 
143 
     | 
    
         
             
                def config
         
     | 
| 
       144 
144 
     | 
    
         
             
                  @config ||= begin
         
     | 
| 
       145 
     | 
    
         
            -
             
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
      
 145 
     | 
    
         
            +
                    conf = Bolt::Config.default
         
     | 
| 
      
 146 
     | 
    
         
            +
                    conf.modulepath = [modulepath].flatten
         
     | 
| 
      
 147 
     | 
    
         
            +
                    conf
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
       149 
149 
     | 
    
         
             
                end
         
     | 
| 
       150 
150 
     | 
    
         | 
| 
       151 
151 
     | 
    
         
             
                def plugins
         
     | 
| 
         @@ -153,7 +153,9 @@ module BoltSpec 
     | 
|
| 
       153 
153 
     | 
    
         
             
                end
         
     | 
| 
       154 
154 
     | 
    
         | 
| 
       155 
155 
     | 
    
         
             
                def pal
         
     | 
| 
       156 
     | 
    
         
            -
                  @pal ||= Bolt::PAL.new(config.modulepath, 
     | 
| 
      
 156 
     | 
    
         
            +
                  @pal ||= Bolt::PAL.new(Bolt::Config::Modulepath.new(config.modulepath),
         
     | 
| 
      
 157 
     | 
    
         
            +
                                         config.hiera_config,
         
     | 
| 
      
 158 
     | 
    
         
            +
                                         config.project.resource_types)
         
     | 
| 
       157 
159 
     | 
    
         
             
                end
         
     | 
| 
       158 
160 
     | 
    
         | 
| 
       159 
161 
     | 
    
         
             
                BoltSpec::Plans::MOCKED_ACTIONS.each do |action|
         
     | 
    
        data/lib/bolt_spec/plans.rb
    CHANGED
    
    
| 
         @@ -40,7 +40,7 @@ module BoltSpec 
     | 
|
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
                  def module_file_id(file)
         
     | 
| 
       42 
42 
     | 
    
         
             
                    modpath = @modulepath.select { |path| file =~ /^#{path}/ }
         
     | 
| 
       43 
     | 
    
         
            -
                    raise "Could not identify  
     | 
| 
      
 43 
     | 
    
         
            +
                    raise "Could not identify modulepath containing #{file}: #{modpath}" unless modpath.size == 1
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                    path = Pathname.new(file)
         
     | 
| 
       46 
46 
     | 
    
         
             
                    relative = path.relative_path_from(Pathname.new(modpath.first))
         
     |