puppet 7.20.0 → 7.22.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +62 -48
  3. data/Guardfile.example +1 -1
  4. data/ext/project_data.yaml +1 -1
  5. data/ext/windows/service/daemon.rb +1 -1
  6. data/lib/puppet/application/lookup.rb +5 -5
  7. data/lib/puppet/defaults.rb +14 -0
  8. data/lib/puppet/indirector/facts/facter.rb +8 -1
  9. data/lib/puppet/info_service/task_information_service.rb +10 -2
  10. data/lib/puppet/transaction/report.rb +18 -1
  11. data/lib/puppet/type/resources.rb +1 -6
  12. data/lib/puppet/type/tidy.rb +3 -2
  13. data/lib/puppet/type/user.rb +1 -3
  14. data/lib/puppet/type.rb +10 -0
  15. data/lib/puppet/version.rb +1 -1
  16. data/man/man5/puppet.conf.5 +18 -2
  17. data/man/man8/puppet-agent.8 +1 -1
  18. data/man/man8/puppet-apply.8 +1 -1
  19. data/man/man8/puppet-catalog.8 +1 -1
  20. data/man/man8/puppet-config.8 +1 -1
  21. data/man/man8/puppet-describe.8 +1 -1
  22. data/man/man8/puppet-device.8 +1 -1
  23. data/man/man8/puppet-doc.8 +1 -1
  24. data/man/man8/puppet-epp.8 +1 -1
  25. data/man/man8/puppet-facts.8 +1 -1
  26. data/man/man8/puppet-filebucket.8 +1 -1
  27. data/man/man8/puppet-generate.8 +1 -1
  28. data/man/man8/puppet-help.8 +1 -1
  29. data/man/man8/puppet-lookup.8 +1 -1
  30. data/man/man8/puppet-module.8 +1 -1
  31. data/man/man8/puppet-node.8 +1 -1
  32. data/man/man8/puppet-parser.8 +1 -1
  33. data/man/man8/puppet-plugin.8 +1 -1
  34. data/man/man8/puppet-report.8 +1 -1
  35. data/man/man8/puppet-resource.8 +1 -1
  36. data/man/man8/puppet-script.8 +1 -1
  37. data/man/man8/puppet-ssl.8 +1 -1
  38. data/man/man8/puppet.8 +2 -2
  39. data/spec/integration/application/agent_spec.rb +100 -1
  40. data/spec/integration/application/lookup_spec.rb +55 -0
  41. data/spec/unit/agent_spec.rb +1 -1
  42. data/spec/unit/application/agent_spec.rb +1 -1
  43. data/spec/unit/application/device_spec.rb +1 -1
  44. data/spec/unit/application/resource_spec.rb +1 -1
  45. data/spec/unit/confiner_spec.rb +1 -1
  46. data/spec/unit/daemon_spec.rb +1 -1
  47. data/spec/unit/file_bucket/dipper_spec.rb +1 -1
  48. data/spec/unit/file_serving/fileset_spec.rb +14 -14
  49. data/spec/unit/file_system_spec.rb +3 -1
  50. data/spec/unit/graph/simple_graph_spec.rb +1 -1
  51. data/spec/unit/http/service/compiler_spec.rb +1 -1
  52. data/spec/unit/indirector/facts/facter_spec.rb +25 -0
  53. data/spec/unit/indirector/file_server_spec.rb +5 -5
  54. data/spec/unit/indirector/indirection_spec.rb +1 -1
  55. data/spec/unit/indirector/node/plain_spec.rb +1 -1
  56. data/spec/unit/info_service_spec.rb +21 -0
  57. data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
  58. data/spec/unit/network/formats_spec.rb +1 -1
  59. data/spec/unit/provider/file/posix_spec.rb +4 -4
  60. data/spec/unit/provider/ldap_spec.rb +3 -3
  61. data/spec/unit/provider/nameservice_spec.rb +15 -15
  62. data/spec/unit/provider/package/aix_spec.rb +1 -1
  63. data/spec/unit/provider/package/dpkg_spec.rb +3 -3
  64. data/spec/unit/provider/package/nim_spec.rb +2 -2
  65. data/spec/unit/provider/package/pkgutil_spec.rb +4 -4
  66. data/spec/unit/provider/parsedfile_spec.rb +4 -4
  67. data/spec/unit/provider/service/bsd_spec.rb +4 -4
  68. data/spec/unit/provider/service/debian_spec.rb +2 -2
  69. data/spec/unit/provider/service/gentoo_spec.rb +20 -20
  70. data/spec/unit/provider/service/openbsd_spec.rb +18 -18
  71. data/spec/unit/provider/service/openrc_spec.rb +19 -19
  72. data/spec/unit/provider/service/systemd_spec.rb +22 -22
  73. data/spec/unit/provider/service/upstart_spec.rb +6 -6
  74. data/spec/unit/provider/user/aix_spec.rb +1 -1
  75. data/spec/unit/provider/user/hpux_spec.rb +1 -1
  76. data/spec/unit/provider/user/openbsd_spec.rb +1 -1
  77. data/spec/unit/provider/user/useradd_spec.rb +1 -1
  78. data/spec/unit/reports/store_spec.rb +5 -1
  79. data/spec/unit/resource/type_spec.rb +2 -2
  80. data/spec/unit/ssl/base_spec.rb +1 -1
  81. data/spec/unit/ssl/certificate_request_spec.rb +1 -1
  82. data/spec/unit/ssl/certificate_spec.rb +1 -1
  83. data/spec/unit/transaction/event_manager_spec.rb +4 -4
  84. data/spec/unit/transaction/report_spec.rb +38 -1
  85. data/spec/unit/transaction_spec.rb +2 -2
  86. data/spec/unit/type/exec_spec.rb +1 -1
  87. data/spec/unit/type/file_spec.rb +4 -4
  88. data/spec/unit/type/filebucket_spec.rb +3 -3
  89. data/spec/unit/type/resources_spec.rb +14 -0
  90. data/spec/unit/type/tidy_spec.rb +27 -17
  91. data/spec/unit/util/backups_spec.rb +1 -1
  92. data/spec/unit/util/execution_spec.rb +6 -6
  93. data/spec/unit/util/filetype_spec.rb +3 -3
  94. data/spec/unit/util/network_device_spec.rb +1 -6
  95. data/spec/unit/util/resource_template_spec.rb +1 -1
  96. data/spec/unit/util/storage_spec.rb +1 -1
  97. data/spec/unit/x509/cert_provider_spec.rb +1 -1
  98. metadata +9 -3
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-LOOKUP" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-LOOKUP" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-lookup\fR \- Interactive Hiera lookup
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-MODULE" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-MODULE" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-module\fR \- Creates, installs and searches for modules on the Puppet Forge\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-NODE" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-NODE" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-node\fR \- View and manage node definitions\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-PARSER" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-PARSER" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-parser\fR \- Interact directly with the parser\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-PLUGIN" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-PLUGIN" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-plugin\fR \- Interact with the Puppet plugin system\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-REPORT" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-REPORT" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-report\fR \- Create, display, and submit reports\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-RESOURCE" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-RESOURCE" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-resource\fR \- The resource abstraction layer shell
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-SCRIPT" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-SCRIPT" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-script\fR \- Run a puppet manifests as a script without compiling a catalog
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-SSL" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-SSL" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-ssl\fR \- Manage SSL keys and certificates for puppet SSL clients
data/man/man8/puppet.8 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET" "8" "October 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET" "8" "January 2023" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\fR
@@ -25,4 +25,4 @@ Specialized:
25
25
  catalog Compile, save, view, and convert catalogs\. describe Display help about resource types device Manage remote network devices doc Generate Puppet references epp Interact directly with the EPP template parser/renderer\. facts Retrieve and store facts\. filebucket Store and retrieve files in a filebucket generate Generates Puppet code from Ruby definitions\. node View and manage node definitions\. parser Interact directly with the parser\. plugin Interact with the Puppet plugin system\. script Run a puppet manifests as a script without compiling a catalog ssl Manage SSL keys and certificates for puppet SSL clients
26
26
  .
27
27
  .P
28
- See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v7\.20\.0
28
+ See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v7\.22\.0
@@ -527,7 +527,7 @@ describe "puppet agent", unless: Puppet::Util::Platform.jruby? do
527
527
  }
528
528
 
529
529
  # ensure file is written before yielding
530
- until File.exists?(path) && File.size(path) > 0 do
530
+ until File.exist?(path) && File.size(path) > 0 do
531
531
  sleep 0.1
532
532
  end
533
533
 
@@ -897,4 +897,103 @@ describe "puppet agent", unless: Puppet::Util::Platform.jruby? do
897
897
  end
898
898
  end
899
899
  end
900
+
901
+ context "legacy facts" do
902
+ let(:mod_dir) { tmpdir('module_dir') }
903
+ let(:custom_dir) { File.join(mod_dir, 'lib') }
904
+ let(:external_dir) { File.join(mod_dir, 'facts.d') }
905
+
906
+ before(:each) do
907
+ # don't stub facter behavior, since we're relying on
908
+ # `Facter.resolve` to omit legacy facts
909
+ Puppet::Node::Facts.indirection.terminus_class = :facter
910
+
911
+ facter_dir = File.join(custom_dir, 'facter')
912
+ FileUtils.mkdir_p(facter_dir)
913
+ File.write(File.join(facter_dir, 'custom.rb'), <<~END)
914
+ Facter.add(:custom) { setcode { 'a custom value' } }
915
+ END
916
+
917
+ FileUtils.mkdir_p(external_dir)
918
+ File.write(File.join(external_dir, 'external.json'), <<~END)
919
+ {"external":"an external value"}
920
+ END
921
+
922
+ # avoid pluginsync'ing contents
923
+ FileUtils.mkdir_p(Puppet[:vardir])
924
+ FileUtils.cp_r(custom_dir, Puppet[:vardir])
925
+ FileUtils.cp_r(external_dir, Puppet[:vardir])
926
+ end
927
+
928
+ def mounts
929
+ {
930
+ # the server needs to provide metadata that matches what the agent has
931
+ # so that the agent doesn't delete them during pluginsync
932
+ file_metadatas: -> (req, res) {
933
+ path = case req.path
934
+ when /pluginfacts/
935
+ external_dir
936
+ when /plugins/
937
+ custom_dir
938
+ else
939
+ raise "Unknown mount #{req.path}"
940
+ end
941
+ request = Puppet::FileServing::Metadata.indirection.request(
942
+ :search, path, nil, recurse: true
943
+ )
944
+ data = Puppet::FileServing::Metadata.indirection.terminus(:file).search(request)
945
+ res.body = formatter.render(data)
946
+ res['Content-Type'] = formatter.mime
947
+ },
948
+ catalog: -> (req, res) {
949
+ data = CGI.unescape(req.query['facts'])
950
+ facts = Puppet::Node::Facts.convert_from('json', data)
951
+ node.fact_merge(facts)
952
+
953
+ catalog = compile_to_catalog(<<~MANIFEST, node)
954
+ notify { "legacy $osfamily": }
955
+ notify { "custom ${facts['custom']}": }
956
+ notify { "external ${facts['external']}": }
957
+ MANIFEST
958
+
959
+ res.body = formatter.render(catalog)
960
+ res['Content-Type'] = formatter.mime
961
+ }
962
+ }
963
+ end
964
+
965
+ it "includes legacy facts by default" do
966
+ server.start_server(mounts: mounts) do |port|
967
+ Puppet[:serverport] = port
968
+
969
+ agent.command_line.args << '--test'
970
+ expect {
971
+ agent.run
972
+ }.to exit_with(2)
973
+ .and output(
974
+ match(/defined 'message' as 'legacy [A-Za-z]+'/)
975
+ .and match(/defined 'message' as 'custom a custom value'/)
976
+ .and match(/defined 'message' as 'external an external value'/)
977
+ ).to_stdout
978
+ end
979
+ end
980
+
981
+ it "can exclude legacy facts" do
982
+ server.start_server(mounts: mounts) do |port|
983
+ Puppet[:serverport] = port
984
+ Puppet[:include_legacy_facts] = false
985
+
986
+ agent.command_line.args << '--test'
987
+ expect {
988
+ agent.run
989
+ }.to exit_with(2)
990
+ .and output(
991
+ match(/defined 'message' as 'legacy '/)
992
+ .and match(/defined 'message' as 'custom a custom value'/)
993
+ .and match(/defined 'message' as 'external an external value'/)
994
+ ).to_stdout
995
+ .and output(/Warning: Unknown variable: 'osfamily'/).to_stderr
996
+ end
997
+ end
998
+ end
900
999
  end
@@ -91,6 +91,61 @@ describe 'lookup' do
91
91
  expect_lookup_with_output(0, /--- value from per node data/)
92
92
  end
93
93
 
94
+ it "resolves hiera data using a top-level node parameter from enc" do
95
+ Puppet.settings[:node_terminus] = 'exec'
96
+ enc = tmpfile('enc.sh')
97
+ Puppet.settings[:external_nodes] = enc
98
+ File.write(File.join(env_dir, env_name, 'hiera.yaml'), <<~YAML)
99
+ ---
100
+ version: 5
101
+ hierarchy:
102
+ - name: "Node parameters"
103
+ data_hash: yaml_data
104
+ path: "%{site}.yaml"
105
+ YAML
106
+
107
+ File.write(File.join(env_dir, env_name, 'data', "pdx.yaml"), <<~YAML)
108
+ ---
109
+ key: value
110
+ YAML
111
+ allow(Puppet::Util::Execution).to receive(:execute).with([enc, fqdn], anything).and_return(<<~YAML)
112
+ parameters:
113
+ site: pdx
114
+ YAML
115
+ app.command_line.args << 'key' << '--compile'
116
+ Puppet.initialize_settings(['-E', env_name])
117
+ expect_lookup_with_output(0, /--- value/)
118
+ end
119
+
120
+ it "prefers the environment specified on the commandline over the enc environment" do
121
+ Puppet.settings[:node_terminus] = 'exec'
122
+ enc = tmpfile('enc.sh')
123
+ Puppet.settings[:external_nodes] = enc
124
+ File.write(File.join(env_dir, env_name, 'hiera.yaml'), <<~YAML)
125
+ ---
126
+ version: 5
127
+ hierarchy:
128
+ - name: "Node parameters"
129
+ data_hash: yaml_data
130
+ path: "%{site}.yaml"
131
+ YAML
132
+
133
+ File.write(File.join(env_dir, env_name, 'data', "pdx.yaml"), <<~YAML)
134
+ ---
135
+ key: value
136
+ YAML
137
+ allow(Puppet::Util::Execution).to receive(:execute).with([enc, fqdn], anything).and_return(<<~YAML)
138
+ ---
139
+ # return 'someother' environment because it doesn't have any hiera data
140
+ environment: someother
141
+ parameters:
142
+ site: pdx
143
+ YAML
144
+ app.command_line.args << 'key' << '--compile'
145
+ Puppet.initialize_settings(['-E', env_name])
146
+ expect_lookup_with_output(0, /--- value/)
147
+ end
148
+
94
149
  it 'loads trusted information from the node certificate' do
95
150
  Puppet.settings[:node_terminus] = 'exec'
96
151
  expect_any_instance_of(Puppet::Node::Exec).to receive(:find) do |args|
@@ -173,7 +173,7 @@ describe Puppet::Agent do
173
173
  client = AgentTestClient.new
174
174
  expect(AgentTestClient).to receive(:new).and_return(client)
175
175
 
176
- expect(client).to receive(:run).with(:pluginsync => true, :other => :options)
176
+ expect(client).to receive(:run).with({:pluginsync => true, :other => :options})
177
177
  @agent.run(:other => :options)
178
178
  end
179
179
 
@@ -524,7 +524,7 @@ describe Puppet::Application::Agent do
524
524
  end
525
525
 
526
526
  it "should stop the daemon" do
527
- expect(@daemon).to receive(:stop).with(:exit => false)
527
+ expect(@daemon).to receive(:stop).with({:exit => false})
528
528
 
529
529
  expect { execute_agent }.to exit_with 0
530
530
  end
@@ -535,7 +535,7 @@ describe Puppet::Application::Device do
535
535
  end
536
536
 
537
537
  it "makes the Puppet::Pops::Loaders available" do
538
- expect(configurer).to receive(:run).with(:network_device => true, :pluginsync => false) do
538
+ expect(configurer).to receive(:run).with({:network_device => true, :pluginsync => false}) do
539
539
  fail('Loaders not available') unless Puppet.lookup(:loaders) { nil }.is_a?(Puppet::Pops::Loaders)
540
540
  true
541
541
  end.and_return(6, 2)
@@ -122,7 +122,7 @@ describe Puppet::Application::Resource do
122
122
  allow(@resource_app.command_line).to receive(:args).and_return(['type','name','param=temp'])
123
123
 
124
124
  expect(Puppet::Resource.indirection).to receive(:save).with(@res, 'type/name').and_return([@res, @report])
125
- expect(Puppet::Resource).to receive(:new).with('type', 'name', :parameters => {'param' => 'temp'}).and_return(@res)
125
+ expect(Puppet::Resource).to receive(:new).with('type', 'name', {:parameters => {'param' => 'temp'}}).and_return(@res)
126
126
 
127
127
  @resource_app.main
128
128
  end
@@ -24,7 +24,7 @@ describe Puppet::Confiner do
24
24
 
25
25
  it "should delegate its confine method to its confine collection" do
26
26
  allow(@object).to receive(:confine_collection).and_return(coll)
27
- expect(coll).to receive(:confine).with(:foo => :bar, :bee => :baz)
27
+ expect(coll).to receive(:confine).with({:foo => :bar, :bee => :baz})
28
28
  @object.confine(:foo => :bar, :bee => :baz)
29
29
  end
30
30
 
@@ -180,7 +180,7 @@ describe Puppet::Daemon, :unless => Puppet::Util::Platform.windows? do
180
180
 
181
181
  it "should shut down without exiting" do
182
182
  daemon.argv = %w{foo}
183
- expect(daemon).to receive(:stop).with(:exit => false)
183
+ expect(daemon).to receive(:stop).with({:exit => false})
184
184
  daemon.reexec
185
185
  end
186
186
 
@@ -322,7 +322,7 @@ describe Puppet::FileBucket::Dipper, :uses_checksums => true do
322
322
  file = make_tmp_file(plaintext)
323
323
 
324
324
  expect(Puppet::FileBucket::File.indirection).to receive(:head).with(
325
- %r{#{digest_algorithm}/#{checksum}}, :bucket_path => "/my/bucket"
325
+ %r{#{digest_algorithm}/#{checksum}}, {:bucket_path => "/my/bucket"}
326
326
  ).and_return(true)
327
327
  expect(Puppet::FileBucket::File.indirection).not_to receive(:save)
328
328
  expect(@dipper.backup(file)).to eq(checksum)
@@ -153,12 +153,12 @@ describe Puppet::FileServing::Fileset do
153
153
  top_names = %w{one two .svn CVS}
154
154
  sub_names = %w{file1 file2 .svn CVS 0 false}
155
155
 
156
- allow(Dir).to receive(:entries).with(path, encoding: Encoding::UTF_8).and_return(top_names)
156
+ allow(Dir).to receive(:entries).with(path, {encoding: Encoding::UTF_8}).and_return(top_names)
157
157
  top_names.each do |subdir|
158
158
  @files << subdir # relative path
159
159
  subpath = File.join(path, subdir)
160
160
  allow(Puppet::FileSystem).to receive(stat_method).with(subpath).and_return(@dirstat)
161
- allow(Dir).to receive(:entries).with(subpath, encoding: Encoding::UTF_8).and_return(sub_names)
161
+ allow(Dir).to receive(:entries).with(subpath, {encoding: Encoding::UTF_8}).and_return(sub_names)
162
162
  sub_names.each do |file|
163
163
  @files << File.join(subdir, file) # relative path
164
164
  subfile_path = File.join(subpath, file)
@@ -176,12 +176,12 @@ describe Puppet::FileServing::Fileset do
176
176
  top_names = (1..10).map {|i| "dir_#{i}" }
177
177
  sub_names = (1..100).map {|i| "file__#{i}" }
178
178
 
179
- allow(Dir).to receive(:entries).with(path, encoding: Encoding::UTF_8).and_return(top_names)
179
+ allow(Dir).to receive(:entries).with(path, {encoding: Encoding::UTF_8}).and_return(top_names)
180
180
  top_names.each do |subdir|
181
181
  @files << subdir # relative path
182
182
  subpath = File.join(path, subdir)
183
183
  allow(Puppet::FileSystem).to receive(stat_method).with(subpath).and_return(@dirstat)
184
- allow(Dir).to receive(:entries).with(subpath, encoding: Encoding::UTF_8).and_return(sub_names)
184
+ allow(Dir).to receive(:entries).with(subpath, {encoding: Encoding::UTF_8}).and_return(sub_names)
185
185
  sub_names.each do |file|
186
186
  @files << File.join(subdir, file) # relative path
187
187
  subfile_path = File.join(subpath, file)
@@ -193,7 +193,7 @@ describe Puppet::FileServing::Fileset do
193
193
  def setup_mocks_for_dir(mock_dir, base_path)
194
194
  path = File.join(base_path, mock_dir.name)
195
195
  allow(Puppet::FileSystem).to receive(:lstat).with(path).and_return(MockStat.new(path, true))
196
- allow(Dir).to receive(:entries).with(path, encoding: Encoding::UTF_8).and_return(['.', '..'] + mock_dir.entries.map(&:name))
196
+ allow(Dir).to receive(:entries).with(path, {encoding: Encoding::UTF_8}).and_return(['.', '..'] + mock_dir.entries.map(&:name))
197
197
  mock_dir.entries.each do |entry|
198
198
  setup_mocks_for_entry(entry, path)
199
199
  end
@@ -360,7 +360,7 @@ describe Puppet::FileServing::Fileset do
360
360
  link_path = File.join(path, "mylink")
361
361
  expect(Puppet::FileSystem).to receive(:stat).with(link_path).and_raise(Errno::ENOENT)
362
362
 
363
- allow(Dir).to receive(:entries).with(path, encoding: Encoding::UTF_8).and_return(["mylink"])
363
+ allow(Dir).to receive(:entries).with(path, {encoding: Encoding::UTF_8}).and_return(["mylink"])
364
364
 
365
365
  fileset = Puppet::FileServing::Fileset.new(path)
366
366
 
@@ -377,16 +377,16 @@ describe Puppet::FileServing::Fileset do
377
377
 
378
378
  @filesets = @paths.collect do |path|
379
379
  allow(Puppet::FileSystem).to receive(:lstat).with(path).and_return(double('stat', :directory? => true))
380
- Puppet::FileServing::Fileset.new(path, :recurse => true)
380
+ Puppet::FileServing::Fileset.new(path, {:recurse => true})
381
381
  end
382
382
 
383
383
  allow(Dir).to receive(:entries).and_return([])
384
384
  end
385
385
 
386
386
  it "returns a hash of all files in each fileset with the value being the base path" do
387
- expect(Dir).to receive(:entries).with(make_absolute("/first/path"), encoding: Encoding::UTF_8).and_return(%w{one uno})
388
- expect(Dir).to receive(:entries).with(make_absolute("/second/path"), encoding: Encoding::UTF_8).and_return(%w{two dos})
389
- expect(Dir).to receive(:entries).with(make_absolute("/third/path"), encoding: Encoding::UTF_8).and_return(%w{three tres})
387
+ expect(Dir).to receive(:entries).with(make_absolute("/first/path"), {encoding: Encoding::UTF_8}).and_return(%w{one uno})
388
+ expect(Dir).to receive(:entries).with(make_absolute("/second/path"), {encoding: Encoding::UTF_8}).and_return(%w{two dos})
389
+ expect(Dir).to receive(:entries).with(make_absolute("/third/path"), {encoding: Encoding::UTF_8}).and_return(%w{three tres})
390
390
 
391
391
  expect(Puppet::FileServing::Fileset.merge(*@filesets)).to eq({
392
392
  "." => make_absolute("/first/path"),
@@ -400,15 +400,15 @@ describe Puppet::FileServing::Fileset do
400
400
  end
401
401
 
402
402
  it "includes the base directory from the first fileset" do
403
- expect(Dir).to receive(:entries).with(make_absolute("/first/path"), encoding: Encoding::UTF_8).and_return(%w{one})
404
- expect(Dir).to receive(:entries).with(make_absolute("/second/path"), encoding: Encoding::UTF_8).and_return(%w{two})
403
+ expect(Dir).to receive(:entries).with(make_absolute("/first/path"), {encoding: Encoding::UTF_8}).and_return(%w{one})
404
+ expect(Dir).to receive(:entries).with(make_absolute("/second/path"), {encoding: Encoding::UTF_8}).and_return(%w{two})
405
405
 
406
406
  expect(Puppet::FileServing::Fileset.merge(*@filesets)["."]).to eq(make_absolute("/first/path"))
407
407
  end
408
408
 
409
409
  it "uses the base path of the first found file when relative file paths conflict" do
410
- expect(Dir).to receive(:entries).with(make_absolute("/first/path"), encoding: Encoding::UTF_8).and_return(%w{one})
411
- expect(Dir).to receive(:entries).with(make_absolute("/second/path"), encoding: Encoding::UTF_8).and_return(%w{one})
410
+ expect(Dir).to receive(:entries).with(make_absolute("/first/path"), {encoding: Encoding::UTF_8}).and_return(%w{one})
411
+ expect(Dir).to receive(:entries).with(make_absolute("/second/path"), {encoding: Encoding::UTF_8}).and_return(%w{one})
412
412
 
413
413
  expect(Puppet::FileServing::Fileset.merge(*@filesets)["one"]).to eq(make_absolute("/first/path"))
414
414
  end
@@ -819,9 +819,11 @@ describe "Puppet::FileSystem" do
819
819
  mode = Puppet::FileSystem.stat(dir).mode
820
820
  Puppet::FileSystem.chmod(0, dir)
821
821
  begin
822
+ # JRuby 9.2.21.0 drops the path from the message..
823
+ message = Puppet::Util::Platform.jruby? ? /^Permission denied/ : /^Permission denied .* #{path}/
822
824
  expect {
823
825
  Puppet::FileSystem.unlink(path)
824
- }.to raise_error(Errno::EACCES, /^Permission denied .* #{path}/)
826
+ }.to raise_error(Errno::EACCES, message)
825
827
  ensure
826
828
  Puppet::FileSystem.chmod(mode, dir)
827
829
  end
@@ -475,7 +475,7 @@ describe Puppet::Graph::SimpleGraph do
475
475
 
476
476
  it "should write a dot file based on the passed name" do
477
477
  expect(File).to receive(:open).with(@file, "w:UTF-8").and_yield(double("file", :puts => nil))
478
- expect(@graph).to receive(:to_dot).with("name" => @name.to_s.capitalize)
478
+ expect(@graph).to receive(:to_dot).with({"name" => @name.to_s.capitalize})
479
479
  Puppet[:graph] = true
480
480
  @graph.write_graph(@name)
481
481
  end
@@ -592,7 +592,7 @@ describe Puppet::HTTP::Service::Compiler do
592
592
  invalid_facts = Puppet::Node::Facts.new(certname, {'invalid_utf8_sequence' => "\xE2\x82".force_encoding('binary')})
593
593
  expect {
594
594
  subject.put_facts(certname, environment: 'production', facts: invalid_facts)
595
- }.to raise_error(Puppet::HTTP::SerializationError, /Failed to serialize Puppet::Node::Facts to json: "\\xE2" from ASCII-8BIT to UTF-8/)
595
+ }.to raise_error(Puppet::HTTP::SerializationError, /Failed to serialize Puppet::Node::Facts to json: ("\\xE2" from ASCII-8BIT to UTF-8|partial character in source, but hit end)/)
596
596
  end
597
597
  end
598
598
 
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet/indirector/facts/facter'
3
3
 
4
+ class Puppet::Node::Facts::Facter::MyCollection < Hash; end
5
+
4
6
  describe Puppet::Node::Facts::Facter do
5
7
  FS = Puppet::FileSystem
6
8
 
@@ -83,6 +85,29 @@ describe Puppet::Node::Facts::Facter do
83
85
 
84
86
  @facter.find(@request)
85
87
  end
88
+
89
+ it "can exclude legacy facts" do
90
+ Puppet[:include_legacy_facts] = false
91
+
92
+ expect(Puppet.runtime[:facter]).to receive(:resolve).with('')
93
+ .and_return({'kernelversion' => '1.2.3'})
94
+
95
+ values = @facter.find(@request).values
96
+ expect(values).to be_an_instance_of(Hash)
97
+ expect(values).to include({'kernelversion' => '1.2.3'})
98
+ end
99
+
100
+ it "can exclude legacy facts using buggy facter implementations that return a Hash subclass" do
101
+ Puppet[:include_legacy_facts] = false
102
+
103
+ collection = Puppet::Node::Facts::Facter::MyCollection["kernelversion" => '1.2.3']
104
+ expect(Puppet.runtime[:facter]).to receive(:resolve).with('')
105
+ .and_return(collection)
106
+
107
+ values = @facter.find(@request).values
108
+ expect(values).to be_an_instance_of(Hash)
109
+ expect(values).to include({'kernelversion' => '1.2.3'})
110
+ end
86
111
  end
87
112
 
88
113
  it 'should fail when saving facts' do
@@ -183,10 +183,10 @@ describe Puppet::Indirector::FileServer do
183
183
  expect(Puppet::FileServing::Fileset).to receive(:merge).and_return("one" => "/one", "two" => "/two")
184
184
 
185
185
  one = double('one', :collect => nil)
186
- expect(model).to receive(:new).with("/one", :relative_path => "one").and_return(one)
186
+ expect(model).to receive(:new).with("/one", {:relative_path => "one"}).and_return(one)
187
187
 
188
188
  two = double('two', :collect => nil)
189
- expect(model).to receive(:new).with("/two", :relative_path => "two").and_return(two)
189
+ expect(model).to receive(:new).with("/two", {:relative_path => "two"}).and_return(two)
190
190
 
191
191
  # order can't be guaranteed
192
192
  result = indirection.search(uri)
@@ -205,7 +205,7 @@ describe Puppet::Indirector::FileServer do
205
205
  expect(Puppet::FileServing::Fileset).to receive(:merge).and_return("one" => "/one")
206
206
 
207
207
  one = double('one', :collect => nil)
208
- expect(model).to receive(:new).with("/one", :relative_path => "one").and_return(one)
208
+ expect(model).to receive(:new).with("/one", {:relative_path => "one"}).and_return(one)
209
209
  expect(one).to receive(:links=).with(true)
210
210
 
211
211
  indirection.search(uri, links: true)
@@ -221,7 +221,7 @@ describe Puppet::Indirector::FileServer do
221
221
  expect(Puppet::FileServing::Fileset).to receive(:merge).and_return("one" => "/one")
222
222
 
223
223
  one = double('one', :collect => nil)
224
- expect(model).to receive(:new).with("/one", :relative_path => "one").and_return(one)
224
+ expect(model).to receive(:new).with("/one", {:relative_path => "one"}).and_return(one)
225
225
 
226
226
  expect(one).to receive(:checksum_type=).with(:checksum)
227
227
 
@@ -238,7 +238,7 @@ describe Puppet::Indirector::FileServer do
238
238
  expect(Puppet::FileServing::Fileset).to receive(:merge).and_return("one" => "/one")
239
239
 
240
240
  one = double('one')
241
- expect(model).to receive(:new).with("/one", :relative_path => "one").and_return(one)
241
+ expect(model).to receive(:new).with("/one", {:relative_path => "one"}).and_return(one)
242
242
  expect(one).to receive(:collect)
243
243
 
244
244
  indirection.search(uri)
@@ -6,7 +6,7 @@ shared_examples_for "Indirection Delegator" do
6
6
  it "should create a request object with the appropriate method name and all of the passed arguments" do
7
7
  request = Puppet::Indirector::Request.new(:indirection, :find, "me", nil)
8
8
 
9
- expect(@indirection).to receive(:request).with(@method, "mystuff", nil, :one => :two).and_return(request)
9
+ expect(@indirection).to receive(:request).with(@method, "mystuff", nil, {:one => :two}).and_return(request)
10
10
 
11
11
  allow(@terminus).to receive(@method)
12
12
 
@@ -21,7 +21,7 @@ describe Puppet::Node::Plain do
21
21
  end
22
22
 
23
23
  it "should find facts if none are supplied" do
24
- expect(Puppet::Node::Facts.indirection).to receive(:find).with(nodename, :environment => environment).and_return(indirection_facts)
24
+ expect(Puppet::Node::Facts.indirection).to receive(:find).with(nodename, {:environment => environment}).and_return(indirection_facts)
25
25
  request.options.delete(:facts)
26
26
  node = node_indirection.find(request)
27
27
  expect(node.parameters).to include(indirection_fact_values)
@@ -33,6 +33,27 @@ describe "Puppet::InfoService" do
33
33
  end
34
34
  end
35
35
 
36
+ it "returns task data for valid tasks in an environment even if invalid tasks exist" do
37
+ Puppet.override(:environments => env_loader) do
38
+ @mod = PuppetSpec::Modules.create(mod_name, modpath, {:environment => env,
39
+ :tasks => [['atask',
40
+ {:name => 'atask.json',
41
+ :content => metadata.to_json}],
42
+ ['btask',
43
+ {:name => 'btask.json',
44
+ :content => metadata.to_json}],
45
+ ['ctask',
46
+ {:name => 'ctask.json',
47
+ :content => metadata.to_json}]]})
48
+ File.write("#{modpath}/#{mod_name}/tasks/atask.json", "NOT JSON")
49
+
50
+ expect(Puppet).to receive(:send_log).with(:err, 'Failed to validate task')
51
+
52
+ @tasks = Puppet::InfoService.tasks_per_environment(env_name)
53
+ expect(@tasks.map{|t| t[:name]}).to contain_exactly('test1::btask', 'test1::ctask')
54
+ end
55
+ end
56
+
36
57
  it "should throw EnvironmentNotFound if given a nonexistent environment" do
37
58
  expect{ Puppet::InfoService.tasks_per_environment('utopia') }.to raise_error(Puppet::Environments::EnvironmentNotFound)
38
59
  end
@@ -82,7 +82,7 @@ describe Puppet::ModuleTool::Tar::Mini, :if => (Puppet.features.minitar? and Pup
82
82
  expect(Zlib::GzipReader).to receive(:open).with(sourcefile).and_yield(reader)
83
83
  expect(minitar).to receive(:find_valid_files).with(reader).and_return([name])
84
84
  entry = MockFileStatEntry.new(mode)
85
- expect(Archive::Tar::Minitar).to receive(:unpack).with(reader, destdir, [name], :fsync => false).
85
+ expect(Archive::Tar::Minitar).to receive(:unpack).with(reader, destdir, [name], {:fsync => false}).
86
86
  and_yield(type, name, {:entry => entry})
87
87
  entry
88
88
  end
@@ -504,7 +504,7 @@ EOT
504
504
 
505
505
  context "when rendering face-related objects" do
506
506
  it "pretty prints facts" do
507
- tm = Time.new("2016-01-27T19:30:00")
507
+ tm = Time.new(2016, 1, 27, 19, 30, 0)
508
508
  values = {
509
509
  "architecture" => "x86_64",
510
510
  "os" => {