bolt 3.20.0 → 3.21.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/lib/bolt/application.rb +172 -0
- data/lib/bolt/bolt_option_parser.rb +87 -22
- data/lib/bolt/cli.rb +44 -1
- data/lib/bolt/config/options.rb +10 -0
- data/lib/bolt/config.rb +4 -0
- data/lib/bolt/outputter/human.rb +43 -0
- data/lib/bolt/outputter/json.rb +8 -0
- data/lib/bolt/pal.rb +14 -0
- data/lib/bolt/project.rb +3 -1
- data/lib/bolt/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 161a4fa9b8f36d32bd32964eeab21d3df8588e900f18999ee3ea9f0d56d56aec
|
4
|
+
data.tar.gz: bd8e0f955123e73058904f8e22335a516f1f41dcb5e8bdf4e7ad9bc0c01fe212
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b27fc4df0159d56610a5c2ebadd0a78234bc4e88815b2705f1000400f786079bddbcff37544024a81bc221afc48c60cfd884d2cee7f18018df1644dc7370548
|
7
|
+
data.tar.gz: 42c757fd3f406760d7b8d01809568270e92fb1ff57771ac07d392e26dd04be2f340a845906b7ea039e095e72e66bf37d56762b4e067db12eedb6773ffd47f492
|
data/lib/bolt/application.rb
CHANGED
@@ -413,6 +413,178 @@ module Bolt
|
|
413
413
|
{ plugins: plugins.list_plugins, modulepath: pal.user_modulepath }
|
414
414
|
end
|
415
415
|
|
416
|
+
# Applies one or more policies to the specified targets.
|
417
|
+
#
|
418
|
+
# @param policies [String] A comma-separated list of policies to apply.
|
419
|
+
# @param targets [Array[String]] The list of targets to apply the policies to.
|
420
|
+
# @param noop [Boolean] Whether to apply the policies in no-operation mode.
|
421
|
+
# @return [Bolt::ResultSet]
|
422
|
+
#
|
423
|
+
def apply_policies(policies, targets, noop: false)
|
424
|
+
policies = policies.split(',')
|
425
|
+
|
426
|
+
# Validate that the policies are available to the project.
|
427
|
+
unavailable_policies = policies.reject do |policy|
|
428
|
+
@config.policies&.any? do |known_policy|
|
429
|
+
File.fnmatch?(known_policy, policy, File::FNM_EXTGLOB)
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
if unavailable_policies.any?
|
434
|
+
command = Bolt::Util.powershell? ? 'Get-BoltPolicy' : 'bolt policy show'
|
435
|
+
|
436
|
+
# CODEREVIEW: Phrasing
|
437
|
+
raise Bolt::Error.new(
|
438
|
+
"The following policies are not available to the project: '#{unavailable_policies.join("', '")}'. "\
|
439
|
+
"You must list policies in a project's 'policies' setting before Bolt can apply them to targets. "\
|
440
|
+
"For a list of policies available to the project, run '#{command}'.",
|
441
|
+
'bolt/unavailable-policy-error'
|
442
|
+
)
|
443
|
+
end
|
444
|
+
|
445
|
+
# Validate that the policies are loadable Puppet classes.
|
446
|
+
unloadable_policies = []
|
447
|
+
|
448
|
+
@pal.in_catalog_compiler do |_|
|
449
|
+
environment = Puppet.lookup(:current_environment)
|
450
|
+
|
451
|
+
unloadable_policies = policies.reject do |policy|
|
452
|
+
environment.known_resource_types.find_hostclass(policy)
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
# CODEREVIEW: Phrasing
|
457
|
+
if unloadable_policies.any?
|
458
|
+
raise Bolt::Error.new(
|
459
|
+
"The following policies cannot be loaded: '#{unloadable_policies.join("', '")}'. "\
|
460
|
+
"Policies must be a Puppet class saved to a project's or module's manifests directory.",
|
461
|
+
'bolt/unloadable-policy-error'
|
462
|
+
)
|
463
|
+
end
|
464
|
+
|
465
|
+
# Execute a single include statement with all the policies to apply them
|
466
|
+
# to the targets. Yay, reusable code!
|
467
|
+
apply(nil, targets, code: "include #{policies.join(', ')}", noop: noop)
|
468
|
+
end
|
469
|
+
|
470
|
+
# Add a new policy to the project.
|
471
|
+
#
|
472
|
+
# @param name [String] The name of the new policy.
|
473
|
+
# @return [Hash]
|
474
|
+
#
|
475
|
+
def new_policy(name)
|
476
|
+
# Validate the policy name
|
477
|
+
unless name =~ Bolt::Module::CONTENT_NAME_REGEX
|
478
|
+
message = <<~MESSAGE.chomp
|
479
|
+
Invalid policy name '#{name}'. Policy names are composed of one or more name segments
|
480
|
+
separated by double colons '::'.
|
481
|
+
|
482
|
+
Each name segment must begin with a lowercase letter, and can only include lowercase
|
483
|
+
letters, digits, and underscores.
|
484
|
+
|
485
|
+
Examples of valid policy names:
|
486
|
+
- #{@config.project.name}
|
487
|
+
- #{@config.project.name}::my_policy
|
488
|
+
MESSAGE
|
489
|
+
|
490
|
+
raise Bolt::ValidationError, message
|
491
|
+
end
|
492
|
+
|
493
|
+
# Validate that we're not running with the default project
|
494
|
+
if @config.project.name.nil?
|
495
|
+
command = Bolt::Util.powershell? ? 'New-BoltProject -Name <NAME>' : 'bolt project init <NAME>'
|
496
|
+
message = <<~MESSAGE.chomp
|
497
|
+
Can't create a policy for the default Bolt project because it doesn't
|
498
|
+
have a name. Run '#{command}' to create a new project.
|
499
|
+
MESSAGE
|
500
|
+
raise Bolt::ValidationError, message
|
501
|
+
end
|
502
|
+
|
503
|
+
prefix, *name_segments, basename = name.split('::')
|
504
|
+
|
505
|
+
# Error if name is not namespaced to project
|
506
|
+
unless prefix == @config.project.name
|
507
|
+
raise Bolt::ValidationError,
|
508
|
+
"Policy name '#{name}' must begin with project name '#{@config.project.name}'. Did "\
|
509
|
+
"you mean '#{@config.project.name}::#{name}'?"
|
510
|
+
end
|
511
|
+
|
512
|
+
# If the policy name is just the project name, use the special init.pp class
|
513
|
+
basename ||= 'init'
|
514
|
+
|
515
|
+
# Policies can be saved in subdirectories in the 'manifests/' directory
|
516
|
+
policy_dir = File.expand_path(File.join(name_segments), @config.project.manifests)
|
517
|
+
policy = File.expand_path("#{basename}.pp", policy_dir)
|
518
|
+
|
519
|
+
# Ensure the policy does not already exist
|
520
|
+
if File.exist?(policy)
|
521
|
+
raise Bolt::Error.new(
|
522
|
+
"A policy with the name '#{name}' already exists at '#{policy}', nothing to do.",
|
523
|
+
'bolt/existing-policy-error'
|
524
|
+
)
|
525
|
+
end
|
526
|
+
|
527
|
+
# Create the policy directory structure in the current project
|
528
|
+
begin
|
529
|
+
FileUtils.mkdir_p(policy_dir)
|
530
|
+
rescue Errno::EEXIST => e
|
531
|
+
raise Bolt::Error.new(
|
532
|
+
"#{e.message}; unable to create manifests directory '#{policy_dir}'",
|
533
|
+
'bolt/existing-file-error'
|
534
|
+
)
|
535
|
+
end
|
536
|
+
|
537
|
+
# Create the new policy
|
538
|
+
begin
|
539
|
+
File.write(policy, <<~POLICY)
|
540
|
+
class #{name} {
|
541
|
+
|
542
|
+
}
|
543
|
+
POLICY
|
544
|
+
rescue Errno::EACCES => e
|
545
|
+
raise Bolt::FileError.new("#{e.message}; unable to create policy", policy)
|
546
|
+
end
|
547
|
+
|
548
|
+
# Update the project configuration to include the new policy
|
549
|
+
project_config = Bolt::Util.read_yaml_hash(@config.project.project_file, 'project config')
|
550
|
+
|
551
|
+
# Add the 'policies' key if it does not exist and de-dupiclate entries
|
552
|
+
project_config['policies'] ||= []
|
553
|
+
project_config['policies'] << name
|
554
|
+
project_config['policies'].uniq!
|
555
|
+
|
556
|
+
begin
|
557
|
+
File.write(@config.project.project_file, project_config.to_yaml)
|
558
|
+
rescue Errno::EACCES => e
|
559
|
+
raise Bolt::FileError.new(
|
560
|
+
"#{e.message}; unable to update project configuration",
|
561
|
+
@config.project.project_file
|
562
|
+
)
|
563
|
+
end
|
564
|
+
|
565
|
+
{ name: name, path: policy }
|
566
|
+
end
|
567
|
+
|
568
|
+
# List policies available to the project.
|
569
|
+
#
|
570
|
+
# @return [Hash]
|
571
|
+
#
|
572
|
+
def list_policies
|
573
|
+
unless @config.policies
|
574
|
+
command = Bolt::Util.powershell? ? 'New-BoltPolicy -Name <NAME>' : 'bolt policy new <NAME>'
|
575
|
+
|
576
|
+
raise Bolt::Error.new(
|
577
|
+
"Project configuration file #{@config.project.project_file} does not "\
|
578
|
+
"specify any policies. You can add policies to the project by including "\
|
579
|
+
"a 'policies' key or creating a new policy using the '#{command}' "\
|
580
|
+
"command.",
|
581
|
+
'bolt/no-policies-error'
|
582
|
+
)
|
583
|
+
end
|
584
|
+
|
585
|
+
{ policies: @config.policies.uniq, modulepath: pal.user_modulepath }
|
586
|
+
end
|
587
|
+
|
416
588
|
# Initialize the current directory as a Bolt project.
|
417
589
|
#
|
418
590
|
# @param name [String] The name of the project.
|
@@ -114,6 +114,21 @@ module Bolt
|
|
114
114
|
{ flags: OPTIONS[:global],
|
115
115
|
banner: PLUGIN_HELP }
|
116
116
|
end
|
117
|
+
when 'policy'
|
118
|
+
case action
|
119
|
+
when 'apply'
|
120
|
+
{ flags: ACTION_OPTS + %w[compile-concurrency hiera-config noop],
|
121
|
+
banner: POLICY_APPLY_HELP }
|
122
|
+
when 'new'
|
123
|
+
{ flags: OPTIONS[:global] + PROJECT_PATHS,
|
124
|
+
banner: POLICY_NEW_HELP }
|
125
|
+
when 'show'
|
126
|
+
{ flags: OPTIONS[:global] + PROJECT_PATHS,
|
127
|
+
banner: POLICY_SHOW_HELP }
|
128
|
+
else
|
129
|
+
{ flags: OPTIONS[:global],
|
130
|
+
banner: POLICY_HELP }
|
131
|
+
end
|
117
132
|
when 'project'
|
118
133
|
case action
|
119
134
|
when 'init'
|
@@ -202,6 +217,7 @@ module Bolt
|
|
202
217
|
lookup Look up a value with Hiera
|
203
218
|
plan Convert, create, show, and run Bolt plans
|
204
219
|
plugin Show available plugins
|
220
|
+
policy Apply, create, and show policies
|
205
221
|
project Create and migrate Bolt projects
|
206
222
|
script Upload a local script and run it remotely
|
207
223
|
secret Create encryption keys and encrypt and decrypt values
|
@@ -250,7 +266,7 @@ module Bolt
|
|
250
266
|
|
251
267
|
COMMAND_RUN_HELP = <<~HELP
|
252
268
|
#{colorize(:cyan, 'Name')}
|
253
|
-
run
|
269
|
+
command run
|
254
270
|
|
255
271
|
#{colorize(:cyan, 'Usage')}
|
256
272
|
bolt command run <command> {--targets TARGETS | --query QUERY | --rerun FILTER}
|
@@ -286,7 +302,7 @@ module Bolt
|
|
286
302
|
|
287
303
|
FILE_DOWNLOAD_HELP = <<~HELP
|
288
304
|
#{colorize(:cyan, 'Name')}
|
289
|
-
download
|
305
|
+
file download
|
290
306
|
|
291
307
|
#{colorize(:cyan, 'Usage')}
|
292
308
|
bolt file download <source> <destination> {--targets TARGETS | --query QUERY | --rerun FILTER}
|
@@ -309,7 +325,7 @@ module Bolt
|
|
309
325
|
|
310
326
|
FILE_UPLOAD_HELP = <<~HELP
|
311
327
|
#{colorize(:cyan, 'Name')}
|
312
|
-
upload
|
328
|
+
file upload
|
313
329
|
|
314
330
|
#{colorize(:cyan, 'Usage')}
|
315
331
|
bolt file upload <source> <destination> {--targets TARGETS | --query QUERY | --rerun FILTER}
|
@@ -344,7 +360,7 @@ module Bolt
|
|
344
360
|
|
345
361
|
GROUP_SHOW_HELP = <<~HELP
|
346
362
|
#{colorize(:cyan, 'Name')}
|
347
|
-
show
|
363
|
+
group show
|
348
364
|
|
349
365
|
#{colorize(:cyan, 'Usage')}
|
350
366
|
bolt group show [options]
|
@@ -395,7 +411,7 @@ module Bolt
|
|
395
411
|
|
396
412
|
INVENTORY_SHOW_HELP = <<~HELP
|
397
413
|
#{colorize(:cyan, 'Name')}
|
398
|
-
show
|
414
|
+
inventory show
|
399
415
|
|
400
416
|
#{colorize(:cyan, 'Usage')}
|
401
417
|
bolt inventory show [options]
|
@@ -453,7 +469,7 @@ module Bolt
|
|
453
469
|
|
454
470
|
MODULE_ADD_HELP = <<~HELP
|
455
471
|
#{colorize(:cyan, 'Name')}
|
456
|
-
add
|
472
|
+
module add
|
457
473
|
|
458
474
|
#{colorize(:cyan, 'Usage')}
|
459
475
|
bolt module add <module> [options]
|
@@ -471,7 +487,7 @@ module Bolt
|
|
471
487
|
|
472
488
|
MODULE_GENERATETYPES_HELP = <<~HELP
|
473
489
|
#{colorize(:cyan, 'Name')}
|
474
|
-
generate-types
|
490
|
+
module generate-types
|
475
491
|
|
476
492
|
#{colorize(:cyan, 'Usage')}
|
477
493
|
bolt module generate-types [options]
|
@@ -486,7 +502,7 @@ module Bolt
|
|
486
502
|
|
487
503
|
MODULE_INSTALL_HELP = <<~HELP
|
488
504
|
#{colorize(:cyan, 'Name')}
|
489
|
-
install
|
505
|
+
module install
|
490
506
|
|
491
507
|
#{colorize(:cyan, 'Usage')}
|
492
508
|
bolt module install [options]
|
@@ -504,7 +520,7 @@ module Bolt
|
|
504
520
|
|
505
521
|
MODULE_SHOW_HELP = <<~HELP
|
506
522
|
#{colorize(:cyan, 'Name')}
|
507
|
-
show
|
523
|
+
module show
|
508
524
|
|
509
525
|
#{colorize(:cyan, 'Usage')}
|
510
526
|
bolt module show [module name] [options]
|
@@ -541,7 +557,7 @@ module Bolt
|
|
541
557
|
|
542
558
|
PLAN_CONVERT_HELP = <<~HELP
|
543
559
|
#{colorize(:cyan, 'Name')}
|
544
|
-
convert
|
560
|
+
plan convert
|
545
561
|
|
546
562
|
#{colorize(:cyan, 'Usage')}
|
547
563
|
bolt plan convert <plan name> [options]
|
@@ -564,7 +580,7 @@ module Bolt
|
|
564
580
|
|
565
581
|
PLAN_NEW_HELP = <<~HELP
|
566
582
|
#{colorize(:cyan, 'Name')}
|
567
|
-
new
|
583
|
+
plan new
|
568
584
|
|
569
585
|
#{colorize(:cyan, 'Usage')}
|
570
586
|
bolt plan new <plan name> [options]
|
@@ -581,7 +597,7 @@ module Bolt
|
|
581
597
|
|
582
598
|
PLAN_RUN_HELP = <<~HELP
|
583
599
|
#{colorize(:cyan, 'Name')}
|
584
|
-
run
|
600
|
+
plan run
|
585
601
|
|
586
602
|
#{colorize(:cyan, 'Usage')}
|
587
603
|
bolt plan run <plan name> [parameters] [options]
|
@@ -598,7 +614,7 @@ module Bolt
|
|
598
614
|
|
599
615
|
PLAN_SHOW_HELP = <<~HELP
|
600
616
|
#{colorize(:cyan, 'Name')}
|
601
|
-
show
|
617
|
+
plan show
|
602
618
|
|
603
619
|
#{colorize(:cyan, 'Usage')}
|
604
620
|
bolt plan show [plan name] [options]
|
@@ -641,7 +657,7 @@ module Bolt
|
|
641
657
|
|
642
658
|
PLUGIN_SHOW_HELP = <<~HELP
|
643
659
|
#{colorize(:cyan, 'Name')}
|
644
|
-
show
|
660
|
+
plugin show
|
645
661
|
|
646
662
|
#{colorize(:cyan, 'Usage')}
|
647
663
|
bolt plugin show [options]
|
@@ -653,6 +669,55 @@ module Bolt
|
|
653
669
|
Learn more about Bolt plugins at https://pup.pt/bolt-plugins.
|
654
670
|
HELP
|
655
671
|
|
672
|
+
POLICY_HELP = <<~HELP
|
673
|
+
#{colorize(:cyan, 'Name')}
|
674
|
+
policy
|
675
|
+
|
676
|
+
#{colorize(:cyan, 'Usage')}
|
677
|
+
bolt policy <action> [options]
|
678
|
+
|
679
|
+
#{colorize(:cyan, 'Description')}
|
680
|
+
Apply, create, and show policies.
|
681
|
+
|
682
|
+
#{colorize(:cyan, 'Actions')}
|
683
|
+
apply Apply a policy to the specified targets
|
684
|
+
new Create a new policy in the current project
|
685
|
+
show Show available policy
|
686
|
+
HELP
|
687
|
+
|
688
|
+
POLICY_APPLY_HELP = <<~HELP
|
689
|
+
#{colorize(:cyan, 'Name')}
|
690
|
+
policy apply
|
691
|
+
|
692
|
+
#{colorize(:cyan, 'Usage')}
|
693
|
+
bolt policy apply <policy> [options]
|
694
|
+
|
695
|
+
#{colorize(:cyan, 'Description')}
|
696
|
+
Apply a policy to the specified targets.
|
697
|
+
HELP
|
698
|
+
|
699
|
+
POLICY_NEW_HELP = <<~HELP
|
700
|
+
#{colorize(:cyan, 'Name')}
|
701
|
+
policy new
|
702
|
+
|
703
|
+
#{colorize(:cyan, 'Usage')}
|
704
|
+
bolt policy new <policy> [options]
|
705
|
+
|
706
|
+
#{colorize(:cyan, 'Description')}
|
707
|
+
Create a new policy in the current project.
|
708
|
+
HELP
|
709
|
+
|
710
|
+
POLICY_SHOW_HELP = <<~HELP
|
711
|
+
#{colorize(:cyan, 'Name')}
|
712
|
+
policy show
|
713
|
+
|
714
|
+
#{colorize(:cyan, 'Usage')}
|
715
|
+
bolt policy show [options]
|
716
|
+
|
717
|
+
#{colorize(:cyan, 'Description')}
|
718
|
+
Show available policies.
|
719
|
+
HELP
|
720
|
+
|
656
721
|
PROJECT_HELP = <<~HELP
|
657
722
|
#{colorize(:cyan, 'Name')}
|
658
723
|
project
|
@@ -673,7 +738,7 @@ module Bolt
|
|
673
738
|
|
674
739
|
PROJECT_INIT_HELP = <<~HELP
|
675
740
|
#{colorize(:cyan, 'Name')}
|
676
|
-
init
|
741
|
+
project init
|
677
742
|
|
678
743
|
#{colorize(:cyan, 'Usage')}
|
679
744
|
bolt project init [name] [options]
|
@@ -697,7 +762,7 @@ module Bolt
|
|
697
762
|
|
698
763
|
PROJECT_MIGRATE_HELP = <<~HELP
|
699
764
|
#{colorize(:cyan, 'Name')}
|
700
|
-
migrate
|
765
|
+
project migrate
|
701
766
|
|
702
767
|
#{colorize(:cyan, 'Usage')}
|
703
768
|
bolt project migrate [options]
|
@@ -729,7 +794,7 @@ module Bolt
|
|
729
794
|
|
730
795
|
SCRIPT_RUN_HELP = <<~HELP
|
731
796
|
#{colorize(:cyan, 'Name')}
|
732
|
-
run
|
797
|
+
script run
|
733
798
|
|
734
799
|
#{colorize(:cyan, 'Usage')}
|
735
800
|
bolt script run <script> [arguments] {--targets TARGETS | --query QUERY | --rerun FILTER}
|
@@ -770,7 +835,7 @@ module Bolt
|
|
770
835
|
|
771
836
|
SECRET_CREATEKEYS_HELP = <<~HELP
|
772
837
|
#{colorize(:cyan, 'Name')}
|
773
|
-
createkeys
|
838
|
+
secret createkeys
|
774
839
|
|
775
840
|
#{colorize(:cyan, 'Usage')}
|
776
841
|
bolt secret createkeys [options]
|
@@ -784,7 +849,7 @@ module Bolt
|
|
784
849
|
|
785
850
|
SECRET_DECRYPT_HELP = <<~HELP
|
786
851
|
#{colorize(:cyan, 'Name')}
|
787
|
-
decrypt
|
852
|
+
secret decrypt
|
788
853
|
|
789
854
|
#{colorize(:cyan, 'Usage')}
|
790
855
|
bolt secret decrypt <ciphertext> [options]
|
@@ -798,7 +863,7 @@ module Bolt
|
|
798
863
|
|
799
864
|
SECRET_ENCRYPT_HELP = <<~HELP
|
800
865
|
#{colorize(:cyan, 'Name')}
|
801
|
-
encrypt
|
866
|
+
secret encrypt
|
802
867
|
|
803
868
|
#{colorize(:cyan, 'Usage')}
|
804
869
|
bolt secret encrypt <plaintext> [options]
|
@@ -830,7 +895,7 @@ module Bolt
|
|
830
895
|
|
831
896
|
TASK_RUN_HELP = <<~HELP
|
832
897
|
#{colorize(:cyan, 'Name')}
|
833
|
-
run
|
898
|
+
task run
|
834
899
|
|
835
900
|
#{colorize(:cyan, 'Usage')}
|
836
901
|
bolt task run <task name> [parameters] {--targets TARGETS | --query QUERY | --rerun FILTER}
|
@@ -850,7 +915,7 @@ module Bolt
|
|
850
915
|
|
851
916
|
TASK_SHOW_HELP = <<~HELP
|
852
917
|
#{colorize(:cyan, 'Name')}
|
853
|
-
show
|
918
|
+
task show
|
854
919
|
|
855
920
|
#{colorize(:cyan, 'Usage')}
|
856
921
|
bolt task show [task name] [options]
|
data/lib/bolt/cli.rb
CHANGED
@@ -44,6 +44,7 @@ module Bolt
|
|
44
44
|
'module' => %w[add generate-types install show],
|
45
45
|
'plan' => %w[show run convert new],
|
46
46
|
'plugin' => %w[show],
|
47
|
+
'policy' => %w[apply new show],
|
47
48
|
'project' => %w[init migrate],
|
48
49
|
'script' => %w[run],
|
49
50
|
'secret' => %w[encrypt decrypt createkeys],
|
@@ -287,6 +288,26 @@ module Bolt
|
|
287
288
|
raise Bolt::CLIError, "Must specify a plan."
|
288
289
|
end
|
289
290
|
|
291
|
+
if options[:subcommand] == 'policy'
|
292
|
+
if options[:action] == 'apply' && !options[:object]
|
293
|
+
raise Bolt::CLIError, "Must specify one or more policies to apply."
|
294
|
+
end
|
295
|
+
|
296
|
+
if options[:action] == 'apply' && options[:leftovers].any?
|
297
|
+
raise Bolt::CLIError, "Unknown argument(s) #{options[:leftovers].join(', ')}. "\
|
298
|
+
"To apply multiple policies, provide a comma-separated list of "\
|
299
|
+
"policy names."
|
300
|
+
end
|
301
|
+
|
302
|
+
if options[:action] == 'new' && !options[:object]
|
303
|
+
raise Bolt::CLIError, "Must specify a name for the new policy."
|
304
|
+
end
|
305
|
+
|
306
|
+
if options[:action] == 'show' && options[:object]
|
307
|
+
raise Bolt::CLIError, "Unknown argument #{options[:object]}."
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
290
311
|
if options[:subcommand] == 'module' && options[:action] == 'install' && options[:object]
|
291
312
|
command = Bolt::Util.powershell? ? 'Add-BoltModule -Module' : 'bolt module add'
|
292
313
|
raise Bolt::CLIError, "Invalid argument '#{options[:object]}'. To add a new module to "\
|
@@ -324,7 +345,9 @@ module Bolt
|
|
324
345
|
end
|
325
346
|
|
326
347
|
if options[:noop] &&
|
327
|
-
!(options[:subcommand] == 'task' && options[:action] == 'run') &&
|
348
|
+
!(options[:subcommand] == 'task' && options[:action] == 'run') &&
|
349
|
+
options[:subcommand] != 'apply' &&
|
350
|
+
options[:action] != 'apply'
|
328
351
|
raise Bolt::CLIError,
|
329
352
|
"Option '--noop' can only be specified when running a task or applying manifest code"
|
330
353
|
end
|
@@ -631,6 +654,26 @@ module Bolt
|
|
631
654
|
outputter.print_plugin_list(**app.list_plugins)
|
632
655
|
SUCCESS
|
633
656
|
|
657
|
+
when 'policy'
|
658
|
+
Bolt::Logger.warn('policy_command', 'This command is experimental and is subject to change.')
|
659
|
+
case action
|
660
|
+
when 'apply'
|
661
|
+
results = outputter.spin do
|
662
|
+
app.apply_policies(options[:object], options[:targets], **options.slice(:noop))
|
663
|
+
end
|
664
|
+
rerun.update(results)
|
665
|
+
app.shutdown
|
666
|
+
outputter.print_apply_result(results)
|
667
|
+
results.ok? ? SUCCESS : FAILURE
|
668
|
+
when 'new'
|
669
|
+
result = app.new_policy(options[:object])
|
670
|
+
outputter.print_new_policy(**result)
|
671
|
+
SUCCESS
|
672
|
+
when 'show'
|
673
|
+
outputter.print_policy_list(**app.list_policies)
|
674
|
+
SUCCESS
|
675
|
+
end
|
676
|
+
|
634
677
|
when 'project'
|
635
678
|
case action
|
636
679
|
when 'init'
|
data/lib/bolt/config/options.rb
CHANGED
@@ -396,6 +396,15 @@ module Bolt
|
|
396
396
|
_plugin: false,
|
397
397
|
_example: { "pkcs7" => { "keysize" => 1024 } }
|
398
398
|
},
|
399
|
+
"policies" => {
|
400
|
+
description: "A list of policy names and glob patterns to filter the project's policies by. This option "\
|
401
|
+
"is used to specify which policies are available to a project and can be applied to targets. "\
|
402
|
+
"When this option is not configured, policies are not available to the project and cannot "\
|
403
|
+
"be applied to targets.",
|
404
|
+
type: Array,
|
405
|
+
_plugin: false,
|
406
|
+
_example: ["myproject::apache", "myproject::postgres"]
|
407
|
+
},
|
399
408
|
"puppetdb" => {
|
400
409
|
description: "A map containing options for [configuring the Bolt PuppetDB "\
|
401
410
|
"client](bolt_connect_puppetdb.md).",
|
@@ -619,6 +628,7 @@ module Bolt
|
|
619
628
|
plugin-cache
|
620
629
|
plugin-hooks
|
621
630
|
plugins
|
631
|
+
policies
|
622
632
|
puppetdb
|
623
633
|
save-rerun
|
624
634
|
spinner
|
data/lib/bolt/config.rb
CHANGED
data/lib/bolt/outputter/human.rb
CHANGED
@@ -658,6 +658,49 @@ module Bolt
|
|
658
658
|
OUTPUT
|
659
659
|
end
|
660
660
|
|
661
|
+
def print_new_policy(name:, path:)
|
662
|
+
if Bolt::Util.powershell?
|
663
|
+
apply_command = "Invoke-BoltPolicy -Name #{name} -Targets <TARGETS>"
|
664
|
+
show_command = 'Get-BoltPolicy'
|
665
|
+
else
|
666
|
+
apply_command = "bolt policy apply #{name} --targets <TARGETS>"
|
667
|
+
show_command = 'bolt policy show'
|
668
|
+
end
|
669
|
+
|
670
|
+
print_message(<<~OUTPUT)
|
671
|
+
Created policy '#{name}' at '#{path}'
|
672
|
+
|
673
|
+
Apply this policy with:
|
674
|
+
#{apply_command}
|
675
|
+
Show available policies with:
|
676
|
+
#{show_command}
|
677
|
+
OUTPUT
|
678
|
+
end
|
679
|
+
|
680
|
+
# Print policies and the modulepath they are loaded from.
|
681
|
+
#
|
682
|
+
# @param policies [Array] The list of available policies.
|
683
|
+
# @param modulepath [Array] The project's modulepath.
|
684
|
+
#
|
685
|
+
def print_policy_list(policies:, modulepath:)
|
686
|
+
info = +''
|
687
|
+
|
688
|
+
info << colorize(:cyan, "Policies\n")
|
689
|
+
|
690
|
+
if policies.any?
|
691
|
+
policies.sort.each { |policy| info << indent(2, "#{policy}\n") }
|
692
|
+
else
|
693
|
+
info << indent(2, "No available policies\n")
|
694
|
+
end
|
695
|
+
|
696
|
+
info << "\n"
|
697
|
+
|
698
|
+
info << colorize(:cyan, "Modulepath\n")
|
699
|
+
info << indent(2, modulepath.join(File::PATH_SEPARATOR).to_s)
|
700
|
+
|
701
|
+
@stream.puts info.chomp
|
702
|
+
end
|
703
|
+
|
661
704
|
# Print target names and where they came from.
|
662
705
|
#
|
663
706
|
# @param adhoc [Hash] Adhoc targets provided on the command line.
|
data/lib/bolt/outputter/json.rb
CHANGED
@@ -87,6 +87,10 @@ module Bolt
|
|
87
87
|
@stream.puts plan.to_json
|
88
88
|
end
|
89
89
|
|
90
|
+
def print_policy_list(**kwargs)
|
91
|
+
print_table(**kwargs)
|
92
|
+
end
|
93
|
+
|
90
94
|
def print_plans(**kwargs)
|
91
95
|
print_table(**kwargs)
|
92
96
|
end
|
@@ -95,6 +99,10 @@ module Bolt
|
|
95
99
|
print_table(**kwargs)
|
96
100
|
end
|
97
101
|
|
102
|
+
def print_new_policy(**kwargs)
|
103
|
+
print_table(**kwargs)
|
104
|
+
end
|
105
|
+
|
98
106
|
def print_apply_result(apply_result)
|
99
107
|
@stream.puts apply_result.to_json
|
100
108
|
end
|
data/lib/bolt/pal.rb
CHANGED
@@ -238,6 +238,20 @@ module Bolt
|
|
238
238
|
Puppet.override(opts, &block)
|
239
239
|
end
|
240
240
|
|
241
|
+
def in_catalog_compiler
|
242
|
+
with_puppet_settings do
|
243
|
+
Puppet.override(bolt_project: @project) do
|
244
|
+
Puppet::Pal.in_tmp_environment('bolt', modulepath: full_modulepath) do |pal|
|
245
|
+
pal.with_catalog_compiler do |compiler|
|
246
|
+
yield compiler
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
rescue Puppet::Error => e
|
251
|
+
raise PALError.from_error(e)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
241
255
|
def in_plan_compiler(executor, inventory, pdb_client, applicator = nil)
|
242
256
|
with_bolt_executor(executor, inventory, pdb_client, applicator) do
|
243
257
|
# TODO: remove this call and see if anything breaks when
|
data/lib/bolt/project.rb
CHANGED
@@ -14,7 +14,8 @@ module Bolt
|
|
14
14
|
attr_reader :path, :data, :inventory_file, :hiera_config,
|
15
15
|
:puppetfile, :rerunfile, :type, :resource_types, :project_file,
|
16
16
|
:downloads, :plans_path, :modulepath, :managed_moduledir,
|
17
|
-
:backup_dir, :plugin_cache_file, :plan_cache_file, :task_cache_file
|
17
|
+
:backup_dir, :plugin_cache_file, :plan_cache_file, :task_cache_file,
|
18
|
+
:manifests
|
18
19
|
|
19
20
|
def self.default_project
|
20
21
|
create_project(File.expand_path(File.join('~', '.puppetlabs', 'bolt')), 'user')
|
@@ -116,6 +117,7 @@ module Bolt
|
|
116
117
|
@plan_cache_file = @path + '.plan_cache.json'
|
117
118
|
@task_cache_file = @path + '.task_cache.json'
|
118
119
|
@modulepath = [(@path + 'modules').to_s]
|
120
|
+
@manifests = @path + 'manifests'
|
119
121
|
|
120
122
|
if (tc = Bolt::Config::INVENTORY_OPTIONS.keys & data.keys).any?
|
121
123
|
Bolt::Logger.warn(
|
data/lib/bolt/version.rb
CHANGED
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: 3.
|
4
|
+
version: 3.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|