bolt 2.24.0 → 2.28.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Puppetfile +1 -1
- data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +2 -1
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +1 -1
- data/bolt-modules/dir/lib/puppet/functions/dir/children.rb +1 -1
- data/lib/bolt/analytics.rb +7 -3
- data/lib/bolt/applicator.rb +21 -21
- data/lib/bolt/bolt_option_parser.rb +75 -7
- data/lib/bolt/catalog.rb +4 -2
- data/lib/bolt/cli.rb +126 -147
- data/lib/bolt/config.rb +56 -26
- data/lib/bolt/config/options.rb +24 -2
- data/lib/bolt/executor.rb +1 -1
- data/lib/bolt/inventory.rb +8 -1
- data/lib/bolt/inventory/group.rb +1 -1
- data/lib/bolt/inventory/inventory.rb +1 -1
- data/lib/bolt/inventory/target.rb +1 -1
- data/lib/bolt/logger.rb +9 -2
- data/lib/bolt/outputter/logger.rb +1 -1
- data/lib/bolt/pal.rb +21 -10
- data/lib/bolt/pal/yaml_plan/evaluator.rb +1 -1
- data/lib/bolt/plugin/puppetdb.rb +1 -1
- data/lib/bolt/project.rb +63 -17
- data/lib/bolt/puppetdb/client.rb +1 -1
- data/lib/bolt/puppetdb/config.rb +1 -1
- data/lib/bolt/puppetfile.rb +160 -0
- data/lib/bolt/puppetfile/installer.rb +43 -0
- data/lib/bolt/puppetfile/module.rb +66 -0
- data/lib/bolt/r10k_log_proxy.rb +1 -1
- data/lib/bolt/rerun.rb +2 -2
- data/lib/bolt/result.rb +23 -0
- data/lib/bolt/shell.rb +1 -1
- data/lib/bolt/task.rb +1 -1
- data/lib/bolt/transport/base.rb +5 -5
- data/lib/bolt/transport/docker/connection.rb +1 -1
- data/lib/bolt/transport/local/connection.rb +1 -1
- data/lib/bolt/transport/ssh.rb +1 -1
- data/lib/bolt/transport/ssh/connection.rb +1 -1
- data/lib/bolt/transport/ssh/exec_connection.rb +1 -1
- data/lib/bolt/transport/winrm.rb +1 -1
- data/lib/bolt/transport/winrm/connection.rb +1 -1
- data/lib/bolt/util.rb +11 -11
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/base_config.rb +1 -1
- data/lib/bolt_server/config.rb +1 -1
- data/lib/bolt_server/file_cache.rb +12 -12
- data/lib/bolt_server/transport_app.rb +125 -26
- data/lib/bolt_spec/bolt_context.rb +4 -4
- data/lib/bolt_spec/run.rb +3 -0
- metadata +9 -12
data/lib/bolt/transport/winrm.rb
CHANGED
@@ -18,7 +18,7 @@ module Bolt
|
|
18
18
|
@user = @target.user
|
19
19
|
# Build set of extensions from extensions config as well as interpreters
|
20
20
|
|
21
|
-
@logger =
|
21
|
+
@logger = Bolt::Logger.logger(@target.safe_name)
|
22
22
|
logger.trace("Initializing winrm connection to #{@target.safe_name}")
|
23
23
|
@transport_logger = transport_logger
|
24
24
|
end
|
data/lib/bolt/util.rb
CHANGED
@@ -6,7 +6,7 @@ module Bolt
|
|
6
6
|
def read_yaml_hash(path, file_name)
|
7
7
|
require 'yaml'
|
8
8
|
|
9
|
-
logger =
|
9
|
+
logger = Bolt::Logger.logger(self)
|
10
10
|
path = File.expand_path(path)
|
11
11
|
content = File.open(path, "r:UTF-8") { |f| YAML.safe_load(f.read) } || {}
|
12
12
|
unless content.is_a?(Hash)
|
@@ -179,16 +179,16 @@ module Bolt
|
|
179
179
|
# object was frozen
|
180
180
|
frozen = obj.frozen?
|
181
181
|
cl = begin
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
182
|
+
obj.clone(freeze: false)
|
183
|
+
# Some datatypes, such as FalseClass, can't be unfrozen. These
|
184
|
+
# aren't the types we recurse on, so we can leave them frozen
|
185
|
+
rescue ArgumentError => e
|
186
|
+
if e.message =~ /can't unfreeze/
|
187
|
+
obj.clone
|
188
|
+
else
|
189
|
+
raise e
|
190
|
+
end
|
191
|
+
end
|
192
192
|
rescue *error_types
|
193
193
|
cloned[obj.object_id] = obj
|
194
194
|
obj
|
data/lib/bolt/version.rb
CHANGED
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
|
@@ -33,7 +33,7 @@ module BoltServer
|
|
33
33
|
@executor = executor
|
34
34
|
@cache_dir = config['cache-dir']
|
35
35
|
@config = config
|
36
|
-
@logger =
|
36
|
+
@logger = Bolt::Logger.logger(self)
|
37
37
|
@cache_dir_mutex = cache_dir_mutex
|
38
38
|
|
39
39
|
if do_purge
|
@@ -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'
|
@@ -191,20 +192,44 @@ module BoltServer
|
|
191
192
|
end
|
192
193
|
|
193
194
|
def in_pe_pal_env(environment)
|
194
|
-
if environment.nil?
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
195
|
+
return [400, '`environment` is a required argument'] if environment.nil?
|
196
|
+
@pal_mutex.synchronize do
|
197
|
+
pal = BoltServer::PE::PAL.new({}, environment)
|
198
|
+
yield pal
|
199
|
+
rescue Puppet::Environments::EnvironmentNotFound
|
200
|
+
[400, {
|
201
|
+
"class" => 'bolt/unknown-environment',
|
202
|
+
"message" => "Environment #{environment} not found"
|
203
|
+
}.to_json]
|
204
|
+
rescue Bolt::Error => e
|
205
|
+
[400, e.to_json]
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def in_bolt_project(bolt_project)
|
210
|
+
return [400, '`project_ref` is a required argument'] if bolt_project.nil?
|
211
|
+
project_dir = File.join(@config['projects-dir'], bolt_project)
|
212
|
+
return [400, "`project_ref`: #{project_dir} does not exist"] unless Dir.exist?(project_dir)
|
213
|
+
@pal_mutex.synchronize do
|
214
|
+
project = Bolt::Project.create_project(project_dir)
|
215
|
+
bolt_config = Bolt::Config.from_project(project, {})
|
216
|
+
pal = Bolt::PAL.new(bolt_config.modulepath, nil, nil, nil, nil, nil, bolt_config.project)
|
217
|
+
module_path = [
|
218
|
+
BoltServer::PE::PAL::PE_BOLTLIB_PATH,
|
219
|
+
Bolt::PAL::BOLTLIB_PATH,
|
220
|
+
*bolt_config.modulepath,
|
221
|
+
Bolt::PAL::MODULES_PATH
|
222
|
+
]
|
223
|
+
# CODEREVIEW: I *think* this is the only thing we need to make different between bolt's PAL. Is it acceptable
|
224
|
+
# to hack this? Modulepath is currently a readable attribute, could we make it writeable?
|
225
|
+
pal.instance_variable_set(:@modulepath, module_path)
|
226
|
+
context = {
|
227
|
+
pal: pal,
|
228
|
+
config: bolt_config
|
229
|
+
}
|
230
|
+
yield context
|
231
|
+
rescue Bolt::Error => e
|
232
|
+
[400, e.to_json]
|
208
233
|
end
|
209
234
|
end
|
210
235
|
|
@@ -221,14 +246,12 @@ module BoltServer
|
|
221
246
|
plan_info
|
222
247
|
end
|
223
248
|
|
224
|
-
def build_puppetserver_uri(file_identifier, module_name,
|
249
|
+
def build_puppetserver_uri(file_identifier, module_name, parameters)
|
225
250
|
segments = file_identifier.split('/', 3)
|
226
251
|
if segments.size == 1
|
227
252
|
{
|
228
253
|
'path' => "/puppet/v3/file_content/tasks/#{module_name}/#{file_identifier}",
|
229
|
-
'params' =>
|
230
|
-
'environment' => environment
|
231
|
-
}
|
254
|
+
'params' => parameters
|
232
255
|
}
|
233
256
|
else
|
234
257
|
module_segment, mount_segment, name_segment = *segments
|
@@ -241,14 +264,12 @@ module BoltServer
|
|
241
264
|
when 'lib'
|
242
265
|
"/puppet/v3/file_content/plugins/#{name_segment}"
|
243
266
|
end,
|
244
|
-
'params' =>
|
245
|
-
'environment' => environment
|
246
|
-
}
|
267
|
+
'params' => parameters
|
247
268
|
}
|
248
269
|
end
|
249
270
|
end
|
250
271
|
|
251
|
-
def pe_task_info(pal, module_name, task_name,
|
272
|
+
def pe_task_info(pal, module_name, task_name, parameters)
|
252
273
|
# Handle case where task name is simply module name with special `init` task
|
253
274
|
task_name = if task_name == 'init' || task_name.nil?
|
254
275
|
module_name
|
@@ -261,7 +282,7 @@ module BoltServer
|
|
261
282
|
'filename' => file_hash['name'],
|
262
283
|
'sha256' => Digest::SHA256.hexdigest(File.read(file_hash['path'])),
|
263
284
|
'size_bytes' => File.size(file_hash['path']),
|
264
|
-
'uri' => build_puppetserver_uri(file_hash['name'], module_name,
|
285
|
+
'uri' => build_puppetserver_uri(file_hash['name'], module_name, parameters)
|
265
286
|
}
|
266
287
|
end
|
267
288
|
{
|
@@ -271,6 +292,21 @@ module BoltServer
|
|
271
292
|
}
|
272
293
|
end
|
273
294
|
|
295
|
+
def allowed_helper(metadata, allowlist)
|
296
|
+
allowed = allowlist.nil? || allowlist.include?(metadata['name']) ? true : false
|
297
|
+
metadata.merge({ 'allowed' => allowed })
|
298
|
+
end
|
299
|
+
|
300
|
+
def task_list(pal)
|
301
|
+
tasks = pal.list_tasks
|
302
|
+
tasks.map { |task_name, _description| { 'name' => task_name } }
|
303
|
+
end
|
304
|
+
|
305
|
+
def plan_list(pal)
|
306
|
+
plans = pal.list_plans.flatten
|
307
|
+
plans.map { |plan_name| { 'name' => plan_name } }
|
308
|
+
end
|
309
|
+
|
274
310
|
get '/' do
|
275
311
|
200
|
276
312
|
end
|
@@ -401,12 +437,40 @@ module BoltServer
|
|
401
437
|
end
|
402
438
|
end
|
403
439
|
|
440
|
+
# Fetches the metadata for a single plan
|
441
|
+
#
|
442
|
+
# @param project_ref [String] the project to fetch the plan from
|
443
|
+
get '/project_plans/:module_name/:plan_name' do
|
444
|
+
in_bolt_project(params['project_ref']) do |context|
|
445
|
+
plan_info = pe_plan_info(context[:pal], params[:module_name], params[:plan_name])
|
446
|
+
plan_info = allowed_helper(plan_info, context[:config].project.plans)
|
447
|
+
[200, plan_info.to_json]
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
404
451
|
# Fetches the metadata for a single task
|
405
452
|
#
|
406
453
|
# @param environment [String] the environment to fetch the task from
|
407
454
|
get '/tasks/:module_name/:task_name' do
|
408
455
|
in_pe_pal_env(params['environment']) do |pal|
|
409
|
-
|
456
|
+
ps_parameters = {
|
457
|
+
'environment' => params['environment']
|
458
|
+
}
|
459
|
+
task_info = pe_task_info(pal, params[:module_name], params[:task_name], ps_parameters)
|
460
|
+
[200, task_info.to_json]
|
461
|
+
end
|
462
|
+
end
|
463
|
+
|
464
|
+
# Fetches the metadata for a single task
|
465
|
+
#
|
466
|
+
# @param bolt_project_ref [String] the reference to the bolt-project directory to load task metadata from
|
467
|
+
get '/project_tasks/:module_name/:task_name' do
|
468
|
+
in_bolt_project(params['project_ref']) do |context|
|
469
|
+
ps_parameters = {
|
470
|
+
'project' => params['project_ref']
|
471
|
+
}
|
472
|
+
task_info = pe_task_info(context[:pal], params[:module_name], params[:task_name], ps_parameters)
|
473
|
+
task_info = allowed_helper(task_info, context[:config].project.tasks)
|
410
474
|
[200, task_info.to_json]
|
411
475
|
end
|
412
476
|
end
|
@@ -435,13 +499,30 @@ module BoltServer
|
|
435
499
|
end
|
436
500
|
end
|
437
501
|
|
502
|
+
# Fetches the list of plans for a project
|
503
|
+
#
|
504
|
+
# @param project_ref [String] the project to fetch the list of plans from
|
505
|
+
get '/project_plans' do
|
506
|
+
in_bolt_project(params['project_ref']) do |context|
|
507
|
+
plans_response = plan_list(context[:pal])
|
508
|
+
|
509
|
+
# Dig in context for the allowlist of plans from project object
|
510
|
+
plans_response.map! { |metadata| allowed_helper(metadata, context[:config].project.plans) }
|
511
|
+
|
512
|
+
# We structure this array of plans to be an array of hashes so that it matches the structure
|
513
|
+
# returned by the puppetserver API that serves data like this. Structuring the output this way
|
514
|
+
# makes switching between puppetserver and bolt-server easier, which makes changes to switch
|
515
|
+
# to bolt-server smaller/simpler.
|
516
|
+
[200, plans_response.to_json]
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
438
520
|
# Fetches the list of tasks for an environment
|
439
521
|
#
|
440
522
|
# @param environment [String] the environment to fetch the list of tasks from
|
441
523
|
get '/tasks' do
|
442
524
|
in_pe_pal_env(params['environment']) do |pal|
|
443
|
-
|
444
|
-
tasks_response = tasks.map { |task_name, _description| { 'name' => task_name } }.to_json
|
525
|
+
tasks_response = task_list(pal).to_json
|
445
526
|
|
446
527
|
# We structure this array of tasks to be an array of hashes so that it matches the structure
|
447
528
|
# returned by the puppetserver API that serves data like this. Structuring the output this way
|
@@ -451,6 +532,24 @@ module BoltServer
|
|
451
532
|
end
|
452
533
|
end
|
453
534
|
|
535
|
+
# Fetches the list of tasks for a bolt-project
|
536
|
+
#
|
537
|
+
# @param project_ref [String] the project to fetch the list of tasks from
|
538
|
+
get '/project_tasks' do
|
539
|
+
in_bolt_project(params['project_ref']) do |context|
|
540
|
+
tasks_response = task_list(context[:pal])
|
541
|
+
|
542
|
+
# Dig in context for the allowlist of tasks from project object
|
543
|
+
tasks_response.map! { |metadata| allowed_helper(metadata, context[:config].project.tasks) }
|
544
|
+
|
545
|
+
# We structure this array of tasks to be an array of hashes so that it matches the structure
|
546
|
+
# returned by the puppetserver API that serves data like this. Structuring the output this way
|
547
|
+
# makes switching between puppetserver and bolt-server easier, which makes changes to switch
|
548
|
+
# to bolt-server smaller/simpler.
|
549
|
+
[200, tasks_response.to_json]
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
454
553
|
error 404 do
|
455
554
|
err = Bolt::Error.new("Could not find route #{request.path}",
|
456
555
|
'boltserver/not-found')
|
@@ -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
|
data/lib/bolt_spec/run.rb
CHANGED
@@ -8,6 +8,7 @@ require 'bolt/pal'
|
|
8
8
|
require 'bolt/plugin'
|
9
9
|
require 'bolt/puppetdb'
|
10
10
|
require 'bolt/util'
|
11
|
+
require 'bolt/logger'
|
11
12
|
|
12
13
|
# This is intended to provide a relatively stable method of executing bolt in process from tests.
|
13
14
|
module BoltSpec
|
@@ -153,6 +154,8 @@ module BoltSpec
|
|
153
154
|
end
|
154
155
|
|
155
156
|
def initialize(config_data, inventory_data, project_path)
|
157
|
+
Bolt::Logger.initialize_logging
|
158
|
+
|
156
159
|
@config_data = config_data || {}
|
157
160
|
@inventory_data = inventory_data || {}
|
158
161
|
@project_path = project_path
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bolt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.28.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -182,22 +182,16 @@ dependencies:
|
|
182
182
|
name: puppet
|
183
183
|
requirement: !ruby/object:Gem::Requirement
|
184
184
|
requirements:
|
185
|
-
- -
|
186
|
-
- !ruby/object:Gem::Version
|
187
|
-
version: 6.16.0
|
188
|
-
- - "<"
|
185
|
+
- - '='
|
189
186
|
- !ruby/object:Gem::Version
|
190
|
-
version:
|
187
|
+
version: 6.18.0
|
191
188
|
type: :runtime
|
192
189
|
prerelease: false
|
193
190
|
version_requirements: !ruby/object:Gem::Requirement
|
194
191
|
requirements:
|
195
|
-
- -
|
196
|
-
- !ruby/object:Gem::Version
|
197
|
-
version: 6.16.0
|
198
|
-
- - "<"
|
192
|
+
- - '='
|
199
193
|
- !ruby/object:Gem::Version
|
200
|
-
version:
|
194
|
+
version: 6.18.0
|
201
195
|
- !ruby/object:Gem::Dependency
|
202
196
|
name: puppetfile-resolver
|
203
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -504,6 +498,9 @@ files:
|
|
504
498
|
- lib/bolt/puppetdb.rb
|
505
499
|
- lib/bolt/puppetdb/client.rb
|
506
500
|
- lib/bolt/puppetdb/config.rb
|
501
|
+
- lib/bolt/puppetfile.rb
|
502
|
+
- lib/bolt/puppetfile/installer.rb
|
503
|
+
- lib/bolt/puppetfile/module.rb
|
507
504
|
- lib/bolt/r10k_log_proxy.rb
|
508
505
|
- lib/bolt/rerun.rb
|
509
506
|
- lib/bolt/resource_instance.rb
|