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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc5c8a79673414cca60534c299b63106ad7abe696bc942e7f913deaf57aa893f
4
- data.tar.gz: 0db5d813eb99b4d452e92bde9d8518b10c60b5613a18cb310dffbc7c86c87d64
3
+ metadata.gz: 161a4fa9b8f36d32bd32964eeab21d3df8588e900f18999ee3ea9f0d56d56aec
4
+ data.tar.gz: bd8e0f955123e73058904f8e22335a516f1f41dcb5e8bdf4e7ad9bc0c01fe212
5
5
  SHA512:
6
- metadata.gz: 2d67559bf87d79ec2adf72b6cf1d7de11a6b3ad925062ff7251e4be99240e551e9704c2fff1767979351f4485420cd7a62988f4f31c8bfe6cae940272898f564
7
- data.tar.gz: 69c73373a0ee02aca8794f66c48cc0c84f9c6ce56c329648915b6cc15714e399f13716f93af439a8362bc1a6c17d736e76e1920d2243fc1f1cf76e7daeb11a49
6
+ metadata.gz: 7b27fc4df0159d56610a5c2ebadd0a78234bc4e88815b2705f1000400f786079bddbcff37544024a81bc221afc48c60cfd884d2cee7f18018df1644dc7370548
7
+ data.tar.gz: 42c757fd3f406760d7b8d01809568270e92fb1ff57771ac07d392e26dd04be2f340a845906b7ea039e095e72e66bf37d56762b4e067db12eedb6773ffd47f492
@@ -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') && options[:subcommand] != 'apply'
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'
@@ -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
@@ -439,6 +439,10 @@ module Bolt
439
439
  @data['plugin-hooks']
440
440
  end
441
441
 
442
+ def policies
443
+ @data['policies']
444
+ end
445
+
442
446
  def trusted_external
443
447
  @data['trusted-external-command']
444
448
  end
@@ -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.
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bolt
4
- VERSION = '3.20.0'
4
+ VERSION = '3.21.0'
5
5
  end
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.20.0
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-10-26 00:00:00.000000000 Z
11
+ date: 2021-12-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable