puppet 7.19.0-x64-mingw32 → 7.21.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +31 -31
  3. data/lib/puppet/application/lookup.rb +5 -5
  4. data/lib/puppet/defaults.rb +14 -0
  5. data/lib/puppet/indirector/facts/facter.rb +5 -1
  6. data/lib/puppet/info_service/task_information_service.rb +10 -2
  7. data/lib/puppet/module/task.rb +6 -1
  8. data/lib/puppet/transaction/report.rb +18 -1
  9. data/lib/puppet/type/resources.rb +1 -6
  10. data/lib/puppet/type/tidy.rb +3 -2
  11. data/lib/puppet/type/user.rb +1 -3
  12. data/lib/puppet/type.rb +10 -0
  13. data/lib/puppet/version.rb +1 -1
  14. data/man/man5/puppet.conf.5 +18 -2
  15. data/man/man8/puppet-agent.8 +1 -1
  16. data/man/man8/puppet-apply.8 +1 -1
  17. data/man/man8/puppet-catalog.8 +1 -1
  18. data/man/man8/puppet-config.8 +1 -1
  19. data/man/man8/puppet-describe.8 +1 -1
  20. data/man/man8/puppet-device.8 +1 -1
  21. data/man/man8/puppet-doc.8 +1 -1
  22. data/man/man8/puppet-epp.8 +1 -1
  23. data/man/man8/puppet-facts.8 +1 -1
  24. data/man/man8/puppet-filebucket.8 +1 -1
  25. data/man/man8/puppet-generate.8 +1 -1
  26. data/man/man8/puppet-help.8 +1 -1
  27. data/man/man8/puppet-lookup.8 +1 -1
  28. data/man/man8/puppet-module.8 +1 -1
  29. data/man/man8/puppet-node.8 +1 -1
  30. data/man/man8/puppet-parser.8 +1 -1
  31. data/man/man8/puppet-plugin.8 +1 -1
  32. data/man/man8/puppet-report.8 +1 -1
  33. data/man/man8/puppet-resource.8 +1 -1
  34. data/man/man8/puppet-script.8 +1 -1
  35. data/man/man8/puppet-ssl.8 +1 -1
  36. data/man/man8/puppet.8 +2 -2
  37. data/spec/integration/application/agent_spec.rb +99 -0
  38. data/spec/integration/application/lookup_spec.rb +55 -0
  39. data/spec/unit/agent_spec.rb +1 -1
  40. data/spec/unit/confiner_spec.rb +1 -1
  41. data/spec/unit/http/service/compiler_spec.rb +1 -1
  42. data/spec/unit/indirector/facts/facter_spec.rb +10 -0
  43. data/spec/unit/indirector/indirection_spec.rb +1 -1
  44. data/spec/unit/info_service_spec.rb +21 -0
  45. data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
  46. data/spec/unit/network/formats_spec.rb +1 -1
  47. data/spec/unit/provider/ldap_spec.rb +2 -2
  48. data/spec/unit/provider/package/dpkg_spec.rb +3 -3
  49. data/spec/unit/provider/package/pkgutil_spec.rb +4 -4
  50. data/spec/unit/provider/parsedfile_spec.rb +4 -4
  51. data/spec/unit/reports/store_spec.rb +5 -1
  52. data/spec/unit/task_spec.rb +11 -0
  53. data/spec/unit/transaction/event_manager_spec.rb +2 -2
  54. data/spec/unit/transaction/report_spec.rb +38 -1
  55. data/spec/unit/transaction_spec.rb +2 -2
  56. data/spec/unit/type/file_spec.rb +4 -4
  57. data/spec/unit/type/filebucket_spec.rb +3 -3
  58. data/spec/unit/type/resources_spec.rb +14 -0
  59. data/spec/unit/type/tidy_spec.rb +27 -17
  60. data/spec/unit/util/execution_spec.rb +6 -6
  61. data/spec/unit/util/network_device_spec.rb +1 -6
  62. data/spec/unit/util/storage_spec.rb +1 -1
  63. data/spec/unit/x509/cert_provider_spec.rb +1 -1
  64. data/tasks/manpages.rake +5 -0
  65. metadata +2 -2
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" "September 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET" "8" "December 2022" "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\.19\.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\.21\.0
@@ -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
 
@@ -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
 
@@ -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
 
@@ -83,6 +83,16 @@ describe Puppet::Node::Facts::Facter do
83
83
 
84
84
  @facter.find(@request)
85
85
  end
86
+
87
+ it "can exclude legacy facts" do
88
+ Puppet[:include_legacy_facts] = false
89
+
90
+ facts = Puppet::Node::Facts.new("foo")
91
+ expect(Puppet::Node::Facts).to receive(:new).and_return(facts)
92
+ expect(Puppet.runtime[:facter]).to receive(:resolve).with('')
93
+
94
+ @facter.find(@request)
95
+ end
86
96
  end
87
97
 
88
98
  it 'should fail when saving facts' do
@@ -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
 
@@ -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" => {
@@ -85,7 +85,7 @@ describe Puppet::Provider::Ldap do
85
85
  it "should create a provider with the results of the find" do
86
86
  expect(@manager).to receive(:find).with("one").and_return("one" => "two")
87
87
 
88
- expect(@class).to receive(:new).with("one" => "two", :ensure => :present).and_return("myprovider")
88
+ expect(@class).to receive(:new).with({"one" => "two", :ensure => :present}).and_return("myprovider")
89
89
 
90
90
  expect(@resource).to receive(:provider=).with("myprovider")
91
91
 
@@ -95,7 +95,7 @@ describe Puppet::Provider::Ldap do
95
95
  it "should set :ensure to :present in the returned values" do
96
96
  expect(@manager).to receive(:find).with("one").and_return("one" => "two")
97
97
 
98
- expect(@class).to receive(:new).with("one" => "two", :ensure => :present).and_return("myprovider")
98
+ expect(@class).to receive(:new).with({"one" => "two", :ensure => :present}).and_return("myprovider")
99
99
 
100
100
  expect(@resource).to receive(:provider=).with("myprovider")
101
101
 
@@ -32,7 +32,7 @@ describe Puppet::Type.type(:package).provider(:dpkg), unless: Puppet::Util::Plat
32
32
  expect(Puppet::Util::Execution).to receive(:execpipe).with(execpipe_args).and_yield(bash_installed_io)
33
33
 
34
34
  installed = double('bash')
35
- expect(described_class).to receive(:new).with(:ensure => "4.2-5ubuntu3", :error => "ok", :desired => "install", :name => "bash", :mark => :none, :status => "installed", :provider => :dpkg).and_return(installed)
35
+ expect(described_class).to receive(:new).with({:ensure => "4.2-5ubuntu3", :error => "ok", :desired => "install", :name => "bash", :mark => :none, :status => "installed", :provider => :dpkg}).and_return(installed)
36
36
 
37
37
  expect(described_class.instances).to eq([installed])
38
38
  end
@@ -41,9 +41,9 @@ describe Puppet::Type.type(:package).provider(:dpkg), unless: Puppet::Util::Plat
41
41
  expect(Puppet::Util::Execution).to receive(:execpipe).with(execpipe_args).and_yield(all_installed_io)
42
42
 
43
43
  bash = double('bash')
44
- expect(described_class).to receive(:new).with(:ensure => "4.2-5ubuntu3", :error => "ok", :desired => "install", :name => "bash", :mark => :none, :status => "installed", :provider => :dpkg).and_return(bash)
44
+ expect(described_class).to receive(:new).with({:ensure => "4.2-5ubuntu3", :error => "ok", :desired => "install", :name => "bash", :mark => :none, :status => "installed", :provider => :dpkg}).and_return(bash)
45
45
  vim = double('vim')
46
- expect(described_class).to receive(:new).with(:ensure => "2:7.3.547-6ubuntu5", :error => "ok", :desired => "install", :name => "vim", :mark => :none, :status => "installed", :provider => :dpkg).and_return(vim)
46
+ expect(described_class).to receive(:new).with({:ensure => "2:7.3.547-6ubuntu5", :error => "ok", :desired => "install", :name => "vim", :mark => :none, :status => "installed", :provider => :dpkg}).and_return(vim)
47
47
 
48
48
  expect(described_class.instances).to eq([bash, vim])
49
49
  end
@@ -195,7 +195,7 @@ Not in catalog"
195
195
  expect(described_class).to receive(:pkguti).with(['-c']).and_return(fake_data)
196
196
 
197
197
  testpkg = double('pkg1')
198
- expect(described_class).to receive(:new).with(:ensure => "1.4.5,REV=2007.11.18", :name => "TESTpkg", :provider => :pkgutil).and_return(testpkg)
198
+ expect(described_class).to receive(:new).with({:ensure => "1.4.5,REV=2007.11.18", :name => "TESTpkg", :provider => :pkgutil}).and_return(testpkg)
199
199
  expect(described_class.instances).to eq([testpkg])
200
200
  end
201
201
 
@@ -207,10 +207,10 @@ Not in catalog"
207
207
  expect(described_class).to receive(:pkguti).with(['-c']).and_return(fake_data)
208
208
 
209
209
  testpkg = double('pkg1')
210
- expect(described_class).to receive(:new).with(:ensure => "1.4.5,REV=2007.11.18", :name => "TESTpkg", :provider => :pkgutil).and_return(testpkg)
210
+ expect(described_class).to receive(:new).with({:ensure => "1.4.5,REV=2007.11.18", :name => "TESTpkg", :provider => :pkgutil}).and_return(testpkg)
211
211
 
212
212
  aliaspkg = double('pkg2')
213
- expect(described_class).to receive(:new).with(:ensure => "1.4.5,REV=2007.11.18", :name => "mypkg", :provider => :pkgutil).and_return(aliaspkg)
213
+ expect(described_class).to receive(:new).with({:ensure => "1.4.5,REV=2007.11.18", :name => "mypkg", :provider => :pkgutil}).and_return(aliaspkg)
214
214
 
215
215
  expect(described_class.instances).to eq([testpkg,aliaspkg])
216
216
  end
@@ -223,7 +223,7 @@ Not in catalog"
223
223
  expect(described_class).to receive(:pkguti).with(['-c']).and_return(fake_data)
224
224
 
225
225
  testpkg = double('pkg1')
226
- expect(described_class).to receive(:new).with(:ensure => "1.4.5,REV=2007.11.18", :name => "TESTpkg", :provider => :pkgutil).and_return(testpkg)
226
+ expect(described_class).to receive(:new).with({:ensure => "1.4.5,REV=2007.11.18", :name => "TESTpkg", :provider => :pkgutil}).and_return(testpkg)
227
227
 
228
228
  expect(described_class.instances).to eq([testpkg])
229
229
  end
@@ -59,10 +59,10 @@ describe Puppet::Provider::ParsedFile do
59
59
  {:name => 'target3_record2'}
60
60
  ])
61
61
  expect(Puppet).to receive(:err).with('Could not prefetch parsedfile_type provider \'parsedfile_provider\' target \'/two\': some error. Treating as empty')
62
- expect(provider).to receive(:new).with(:name => 'target1_record1', :on_disk => true, :target => '/one', :ensure => :present).and_return('r1')
63
- expect(provider).to receive(:new).with(:name => 'target1_record2', :on_disk => true, :target => '/one', :ensure => :present).and_return('r2')
64
- expect(provider).to receive(:new).with(:name => 'target3_record1', :on_disk => true, :target => '/three', :ensure => :present).and_return('r3')
65
- expect(provider).to receive(:new).with(:name => 'target3_record2', :on_disk => true, :target => '/three', :ensure => :present).and_return('r4')
62
+ expect(provider).to receive(:new).with({:name => 'target1_record1', :on_disk => true, :target => '/one', :ensure => :present}).and_return('r1')
63
+ expect(provider).to receive(:new).with({:name => 'target1_record2', :on_disk => true, :target => '/one', :ensure => :present}).and_return('r2')
64
+ expect(provider).to receive(:new).with({:name => 'target3_record1', :on_disk => true, :target => '/three', :ensure => :present}).and_return('r3')
65
+ expect(provider).to receive(:new).with({:name => 'target3_record2', :on_disk => true, :target => '/three', :ensure => :present}).and_return('r4')
66
66
 
67
67
  expect(provider.instances).to eq(%w{r1 r2 r3 r4})
68
68
  end
@@ -15,7 +15,11 @@ describe Puppet::Reports.report(:store) do
15
15
  end
16
16
 
17
17
  let(:report) do
18
- report = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml/report2.6.x.yaml'))
18
+ if RUBY_VERSION < "3.0"
19
+ report = YAML.load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml/report2.6.x.yaml'))
20
+ else
21
+ report = YAML.unsafe_load_file(File.join(PuppetSpec::FIXTURE_DIR, 'yaml/report2.6.x.yaml'))
22
+ end
19
23
  report.extend(described_class)
20
24
  report
21
25
  end
@@ -235,6 +235,17 @@ describe Puppet::Module::Task do
235
235
  tasks[0].metadata
236
236
  }.to raise_error(Puppet::Module::Task::InvalidMetadata, /whoops/)
237
237
  end
238
+
239
+ it 'returns empty hash for metadata when json metadata file is empty' do
240
+ FileUtils.mkdir_p(tasks_path)
241
+ FileUtils.touch(File.join(tasks_path, 'task.json'))
242
+ FileUtils.touch(File.join(tasks_path, 'task'))
243
+
244
+ tasks = Puppet::Module::Task.tasks_in_module(mymod)
245
+
246
+ expect(tasks.count).to eq(1)
247
+ expect(tasks[0].metadata).to eq({})
248
+ end
238
249
  end
239
250
 
240
251
  describe :validate do
@@ -191,8 +191,8 @@ describe Puppet::Transaction::EventManager do
191
191
 
192
192
  allow(@resource).to receive(:callback1)
193
193
 
194
- expect(@resource).to receive(:event).with(:message => "Triggered 'callback1' from 1 event", :status => 'success', :name => 'callback1')
195
- expect(@resource).to receive(:event).with(:name => :restarted, :status => "success").and_return("myevent")
194
+ expect(@resource).to receive(:event).with({:message => "Triggered 'callback1' from 1 event", :status => 'success', :name => 'callback1'})
195
+ expect(@resource).to receive(:event).with({:name => :restarted, :status => "success"}).and_return("myevent")
196
196
  expect(@manager).to receive(:queue_events).with(@resource, ["myevent"])
197
197
 
198
198
  @manager.process_events(@resource)
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
-
2
+ require 'puppet_spec/compiler'
3
3
  require 'puppet'
4
4
  require 'puppet/transaction/report'
5
5
  require 'matchers/json'
@@ -7,6 +7,7 @@ require 'matchers/json'
7
7
  describe Puppet::Transaction::Report do
8
8
  include JSONMatchers
9
9
  include PuppetSpec::Files
10
+ include PuppetSpec::Compiler
10
11
 
11
12
  before do
12
13
  allow(Puppet::Util::Storage).to receive(:store)
@@ -136,6 +137,42 @@ describe Puppet::Transaction::Report do
136
137
  expect(report.metrics['time'].values.any? {|metric| metric.first =~ /whit/i}).to be_falsey
137
138
  end
138
139
 
140
+ describe "when exclude_unchanged_resources is true" do
141
+ before do
142
+ Puppet[:exclude_unchanged_resources] = true
143
+ end
144
+
145
+ let(:test_dir) { tmpdir('unchanged_resources') }
146
+ let(:test_dir2) { tmpdir('unchanged_resources') }
147
+ let(:test_file) { tmpfile('some_path')}
148
+ it 'should still list "changed" resource statuses but remove "unchanged"' do
149
+ transaction = apply_compiled_manifest(<<-END)
150
+ notify { "hi": } ~>
151
+ exec { "/bin/this_command_does_not_exist":
152
+ command => "#{make_absolute('/bin/this_command_does_not_exist')}",
153
+ refreshonly => true,
154
+ }
155
+ file { '#{test_dir}':
156
+ ensure => directory
157
+ }
158
+ file { 'failing_file':
159
+ path => '#{test_dir2}',
160
+ ensure => file
161
+ }
162
+ file { 'skipped_file':
163
+ path => '#{test_file}',
164
+ require => File[failing_file]
165
+ }
166
+ END
167
+ rs = transaction.report.to_data_hash['resource_statuses']
168
+ expect(rs["Notify[hi]"]['out_of_sync']).to be true
169
+ expect(rs["Exec[/bin/this_command_does_not_exist]"]['failed_to_restart']).to be true
170
+ expect(rs["File[failing_file]"]['failed']).to be true
171
+ expect(rs["File[skipped_file]"]['skipped']).to be true
172
+ expect(rs).to_not have_key(["File[#{test_dir}]"])
173
+ end
174
+ end
175
+
139
176
  describe "when accepting logs" do
140
177
  before do
141
178
  @report = Puppet::Transaction::Report.new
@@ -570,7 +570,7 @@ describe Puppet::Transaction do
570
570
  end
571
571
 
572
572
  it "should match resources by name, not title" do
573
- expect(resource.provider.class).to receive(:prefetch).with("bar" => resource)
573
+ expect(resource.provider.class).to receive(:prefetch).with({"bar" => resource})
574
574
 
575
575
  transaction.prefetch_if_necessary(resource)
576
576
  end
@@ -598,7 +598,7 @@ describe Puppet::Transaction do
598
598
  catalog.add_resource other
599
599
 
600
600
  allow(resource.class).to receive(:defaultprovider).and_return(resource.provider.class)
601
- expect(resource.provider.class).to receive(:prefetch).with('bar' => resource, 'other' => other)
601
+ expect(resource.provider.class).to receive(:prefetch).with({'bar' => resource, 'other' => other})
602
602
 
603
603
  transaction.prefetch_if_necessary(resource)
604
604
  end
@@ -516,8 +516,8 @@ describe Puppet::Type.type(:file) do
516
516
  it "should pass the already-discovered resources to recurse_remote" do
517
517
  file[:source] = File.expand_path(__FILE__)
518
518
  allow(child).to receive(:[]).with(:path).and_return(name)
519
- allow(file).to receive(:recurse_local).and_return(name => child)
520
- expect(file).to receive(:recurse_remote).with(name => child).and_return([])
519
+ allow(file).to receive(:recurse_local).and_return({name => child})
520
+ expect(file).to receive(:recurse_remote).with({name => child}).and_return([])
521
521
  file.recurse
522
522
  end
523
523
  end
@@ -526,8 +526,8 @@ describe Puppet::Type.type(:file) do
526
526
  it "should use recurse_link" do
527
527
  file[:target] = File.expand_path(__FILE__)
528
528
  allow(child).to receive(:[]).with(:path).and_return(name)
529
- allow(file).to receive(:recurse_local).and_return(name => child)
530
- expect(file).to receive(:recurse_link).with(name => child).and_return([])
529
+ allow(file).to receive(:recurse_local).and_return({name => child})
530
+ expect(file).to receive(:recurse_link).with({name => child}).and_return([])
531
531
  file.recurse
532
532
  end
533
533
  end
@@ -82,20 +82,20 @@ describe Puppet::Type.type(:filebucket) do
82
82
  it "should use any provided path" do
83
83
  path = make_absolute("/foo/bar")
84
84
  bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => path
85
- expect(Puppet::FileBucket::Dipper).to receive(:new).with(:Path => path).and_return(@bucket)
85
+ expect(Puppet::FileBucket::Dipper).to receive(:new).with({:Path => path}).and_return(@bucket)
86
86
  bucket.bucket
87
87
  end
88
88
 
89
89
  it "should use any provided server and port" do
90
90
  bucket = Puppet::Type.type(:filebucket).new :name => "main", :server => "myserv", :port => "myport", :path => false
91
- expect(Puppet::FileBucket::Dipper).to receive(:new).with(:Server => "myserv", :Port => "myport").and_return(@bucket)
91
+ expect(Puppet::FileBucket::Dipper).to receive(:new).with({:Server => "myserv", :Port => "myport"}).and_return(@bucket)
92
92
  bucket.bucket
93
93
  end
94
94
 
95
95
  it "should not try to guess server or port if the path is unset and no server is provided" do
96
96
  Puppet.settings[:server] = "myserv"
97
97
  Puppet.settings[:server_list] = ['server_list_0', 'server_list_1']
98
- expect(Puppet::FileBucket::Dipper).to receive(:new).with(:Server => nil, :Port => nil).and_return(@bucket)
98
+ expect(Puppet::FileBucket::Dipper).to receive(:new).with({:Server => nil, :Port => nil}).and_return(@bucket)
99
99
 
100
100
  bucket = Puppet::Type.type(:filebucket).new :name => "main", :path => false
101
101
  bucket.bucket
@@ -270,6 +270,20 @@ describe resources do
270
270
  @catalog = Puppet::Resource::Catalog.new
271
271
  end
272
272
 
273
+ context "when the catalog contains a purging resource with an alias" do
274
+ before do
275
+ @resource = Puppet::Type.type(:resources).new(:name => "purgeable_test", :purge => true)
276
+ @catalog.add_resource @resource
277
+ @catalog.alias(@resource, "purgeable_test_alias")
278
+ end
279
+
280
+ it "should not copy the alias metaparameter" do
281
+ allow(Puppet::Type.type(:purgeable_test)).to receive(:instances).and_return([@purgee])
282
+ generated = @resource.generate.first
283
+ expect(generated[:alias]).to be_nil
284
+ end
285
+ end
286
+
273
287
  context "when dealing with non-purging resources" do
274
288
  before do
275
289
  @resources = Puppet::Type.type(:resources).new(:name => 'purgeable_test')