puppet 7.20.0 → 7.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +23 -23
  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/transaction/report.rb +18 -1
  8. data/lib/puppet/type/resources.rb +1 -6
  9. data/lib/puppet/type/tidy.rb +3 -2
  10. data/lib/puppet/type/user.rb +1 -3
  11. data/lib/puppet/type.rb +10 -0
  12. data/lib/puppet/version.rb +1 -1
  13. data/man/man5/puppet.conf.5 +18 -2
  14. data/man/man8/puppet-agent.8 +1 -1
  15. data/man/man8/puppet-apply.8 +1 -1
  16. data/man/man8/puppet-catalog.8 +1 -1
  17. data/man/man8/puppet-config.8 +1 -1
  18. data/man/man8/puppet-describe.8 +1 -1
  19. data/man/man8/puppet-device.8 +1 -1
  20. data/man/man8/puppet-doc.8 +1 -1
  21. data/man/man8/puppet-epp.8 +1 -1
  22. data/man/man8/puppet-facts.8 +1 -1
  23. data/man/man8/puppet-filebucket.8 +1 -1
  24. data/man/man8/puppet-generate.8 +1 -1
  25. data/man/man8/puppet-help.8 +1 -1
  26. data/man/man8/puppet-lookup.8 +1 -1
  27. data/man/man8/puppet-module.8 +1 -1
  28. data/man/man8/puppet-node.8 +1 -1
  29. data/man/man8/puppet-parser.8 +1 -1
  30. data/man/man8/puppet-plugin.8 +1 -1
  31. data/man/man8/puppet-report.8 +1 -1
  32. data/man/man8/puppet-resource.8 +1 -1
  33. data/man/man8/puppet-script.8 +1 -1
  34. data/man/man8/puppet-ssl.8 +1 -1
  35. data/man/man8/puppet.8 +2 -2
  36. data/spec/integration/application/agent_spec.rb +99 -0
  37. data/spec/integration/application/lookup_spec.rb +55 -0
  38. data/spec/unit/agent_spec.rb +1 -1
  39. data/spec/unit/confiner_spec.rb +1 -1
  40. data/spec/unit/http/service/compiler_spec.rb +1 -1
  41. data/spec/unit/indirector/facts/facter_spec.rb +10 -0
  42. data/spec/unit/indirector/indirection_spec.rb +1 -1
  43. data/spec/unit/info_service_spec.rb +21 -0
  44. data/spec/unit/module_tool/tar/mini_spec.rb +1 -1
  45. data/spec/unit/network/formats_spec.rb +1 -1
  46. data/spec/unit/provider/ldap_spec.rb +2 -2
  47. data/spec/unit/provider/package/dpkg_spec.rb +3 -3
  48. data/spec/unit/provider/package/pkgutil_spec.rb +4 -4
  49. data/spec/unit/provider/parsedfile_spec.rb +4 -4
  50. data/spec/unit/reports/store_spec.rb +5 -1
  51. data/spec/unit/transaction/event_manager_spec.rb +2 -2
  52. data/spec/unit/transaction/report_spec.rb +38 -1
  53. data/spec/unit/transaction_spec.rb +2 -2
  54. data/spec/unit/type/file_spec.rb +4 -4
  55. data/spec/unit/type/filebucket_spec.rb +3 -3
  56. data/spec/unit/type/resources_spec.rb +14 -0
  57. data/spec/unit/type/tidy_spec.rb +27 -17
  58. data/spec/unit/util/execution_spec.rb +6 -6
  59. data/spec/unit/util/network_device_spec.rb +1 -6
  60. data/spec/unit/util/storage_spec.rb +1 -1
  61. data/spec/unit/x509/cert_provider_spec.rb +1 -1
  62. metadata +2 -2
@@ -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
@@ -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')
@@ -141,27 +141,20 @@ describe tidy do
141
141
  describe "and generating files" do
142
142
  it "should set the backup on the file if backup is set on the tidy instance" do
143
143
  @tidy[:backup] = "whatever"
144
- expect(Puppet::Type.type(:file)).to receive(:new).with(hash_including(backup: "whatever"))
145
144
 
146
- @tidy.mkfile(@basepath)
145
+ expect(@tidy.mkfile(@basepath)[:backup]).to eq("whatever")
147
146
  end
148
147
 
149
148
  it "should set the file's path to the tidy's path" do
150
- expect(Puppet::Type.type(:file)).to receive(:new).with(hash_including(path: @basepath))
151
-
152
- @tidy.mkfile(@basepath)
149
+ expect(@tidy.mkfile(@basepath)[:path]).to eq(@basepath)
153
150
  end
154
151
 
155
152
  it "should configure the file for deletion" do
156
- expect(Puppet::Type.type(:file)).to receive(:new).with(hash_including(ensure: :absent))
157
-
158
- @tidy.mkfile(@basepath)
153
+ expect(@tidy.mkfile(@basepath)[:ensure]).to eq(:absent)
159
154
  end
160
155
 
161
156
  it "should force deletion on the file" do
162
- expect(Puppet::Type.type(:file)).to receive(:new).with(hash_including(force: true))
163
-
164
- @tidy.mkfile(@basepath)
157
+ expect(@tidy.mkfile(@basepath)[:force]).to eq(true)
165
158
  end
166
159
 
167
160
  it "should do nothing if the targeted file does not exist" do
@@ -196,7 +189,7 @@ describe tidy do
196
189
  end
197
190
 
198
191
  it "should use a Fileset with default max_files for infinite recursion" do
199
- expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, :recurse => true, :max_files=>0).and_return(@fileset)
192
+ expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, {:recurse => true, :max_files=>0}).and_return(@fileset)
200
193
  expect(@fileset).to receive(:files).and_return(%w{. one two})
201
194
  allow(@tidy).to receive(:tidy?).and_return(false)
202
195
 
@@ -205,7 +198,7 @@ describe tidy do
205
198
 
206
199
  it "should use a Fileset with default max_files for limited recursion" do
207
200
  @tidy[:recurse] = 42
208
- expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, :recurse => true, :recurselimit => 42, :max_files=>0).and_return(@fileset)
201
+ expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, {:recurse => true, :recurselimit => 42, :max_files=>0}).and_return(@fileset)
209
202
  expect(@fileset).to receive(:files).and_return(%w{. one two})
210
203
  allow(@tidy).to receive(:tidy?).and_return(false)
211
204
 
@@ -215,7 +208,7 @@ describe tidy do
215
208
  it "should use a Fileset with max_files for limited recursion" do
216
209
  @tidy[:recurse] = 42
217
210
  @tidy[:max_files] = 9876
218
- expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, :recurse => true, :recurselimit => 42, :max_files=>9876).and_return(@fileset)
211
+ expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, {:recurse => true, :recurselimit => 42, :max_files=>9876}).and_return(@fileset)
219
212
  expect(@fileset).to receive(:files).and_return(%w{. one two})
220
213
  allow(@tidy).to receive(:tidy?).and_return(false)
221
214
 
@@ -428,7 +421,7 @@ describe tidy do
428
421
  @tidy[:recurse] = true
429
422
  @tidy[:rmdirs] = true
430
423
  fileset = double('fileset')
431
- expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, :recurse => true, :max_files=>0).and_return(fileset)
424
+ expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, {:recurse => true, :max_files=>0}).and_return(fileset)
432
425
  expect(fileset).to receive(:files).and_return(%w{. one two one/subone two/subtwo one/subone/ssone})
433
426
  allow(@tidy).to receive(:tidy?).and_return(true)
434
427
 
@@ -450,7 +443,7 @@ describe tidy do
450
443
  @tidy[:recurse] = true
451
444
  @tidy[:rmdirs] = true
452
445
  fileset = double('fileset')
453
- expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, :recurse => true, :max_files=>0).and_return(fileset)
446
+ expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, {:recurse => true, :max_files=>0}).and_return(fileset)
454
447
  expect(fileset).to receive(:files).and_return(%w{. a a/2 a/1 a/3})
455
448
  allow(@tidy).to receive(:tidy?).and_return(true)
456
449
 
@@ -463,7 +456,7 @@ describe tidy do
463
456
  @tidy[:noop] = true
464
457
 
465
458
  fileset = double('fileset')
466
- expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, :recurse => true, :max_files=>0).and_return(fileset)
459
+ expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, {:recurse => true, :max_files=>0}).and_return(fileset)
467
460
  expect(fileset).to receive(:files).and_return(%w{. a a/2 a/1 a/3})
468
461
  allow(@tidy).to receive(:tidy?).and_return(true)
469
462
 
@@ -471,6 +464,23 @@ describe tidy do
471
464
 
472
465
  expect(result.values).to all(be_noop)
473
466
  end
467
+
468
+ it "generates resources whose schedule parameter matches the managed resource's schedule parameter" do
469
+ @tidy[:recurse] = true
470
+ @tidy[:schedule] = 'fake_schedule'
471
+
472
+ fileset = double('fileset')
473
+ expect(Puppet::FileServing::Fileset).to receive(:new).with(@basepath, {:recurse => true, :max_files=>0}).and_return(fileset)
474
+ expect(fileset).to receive(:files).and_return(%w{. a a/2 a/1 a/3})
475
+ allow(@tidy).to receive(:tidy?).and_return(true)
476
+
477
+ result = @tidy.generate.inject({}) { |hash, res| hash[res[:path]] = res; hash }
478
+
479
+ result.each do |file_resource|
480
+ expect(file_resource[1][:schedule]).to eq('fake_schedule')
481
+ end
482
+
483
+ end
474
484
  end
475
485
 
476
486
  def lstat_is(path, stat)