puppet 6.12.0 → 6.13.0

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

Potentially problematic release.


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

Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +12 -12
  3. data/README.md +1 -1
  4. data/ext/project_data.yaml +1 -1
  5. data/lib/puppet.rb +22 -7
  6. data/lib/puppet/application/resource.rb +1 -1
  7. data/lib/puppet/configurer.rb +8 -13
  8. data/lib/puppet/defaults.rb +83 -49
  9. data/lib/puppet/environments.rb +26 -18
  10. data/lib/puppet/face/facts.rb +8 -5
  11. data/lib/puppet/file_system/memory_file.rb +6 -0
  12. data/lib/puppet/file_system/memory_impl.rb +13 -0
  13. data/lib/puppet/file_system/windows.rb +7 -10
  14. data/lib/puppet/http.rb +2 -0
  15. data/lib/puppet/http/client.rb +30 -0
  16. data/lib/puppet/http/errors.rb +2 -0
  17. data/lib/puppet/http/service.rb +61 -2
  18. data/lib/puppet/http/service/compiler.rb +86 -0
  19. data/lib/puppet/http/service/file_server.rb +85 -0
  20. data/lib/puppet/http/service/report.rb +4 -8
  21. data/lib/puppet/http/session.rb +8 -1
  22. data/lib/puppet/indirector/catalog/compiler.rb +10 -0
  23. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  24. data/lib/puppet/indirector/json.rb +1 -1
  25. data/lib/puppet/indirector/msgpack.rb +1 -1
  26. data/lib/puppet/network/http/connection.rb +4 -0
  27. data/lib/puppet/network/http/nocache_pool.rb +1 -0
  28. data/lib/puppet/network/http/pool.rb +5 -1
  29. data/lib/puppet/parser/ast/pops_bridge.rb +6 -11
  30. data/lib/puppet/pops/evaluator/access_operator.rb +2 -2
  31. data/lib/puppet/pops/evaluator/evaluator_impl.rb +1 -1
  32. data/lib/puppet/pops/loader/puppet_plan_instantiator.rb +12 -3
  33. data/lib/puppet/pops/parser/evaluating_parser.rb +5 -7
  34. data/lib/puppet/pops/types/p_object_type_extension.rb +10 -0
  35. data/lib/puppet/pops/types/type_calculator.rb +24 -0
  36. data/lib/puppet/pops/validation/checker4_0.rb +1 -1
  37. data/lib/puppet/pops/validation/tasks_checker.rb +5 -1
  38. data/lib/puppet/provider/aix_object.rb +4 -2
  39. data/lib/puppet/provider/group/aix.rb +1 -0
  40. data/lib/puppet/provider/group/groupadd.rb +52 -24
  41. data/lib/puppet/provider/package/apt.rb +14 -3
  42. data/lib/puppet/provider/package/dnfmodule.rb +9 -2
  43. data/lib/puppet/provider/package/dpkg.rb +14 -7
  44. data/lib/puppet/provider/package/fink.rb +20 -3
  45. data/lib/puppet/provider/package/openbsd.rb +13 -1
  46. data/lib/puppet/provider/package/pkg.rb +18 -5
  47. data/lib/puppet/provider/package/yum.rb +9 -5
  48. data/lib/puppet/provider/user/aix.rb +1 -0
  49. data/lib/puppet/provider/user/directoryservice.rb +30 -5
  50. data/lib/puppet/provider/user/useradd.rb +6 -7
  51. data/lib/puppet/reports/store.rb +1 -1
  52. data/lib/puppet/settings.rb +2 -0
  53. data/lib/puppet/ssl/certificate.rb +2 -1
  54. data/lib/puppet/test/test_helper.rb +4 -0
  55. data/lib/puppet/transaction/resource_harness.rb +1 -1
  56. data/lib/puppet/type/group.rb +2 -2
  57. data/lib/puppet/type/package.rb +63 -9
  58. data/lib/puppet/type/user.rb +2 -2
  59. data/lib/puppet/util/log/destinations.rb +1 -1
  60. data/lib/puppet/util/pidlock.rb +26 -6
  61. data/lib/puppet/util/plist.rb +6 -0
  62. data/lib/puppet/util/storage.rb +0 -1
  63. data/lib/puppet/util/yaml.rb +1 -1
  64. data/lib/puppet/version.rb +1 -1
  65. data/locales/puppet.pot +127 -115
  66. data/man/man5/puppet.conf.5 +21 -7
  67. data/man/man8/puppet-agent.8 +1 -1
  68. data/man/man8/puppet-apply.8 +1 -1
  69. data/man/man8/puppet-catalog.8 +1 -1
  70. data/man/man8/puppet-config.8 +1 -1
  71. data/man/man8/puppet-describe.8 +1 -1
  72. data/man/man8/puppet-device.8 +1 -1
  73. data/man/man8/puppet-doc.8 +1 -1
  74. data/man/man8/puppet-epp.8 +1 -1
  75. data/man/man8/puppet-facts.8 +1 -1
  76. data/man/man8/puppet-filebucket.8 +1 -1
  77. data/man/man8/puppet-generate.8 +1 -1
  78. data/man/man8/puppet-help.8 +1 -1
  79. data/man/man8/puppet-key.8 +1 -1
  80. data/man/man8/puppet-lookup.8 +1 -1
  81. data/man/man8/puppet-man.8 +1 -1
  82. data/man/man8/puppet-module.8 +1 -1
  83. data/man/man8/puppet-node.8 +1 -1
  84. data/man/man8/puppet-parser.8 +1 -1
  85. data/man/man8/puppet-plugin.8 +1 -1
  86. data/man/man8/puppet-report.8 +1 -1
  87. data/man/man8/puppet-resource.8 +1 -1
  88. data/man/man8/puppet-script.8 +1 -1
  89. data/man/man8/puppet-ssl.8 +1 -1
  90. data/man/man8/puppet-status.8 +1 -1
  91. data/man/man8/puppet.8 +2 -2
  92. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_fetch_if_not_on_the_local_disk.yml +0 -35
  93. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_not_update_if_content_on_disk_is_up-to-date.yml +0 -37
  94. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_md5/should_update_if_content_differs_on_disk.yml +0 -37
  95. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_mtime_is_older_on_disk.yml +0 -35
  96. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_no_header_specified.yml +0 -33
  97. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_fetch_if_not_on_the_local_disk.yml +0 -35
  98. data/spec/fixtures/vcr/cassettes/Puppet_Type_File/when_sourcing/from_http/using_mtime/should_not_update_if_mtime_is_newer_on_disk.yml +0 -35
  99. data/spec/integration/configurer_spec.rb +26 -7
  100. data/spec/integration/indirector/facts/facter_spec.rb +4 -0
  101. data/spec/unit/application/apply_spec.rb +2 -12
  102. data/spec/unit/application/resource_spec.rb +2 -2
  103. data/spec/unit/configurer/fact_handler_spec.rb +0 -4
  104. data/spec/unit/configurer_spec.rb +0 -3
  105. data/spec/unit/defaults_spec.rb +1 -1
  106. data/spec/unit/environments_spec.rb +57 -28
  107. data/spec/unit/face/facts_spec.rb +24 -20
  108. data/spec/unit/file_system_spec.rb +16 -2
  109. data/spec/unit/http/client_spec.rb +6 -0
  110. data/spec/unit/http/service/compiler_spec.rb +322 -0
  111. data/spec/unit/http/service/file_server_spec.rb +219 -0
  112. data/spec/unit/http/service/report_spec.rb +8 -1
  113. data/spec/unit/http/service_spec.rb +4 -0
  114. data/spec/unit/http/session_spec.rb +31 -0
  115. data/spec/unit/indirector/catalog/compiler_spec.rb +46 -29
  116. data/spec/unit/network/http/connection_spec.rb +23 -1
  117. data/spec/unit/network/http/nocache_pool_spec.rb +3 -3
  118. data/spec/unit/network/http/pool_spec.rb +32 -0
  119. data/spec/unit/node/facts_spec.rb +2 -1
  120. data/spec/unit/node_spec.rb +7 -4
  121. data/spec/unit/pops/serialization/to_from_hr_spec.rb +6 -1
  122. data/spec/unit/pops/validator/validator_spec.rb +7 -2
  123. data/spec/unit/provider/aix_object_spec.rb +16 -2
  124. data/spec/unit/provider/group/groupadd_spec.rb +167 -56
  125. data/spec/unit/provider/package/apt_spec.rb +13 -2
  126. data/spec/unit/provider/package/aptitude_spec.rb +1 -0
  127. data/spec/unit/provider/package/dnfmodule_spec.rb +22 -0
  128. data/spec/unit/provider/package/dpkg_spec.rb +28 -6
  129. data/spec/unit/provider/package/openbsd_spec.rb +17 -0
  130. data/spec/unit/provider/package/pkg_spec.rb +15 -1
  131. data/spec/unit/provider/package/yum_spec.rb +50 -0
  132. data/spec/unit/provider/user/directoryservice_spec.rb +41 -0
  133. data/spec/unit/provider/user/useradd_spec.rb +13 -8
  134. data/spec/unit/puppet_pal_2pec.rb +3 -0
  135. data/spec/unit/puppet_pal_catalog_spec.rb +3 -0
  136. data/spec/unit/puppet_spec.rb +14 -0
  137. data/spec/unit/ssl/certificate_spec.rb +7 -0
  138. data/spec/unit/transaction/persistence_spec.rb +1 -10
  139. data/spec/unit/type/package_spec.rb +8 -0
  140. data/spec/unit/type/user_spec.rb +0 -1
  141. data/spec/unit/util/pidlock_spec.rb +38 -16
  142. data/spec/unit/util/plist_spec.rb +20 -0
  143. data/spec/unit/util/storage_spec.rb +1 -8
  144. metadata +10 -4
@@ -0,0 +1,219 @@
1
+ require 'spec_helper'
2
+ require 'webmock/rspec'
3
+ require 'puppet/http'
4
+
5
+ describe Puppet::HTTP::Service::FileServer do
6
+ include PuppetSpec::Files
7
+
8
+ let(:ssl_context) { Puppet::SSL::SSLContext.new }
9
+ let(:client) { Puppet::HTTP::Client.new(ssl_context: ssl_context) }
10
+ let(:subject) { client.create_session.route_to(:fileserver) }
11
+ let(:environment) { 'testing' }
12
+ let(:report) { Puppet::Transaction::Report.new }
13
+
14
+ before :each do
15
+ Puppet[:server] = 'www.example.com'
16
+ Puppet[:masterport] = 443
17
+ end
18
+
19
+ context 'when making requests' do
20
+ let(:uri) {"https://www.example.com:443/puppet/v3/file_content/:mount/:path?environment=testing"}
21
+
22
+ it 'includes default HTTP headers' do
23
+ stub_request(:get, uri).with do |request|
24
+ expect(request.headers).to include({'X-Puppet-Version' => /./, 'User-Agent' => /./})
25
+ expect(request.headers).to_not include('X-Puppet-Profiling')
26
+ end
27
+
28
+ subject.get_file_content(path: '/:mount/:path', environment: environment) { |data| }
29
+ end
30
+
31
+ it 'includes the X-Puppet-Profiling header when Puppet[:profile] is true' do
32
+ stub_request(:get, uri).with(headers: {'X-Puppet-Version' => /./, 'User-Agent' => /./, 'X-Puppet-Profiling' => 'true'})
33
+
34
+ Puppet[:profile] = true
35
+
36
+ subject.get_file_content(path: '/:mount/:path', environment: environment) { |data| }
37
+ end
38
+ end
39
+
40
+ context 'when routing to the file service' do
41
+ it 'defaults the server and port based on settings' do
42
+ Puppet[:server] = 'file.example.com'
43
+ Puppet[:masterport] = 8141
44
+
45
+ stub_request(:get, "https://file.example.com:8141/puppet/v3/file_content/:mount/:path?environment=testing")
46
+
47
+ subject.get_file_content(path: '/:mount/:path', environment: environment) { |data| }
48
+ end
49
+ end
50
+
51
+ context 'retrieving file metadata' do
52
+ let(:path) { tmpfile('get_file_metadata') }
53
+ let(:url) { "https://www.example.com/puppet/v3/file_metadata/:mount/#{path}?checksum_type=md5&environment=testing&links=manage&source_permissions=ignore" }
54
+ let(:filemetadata) { Puppet::FileServing::Metadata.new(path) }
55
+ let(:request_path) { "/:mount/#{path}"}
56
+
57
+ it 'submits a request for file metadata to the server' do
58
+ stub_request(:get, url).with(
59
+ headers: {'Accept'=>'application/json, application/x-msgpack, text/pson',}
60
+ ).to_return(
61
+ status: 200, body: filemetadata.render, headers: { 'Content-Type' => 'application/json' }
62
+ )
63
+
64
+ metadata = subject.get_file_metadata(path: request_path, environment: environment)
65
+ expect(metadata.path).to eq(path)
66
+ end
67
+
68
+ it 'raises a protocol error if the Content-Type header is missing from the response' do
69
+ stub_request(:get, url).to_return(status: 200, body: '', headers: {})
70
+
71
+ expect {
72
+ subject.get_file_metadata(path: request_path, environment: environment)
73
+ }.to raise_error(Puppet::HTTP::ProtocolError, "No content type in http response; cannot parse")
74
+ end
75
+
76
+ it 'raises an error if the Content-Type is unsupported' do
77
+ stub_request(:get, url).to_return(status: 200, body: '', headers: { 'Content-Type' => 'text/yaml' })
78
+
79
+ expect {
80
+ subject.get_file_metadata(path: request_path, environment: environment)
81
+ }.to raise_error(Puppet::HTTP::ProtocolError, "Content-Type is unsupported")
82
+ end
83
+
84
+ it 'raises response error if unsuccessful' do
85
+ stub_request(:get, url).to_return(status: [400, 'Bad Request'])
86
+
87
+ expect {
88
+ subject.get_file_metadata(path: request_path, environment: environment)
89
+ }.to raise_error do |err|
90
+ expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
91
+ expect(err.message).to eq('Bad Request')
92
+ expect(err.response.code).to eq(400)
93
+ end
94
+ end
95
+
96
+ it 'raises a serialization error if serialization fails' do
97
+ stub_request(:get, url).to_return(
98
+ status: 200, body: '', headers: { 'Content-Type' => 'application/json' }
99
+ )
100
+
101
+ expect {
102
+ subject.get_file_metadata(path: request_path, environment: environment)
103
+ }.to raise_error(Puppet::HTTP::SerializationError, /Failed to deserialize Puppet::FileServing::Metadata from json/)
104
+ end
105
+
106
+ it 'raises response error if path is relative' do
107
+ expect {
108
+ subject.get_file_metadata(path: 'relative_path', environment: environment)
109
+ }.to raise_error(ArgumentError, 'Path must start with a slash')
110
+ end
111
+ end
112
+
113
+ context 'retrieving multiple file metadatas' do
114
+ let(:path) { tmpfile('get_file_metadatas') }
115
+ let(:url) { "https://www.example.com/puppet/v3/file_metadatas/:mount/#{path}?checksum_type=md5&links=manage&recurse=false&source_permissions=ignore&environment=testing" }
116
+ let(:filemetadatas) { [Puppet::FileServing::Metadata.new(path)] }
117
+ let(:formatter) { Puppet::Network::FormatHandler.format(:json) }
118
+ let(:request_path) { "/:mount/#{path}"}
119
+
120
+ it 'submits a request for file metadata to the server' do
121
+ stub_request(:get, url).with(
122
+ headers: {'Accept'=>'application/json, application/x-msgpack, text/pson',}
123
+ ).to_return(
124
+ status: 200, body: formatter.render_multiple(filemetadatas), headers: { 'Content-Type' => 'application/json' }
125
+ )
126
+
127
+ metadatas = subject.get_file_metadatas(path: request_path, environment: environment)
128
+ expect(metadatas.first.path).to eq(path)
129
+ end
130
+
131
+ it 'automatically converts an array of parameters to the stringified query' do
132
+ url = "https://www.example.com/puppet/v3/file_metadatas/:mount/#{path}?checksum_type=md5&environment=testing&ignore=CVS&ignore=.git&ignore=.hg&links=manage&recurse=false&source_permissions=ignore"
133
+ stub_request(:get, url).with(
134
+ headers: {'Accept'=>'application/json, application/x-msgpack, text/pson',}
135
+ ).to_return(
136
+ status: 200, body: formatter.render_multiple(filemetadatas), headers: { 'Content-Type' => 'application/json' }
137
+ )
138
+
139
+ metadatas = subject.get_file_metadatas(path: request_path, environment: environment, ignore: ['CVS', '.git', '.hg'])
140
+ expect(metadatas.first.path).to eq(path)
141
+ end
142
+
143
+ it 'raises a protocol error if the Content-Type header is missing from the response' do
144
+ stub_request(:get, url).to_return(status: 200, body: '', headers: {})
145
+
146
+ expect {
147
+ subject.get_file_metadatas(path: request_path, environment: environment)
148
+ }.to raise_error(Puppet::HTTP::ProtocolError, "No content type in http response; cannot parse")
149
+ end
150
+
151
+ it 'raises an error if the Content-Type is unsupported' do
152
+ stub_request(:get, url).to_return(status: 200, body: '', headers: { 'Content-Type' => 'text/yaml' })
153
+
154
+ expect {
155
+ subject.get_file_metadatas(path: request_path, environment: environment)
156
+ }.to raise_error(Puppet::HTTP::ProtocolError, "Content-Type is unsupported")
157
+ end
158
+
159
+ it 'raises response error if unsuccessful' do
160
+ stub_request(:get, url).to_return(status: [400, 'Bad Request'])
161
+
162
+ expect {
163
+ subject.get_file_metadatas(path: request_path, environment: environment)
164
+ }.to raise_error do |err|
165
+ expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
166
+ expect(err.message).to eq('Bad Request')
167
+ expect(err.response.code).to eq(400)
168
+ end
169
+ end
170
+
171
+ it 'raises a serialization error if serialization fails' do
172
+ stub_request(:get, url).to_return(
173
+ status: 200, body: '', headers: { 'Content-Type' => 'application/json' }
174
+ )
175
+
176
+ expect {
177
+ subject.get_file_metadatas(path: request_path, environment: environment)
178
+ }.to raise_error(Puppet::HTTP::SerializationError, /Failed to deserialize multiple Puppet::FileServing::Metadata from json/)
179
+ end
180
+
181
+ it 'raises response error if path is relative' do
182
+ expect {
183
+ subject.get_file_metadatas(path: 'relative_path', environment: environment)
184
+ }.to raise_error(ArgumentError, 'Path must start with a slash')
185
+ end
186
+ end
187
+
188
+ context 'getting file content' do
189
+ let(:uri) {"https://www.example.com:443/puppet/v3/file_content/:mount/:path?environment=testing"}
190
+
191
+ it 'yields file content' do
192
+ stub_request(:get, uri).with do |request|
193
+ expect(request.headers).to include({'Accept' => 'application/octet-stream'})
194
+ end.to_return(status: 200, body: "and beyond")
195
+
196
+ expect { |b|
197
+ subject.get_file_content(path: '/:mount/:path', environment: environment, &b)
198
+ }.to yield_with_args("and beyond")
199
+ end
200
+
201
+ it 'raises response error if unsuccessful' do
202
+ stub_request(:get, uri).to_return(status: [400, 'Bad Request'])
203
+
204
+ expect {
205
+ subject.get_file_content(path: '/:mount/:path', environment: environment) { |data| }
206
+ }.to raise_error do |err|
207
+ expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
208
+ expect(err.message).to eq('Bad Request')
209
+ expect(err.response.code).to eq(400)
210
+ end
211
+ end
212
+
213
+ it 'raises response error if path is relative' do
214
+ expect {
215
+ subject.get_file_content(path: 'relative_path', environment: environment) { |data| }
216
+ }.to raise_error(ArgumentError, 'Path must start with a slash')
217
+ end
218
+ end
219
+ end
@@ -6,7 +6,7 @@ describe Puppet::HTTP::Service::Report do
6
6
  let(:ssl_context) { Puppet::SSL::SSLContext.new }
7
7
  let(:client) { Puppet::HTTP::Client.new(ssl_context: ssl_context) }
8
8
  let(:subject) { client.create_session.route_to(:report) }
9
- let(:environment) { Puppet::Node::Environment.create(:testing, []) }
9
+ let(:environment) { 'testing' }
10
10
  let(:report) { Puppet::Transaction::Report.new }
11
11
 
12
12
  before :each do
@@ -72,6 +72,13 @@ describe Puppet::HTTP::Service::Report do
72
72
  subject.put_report('infinity', report, environment: environment)
73
73
  end
74
74
 
75
+ it 'percent encodes the uri before submitting the report' do
76
+ stub_request(:put, "https://www.example.com/puppet/v3/report/node%20name?environment=testing")
77
+ .to_return(status: 200, body: "", headers: {})
78
+
79
+ subject.put_report('node name', report, environment: environment)
80
+ end
81
+
75
82
  it 'raises response error if unsuccessful' do
76
83
  stub_request(:put, url).to_return(status: [400, 'Bad Request'], headers: {'X-Puppet-Version' => '6.1.8' })
77
84
 
@@ -17,6 +17,10 @@ describe Puppet::HTTP::Service do
17
17
  service.with_base_url('/puppet/v3')
18
18
  end
19
19
 
20
+ it "percent encodes paths before appending them to the path" do
21
+ expect(service.with_base_url('/path/with/a space')).to eq(URI.parse("https://www.example.com/path/with/a%20space"))
22
+ end
23
+
20
24
  it "connects to the base URL with a nil ssl context" do
21
25
  expect(client).to receive(:connect).with(url, ssl_context: nil)
22
26
 
@@ -73,6 +73,37 @@ describe Puppet::HTTP::Session do
73
73
  session.route_to(:westbound)
74
74
  }.to raise_error(ArgumentError, "Unknown service westbound")
75
75
  end
76
+
77
+ it 'routes to the service when given a puppet URL with an explicit host' do
78
+ allow_any_instance_of(Net::HTTP).to receive(:start)
79
+
80
+ session = described_class.new(client, [])
81
+ url = URI("puppet://example.com:8140/:modules/:module/path/to/file")
82
+ service = session.route_to(:fileserver, url: url)
83
+
84
+ expect(service.url.to_s).to eq("https://example.com:8140/puppet/v3")
85
+ end
86
+
87
+ it 'raises a connection error if we cannot connect' do
88
+ allow_any_instance_of(Net::HTTP).to receive(:start).and_raise(Net::OpenTimeout)
89
+
90
+ session = described_class.new(client, [])
91
+ url = URI('puppet://example.com:8140/:modules/:module/path/to/file')
92
+
93
+ expect {
94
+ session.route_to(:fileserver, url: url)
95
+ }.to raise_error(Puppet::HTTP::ConnectionError,
96
+ %r{Request to https://example.com:8140/puppet/v3 timed out connect operation after .* seconds})
97
+ end
98
+
99
+ it 'resolves the route when given a generic puppet:/// URL' do
100
+ resolvers = [DummyResolver.new(good_service)]
101
+ session = described_class.new(client, resolvers)
102
+ url = URI('puppet:///:modules/:module/path/to/file')
103
+ service = session.route_to(:fileserver, url: url)
104
+
105
+ expect(service.url).to eq(good_service.url)
106
+ end
76
107
  end
77
108
 
78
109
  context 'when resolving using multiple resolvers' do
@@ -15,22 +15,9 @@ describe Puppet::Resource::Catalog::Compiler do
15
15
  let(:node_name) { "foo" }
16
16
  let(:node) { Puppet::Node.new(node_name)}
17
17
 
18
- before do
19
- allow(Facter).to receive(:to_hash).and_return({})
20
- end
21
-
22
18
  describe "when initializing" do
23
19
  before do
24
- expect(Puppet).to receive(:version).and_return(1)
25
- set_facts({
26
- 'fqdn' => "my.server.com",
27
- 'ipaddress' => "my.ip.address",
28
- 'ipaddress6' => nil
29
- })
30
- end
31
-
32
- it "should gather data about itself" do
33
- Puppet::Resource::Catalog::Compiler.new
20
+ allow(Puppet).to receive(:version).and_return(1)
34
21
  end
35
22
 
36
23
  it "should cache the server metadata and reuse it" do
@@ -47,8 +34,6 @@ describe Puppet::Resource::Catalog::Compiler do
47
34
 
48
35
  describe "when finding catalogs" do
49
36
  before do
50
- allow(Facter).to receive(:value).and_return("whatever")
51
-
52
37
  allow(node).to receive(:merge)
53
38
  allow(Puppet::Node.indirection).to receive(:find).and_return(node)
54
39
  @request = Puppet::Indirector::Request.new(:catalog, :find, node_name, nil, :node => node_name)
@@ -255,10 +240,10 @@ describe Puppet::Resource::Catalog::Compiler do
255
240
 
256
241
  describe "when handling a request with facts" do
257
242
  before do
258
- Puppet::Node::Facts.indirection.terminus_class = :memory
259
243
  allow(Facter).to receive(:value).and_return("something")
260
244
 
261
- @facts = Puppet::Node::Facts.new('hostname', "fact" => "value", "architecture" => "i386")
245
+ facts = Puppet::Node::Facts.new('hostname', "fact" => "value", "architecture" => "i386")
246
+ Puppet::Node::Facts.indirection.save(facts)
262
247
  end
263
248
 
264
249
  def a_legacy_request_that_contains(facts, format = :pson)
@@ -276,6 +261,8 @@ describe Puppet::Resource::Catalog::Compiler do
276
261
  end
277
262
 
278
263
  context "when extracting facts from the request" do
264
+ let(:facts) { Puppet::Node::Facts.new("hostname") }
265
+
279
266
  it "should do nothing if no facts are provided" do
280
267
  request = Puppet::Indirector::Request.new(:catalog, :find, "hostname", nil)
281
268
  request.options[:facts] = nil
@@ -285,21 +272,21 @@ describe Puppet::Resource::Catalog::Compiler do
285
272
 
286
273
  it "should deserialize the facts without changing the timestamp" do
287
274
  time = Time.now
288
- @facts.timestamp = time
289
- request = a_request_that_contains(@facts)
275
+ facts.timestamp = time
276
+ request = a_request_that_contains(facts)
290
277
  facts = compiler.extract_facts_from_request(request)
291
278
  expect(facts.timestamp).to eq(time)
292
279
  end
293
280
 
294
281
  it "accepts PSON facts from older agents" do
295
- request = a_legacy_request_that_contains(@facts)
282
+ request = a_legacy_request_that_contains(facts)
296
283
 
297
284
  facts = compiler.extract_facts_from_request(request)
298
- expect(facts).to eq(@facts)
285
+ expect(facts).to eq(facts)
299
286
  end
300
287
 
301
288
  it "rejects YAML facts" do
302
- request = a_legacy_request_that_contains(@facts, :yaml)
289
+ request = a_legacy_request_that_contains(facts, :yaml)
303
290
 
304
291
  expect {
305
292
  compiler.extract_facts_from_request(request)
@@ -307,7 +294,7 @@ describe Puppet::Resource::Catalog::Compiler do
307
294
  end
308
295
 
309
296
  it "rejects unknown fact formats" do
310
- request = a_request_that_contains(@facts)
297
+ request = a_request_that_contains(facts)
311
298
  request.options[:facts_format] = 'unknown-format'
312
299
 
313
300
  expect {
@@ -317,15 +304,17 @@ describe Puppet::Resource::Catalog::Compiler do
317
304
  end
318
305
 
319
306
  context "when saving facts from the request" do
307
+ let(:facts) { Puppet::Node::Facts.new("hostname") }
308
+
320
309
  it "should save facts if they were issued by the request" do
321
- request = a_request_that_contains(@facts)
310
+ request = a_request_that_contains(facts)
322
311
 
323
312
  options = {
324
313
  :environment => request.environment,
325
314
  :transaction_uuid => request.options[:transaction_uuid],
326
315
  }
327
316
 
328
- expect(Puppet::Node::Facts.indirection).to receive(:save).with(@facts, nil, options)
317
+ expect(Puppet::Node::Facts.indirection).to receive(:save).with(facts, nil, options)
329
318
  compiler.find(request)
330
319
  end
331
320
 
@@ -337,7 +326,7 @@ describe Puppet::Resource::Catalog::Compiler do
337
326
  :transaction_uuid => request.options[:transaction_uuid],
338
327
  }
339
328
 
340
- expect(Puppet::Node::Facts.indirection).not_to receive(:save).with(@facts, nil, options)
329
+ expect(Puppet::Node::Facts.indirection).not_to receive(:save).with(facts, nil, options)
341
330
  compiler.find(request)
342
331
  end
343
332
  end
@@ -345,7 +334,6 @@ describe Puppet::Resource::Catalog::Compiler do
345
334
 
346
335
  describe "when finding nodes" do
347
336
  it "should look node information up via the Node class with the provided key" do
348
- allow(Facter).to receive(:value).and_return("whatever")
349
337
  request = Puppet::Indirector::Request.new(:catalog, :find, node_name, nil)
350
338
  allow(compiler).to receive(:compile)
351
339
 
@@ -471,9 +459,38 @@ describe Puppet::Resource::Catalog::Compiler do
471
459
  end
472
460
  end
473
461
 
462
+ describe "after finding nodes when checking for a PE version" do
463
+ include PuppetSpec::Compiler
464
+
465
+ let(:pe_version_file) { '/opt/puppetlabs/server/pe_version' }
466
+ let(:request) { Puppet::Indirector::Request.new(:catalog, :find, node_name, nil) }
467
+
468
+ before :each do
469
+ Puppet[:code] = 'notify { "PE Version: $pe_serverversion": }'
470
+ end
471
+
472
+ it "should not add 'pe_serverversion' when FOSS" do
473
+ allow(Puppet::Node.indirection).to receive(:find).with(node_name, anything).and_return(node)
474
+ catalog = compiler.find(request)
475
+
476
+ expect(catalog.resource('notify', 'PE Version: 2019.2.0')).to be_nil
477
+ end
478
+
479
+ it "should add 'pe_serverversion' when PE" do
480
+ allow(File).to receive(:readable?).with(pe_version_file).and_return(true)
481
+ allow(File).to receive(:zero?).with(pe_version_file).and_return(false)
482
+ allow(File).to receive(:read).and_call_original
483
+ allow(File).to receive(:read).with(pe_version_file).and_return('2019.2.0')
484
+
485
+ allow(Puppet::Node.indirection).to receive(:find).with(node_name, anything).and_return(node)
486
+ catalog = compiler.find(request)
487
+
488
+ expect(catalog.resource('notify', 'PE Version: 2019.2.0')).to be
489
+ end
490
+ end
491
+
474
492
  describe "when filtering resources" do
475
493
  before :each do
476
- allow(Facter).to receive(:value)
477
494
  @catalog = double('catalog')
478
495
  allow(@catalog).to receive(:respond_to?).with(:filter).and_return(true)
479
496
  end