puppet 6.21.1-universal-darwin → 6.22.1-universal-darwin

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +24 -18
  4. data/ext/project_data.yaml +2 -2
  5. data/lib/puppet/application/ssl.rb +11 -0
  6. data/lib/puppet/defaults.rb +22 -2
  7. data/lib/puppet/environments.rb +16 -1
  8. data/lib/puppet/face/facts.rb +128 -30
  9. data/lib/puppet/file_system/memory_file.rb +8 -1
  10. data/lib/puppet/file_system/windows.rb +2 -0
  11. data/lib/puppet/functions/partition.rb +8 -0
  12. data/lib/puppet/indirector/facts/facter.rb +24 -3
  13. data/lib/puppet/network/formats.rb +67 -0
  14. data/lib/puppet/network/http/factory.rb +4 -0
  15. data/lib/puppet/provider/package/dnfmodule.rb +1 -1
  16. data/lib/puppet/provider/service/systemd.rb +1 -1
  17. data/lib/puppet/provider/user/useradd.rb +1 -1
  18. data/lib/puppet/settings/environment_conf.rb +1 -0
  19. data/lib/puppet/util/fact_dif.rb +36 -17
  20. data/lib/puppet/util/monkey_patches.rb +7 -0
  21. data/lib/puppet/util/windows/adsi.rb +46 -0
  22. data/lib/puppet/util/windows/api_types.rb +1 -1
  23. data/lib/puppet/util/windows/principal.rb +9 -2
  24. data/lib/puppet/util/windows/sid.rb +4 -2
  25. data/lib/puppet/version.rb +1 -1
  26. data/locales/puppet.pot +139 -87
  27. data/man/man5/puppet.conf.5 +11 -3
  28. data/man/man8/puppet-agent.8 +1 -1
  29. data/man/man8/puppet-apply.8 +1 -1
  30. data/man/man8/puppet-catalog.8 +1 -1
  31. data/man/man8/puppet-config.8 +1 -1
  32. data/man/man8/puppet-describe.8 +1 -1
  33. data/man/man8/puppet-device.8 +1 -1
  34. data/man/man8/puppet-doc.8 +1 -1
  35. data/man/man8/puppet-epp.8 +1 -1
  36. data/man/man8/puppet-facts.8 +60 -2
  37. data/man/man8/puppet-filebucket.8 +1 -1
  38. data/man/man8/puppet-generate.8 +1 -1
  39. data/man/man8/puppet-help.8 +1 -1
  40. data/man/man8/puppet-key.8 +1 -1
  41. data/man/man8/puppet-lookup.8 +1 -1
  42. data/man/man8/puppet-man.8 +1 -1
  43. data/man/man8/puppet-module.8 +1 -1
  44. data/man/man8/puppet-node.8 +1 -1
  45. data/man/man8/puppet-parser.8 +1 -1
  46. data/man/man8/puppet-plugin.8 +1 -1
  47. data/man/man8/puppet-report.8 +1 -1
  48. data/man/man8/puppet-resource.8 +1 -1
  49. data/man/man8/puppet-script.8 +1 -1
  50. data/man/man8/puppet-ssl.8 +5 -1
  51. data/man/man8/puppet-status.8 +1 -1
  52. data/man/man8/puppet.8 +2 -2
  53. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services_vendor_preset +9 -0
  54. data/spec/integration/application/plugin_spec.rb +1 -1
  55. data/spec/integration/http/client_spec.rb +12 -0
  56. data/spec/integration/indirector/direct_file_server_spec.rb +1 -3
  57. data/spec/integration/util/windows/adsi_spec.rb +18 -0
  58. data/spec/integration/util/windows/principal_spec.rb +21 -0
  59. data/spec/integration/util/windows/registry_spec.rb +6 -0
  60. data/spec/spec_helper.rb +11 -1
  61. data/spec/unit/application/facts_spec.rb +482 -3
  62. data/spec/unit/application/ssl_spec.rb +23 -0
  63. data/spec/unit/defaults_spec.rb +16 -0
  64. data/spec/unit/environments_spec.rb +164 -88
  65. data/spec/unit/face/facts_spec.rb +4 -0
  66. data/spec/unit/file_system_spec.rb +9 -0
  67. data/spec/unit/indirector/facts/facter_spec.rb +95 -0
  68. data/spec/unit/network/formats_spec.rb +41 -0
  69. data/spec/unit/network/http/factory_spec.rb +19 -0
  70. data/spec/unit/provider/package/dnfmodule_spec.rb +10 -1
  71. data/spec/unit/provider/service/systemd_spec.rb +11 -0
  72. data/spec/unit/provider/user/useradd_spec.rb +18 -3
  73. data/spec/unit/resource/catalog_spec.rb +1 -1
  74. data/spec/unit/util/windows/sid_spec.rb +6 -0
  75. metadata +4 -6
  76. data/spec/lib/matchers/include.rb +0 -27
  77. data/spec/lib/matchers/include_spec.rb +0 -32
@@ -1,13 +1,8 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet/environments'
3
3
  require 'puppet/file_system'
4
- require 'matchers/include'
5
- require 'matchers/include_in_order'
6
4
 
7
- module PuppetEnvironments
8
5
  describe Puppet::Environments do
9
- include Matchers::Include
10
-
11
6
  FS = Puppet::FileSystem
12
7
 
13
8
  before(:each) do
@@ -49,7 +44,7 @@ describe Puppet::Environments do
49
44
  loader_from(:filesystem => [directory_tree, global_path_1, global_path_2],
50
45
  :directory => directory_tree.children.first,
51
46
  :modulepath => [global_path_1_location, global_path_2_location]) do |loader|
52
- expect(loader.list).to include_in_any_order(
47
+ expect(loader.list).to contain_exactly(
53
48
  environment(:an_environment).
54
49
  with_manifest("#{FS.path_string(directory_tree)}/envdir/an_environment/manifests").
55
50
  with_modulepath(["#{FS.path_string(directory_tree)}/envdir/an_environment/modules",
@@ -87,7 +82,7 @@ describe Puppet::Environments do
87
82
 
88
83
  loader_from(:filesystem => [envdir],
89
84
  :directory => envdir) do |loader|
90
- expect(loader.list).to include_in_any_order(environment(:env1), environment(:env2))
85
+ expect(loader.list).to contain_exactly(environment(:env1), environment(:env2))
91
86
  end
92
87
  end
93
88
 
@@ -406,33 +401,29 @@ config_version=$vardir/random/scripts
406
401
  ]),
407
402
  ])
408
403
 
409
- FS.overlay(original_envdir) do
410
- dir_loader = Puppet::Environments::Directories.new(original_envdir, [])
411
- loader = Puppet::Environments::Cached.new(dir_loader)
412
- Puppet.override(:environments => loader) do
413
- original_env = loader.get("env3") # force the environment.conf to be read
414
-
415
- changed_envdir = FS::MemoryFile.a_directory(base_dir, [
416
- FS::MemoryFile.a_directory("env3", [
417
- FS::MemoryFile.a_regular_file_containing("environment.conf", <<-EOF)
418
- manifest=/manifest_changed
419
- modulepath=/modules_changed
420
- environment_timeout=0
421
- EOF
422
- ]),
423
- ])
404
+ cached_loader_from(:filesystem => [original_envdir], :directory => original_envdir) do |loader|
405
+ original_env = loader.get("env3") # force the environment.conf to be read
424
406
 
425
- FS.overlay(changed_envdir) do
426
- changed_env = loader.get("env3")
407
+ changed_envdir = FS::MemoryFile.a_directory(base_dir, [
408
+ FS::MemoryFile.a_directory("env3", [
409
+ FS::MemoryFile.a_regular_file_containing("environment.conf", <<-EOF)
410
+ manifest=/manifest_changed
411
+ modulepath=/modules_changed
412
+ environment_timeout=0
413
+ EOF
414
+ ]),
415
+ ])
427
416
 
428
- expect(original_env).to environment(:env3).
429
- with_manifest(File.expand_path("/manifest_orig")).
430
- with_full_modulepath([File.expand_path("/modules_orig")])
417
+ FS.overlay(changed_envdir) do
418
+ changed_env = loader.get("env3")
431
419
 
432
- expect(changed_env).to environment(:env3).
433
- with_manifest(File.expand_path("/manifest_changed")).
434
- with_full_modulepath([File.expand_path("/modules_changed")])
435
- end
420
+ expect(original_env).to environment(:env3).
421
+ with_manifest(File.expand_path("/manifest_orig")).
422
+ with_full_modulepath([File.expand_path("/modules_orig")])
423
+
424
+ expect(changed_env).to environment(:env3).
425
+ with_manifest(File.expand_path("/manifest_changed")).
426
+ with_full_modulepath([File.expand_path("/modules_changed")])
436
427
  end
437
428
  end
438
429
  end
@@ -558,24 +549,49 @@ config_version=$vardir/random/scripts
558
549
 
559
550
  describe "cached loaders" do
560
551
  it "lists environments" do
561
- loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
562
- expect(Puppet::Environments::Cached.new(loader).list).to include_in_any_order(
552
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
553
+ expect(loader.list).to contain_exactly(
563
554
  environment(:an_environment),
564
555
  environment(:another_environment),
565
556
  environment(:symlinked_environment))
566
557
  end
567
558
  end
568
559
 
560
+ it "returns the same cached environment object for list and get methods" do
561
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
562
+ env = loader.list.find { |e| e.name == :an_environment }
563
+
564
+ expect(env).to equal(loader.get(:an_environment)) # same object
565
+ end
566
+ end
567
+
568
+ it "returns the same cached environment object for multiple list calls" do
569
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
570
+ expect(loader.list.first).to equal(loader.list.first) # same object
571
+ end
572
+ end
573
+
574
+ it "expires environments and returns a new environment object with the same value" do
575
+ Puppet[:environment_timeout] = "0"
576
+
577
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
578
+ a = loader.list.first
579
+ b = loader.list.first
580
+ expect(a).to eq(b) # same value
581
+ expect(a).to_not equal(b) # not same object
582
+ end
583
+ end
584
+
569
585
  it "has search_paths" do
570
- loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
571
- expect(Puppet::Environments::Cached.new(loader).search_paths).to eq(["file://#{directory_tree.children.first}"])
586
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
587
+ expect(loader.search_paths).to eq(["file://#{directory_tree.children.first}"])
572
588
  end
573
589
  end
574
590
 
575
591
  context "#get" do
576
592
  it "gets an environment" do
577
- loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
578
- expect(Puppet::Environments::Cached.new(loader).get(:an_environment)).to environment(:an_environment)
593
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
594
+ expect(loader.get(:an_environment)).to environment(:an_environment)
579
595
  end
580
596
  end
581
597
 
@@ -592,16 +608,16 @@ config_version=$vardir/random/scripts
592
608
  end
593
609
 
594
610
  it "returns nil if env not found" do
595
- loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
596
- expect(Puppet::Environments::Cached.new(loader).get(:doesnotexist)).to be_nil
611
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
612
+ expect(loader.get(:doesnotexist)).to be_nil
597
613
  end
598
614
  end
599
615
  end
600
616
 
601
617
  context "#get!" do
602
618
  it "gets an environment" do
603
- loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
604
- expect(Puppet::Environments::Cached.new(loader).get!(:an_environment)).to environment(:an_environment)
619
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
620
+ expect(loader.get!(:an_environment)).to environment(:an_environment)
605
621
  end
606
622
  end
607
623
 
@@ -618,14 +634,41 @@ config_version=$vardir/random/scripts
618
634
  end
619
635
 
620
636
  it "raises error if environment is not found" do
621
- loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
637
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
622
638
  expect do
623
- Puppet::Environments::Cached.new(loader).get!(:doesnotexist)
639
+ loader.get!(:doesnotexist)
624
640
  end.to raise_error(Puppet::Environments::EnvironmentNotFound)
625
641
  end
626
642
  end
627
643
  end
628
644
 
645
+ context "#get_conf" do
646
+ it "loads environment.conf" do
647
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
648
+ expect(loader.get_conf(:an_environment)).to match_environment_conf(:an_environment).
649
+ with_env_path(directory_tree.children.first).
650
+ with_global_module_path([])
651
+ end
652
+ end
653
+
654
+ it "always reloads environment.conf" do
655
+ env = Puppet::Node::Environment.create(:cached, [])
656
+ mocked_loader = double('loader')
657
+ expect(mocked_loader).to receive(:get_conf).with(:cached).and_return(Puppet::Settings::EnvironmentConf.static_for(env, 20)).twice
658
+
659
+ cached = Puppet::Environments::Cached.new(mocked_loader)
660
+
661
+ cached.get_conf(:cached)
662
+ cached.get_conf(:cached)
663
+ end
664
+
665
+ it "returns nil if environment is not found" do
666
+ cached_loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
667
+ expect(loader.get_conf(:doesnotexist)).to be_nil
668
+ end
669
+ end
670
+ end
671
+
629
672
  context "expiration policies" do
630
673
  let(:service) { ReplayExpirationService.new }
631
674
 
@@ -647,8 +690,6 @@ config_version=$vardir/random/scripts
647
690
  end
648
691
 
649
692
  it "evicts an expired environment" do
650
- service = ReplayExpirationService.new
651
-
652
693
  expect(service).to receive(:expired?).and_return(true)
653
694
 
654
695
  with_environment_loaded(service) do |cached|
@@ -703,13 +744,15 @@ config_version=$vardir/random/scripts
703
744
  expect(service.created_envs).to eq([:an_environment, :an_environment])
704
745
  expect(service.evicted_envs).to eq([:an_environment])
705
746
  end
706
- end
707
747
 
708
- it "gets an environment.conf" do
709
- loader_from(:filesystem => [directory_tree], :directory => directory_tree.children.first) do |loader|
710
- expect(Puppet::Environments::Cached.new(loader).get_conf(:an_environment)).to match_environment_conf(:an_environment).
711
- with_env_path(directory_tree.children.first).
712
- with_global_module_path([])
748
+ it "evicts expired environments when listing" do
749
+ expect(service).to receive(:expired?).with(:an_environment).and_return(true)
750
+
751
+ with_environment_loaded(service) do |cached|
752
+ cached.list
753
+ end
754
+
755
+ expect(service.evicted_envs).to eq([:an_environment])
713
756
  end
714
757
  end
715
758
 
@@ -727,6 +770,30 @@ config_version=$vardir/random/scripts
727
770
 
728
771
  context '#clear_all' do
729
772
  let(:service) { ReplayExpirationService.new }
773
+ let(:envdir) { File.expand_path("envdir") }
774
+ let(:default_dir) { File.join(envdir, "cached_env", "modules") }
775
+ let(:expected_dir) { File.join(envdir, "cached_env", "site") }
776
+
777
+ let(:base_dir) do
778
+ FS::MemoryFile.a_directory(envdir, [
779
+ FS::MemoryFile.a_directory("cached_env", [
780
+ FS::MemoryFile.a_missing_file("environment.conf")
781
+ ])
782
+ ])
783
+ end
784
+
785
+ let(:updated_dir) do
786
+ FS::MemoryFile.a_directory(envdir, [
787
+ FS::MemoryFile.a_directory("cached_env", [
788
+ FS::MemoryFile.a_directory("site"),
789
+ FS::MemoryFile.a_missing_directory("modules"),
790
+ FS::MemoryFile.a_regular_file_containing("environment.conf", <<-EOF)
791
+ modulepath=site
792
+ environment_timeout=unlimited
793
+ EOF
794
+ ])
795
+ ])
796
+ end
730
797
 
731
798
  it 'evicts all environments' do
732
799
  with_environment_loaded(service) do |cached|
@@ -738,48 +805,44 @@ config_version=$vardir/random/scripts
738
805
  end
739
806
  end
740
807
 
741
- it 'clears cached environment settings' do
742
- base_dir = File.expand_path("envdir")
743
- original_envdir = FS::MemoryFile.a_directory(base_dir, [
744
- FS::MemoryFile.a_directory("env3", [
745
- FS::MemoryFile.a_regular_file_containing("environment.conf", <<-EOF)
746
- manifest=/manifest_orig
747
- modulepath=/modules_orig
748
- environment_timeout=60
749
- EOF
750
- ]),
751
- ])
808
+ it "recomputes modulepath if 'get' is called before 'clear_all'" do
809
+ cached_loader_from(:filesystem => [base_dir], :directory => base_dir) do |loader|
810
+ loader.get(:cached_env)
752
811
 
753
- FS.overlay(original_envdir) do
754
- dir_loader = Puppet::Environments::Directories.new(original_envdir, [])
755
- loader = Puppet::Environments::Cached.new(dir_loader)
756
- Puppet.override(:environments => loader) do
757
- original_env = loader.get("env3") # force the environment.conf to be read
758
-
759
- changed_envdir = FS::MemoryFile.a_directory(base_dir, [
760
- FS::MemoryFile.a_directory("env3", [
761
- FS::MemoryFile.a_regular_file_containing("environment.conf", <<-EOF)
762
- manifest=/manifest_changed
763
- modulepath=/modules_changed
764
- environment_timeout=60
765
- EOF
766
- ]),
767
- ])
812
+ expect(Puppet.settings.value(:modulepath, :cached_env)).to eq(default_dir)
768
813
 
769
- #Clear all cached environments
814
+ FS.overlay(updated_dir) do
770
815
  loader.clear_all
771
816
 
772
- FS.overlay(changed_envdir) do
773
- changed_env = loader.get("env3")
817
+ expect(loader.get(:cached_env).modulepath).to contain_exactly(expected_dir)
818
+ end
819
+ end
820
+ end
821
+
822
+ it "recomputes modulepath if 'list' is called before 'clear_all'" do
823
+ cached_loader_from(:filesystem => [base_dir], :directory => base_dir) do |loader|
824
+ loader.list
774
825
 
775
- expect(original_env).to environment(:env3).
776
- with_manifest(File.expand_path("/manifest_orig")).
777
- with_full_modulepath([File.expand_path("/modules_orig")])
826
+ expect(Puppet.settings.value(:modulepath, :cached_env)).to eq(default_dir)
778
827
 
779
- expect(changed_env).to environment(:env3).
780
- with_manifest(File.expand_path("/manifest_changed")).
781
- with_full_modulepath([File.expand_path("/modules_changed")])
782
- end
828
+ FS.overlay(updated_dir) do
829
+ loader.clear_all
830
+
831
+ expect(loader.get(:cached_env).modulepath).to contain_exactly(expected_dir)
832
+ end
833
+ end
834
+ end
835
+
836
+ it "recomputes modulepath if 'get_conf' is called before 'clear_all'" do
837
+ cached_loader_from(:filesystem => [base_dir], :directory => base_dir) do |loader|
838
+ loader.get_conf(:cached_env)
839
+
840
+ expect(Puppet.settings.value(:modulepath, :cached_env)).to eq(default_dir)
841
+
842
+ FS.overlay(updated_dir) do
843
+ loader.clear_all
844
+
845
+ expect(loader.get(:cached_env).modulepath).to contain_exactly(expected_dir)
783
846
  end
784
847
  end
785
848
  end
@@ -865,6 +928,20 @@ config_version=$vardir/random/scripts
865
928
  end
866
929
  end
867
930
 
931
+ def cached_loader_from(options, &block)
932
+ FS.overlay(*options[:filesystem]) do
933
+ environments = Puppet::Environments::Cached.new(
934
+ Puppet::Environments::Directories.new(
935
+ options[:directory],
936
+ options[:modulepath] || []
937
+ )
938
+ )
939
+ Puppet.override(:environments => environments) do
940
+ yield environments
941
+ end
942
+ end
943
+ end
944
+
868
945
  def loader_from(options, &block)
869
946
  FS.overlay(*options[:filesystem]) do
870
947
  environments = Puppet::Environments::Directories.new(
@@ -917,4 +994,3 @@ config_version=$vardir/random/scripts
917
994
  end
918
995
  end
919
996
  end
920
- end
@@ -71,4 +71,8 @@ CONF
71
71
  log.message =~ /Uploading facts for '.*' to 'puppet\.server\.test'/}
72
72
  end
73
73
  end
74
+
75
+ describe "#show" do
76
+ it { is_expected.to be_action :show }
77
+ end
74
78
  end
@@ -999,6 +999,15 @@ describe "Puppet::FileSystem" do
999
999
  Puppet::FileSystem.replace_file(dest, 0755) { |_| }
1000
1000
  }.to raise_error(ArgumentError, /Only modes 0644, 0640, 0660, and 0440 are allowed/)
1001
1001
  end
1002
+
1003
+ it 'falls back to fully qualified user name when sid retrieval fails' do
1004
+ current_user_sid = Puppet::Util::Windows::SID.name_to_sid(Puppet::Util::Windows::ADSI::User.current_user_name)
1005
+ allow(Puppet::Util::Windows::SID).to receive(:name_to_sid).with(Puppet::Util::Windows::ADSI::User.current_user_name).and_return(nil, current_user_sid)
1006
+ allow(Puppet::Util::Windows::SID).to receive(:name_to_sid).with(Puppet::Util::Windows::ADSI::User.current_sam_compatible_user_name).and_call_original
1007
+
1008
+ Puppet::FileSystem.replace_file(dest, 0644) { |f| f.write(content) }
1009
+ expects_public_file(dest)
1010
+ end
1002
1011
  end
1003
1012
  end
1004
1013
 
@@ -28,6 +28,7 @@ describe Puppet::Node::Facts::Facter do
28
28
  @request = double('request', :key => @name)
29
29
  @environment = double('environment')
30
30
  allow(@request).to receive(:environment).and_return(@environment)
31
+ allow(@request).to receive(:options).and_return({})
31
32
  allow(@request.environment).to receive(:modules).and_return([])
32
33
  allow(@request.environment).to receive(:modulepath).and_return([])
33
34
  end
@@ -104,6 +105,7 @@ describe Puppet::Node::Facts::Facter do
104
105
  expect(FileTest).to receive(:directory?).with(factpath1).and_return(true)
105
106
  expect(FileTest).to receive(:directory?).with(factpath2).and_return(true)
106
107
  allow(@request.environment).to receive(:modulepath).and_return([modulepath])
108
+ allow(@request).to receive(:options).and_return({})
107
109
  expect(Dir).to receive(:glob).with("#{modulepath}/*/lib/facter").and_return([modulelibfacter])
108
110
  expect(Dir).to receive(:glob).with("#{modulepath}/*/plugins/facter").and_return([modulepluginsfacter])
109
111
 
@@ -149,4 +151,97 @@ describe Puppet::Node::Facts::Facter do
149
151
  Puppet::Node::Facts::Facter.setup_external_search_paths @request
150
152
  end
151
153
  end
154
+
155
+ describe 'when :resolve_options is true' do
156
+ let(:options) { { resolve_options: true, user_query: ["os", "timezone"], show_legacy: true } }
157
+ let(:facts) { Puppet::Node::Facts.new("foo") }
158
+
159
+ before :each do
160
+ allow(@request).to receive(:options).and_return(options)
161
+ allow(Puppet::Node::Facts).to receive(:new).and_return(facts)
162
+ allow(facts).to receive(:add_local_facts)
163
+ end
164
+
165
+ it 'should call Facter.resolve method' do
166
+ expect(Facter).to receive(:resolve).with("os timezone --show-legacy")
167
+ @facter.find(@request)
168
+ end
169
+
170
+ it 'should NOT add local facts' do
171
+ expect(facts).not_to receive(:add_local_facts)
172
+
173
+ @facter.find(@request)
174
+ end
175
+
176
+ describe 'when Facter version is lower than 4.0.40' do
177
+ before :each do
178
+ allow(Facter).to receive(:respond_to?).and_return(false)
179
+ allow(Facter).to receive(:respond_to?).with(:resolve).and_return(false)
180
+ end
181
+
182
+ it 'raises an error' do
183
+ expect { @facter.find(@request) }.to raise_error(Puppet::Error, "puppet facts show requires version 4.0.40 or greater of Facter.")
184
+ end
185
+ end
186
+
187
+ describe 'when setting up external search paths' do
188
+ let(:options) { { resolve_options: true, user_query: ["os", "timezone"], external_dir: 'some/dir' } }
189
+ let(:pluginfactdest) { File.expand_path 'plugin/dest' }
190
+ let(:modulepath) { File.expand_path 'module/foo' }
191
+ let(:modulefactsd) { File.expand_path 'module/foo/facts.d' }
192
+
193
+ before :each do
194
+ expect(FileTest).to receive(:directory?).with(pluginfactdest).and_return(true)
195
+ mod = Puppet::Module.new('foo', modulepath, @request.environment)
196
+ allow(@request.environment).to receive(:modules).and_return([mod])
197
+ Puppet[:pluginfactdest] = pluginfactdest
198
+ end
199
+
200
+ it 'should skip files' do
201
+ expect(File).to receive(:directory?).with(modulefactsd).and_return(false)
202
+ expect(Facter).to receive(:search_external).with([pluginfactdest, options[:external_dir]])
203
+ Puppet::Node::Facts::Facter.setup_external_search_paths @request
204
+ end
205
+
206
+ it 'should add directories' do
207
+ expect(File).to receive(:directory?).with(modulefactsd).and_return(true)
208
+ expect(Facter).to receive(:search_external).with([modulefactsd, pluginfactdest, options[:external_dir]])
209
+ Puppet::Node::Facts::Facter.setup_external_search_paths @request
210
+ end
211
+ end
212
+
213
+ describe 'when setting up search paths' do
214
+ let(:factpath1) { File.expand_path 'one' }
215
+ let(:factpath2) { File.expand_path 'two' }
216
+ let(:factpath) { [factpath1, factpath2].join(File::PATH_SEPARATOR) }
217
+ let(:modulepath) { File.expand_path 'module/foo' }
218
+ let(:modulelibfacter) { File.expand_path 'module/foo/lib/facter' }
219
+ let(:modulepluginsfacter) { File.expand_path 'module/foo/plugins/facter' }
220
+ let(:options) { { resolve_options: true, custom_dir: 'some/dir' } }
221
+
222
+ before :each do
223
+ expect(FileTest).to receive(:directory?).with(factpath1).and_return(true)
224
+ expect(FileTest).to receive(:directory?).with(factpath2).and_return(true)
225
+ allow(@request.environment).to receive(:modulepath).and_return([modulepath])
226
+ expect(Dir).to receive(:glob).with("#{modulepath}/*/lib/facter").and_return([modulelibfacter])
227
+ expect(Dir).to receive(:glob).with("#{modulepath}/*/plugins/facter").and_return([modulepluginsfacter])
228
+
229
+ Puppet[:factpath] = factpath
230
+ end
231
+
232
+ it 'should skip files' do
233
+ expect(FileTest).to receive(:directory?).with(modulelibfacter).and_return(false)
234
+ expect(FileTest).to receive(:directory?).with(modulepluginsfacter).and_return(false)
235
+ expect(Facter).to receive(:search).with(factpath1, factpath2, options[:custom_dir])
236
+ Puppet::Node::Facts::Facter.setup_search_paths @request
237
+ end
238
+
239
+ it 'should add directories' do
240
+ expect(FileTest).to receive(:directory?).with(modulelibfacter).and_return(true)
241
+ expect(FileTest).to receive(:directory?).with(modulepluginsfacter).and_return(false)
242
+ expect(Facter).to receive(:search).with(modulelibfacter, factpath1, factpath2, options[:custom_dir])
243
+ Puppet::Node::Facts::Facter.setup_search_paths @request
244
+ end
245
+ end
246
+ end
152
247
  end
@@ -534,4 +534,45 @@ EOT
534
534
  end
535
535
  end
536
536
  end
537
+
538
+ describe ":flat format" do
539
+ let(:flat) { Puppet::Network::FormatHandler.format(:flat) }
540
+
541
+ it "should include a flat format" do
542
+ expect(flat).to be_an_instance_of Puppet::Network::Format
543
+ end
544
+
545
+ [:intern, :intern_multiple].each do |method|
546
+ it "should not implement #{method}" do
547
+ expect { flat.send(method, String, 'blah') }.to raise_error NotImplementedError
548
+ end
549
+ end
550
+
551
+ context "when rendering arrays" do
552
+ {
553
+ [] => "",
554
+ [1, 2] => "0=1\n1=2\n",
555
+ ["one"] => "0=one\n",
556
+ [{"one" => 1}, {"two" => 2}] => "0.one=1\n1.two=2\n",
557
+ [['something', 'for'], ['the', 'test']] => "0=[\"something\", \"for\"]\n1=[\"the\", \"test\"]\n"
558
+ }.each_pair do |input, output|
559
+ it "should render #{input.inspect} as one item per line" do
560
+ expect(flat.render(input)).to eq(output)
561
+ end
562
+ end
563
+ end
564
+
565
+ context "when rendering hashes" do
566
+ {
567
+ {} => "",
568
+ {1 => 2} => "1=2\n",
569
+ {"one" => "two"} => "one=two\n",
570
+ {[1,2] => 3, [2,3] => 5, [3,4] => 7} => "[1, 2]=3\n[2, 3]=5\n[3, 4]=7\n",
571
+ }.each_pair do |input, output|
572
+ it "should render #{input.inspect}" do
573
+ expect(flat.render(input)).to eq(output)
574
+ end
575
+ end
576
+ end
577
+ end
537
578
  end
@@ -144,4 +144,23 @@ describe Puppet::Network::HTTP::Factory do
144
144
  expect(conn.local_host).to eq('127.0.0.1')
145
145
  end
146
146
  end
147
+
148
+ context 'tls' do
149
+ it "sets the minimum version to TLS 1.0", if: RUBY_VERSION.to_f >= 2.5 do
150
+ conn = create_connection(site)
151
+ expect(conn.min_version).to eq(OpenSSL::SSL::TLS1_VERSION)
152
+ end
153
+
154
+ it "defaults to ciphersuites providing 128 bits of security or greater" do
155
+ conn = create_connection(site)
156
+ expect(conn.ciphers).to eq("ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256")
157
+ end
158
+
159
+ it "can be restricted to TLSv1.3 ciphers" do
160
+ tls13_ciphers = "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
161
+ Puppet[:ciphers] = tls13_ciphers
162
+ conn = create_connection(site)
163
+ expect(conn.ciphers).to eq(tls13_ciphers)
164
+ end
165
+ end
147
166
  end
@@ -123,7 +123,7 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
123
123
  provider.install
124
124
  end
125
125
 
126
- it "should just enable the module if it has no default profile" do
126
+ it "should just enable the module if it has no default profile(missing groups or modules)" do
127
127
  dnf_exception = Puppet::ExecutionFailure.new("Error: Problems in request:\nmissing groups or modules: #{resource[:name]}")
128
128
  allow(provider).to receive(:execute).with(array_including('install')).and_raise(dnf_exception)
129
129
  resource[:ensure] = :present
@@ -132,6 +132,15 @@ describe Puppet::Type.type(:package).provider(:dnfmodule) do
132
132
  provider.install
133
133
  end
134
134
 
135
+ it "should just enable the module if it has no default profile(broken groups or modules)" do
136
+ dnf_exception = Puppet::ExecutionFailure.new("Error: Problems in request:\nbroken groups or modules: #{resource[:name]}")
137
+ allow(provider).to receive(:execute).with(array_including('install')).and_raise(dnf_exception)
138
+ resource[:ensure] = :present
139
+ expect(provider).to receive(:execute).with(array_including('install')).ordered
140
+ expect(provider).to receive(:execute).with(array_including('enable')).ordered
141
+ provider.install
142
+ end
143
+
135
144
  it "should just enable the module if enable_only = true" do
136
145
  resource[:ensure] = :present
137
146
  resource[:enable_only] = true
@@ -200,6 +200,17 @@ describe 'Puppet::Type::Service::Provider::Systemd',
200
200
  })
201
201
  end
202
202
 
203
+ it "correctly parses services when list-unit-files has an additional column" do
204
+ expect(provider_class).to receive(:systemctl).with('list-unit-files', '--type', 'service', '--full', '--all', '--no-pager').and_return(File.read(my_fixture('list_unit_files_services_vendor_preset')))
205
+ expect(provider_class.instances.map(&:name)).to match_array(%w{
206
+ arp-ethers.service
207
+ auditd.service
208
+ dbus.service
209
+ umountnfs.service
210
+ urandom.service
211
+ })
212
+ end
213
+
203
214
  it "should print a debug message when a service with the state `bad` is found" do
204
215
  expect(provider_class).to receive(:systemctl).with('list-unit-files', '--type', 'service', '--full', '--all', '--no-pager').and_return(File.read(my_fixture('list_unit_files_services')))
205
216
  expect(Puppet).to receive(:debug).with("apparmor.service marked as bad by `systemctl`. It is recommended to be further checked.")
@@ -375,21 +375,36 @@ describe Puppet::Type.type(:user).provider(:useradd) do
375
375
  before { described_class.has_feature :manages_local_users_and_groups }
376
376
 
377
377
  let(:content) do
378
- <<~EOF
378
+ StringIO.new(<<~EOF)
379
379
  group1:x:0:myuser
380
380
  group2:x:999:
381
381
  group3:x:998:myuser
382
382
  EOF
383
383
  end
384
384
 
385
+ let(:content_with_empty_line) do
386
+ StringIO.new(<<~EOF)
387
+ group1:x:0:myuser
388
+ group2:x:999:
389
+ group3:x:998:myuser
390
+
391
+ EOF
392
+ end
393
+
385
394
  it "should return the local groups string when forcelocal is true" do
386
395
  resource[:forcelocal] = true
387
- group1, group2, group3 = content.split
388
396
  allow(Puppet::FileSystem).to receive(:exist?).with('/etc/group').and_return(true)
389
- allow(Puppet::FileSystem).to receive(:each_line).with('/etc/group').and_yield(group1).and_yield(group2).and_yield(group3)
397
+ allow(File).to receive(:open).with(Pathname.new('/etc/group')).and_yield(content)
390
398
  expect(provider.groups).to eq(['group1', 'group3'])
391
399
  end
392
400
 
401
+ it "does not raise when parsing empty lines in /etc/group" do
402
+ resource[:forcelocal] = true
403
+ allow(Puppet::FileSystem).to receive(:exist?).with('/etc/group').and_return(true)
404
+ allow(File).to receive(:open).with(Pathname.new('/etc/group')).and_yield(content_with_empty_line)
405
+ expect { provider.groups }.not_to raise_error
406
+ end
407
+
393
408
  it "should fall back to nameservice groups when forcelocal is false" do
394
409
  resource[:forcelocal] = false
395
410
  allow(Puppet::Util::POSIX).to receive(:groups_of).with('myuser').and_return(['remote groups'])