puppet 6.4.4-x86-mingw32 → 6.4.5-x86-mingw32

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 (221) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +1 -1
  3. data/Gemfile +4 -4
  4. data/Gemfile.lock +38 -32
  5. data/ext/build_defaults.yaml +1 -0
  6. data/ext/cert_inspector +3 -3
  7. data/ext/puppet-test +2 -2
  8. data/ext/regexp_nodes/regexp_nodes.rb +4 -4
  9. data/ext/windows/service/daemon.rb +38 -8
  10. data/install.rb +6 -6
  11. data/lib/puppet/application.rb +1 -1
  12. data/lib/puppet/application/apply.rb +2 -2
  13. data/lib/puppet/application/describe.rb +3 -9
  14. data/lib/puppet/application/doc.rb +1 -1
  15. data/lib/puppet/application/lookup.rb +1 -1
  16. data/lib/puppet/application/script.rb +2 -2
  17. data/lib/puppet/application/ssl.rb +4 -1
  18. data/lib/puppet/configurer.rb +86 -30
  19. data/lib/puppet/configurer/downloader.rb +2 -6
  20. data/lib/puppet/defaults.rb +32 -6
  21. data/lib/puppet/error.rb +9 -1
  22. data/lib/puppet/face/module/list.rb +5 -5
  23. data/lib/puppet/face/module/search.rb +1 -1
  24. data/lib/puppet/face/module/uninstall.rb +1 -1
  25. data/lib/puppet/face/module/upgrade.rb +1 -1
  26. data/lib/puppet/file_serving/http_metadata.rb +1 -1
  27. data/lib/puppet/file_system.rb +0 -8
  28. data/lib/puppet/file_system/memory_file.rb +1 -1
  29. data/lib/puppet/file_system/posix.rb +3 -2
  30. data/lib/puppet/forge.rb +3 -3
  31. data/lib/puppet/functions.rb +1 -2
  32. data/lib/puppet/functions/camelcase.rb +2 -2
  33. data/lib/puppet/functions/epp.rb +4 -4
  34. data/lib/puppet/functions/find_file.rb +9 -9
  35. data/lib/puppet/functions/inline_epp.rb +5 -5
  36. data/lib/puppet/gettext/module_translations.rb +1 -1
  37. data/lib/puppet/graph/rb_tree_map.rb +2 -2
  38. data/lib/puppet/graph/simple_graph.rb +4 -3
  39. data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
  40. data/lib/puppet/indirector/hiera.rb +2 -0
  41. data/lib/puppet/indirector/resource/ral.rb +1 -3
  42. data/lib/puppet/indirector/resource/validator.rb +1 -1
  43. data/lib/puppet/interface.rb +2 -1
  44. data/lib/puppet/loaders.rb +0 -1
  45. data/lib/puppet/metatype/manager.rb +1 -1
  46. data/lib/puppet/module.rb +1 -1
  47. data/lib/puppet/module/task.rb +20 -4
  48. data/lib/puppet/module_tool/applications/installer.rb +1 -1
  49. data/lib/puppet/module_tool/applications/uninstaller.rb +3 -3
  50. data/lib/puppet/module_tool/metadata.rb +1 -1
  51. data/lib/puppet/module_tool/shared_behaviors.rb +4 -4
  52. data/lib/puppet/module_tool/tar/mini.rb +1 -1
  53. data/lib/puppet/network/http/api/indirected_routes.rb +12 -11
  54. data/lib/puppet/network/http/connection.rb +10 -12
  55. data/lib/puppet/network/http/pool.rb +2 -0
  56. data/lib/puppet/network/http/site.rb +1 -1
  57. data/lib/puppet/network/resolver.rb +2 -2
  58. data/lib/puppet/node/environment.rb +4 -2
  59. data/lib/puppet/pal/pal_impl.rb +2 -2
  60. data/lib/puppet/parser/ast.rb +1 -1
  61. data/lib/puppet/parser/ast/resourceparam.rb +1 -1
  62. data/lib/puppet/parser/functions.rb +1 -1
  63. data/lib/puppet/parser/functions/epp.rb +3 -3
  64. data/lib/puppet/parser/functions/inline_epp.rb +5 -5
  65. data/lib/puppet/parser/scope.rb +8 -7
  66. data/lib/puppet/pops/evaluator/collectors/catalog_collector.rb +1 -1
  67. data/lib/puppet/pops/evaluator/collectors/exported_collector.rb +1 -1
  68. data/lib/puppet/pops/evaluator/external_syntax_support.rb +3 -2
  69. data/lib/puppet/pops/evaluator/runtime3_support.rb +4 -4
  70. data/lib/puppet/pops/loader/task_instantiator.rb +4 -0
  71. data/lib/puppet/pops/loaders.rb +1 -1
  72. data/lib/puppet/pops/lookup/hiera_config.rb +1 -0
  73. data/lib/puppet/pops/lookup/sub_lookup.rb +1 -1
  74. data/lib/puppet/pops/merge_strategy.rb +22 -18
  75. data/lib/puppet/pops/parser/heredoc_support.rb +1 -1
  76. data/lib/puppet/pops/parser/interpolation_support.rb +4 -4
  77. data/lib/puppet/pops/parser/locator.rb +1 -1
  78. data/lib/puppet/pops/parser/pn_parser.rb +17 -16
  79. data/lib/puppet/pops/puppet_stack.rb +51 -49
  80. data/lib/puppet/pops/types/p_sensitive_type.rb +1 -1
  81. data/lib/puppet/pops/types/string_converter.rb +10 -10
  82. data/lib/puppet/pops/types/types.rb +3 -3
  83. data/lib/puppet/property.rb +1 -1
  84. data/lib/puppet/property/ensure.rb +1 -1
  85. data/lib/puppet/provider/exec.rb +6 -2
  86. data/lib/puppet/provider/nameservice/directoryservice.rb +1 -1
  87. data/lib/puppet/provider/nameservice/pw.rb +2 -2
  88. data/lib/puppet/provider/package/apt.rb +5 -1
  89. data/lib/puppet/provider/package/dnfmodule.rb +87 -0
  90. data/lib/puppet/provider/package/dpkg.rb +34 -18
  91. data/lib/puppet/provider/package/openbsd.rb +1 -1
  92. data/lib/puppet/provider/package/pip.rb +34 -9
  93. data/lib/puppet/provider/package/portage.rb +4 -4
  94. data/lib/puppet/provider/package/rpm.rb +5 -5
  95. data/lib/puppet/provider/package/windows/package.rb +1 -1
  96. data/lib/puppet/provider/package/yum.rb +1 -1
  97. data/lib/puppet/provider/package_targetable.rb +5 -4
  98. data/lib/puppet/provider/parsedfile.rb +1 -1
  99. data/lib/puppet/provider/service/daemontools.rb +9 -9
  100. data/lib/puppet/provider/service/openbsd.rb +1 -1
  101. data/lib/puppet/provider/service/rcng.rb +2 -2
  102. data/lib/puppet/provider/service/runit.rb +2 -8
  103. data/lib/puppet/provider/service/systemd.rb +9 -9
  104. data/lib/puppet/provider/user/directoryservice.rb +1 -1
  105. data/lib/puppet/provider/user/hpux.rb +1 -1
  106. data/lib/puppet/provider/user/user_role_add.rb +1 -1
  107. data/lib/puppet/provider/user/useradd.rb +22 -13
  108. data/lib/puppet/provider/user/windows_adsi.rb +4 -5
  109. data/lib/puppet/reference/indirection.rb +2 -2
  110. data/lib/puppet/reference/metaparameter.rb +1 -3
  111. data/lib/puppet/reference/providers.rb +1 -3
  112. data/lib/puppet/reference/type.rb +3 -9
  113. data/lib/puppet/reports.rb +1 -1
  114. data/lib/puppet/resource.rb +1 -1
  115. data/lib/puppet/resource/catalog.rb +1 -1
  116. data/lib/puppet/settings.rb +3 -3
  117. data/lib/puppet/settings/environment_conf.rb +1 -0
  118. data/lib/puppet/ssl/host.rb +1 -1
  119. data/lib/puppet/ssl/oids.rb +1 -1
  120. data/lib/puppet/transaction.rb +33 -11
  121. data/lib/puppet/transaction/report.rb +1 -1
  122. data/lib/puppet/type.rb +2 -4
  123. data/lib/puppet/type/exec.rb +7 -3
  124. data/lib/puppet/type/file.rb +1 -2
  125. data/lib/puppet/type/file/data_sync.rb +5 -1
  126. data/lib/puppet/type/group.rb +4 -2
  127. data/lib/puppet/type/notify.rb +3 -2
  128. data/lib/puppet/type/package.rb +10 -3
  129. data/lib/puppet/type/schedule.rb +1 -1
  130. data/lib/puppet/type/service.rb +1 -1
  131. data/lib/puppet/type/user.rb +4 -2
  132. data/lib/puppet/util.rb +35 -12
  133. data/lib/puppet/util/command_line/trollop.rb +1 -1
  134. data/lib/puppet/util/http_proxy.rb +8 -14
  135. data/lib/puppet/util/log.rb +2 -2
  136. data/lib/puppet/util/log/destinations.rb +2 -2
  137. data/lib/puppet/util/logging.rb +32 -20
  138. data/lib/puppet/util/metric.rb +2 -2
  139. data/lib/puppet/util/provider_features.rb +2 -4
  140. data/lib/puppet/util/rdoc.rb +1 -1
  141. data/lib/puppet/util/reference.rb +1 -1
  142. data/lib/puppet/util/resource_template.rb +1 -1
  143. data/lib/puppet/util/selinux.rb +3 -1
  144. data/lib/puppet/util/windows/adsi.rb +48 -18
  145. data/lib/puppet/util/windows/registry.rb +7 -5
  146. data/lib/puppet/vendor.rb +1 -1
  147. data/lib/puppet/version.rb +1 -1
  148. data/lib/puppet/x509/cert_provider.rb +13 -6
  149. data/locales/puppet.pot +199 -159
  150. data/man/man5/puppet.conf.5 +35 -5
  151. data/man/man8/puppet-agent.8 +1 -1
  152. data/man/man8/puppet-apply.8 +1 -1
  153. data/man/man8/puppet-catalog.8 +1 -1
  154. data/man/man8/puppet-config.8 +1 -1
  155. data/man/man8/puppet-describe.8 +1 -1
  156. data/man/man8/puppet-device.8 +1 -1
  157. data/man/man8/puppet-doc.8 +1 -1
  158. data/man/man8/puppet-epp.8 +1 -1
  159. data/man/man8/puppet-facts.8 +1 -1
  160. data/man/man8/puppet-filebucket.8 +1 -1
  161. data/man/man8/puppet-generate.8 +1 -1
  162. data/man/man8/puppet-help.8 +1 -1
  163. data/man/man8/puppet-key.8 +1 -1
  164. data/man/man8/puppet-lookup.8 +1 -1
  165. data/man/man8/puppet-man.8 +1 -1
  166. data/man/man8/puppet-module.8 +1 -1
  167. data/man/man8/puppet-node.8 +1 -1
  168. data/man/man8/puppet-parser.8 +1 -1
  169. data/man/man8/puppet-plugin.8 +1 -1
  170. data/man/man8/puppet-report.8 +1 -1
  171. data/man/man8/puppet-resource.8 +1 -1
  172. data/man/man8/puppet-script.8 +1 -1
  173. data/man/man8/puppet-ssl.8 +1 -1
  174. data/man/man8/puppet-status.8 +1 -1
  175. data/man/man8/puppet.8 +2 -2
  176. data/spec/fixtures/unit/provider/package/dnfmodule/dnf-module-list-installed.txt +11 -0
  177. data/spec/integration/configurer_spec.rb +52 -0
  178. data/spec/integration/type/notify_spec.rb +46 -0
  179. data/spec/lib/puppet/certificate_factory.rb +2 -2
  180. data/spec/spec_helper.rb +28 -0
  181. data/spec/unit/application/ssl_spec.rb +4 -7
  182. data/spec/unit/configurer_spec.rb +394 -398
  183. data/spec/unit/defaults_spec.rb +4 -4
  184. data/spec/unit/forge/forge_spec.rb +1 -3
  185. data/spec/unit/forge/repository_spec.rb +1 -3
  186. data/spec/unit/indirector/resource/ral_spec.rb +4 -4
  187. data/spec/unit/network/http/connection_spec.rb +119 -145
  188. data/spec/unit/parser/scope_spec.rb +10 -0
  189. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +8 -3
  190. data/spec/unit/pops/loaders/module_loaders_spec.rb +37 -0
  191. data/spec/unit/provider/exec_spec.rb +209 -0
  192. data/spec/unit/provider/package/dnfmodule_spec.rb +186 -0
  193. data/spec/unit/provider/package/dpkg_spec.rb +238 -78
  194. data/spec/unit/provider/package/pip_spec.rb +51 -6
  195. data/spec/unit/provider/package/portage_spec.rb +4 -4
  196. data/spec/unit/provider/package_targetable_spec.rb +60 -0
  197. data/spec/unit/provider/service/daemontools_spec.rb +24 -0
  198. data/spec/unit/provider/service/runit_spec.rb +24 -0
  199. data/spec/unit/provider/service/systemd_spec.rb +25 -25
  200. data/spec/unit/provider/user/hpux_spec.rb +2 -2
  201. data/spec/unit/provider/user/useradd_spec.rb +46 -0
  202. data/spec/unit/ssl/host_spec.rb +0 -5
  203. data/spec/unit/ssl/state_machine_spec.rb +0 -6
  204. data/spec/unit/transaction_spec.rb +46 -0
  205. data/spec/unit/type/exec_spec.rb +6 -12
  206. data/spec/unit/type/file/content_spec.rb +9 -3
  207. data/spec/unit/type/file_spec.rb +9 -4
  208. data/spec/unit/type/package_spec.rb +5 -0
  209. data/spec/unit/util/execution_spec.rb +16 -0
  210. data/spec/unit/util/http_proxy_spec.rb +118 -27
  211. data/spec/unit/util/log/destinations_spec.rb +7 -3
  212. data/spec/unit/util/log_spec.rb +0 -138
  213. data/spec/unit/util/logging_spec.rb +200 -0
  214. data/spec/unit/util/windows/adsi_spec.rb +51 -0
  215. data/spec/unit/x509/cert_provider_spec.rb +24 -4
  216. data/tasks/manpages.rake +1 -0
  217. metadata +12 -10
  218. data/lib/puppet/pops/loader/null_loader.rb +0 -60
  219. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_get/should_yield_to_the_block.yml +0 -24
  220. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_head/should_yield_to_the_block.yml +0 -24
  221. data/spec/fixtures/vcr/cassettes/Puppet_Network_HTTP_Connection/when_handling_requests/_request_post/should_yield_to_the_block.yml +0 -24
@@ -25,9 +25,9 @@ module Puppet::CertificateFactory
25
25
  # @return [OpenSSL::X509::Certificate]
26
26
  def self.build(cert_type, csr, issuer, serial, ttl = 3600)
27
27
  # Work out if we can even build the requested type of certificate.
28
- build_extensions = "build_#{cert_type.to_s}_extensions"
28
+ build_extensions = "build_#{cert_type}_extensions"
29
29
  respond_to?(build_extensions) or
30
- raise ArgumentError, _("%{cert_type} is an invalid certificate type!") % { cert_type: cert_type.to_s }
30
+ raise ArgumentError, _("%{cert_type} is an invalid certificate type!") % { cert_type: cert_type }
31
31
 
32
32
  raise ArgumentError, _("Certificate TTL must be an integer") unless ttl.nil? || ttl.is_a?(Integer)
33
33
 
@@ -54,13 +54,19 @@ Pathname.glob("#{dir}/shared_examples/**/*.rb") do |behaviour|
54
54
  require behaviour.relative_path_from(Pathname.new(dir))
55
55
  end
56
56
 
57
+ require 'webmock/rspec'
57
58
  require 'vcr'
58
59
  VCR.configure do |vcr|
59
60
  vcr.cassette_library_dir = File.expand_path('vcr/cassettes', PuppetSpec::FIXTURE_DIR)
60
61
  vcr.hook_into :webmock
61
62
  vcr.configure_rspec_metadata!
63
+ # Uncomment next line to debug vcr
64
+ # vcr.debug_logger = $stderr
62
65
  end
63
66
 
67
+ # Disable VCR by default
68
+ VCR.turn_off!
69
+
64
70
  RSpec.configure do |config|
65
71
  include PuppetSpec::Fixtures
66
72
 
@@ -155,6 +161,28 @@ RSpec.configure do |config|
155
161
  Puppet::Test::TestHelper.before_each_test()
156
162
  end
157
163
 
164
+ # Facter 2 uses two versions of the GCE API, so match using regex
165
+ PUPPET_FACTER_2_GCE_URL = %r{^http://metadata/computeMetadata/v1(beta1)?}.freeze
166
+ PUPPET_FACTER_3_GCE_URL = "http://metadata.google.internal/computeMetadata/v1/?recursive=true&alt=json".freeze
167
+
168
+ config.around :each do |example|
169
+ # Ignore requests from Facter GCE fact in Travis
170
+ stub_request(:get, PUPPET_FACTER_2_GCE_URL)
171
+ stub_request(:get, PUPPET_FACTER_3_GCE_URL)
172
+
173
+ # Enable VCR if the example is tagged with `:vcr` metadata.
174
+ if example.metadata[:vcr]
175
+ VCR.turn_on!
176
+ begin
177
+ example.run
178
+ ensure
179
+ VCR.turn_off!
180
+ end
181
+ else
182
+ example.run
183
+ end
184
+ end
185
+
158
186
  config.after :each do
159
187
  Puppet::Test::TestHelper.after_each_test()
160
188
 
@@ -1,6 +1,5 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet/application/ssl'
3
- require 'webmock/rspec'
4
3
  require 'openssl'
5
4
  require 'puppet/test_ca'
6
5
 
@@ -23,11 +22,6 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
23
22
  end
24
23
 
25
24
  before do
26
- WebMock.disable_net_connect!
27
-
28
- allow_any_instance_of(Net::HTTP).to receive(:start)
29
- allow_any_instance_of(Net::HTTP).to receive(:finish)
30
-
31
25
  Puppet.settings.use(:main)
32
26
  Puppet[:certname] = name
33
27
  Puppet[:vardir] = tmpdir("ssl_testing")
@@ -107,8 +101,11 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
107
101
  it_behaves_like 'an ssl action'
108
102
 
109
103
  it 'registers OIDs' do
104
+ stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
105
+ stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
106
+
110
107
  expect(Puppet::SSL::Oids).to receive(:register_puppet_oids)
111
- expects_command_to_fail(%r{Failed to submit certificate request})
108
+ expects_command_to_pass(%r{Submitted certificate request for '#{name}' to https://.*})
112
109
  end
113
110
 
114
111
  it 'submits the CSR and saves it locally' do
@@ -1,108 +1,90 @@
1
1
  require 'spec_helper'
2
2
  require 'puppet/configurer'
3
+ require 'webmock/rspec'
3
4
 
4
5
  describe Puppet::Configurer do
5
6
  before do
6
- allow(Puppet.settings).to receive(:use).and_return(true)
7
- @agent = Puppet::Configurer.new
8
- allow(@agent).to receive(:init_storage)
9
- allow(Puppet::Util::Storage).to receive(:store)
7
+ Puppet::Node::Facts.indirection.terminus_class = :memory
8
+ Puppet::Node::Facts.indirection.save(facts)
9
+
10
10
  Puppet[:server] = "puppetmaster"
11
11
  Puppet[:report] = true
12
- end
13
12
 
14
- it "should include the Fact Handler module" do
15
- expect(Puppet::Configurer.ancestors).to be_include(Puppet::Configurer::FactHandler)
13
+ catalog.add_resource(resource)
16
14
  end
17
15
 
16
+ let(:configurer) { Puppet::Configurer.new }
17
+ let(:report) { Puppet::Transaction::Report.new }
18
+ let(:catalog) { Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment].to_sym)) }
19
+ let(:resource) { Puppet::Resource.new(:notice, 'a') }
20
+ let(:facts) { Puppet::Node::Facts.new(Puppet[:node_name_value]) }
21
+
18
22
  describe "when executing a pre-run hook" do
19
23
  it "should do nothing if the hook is set to an empty string" do
20
24
  Puppet.settings[:prerun_command] = ""
21
- expect(Puppet::Util).not_to receive(:exec)
25
+ expect(Puppet::Util::Execution).not_to receive(:execute)
22
26
 
23
- @agent.execute_prerun_command
27
+ configurer.execute_prerun_command
24
28
  end
25
29
 
26
30
  it "should execute any pre-run command provided via the 'prerun_command' setting" do
27
31
  Puppet.settings[:prerun_command] = "/my/command"
28
32
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
29
33
 
30
- @agent.execute_prerun_command
34
+ configurer.execute_prerun_command
31
35
  end
32
36
 
33
37
  it "should fail if the command fails" do
34
38
  Puppet.settings[:prerun_command] = "/my/command"
35
39
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
36
40
 
37
- expect(@agent.execute_prerun_command).to be_falsey
41
+ expect(configurer.execute_prerun_command).to be_falsey
38
42
  end
39
43
  end
40
44
 
41
45
  describe "when executing a post-run hook" do
42
46
  it "should do nothing if the hook is set to an empty string" do
43
47
  Puppet.settings[:postrun_command] = ""
44
- expect(Puppet::Util).not_to receive(:exec)
48
+ expect(Puppet::Util::Execution).not_to receive(:execute)
45
49
 
46
- @agent.execute_postrun_command
50
+ configurer.execute_postrun_command
47
51
  end
48
52
 
49
53
  it "should execute any post-run command provided via the 'postrun_command' setting" do
50
54
  Puppet.settings[:postrun_command] = "/my/command"
51
55
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
52
56
 
53
- @agent.execute_postrun_command
57
+ configurer.execute_postrun_command
54
58
  end
55
59
 
56
60
  it "should fail if the command fails" do
57
61
  Puppet.settings[:postrun_command] = "/my/command"
58
62
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
59
63
 
60
- expect(@agent.execute_postrun_command).to be_falsey
64
+ expect(configurer.execute_postrun_command).to be_falsey
61
65
  end
62
66
  end
63
67
 
64
68
  describe "when executing a catalog run" do
65
69
  before do
66
- allow(Puppet.settings).to receive(:use).and_return(true)
67
- allow(@agent).to receive(:download_plugins)
68
- Puppet::Node::Facts.indirection.terminus_class = :memory
69
- @facts = Puppet::Node::Facts.new(Puppet[:node_name_value])
70
- Puppet::Node::Facts.indirection.save(@facts)
71
-
72
- @catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment].to_sym))
73
- allow(@catalog).to receive(:to_ral).and_return(@catalog)
74
70
  Puppet::Resource::Catalog.indirection.terminus_class = :rest
75
- allow(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(@catalog)
76
- allow(@agent).to receive(:send_report)
77
- allow(@agent).to receive(:save_last_run_summary)
78
-
79
- allow(Puppet::Util::Log).to receive(:close_all)
80
- end
81
-
82
- after :all do
83
- Puppet::Node::Facts.indirection.reset_terminus_class
84
- Puppet::Resource::Catalog.indirection.reset_terminus_class
85
- end
86
-
87
- it "should initialize storage" do
88
- expect(Puppet::Util::Storage).to receive(:load)
89
- @agent.run
71
+ allow(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(catalog)
90
72
  end
91
73
 
92
74
  it "downloads plugins when told" do
93
- expect(@agent).to receive(:download_plugins)
94
- @agent.run(:pluginsync => true)
75
+ expect(configurer).to receive(:download_plugins)
76
+ configurer.run(:pluginsync => true)
95
77
  end
96
78
 
97
79
  it "does not download plugins when told" do
98
- expect(@agent).not_to receive(:download_plugins)
99
- @agent.run(:pluginsync => false)
80
+ expect(configurer).not_to receive(:download_plugins)
81
+ configurer.run(:pluginsync => false)
100
82
  end
101
83
 
102
84
  it "should carry on when it can't fetch its node definition" do
103
85
  error = Net::HTTPError.new(400, 'dummy server communication error')
104
86
  expect(Puppet::Node.indirection).to receive(:find).and_raise(error)
105
- expect(@agent.run).to eq(0)
87
+ expect(configurer.run).to eq(0)
106
88
  end
107
89
 
108
90
  it "applies a cached catalog when it can't connect to the master" do
@@ -110,200 +92,157 @@ describe Puppet::Configurer do
110
92
 
111
93
  expect(Puppet::Node.indirection).to receive(:find).and_raise(error)
112
94
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(:ignore_cache => true)).and_raise(error)
113
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(:ignore_terminus => true)).and_return(@catalog)
95
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(:ignore_terminus => true)).and_return(catalog)
114
96
 
115
- expect(@agent.run).to eq(0)
97
+ expect(configurer.run).to eq(0)
116
98
  end
117
99
 
118
100
  it "should initialize a transaction report if one is not provided" do
119
- report = Puppet::Transaction::Report.new
120
101
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
121
102
 
122
- @agent.run
103
+ configurer.run
123
104
  end
124
105
 
125
106
  it "should respect node_name_fact when setting the host on a report" do
126
107
  Puppet[:node_name_fact] = 'my_name_fact'
127
- @facts.values = {'my_name_fact' => 'node_name_from_fact'}
128
-
129
- report = Puppet::Transaction::Report.new
108
+ facts.values = {'my_name_fact' => 'node_name_from_fact'}
109
+ Puppet::Node::Facts.indirection.save(facts)
130
110
 
131
- @agent.run(:report => report)
111
+ configurer.run(:report => report)
132
112
  expect(report.host).to eq('node_name_from_fact')
133
113
  end
134
114
 
135
- it "should pass the new report to the catalog" do
136
- report = Puppet::Transaction::Report.new
137
- allow(Puppet::Transaction::Report).to receive(:new).and_return(report)
138
- expect(@catalog).to receive(:apply).with(hash_including(report: report))
139
-
140
- @agent.run
141
- end
142
-
143
- it "should use the provided report if it was passed one" do
144
- report = Puppet::Transaction::Report.new
145
- expect(@catalog).to receive(:apply).with(hash_including(report: report))
146
-
147
- @agent.run(:report => report)
148
- end
149
-
150
- it "should set the report as a log destination" do
151
- report = Puppet::Transaction::Report.new
152
-
153
- expect(report).to receive(:<<).with(instance_of(Puppet::Util::Log)).at_least(:once)
115
+ it "creates a new report when applying the catalog" do
116
+ options = {}
117
+ configurer.run(options)
154
118
 
155
- @agent.run(:report => report)
119
+ expect(options[:report].metrics['time']['catalog_application']).to be_an_instance_of(Float)
156
120
  end
157
121
 
158
- it "should retrieve the catalog" do
159
- expect(@agent).to receive(:retrieve_catalog)
122
+ it "uses the provided report when applying the catalog" do
123
+ configurer.run(:report => report)
160
124
 
161
- @agent.run
125
+ expect(report.metrics['time']['catalog_application']).to be_an_instance_of(Float)
162
126
  end
163
127
 
164
128
  it "should log a failure and do nothing if no catalog can be retrieved" do
165
- expect(@agent).to receive(:retrieve_catalog).and_return(nil)
129
+ expect(configurer).to receive(:retrieve_catalog).and_return(nil)
166
130
 
167
131
  expect(Puppet).to receive(:err).with("Could not retrieve catalog; skipping run")
168
132
 
169
- @agent.run
133
+ configurer.run
170
134
  end
171
135
 
172
- it "should apply the catalog with all options to :run" do
173
- expect(@agent).to receive(:retrieve_catalog).and_return(@catalog)
136
+ it "passes arbitrary options when applying the catalog" do
137
+ expect(catalog).to receive(:apply).with(hash_including(one: true))
174
138
 
175
- expect(@catalog).to receive(:apply).with(hash_including(one: true))
176
- @agent.run :one => true
177
- end
178
-
179
- it "should accept a catalog and use it instead of retrieving a different one" do
180
- expect(@agent).not_to receive(:retrieve_catalog)
181
-
182
- expect(@catalog).to receive(:apply)
183
- @agent.run :one => true, :catalog => @catalog
139
+ configurer.run(catalog: catalog, one: true)
184
140
  end
185
141
 
186
142
  it "should benchmark how long it takes to apply the catalog" do
187
- expect(@agent).to receive(:benchmark).with(:notice, instance_of(String))
188
-
189
- expect(@agent).to receive(:retrieve_catalog).and_return(@catalog)
143
+ configurer.run(report: report)
190
144
 
191
- expect(@catalog).not_to receive(:apply) # because we're not yielding
192
- @agent.run
193
- end
194
-
195
- it "should execute post-run hooks after the run" do
196
- expect(@agent).to receive(:execute_postrun_command)
197
-
198
- @agent.run
145
+ expect(report.logs).to include(an_object_having_attributes(level: :notice, message: /Applied catalog in .* seconds/))
199
146
  end
200
147
 
201
148
  it "should create report with passed transaction_uuid and job_id" do
202
- @agent = Puppet::Configurer.new("test_tuuid", "test_jid")
203
- allow(@agent).to receive(:init_storage)
149
+ configurer = Puppet::Configurer.new("test_tuuid", "test_jid")
204
150
 
205
151
  report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
206
152
  expect(Puppet::Transaction::Report).to receive(:new).with(anything, anything, 'test_tuuid', 'test_jid').and_return(report)
207
- expect(@agent).to receive(:send_report).with(report)
153
+ expect(configurer).to receive(:send_report).with(report)
208
154
 
209
- @agent.run
155
+ configurer.run
210
156
  end
211
157
 
212
158
  it "should send the report" do
213
159
  report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
214
160
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
215
- expect(@agent).to receive(:send_report).with(report)
161
+ expect(configurer).to receive(:send_report).with(report)
216
162
 
217
163
  expect(report.environment).to eq("test")
218
164
  expect(report.transaction_uuid).to eq("aaaa")
219
165
 
220
- @agent.run
166
+ configurer.run
221
167
  end
222
168
 
223
169
  it "should send the transaction report even if the catalog could not be retrieved" do
224
- expect(@agent).to receive(:retrieve_catalog).and_return(nil)
170
+ expect(configurer).to receive(:retrieve_catalog).and_return(nil)
225
171
 
226
172
  report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
227
173
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
228
- expect(@agent).to receive(:send_report).with(report)
174
+ expect(configurer).to receive(:send_report).with(report)
229
175
 
230
176
  expect(report.environment).to eq("test")
231
177
  expect(report.transaction_uuid).to eq("aaaa")
232
178
 
233
- @agent.run
179
+ configurer.run
234
180
  end
235
181
 
236
182
  it "should send the transaction report even if there is a failure" do
237
- expect(@agent).to receive(:retrieve_catalog).and_raise("whatever")
183
+ expect(configurer).to receive(:retrieve_catalog).and_raise("whatever")
238
184
 
239
185
  report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
240
186
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
241
- expect(@agent).to receive(:send_report).with(report)
187
+ expect(configurer).to receive(:send_report).with(report)
242
188
 
243
189
  expect(report.environment).to eq("test")
244
190
  expect(report.transaction_uuid).to eq("aaaa")
245
191
 
246
- expect(@agent.run).to be_nil
192
+ expect(configurer.run).to be_nil
247
193
  end
248
194
 
249
195
  it "should remove the report as a log destination when the run is finished" do
250
- report = Puppet::Transaction::Report.new
251
196
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
252
197
 
253
- @agent.run
198
+ configurer.run
254
199
 
255
200
  expect(Puppet::Util::Log.destinations).not_to include(report)
256
201
  end
257
202
 
258
203
  it "should return the report exit_status as the result of the run" do
259
- report = Puppet::Transaction::Report.new
260
204
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
261
205
  expect(report).to receive(:exit_status).and_return(1234)
262
206
 
263
- expect(@agent.run).to eq(1234)
207
+ expect(configurer.run).to eq(1234)
264
208
  end
265
209
 
266
210
  it "should return nil if catalog application fails" do
267
- expect(@catalog).to receive(:apply).and_raise(Puppet::Error, 'One or more resource dependency cycles detected in graph')
268
- report = Puppet::Transaction::Report.new
269
- expect(@agent.run(catalog: @catalog, report: report)).to be_nil
211
+ expect_any_instance_of(Puppet::Resource::Catalog).to receive(:apply).and_raise(Puppet::Error, 'One or more resource dependency cycles detected in graph')
212
+ expect(configurer.run(catalog: catalog, report: report)).to be_nil
270
213
  end
271
214
 
272
215
  it "should send the transaction report even if the pre-run command fails" do
273
- report = Puppet::Transaction::Report.new
274
216
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
275
217
 
276
218
  Puppet.settings[:prerun_command] = "/my/command"
277
219
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
278
- expect(@agent).to receive(:send_report).with(report)
220
+ expect(configurer).to receive(:send_report).with(report)
279
221
 
280
- expect(@agent.run).to be_nil
222
+ expect(configurer.run).to be_nil
281
223
  end
282
224
 
283
225
  it "should include the pre-run command failure in the report" do
284
- report = Puppet::Transaction::Report.new
285
226
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
286
227
 
287
228
  Puppet.settings[:prerun_command] = "/my/command"
288
229
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
289
230
 
290
- expect(@agent.run).to be_nil
231
+ expect(configurer.run).to be_nil
291
232
  expect(report.logs.find { |x| x.message =~ /Could not run command from prerun_command/ }).to be
292
233
  end
293
234
 
294
235
  it "should send the transaction report even if the post-run command fails" do
295
- report = Puppet::Transaction::Report.new
296
236
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
297
237
 
298
238
  Puppet.settings[:postrun_command] = "/my/command"
299
239
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
300
- expect(@agent).to receive(:send_report).with(report)
240
+ expect(configurer).to receive(:send_report).with(report)
301
241
 
302
- expect(@agent.run).to be_nil
242
+ expect(configurer.run).to be_nil
303
243
  end
304
244
 
305
245
  it "should include the post-run command failure in the report" do
306
- report = Puppet::Transaction::Report.new
307
246
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
308
247
 
309
248
  Puppet.settings[:postrun_command] = "/my/command"
@@ -311,7 +250,7 @@ describe Puppet::Configurer do
311
250
 
312
251
  expect(report).to receive(:<<) { |log, _| expect(log.message).to match(/Could not run command from postrun_command/) }.at_least(:once)
313
252
 
314
- expect(@agent.run).to be_nil
253
+ expect(configurer.run).to be_nil
315
254
  end
316
255
 
317
256
  it "should execute post-run command even if the pre-run command fails" do
@@ -320,47 +259,42 @@ describe Puppet::Configurer do
320
259
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/precommand"]).and_raise(Puppet::ExecutionFailure, "Failed")
321
260
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/postcommand"])
322
261
 
323
- expect(@agent.run).to be_nil
262
+ expect(configurer.run).to be_nil
324
263
  end
325
264
 
326
265
  it "should finalize the report" do
327
- report = Puppet::Transaction::Report.new
328
266
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
329
267
 
330
268
  expect(report).to receive(:finalize_report)
331
- @agent.run
269
+ configurer.run
332
270
  end
333
271
 
334
272
  it "should not apply the catalog if the pre-run command fails" do
335
- report = Puppet::Transaction::Report.new
336
273
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
337
274
 
338
275
  Puppet.settings[:prerun_command] = "/my/command"
339
276
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
340
277
 
341
- expect(@catalog).not_to receive(:apply)
342
- expect(@agent).to receive(:send_report)
278
+ expect_any_instance_of(Puppet::Resource::Catalog).not_to receive(:apply)
279
+ expect(configurer).to receive(:send_report)
343
280
 
344
- expect(@agent.run).to be_nil
281
+ expect(configurer.run).to be_nil
345
282
  end
346
283
 
347
284
  it "should apply the catalog, send the report, and return nil if the post-run command fails" do
348
- report = Puppet::Transaction::Report.new
349
285
  expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
350
286
 
351
287
  Puppet.settings[:postrun_command] = "/my/command"
352
288
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
353
289
 
354
- expect(@catalog).to receive(:apply)
355
- expect(@agent).to receive(:send_report)
290
+ expect_any_instance_of(Puppet::Resource::Catalog).to receive(:apply)
291
+ expect(configurer).to receive(:send_report)
356
292
 
357
- expect(@agent.run).to be_nil
293
+ expect(configurer.run).to be_nil
358
294
  end
359
295
 
360
296
  it 'includes total time metrics in the report after successfully applying the catalog' do
361
- report = Puppet::Transaction::Report.new
362
- allow(@catalog).to receive(:apply).with(hash_including(report: report))
363
- @agent.run(report: report)
297
+ configurer.run(report: report)
364
298
 
365
299
  expect(report.metrics['time']).to be
366
300
  expect(report.metrics['time']['total']).to be_a_kind_of(Numeric)
@@ -370,17 +304,15 @@ describe Puppet::Configurer do
370
304
  Puppet.settings[:prerun_command] = "/my/command"
371
305
  expect(Puppet::Util::Execution).to receive(:execute).with(["/my/command"]).and_raise(Puppet::ExecutionFailure, "Failed")
372
306
 
373
- report = Puppet::Transaction::Report.new
374
- @agent.run(report: report)
307
+ configurer.run(report: report)
375
308
 
376
309
  expect(report.metrics['time']).to be
377
310
  expect(report.metrics['time']['total']).to be_a_kind_of(Numeric)
378
311
  end
379
312
 
380
313
  it 'includes total time metrics in the report even if catalog retrieval fails' do
381
- report = Puppet::Transaction::Report.new
382
- allow(@agent).to receive(:prepare_and_retrieve_catalog_from_cache).and_raise
383
- @agent.run(:report => report)
314
+ allow(configurer).to receive(:prepare_and_retrieve_catalog_from_cache).and_raise
315
+ configurer.run(:report => report)
384
316
 
385
317
  expect(report.metrics['time']).to be
386
318
  expect(report.metrics['time']['total']).to be_a_kind_of(Numeric)
@@ -388,102 +320,93 @@ describe Puppet::Configurer do
388
320
 
389
321
  it "should refetch the catalog if the server specifies a new environment in the catalog" do
390
322
  catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
391
- expect(@agent).to receive(:retrieve_catalog).and_return(catalog).twice
323
+ expect(configurer).to receive(:retrieve_catalog).and_return(catalog).twice
392
324
 
393
- @agent.run
325
+ configurer.run
394
326
  end
395
327
 
396
- it "should change the environment setting if the server specifies a new environment in the catalog" do
397
- allow(@catalog).to receive(:environment).and_return("second_env")
328
+ it "changes the configurer's environment if the server specifies a new environment in the catalog" do
329
+ allow_any_instance_of(Puppet::Resource::Catalog).to receive(:environment).and_return("second_env")
398
330
 
399
- @agent.run
331
+ configurer.run
400
332
 
401
- expect(@agent.environment).to eq("second_env")
333
+ expect(configurer.environment).to eq("second_env")
402
334
  end
403
335
 
404
- it "should fix the report if the server specifies a new environment in the catalog" do
405
- report = Puppet::Transaction::Report.new(nil, "test", "aaaa")
406
- expect(Puppet::Transaction::Report).to receive(:new).and_return(report)
407
- expect(@agent).to receive(:send_report).with(report)
408
-
409
- allow(@catalog).to receive(:environment).and_return("second_env")
410
- allow(@agent).to receive(:retrieve_catalog).and_return(@catalog)
336
+ it "changes the report's environment if the server specifies a new environment in the catalog" do
337
+ allow_any_instance_of(Puppet::Resource::Catalog).to receive(:environment).and_return("second_env")
411
338
 
412
- @agent.run
339
+ configurer.run(report: report)
413
340
 
414
341
  expect(report.environment).to eq("second_env")
415
342
  end
416
343
 
417
344
  it "sends the transaction uuid in a catalog request" do
418
- @agent.instance_variable_set(:@transaction_uuid, 'aaa')
345
+ configurer = Puppet::Configurer.new('aaa')
419
346
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(transaction_uuid: 'aaa'))
420
- @agent.run
347
+ configurer.run
421
348
  end
422
349
 
423
350
  it "sends the transaction uuid in a catalog request" do
424
- @agent.instance_variable_set(:@job_id, 'aaa')
351
+ configurer = Puppet::Configurer.new('b', 'aaa')
425
352
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(job_id: 'aaa'))
426
- @agent.run
353
+ configurer.run
427
354
  end
428
355
 
429
356
  it "sets the static_catalog query param to true in a catalog request" do
430
357
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(static_catalog: true))
431
- @agent.run
358
+ configurer.run
432
359
  end
433
360
 
434
361
  it "sets the checksum_type query param to the default supported_checksum_types in a catalog request" do
435
362
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything,
436
363
  hash_including(checksum_type: 'md5.sha256.sha384.sha512.sha224'))
437
- @agent.run
364
+ configurer.run
438
365
  end
439
366
 
440
367
  it "sets the checksum_type query param to the supported_checksum_types setting in a catalog request" do
441
- # Regenerate the agent to pick up the new setting
442
368
  Puppet[:supported_checksum_types] = ['sha256']
443
- @agent = Puppet::Configurer.new
444
- allow(@agent).to receive(:init_storage)
445
- allow(@agent).to receive(:download_plugins)
446
- allow(@agent).to receive(:send_report)
447
- allow(@agent).to receive(:save_last_run_summary)
369
+ # Regenerate the agent to pick up the new setting
370
+ configurer = Puppet::Configurer.new
448
371
 
449
372
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(checksum_type: 'sha256'))
450
- @agent.run
373
+ configurer.run
451
374
  end
452
375
 
453
376
  describe "when not using a REST terminus for catalogs" do
454
377
  it "should not pass any facts when retrieving the catalog" do
378
+ # This is weird, we collect facts when constructing the node,
379
+ # but we don't send them in the indirector request. Then the compiler
380
+ # looks up the node, and collects its facts, which we could have sent
381
+ # in the first place. This seems like a bug.
455
382
  Puppet::Resource::Catalog.indirection.terminus_class = :compiler
456
- expect(@agent).not_to receive(:facts_for_uploading)
383
+
457
384
  expect(Puppet::Resource::Catalog.indirection).to receive(:find) do |name, options|
458
- options[:facts].nil?
459
- end.and_return(@catalog)
385
+ expect(options[:facts]).to be_nil
386
+ end.and_return(catalog)
460
387
 
461
- @agent.run
388
+ configurer.run
462
389
  end
463
390
  end
464
391
 
465
392
  describe "when using a REST terminus for catalogs" do
466
- it "should pass the prepared facts and the facts format as arguments when retrieving the catalog" do
393
+ it "should pass the url encoded facts and facts format as arguments when retrieving the catalog" do
467
394
  Puppet::Resource::Catalog.indirection.terminus_class = :rest
468
- # the "facts_for_uploading" are prepeared by first finding facts, and then encoding them
469
- # this mocks the "find" with a special value 12345, which is then expected back in the
470
- # call to "encode" - the encode in turn returns mocked data that is asserted as being
471
- # presented to the catalog terminus as options.
472
- #
473
- expect(@agent).to receive(:find_facts).and_return(12345)
474
- expect(@agent).to receive(:encode_facts).with(12345).and_return(:facts => "myfacts", :facts_format => :foo)
475
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(facts: "myfacts", facts_format: :foo)).and_return(@catalog)
476
-
477
- @agent.run
478
- end
479
- end
480
- end
481
395
 
482
- describe "when initialized with a transaction_uuid" do
483
- it "stores it" do
484
- expect(SecureRandom).not_to receive(:uuid)
485
- configurer = Puppet::Configurer.new('foo')
486
- expect(configurer.instance_variable_get(:@transaction_uuid) == 'foo')
396
+ facts.values = { 'foo' => 'bar' }
397
+ Puppet::Node::Facts.indirection.save(facts)
398
+
399
+ expect(
400
+ Puppet::Resource::Catalog.indirection
401
+ ).to receive(:find) do |_, options|
402
+ expect(options[:facts_format]).to eq("application/json")
403
+
404
+ unescaped = JSON.parse(CGI.unescape(options[:facts]))
405
+ expect(unescaped).to include("values" => {"foo" => "bar"})
406
+ end.and_return(catalog)
407
+
408
+ configurer.run
409
+ end
487
410
  end
488
411
  end
489
412
 
@@ -491,56 +414,52 @@ describe Puppet::Configurer do
491
414
  include PuppetSpec::Files
492
415
 
493
416
  before do
494
- allow(Puppet.settings).to receive(:use).and_return(true)
495
- @configurer = Puppet::Configurer.new
496
417
  Puppet[:lastrunfile] = tmpfile('last_run_file')
497
-
498
- @report = Puppet::Transaction::Report.new
499
418
  Puppet[:reports] = "none"
500
419
  end
501
420
 
502
421
  it "should print a report summary if configured to do so" do
503
422
  Puppet.settings[:summarize] = true
504
423
 
505
- expect(@report).to receive(:summary).and_return("stuff")
424
+ expect(report).to receive(:summary).and_return("stuff")
506
425
 
507
- expect(@configurer).to receive(:puts).with("stuff")
508
- @configurer.send_report(@report)
426
+ expect(configurer).to receive(:puts).with("stuff")
427
+ configurer.send_report(report)
509
428
  end
510
429
 
511
430
  it "should not print a report summary if not configured to do so" do
512
431
  Puppet.settings[:summarize] = false
513
432
 
514
- expect(@configurer).not_to receive(:puts)
515
- @configurer.send_report(@report)
433
+ expect(configurer).not_to receive(:puts)
434
+ configurer.send_report(report)
516
435
  end
517
436
 
518
437
  it "should save the report if reporting is enabled" do
519
438
  Puppet.settings[:report] = true
520
439
 
521
- expect(Puppet::Transaction::Report.indirection).to receive(:save).with(@report, nil, instance_of(Hash))
522
- @configurer.send_report(@report)
440
+ expect(Puppet::Transaction::Report.indirection).to receive(:save).with(report, nil, instance_of(Hash))
441
+ configurer.send_report(report)
523
442
  end
524
443
 
525
444
  it "should not save the report if reporting is disabled" do
526
445
  Puppet.settings[:report] = false
527
446
 
528
- expect(Puppet::Transaction::Report.indirection).not_to receive(:save).with(@report, nil, instance_of(Hash))
529
- @configurer.send_report(@report)
447
+ expect(Puppet::Transaction::Report.indirection).not_to receive(:save).with(report, nil, instance_of(Hash))
448
+ configurer.send_report(report)
530
449
  end
531
450
 
532
451
  it "should save the last run summary if reporting is enabled" do
533
452
  Puppet.settings[:report] = true
534
453
 
535
- expect(@configurer).to receive(:save_last_run_summary).with(@report)
536
- @configurer.send_report(@report)
454
+ expect(configurer).to receive(:save_last_run_summary).with(report)
455
+ configurer.send_report(report)
537
456
  end
538
457
 
539
458
  it "should save the last run summary if reporting is disabled" do
540
459
  Puppet.settings[:report] = false
541
460
 
542
- expect(@configurer).to receive(:save_last_run_summary).with(@report)
543
- @configurer.send_report(@report)
461
+ expect(configurer).to receive(:save_last_run_summary).with(report)
462
+ configurer.send_report(report)
544
463
  end
545
464
 
546
465
  it "should log but not fail if saving the report fails" do
@@ -548,8 +467,9 @@ describe Puppet::Configurer do
548
467
 
549
468
  expect(Puppet::Transaction::Report.indirection).to receive(:save).and_raise("whatever")
550
469
 
551
- expect(Puppet).to receive(:send_log).with(:err, 'Could not send report: whatever')
552
- @configurer.send_report(@report)
470
+ configurer.send_report(report)
471
+
472
+ expect(@logs).to include(an_object_having_attributes(level: :err, message: 'Could not send report: whatever'))
553
473
  end
554
474
  end
555
475
 
@@ -557,22 +477,17 @@ describe Puppet::Configurer do
557
477
  include PuppetSpec::Files
558
478
 
559
479
  before do
560
- allow(Puppet.settings).to receive(:use).and_return(true)
561
- @configurer = Puppet::Configurer.new
562
-
563
- @report = double('report', :raw_summary => {})
564
-
565
480
  Puppet[:lastrunfile] = tmpfile('last_run_file')
566
481
  end
567
482
 
568
483
  it "should write the last run file" do
569
- @configurer.save_last_run_summary(@report)
484
+ configurer.save_last_run_summary(report)
570
485
  expect(Puppet::FileSystem.exist?(Puppet[:lastrunfile])).to be_truthy
571
486
  end
572
487
 
573
488
  it "should write the raw summary as yaml" do
574
- expect(@report).to receive(:raw_summary).and_return("summary")
575
- @configurer.save_last_run_summary(@report)
489
+ expect(report).to receive(:raw_summary).and_return("summary")
490
+ configurer.save_last_run_summary(report)
576
491
  expect(File.read(Puppet[:lastrunfile])).to eq(YAML.dump("summary"))
577
492
  end
578
493
 
@@ -587,13 +502,14 @@ describe Puppet::Configurer do
587
502
 
588
503
  expect(Puppet::Util).to receive(:replace_file).and_yield(fh)
589
504
 
590
- expect(Puppet).to receive(:send_log).with(:err, 'Could not save last run local report: failed to do print')
591
- @configurer.save_last_run_summary(@report)
505
+ configurer.save_last_run_summary(report)
506
+
507
+ expect(@logs).to include(an_object_having_attributes(level: :err, message: 'Could not save last run local report: failed to do print'))
592
508
  end
593
509
 
594
510
  it "should create the last run file with the correct mode" do
595
511
  expect(Puppet.settings.setting(:lastrunfile)).to receive(:mode).and_return('664')
596
- @configurer.save_last_run_summary(@report)
512
+ configurer.save_last_run_summary(report)
597
513
 
598
514
  if Puppet::Util::Platform.windows?
599
515
  require 'puppet/util/windows/security'
@@ -606,26 +522,28 @@ describe Puppet::Configurer do
606
522
 
607
523
  it "should report invalid last run file permissions" do
608
524
  expect(Puppet.settings.setting(:lastrunfile)).to receive(:mode).and_return('892')
609
- expect(Puppet).to receive(:send_log).with(:err, /Could not save last run local report.*892 is invalid/)
610
- @configurer.save_last_run_summary(@report)
525
+
526
+ configurer.save_last_run_summary(report)
527
+
528
+ expect(@logs).to include(an_object_having_attributes(level: :err, message: /Could not save last run local report.*892 is invalid/))
611
529
  end
612
530
  end
613
531
 
614
532
  describe "when requesting a node" do
615
533
  it "uses the transaction uuid in the request" do
616
534
  expect(Puppet::Node.indirection).to receive(:find).with(anything, hash_including(transaction_uuid: anything)).twice
617
- @agent.run
535
+ configurer.run
618
536
  end
619
537
 
620
538
  it "sends an explicitly configured environment request" do
621
539
  expect(Puppet.settings).to receive(:set_by_config?).with(:environment).and_return(true)
622
540
  expect(Puppet::Node.indirection).to receive(:find).with(anything, hash_including(configured_environment: Puppet[:environment])).twice
623
- @agent.run
541
+ configurer.run
624
542
  end
625
543
 
626
544
  it "does not send a configured_environment when using the default" do
627
545
  expect(Puppet::Node.indirection).to receive(:find).with(anything, hash_including(configured_environment: nil)).twice
628
- @agent.run
546
+ configurer.run
629
547
  end
630
548
  end
631
549
 
@@ -656,14 +574,6 @@ describe Puppet::Configurer do
656
574
 
657
575
  describe "when retrieving a catalog" do
658
576
  before do
659
- allow(Puppet.settings).to receive(:use).and_return(true)
660
- allow(@agent).to receive(:facts_for_uploading).and_return({})
661
- allow(@agent).to receive(:download_plugins)
662
-
663
- # retrieve a catalog in the current environment, so we don't try to converge unexpectedly
664
- @catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment].to_sym))
665
-
666
- # this is the default when using a Configurer instance
667
577
  allow(Puppet::Resource::Catalog.indirection).to receive(:terminus_class).and_return(:rest)
668
578
  end
669
579
 
@@ -673,100 +583,139 @@ describe Puppet::Configurer do
673
583
  end
674
584
 
675
585
  it "should first look in the cache for a catalog" do
676
- expects_cached_catalog_only(@catalog)
586
+ expects_cached_catalog_only(catalog)
677
587
 
678
- expect(@agent.retrieve_catalog({})).to eq(@catalog)
588
+ configurer.run
679
589
  end
680
590
 
681
591
  it "should not make a node request or pluginsync when a cached catalog is successfully retrieved" do
682
592
  expect(Puppet::Node.indirection).not_to receive(:find)
683
- expects_cached_catalog_only(@catalog)
684
- expect(@agent).not_to receive(:download_plugins)
593
+ expects_cached_catalog_only(catalog)
594
+ expect(configurer).not_to receive(:download_plugins)
685
595
 
686
- @agent.run
596
+ configurer.run
687
597
  end
688
598
 
689
599
  it "should make a node request and pluginsync when a cached catalog cannot be retrieved" do
690
600
  expect(Puppet::Node.indirection).to receive(:find).and_return(nil)
691
- expects_fallback_to_new_catalog(@catalog)
692
- expect(@agent).to receive(:download_plugins)
601
+ expects_fallback_to_new_catalog(catalog)
602
+ expect(configurer).to receive(:download_plugins)
693
603
 
694
- @agent.run
604
+ configurer.run
695
605
  end
696
606
 
697
607
  it "should set its cached_catalog_status to 'explicitly_requested'" do
698
- expects_cached_catalog_only(@catalog)
608
+ expects_cached_catalog_only(catalog)
699
609
 
700
- @agent.retrieve_catalog({})
701
- expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('explicitly_requested')
610
+ options = {}
611
+ configurer.run(options)
612
+
613
+ expect(options[:report].cached_catalog_status).to eq('explicitly_requested')
702
614
  end
703
615
 
704
616
  it "should set its cached_catalog_status to 'explicitly requested' if the cached catalog is from a different environment" do
705
617
  cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
706
618
  expects_cached_catalog_only(cached_catalog)
707
619
 
708
- @agent.retrieve_catalog({})
709
- expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('explicitly_requested')
710
- end
711
-
712
- it "should compile a new catalog if none is found in the cache" do
713
- expects_fallback_to_new_catalog(@catalog)
620
+ options = {}
621
+ configurer.run(options)
714
622
 
715
- expect(@agent.retrieve_catalog({})).to eq(@catalog)
623
+ expect(options[:report].cached_catalog_status).to eq('explicitly_requested')
716
624
  end
717
625
 
718
- it "should set its cached_catalog_status to 'not_used' if no catalog is found in the cache" do
719
- expects_fallback_to_new_catalog(@catalog)
626
+ it "should pluginsync and compile a new catalog if none is found in the cache" do
627
+ expects_fallback_to_new_catalog(catalog)
628
+ stub_request(:get, %r{/puppet/v3/file_metadatas?/plugins}).to_return(:status => 404)
629
+ stub_request(:get, %r{/puppet/v3/file_metadatas?/pluginfacts}).to_return(:status => 404)
630
+
631
+ options = {}
632
+ configurer.run(options)
720
633
 
721
- @agent.retrieve_catalog({})
722
- expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('not_used')
634
+ expect(options[:report].cached_catalog_status).to eq('not_used')
723
635
  end
724
636
 
725
637
  it "should not attempt to retrieve a cached catalog again if the first attempt failed" do
726
638
  expect(Puppet::Node.indirection).to receive(:find).and_return(nil)
727
639
  expects_neither_new_or_cached_catalog
728
640
 
729
- @agent.run
641
+ # after failing to use a cached catalog, we'll need to pluginsync before getting
642
+ # a new catalog, which also fails.
643
+ stub_request(:get, %r{/puppet/v3/file_metadatas?/plugins}).to_return(:status => 404)
644
+ stub_request(:get, %r{/puppet/v3/file_metadatas?/pluginfacts}).to_return(:status => 404)
645
+
646
+ configurer.run
730
647
  end
731
648
 
732
649
  it "should return the cached catalog when the environment doesn't match" do
733
650
  cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
734
651
  expects_cached_catalog_only(cached_catalog)
735
652
 
653
+ allow(Puppet).to receive(:info)
736
654
  expect(Puppet).to receive(:info).with("Using cached catalog from environment 'second_env'")
737
- expect(@agent.retrieve_catalog({})).to eq(cached_catalog)
655
+
656
+ configurer.run
657
+ end
658
+
659
+ it "applies the catalog passed as options when the catalog cache terminus is not set" do
660
+ stub_request(:get, %r{/puppet/v3/file_metadatas?/plugins}).to_return(:status => 404)
661
+ stub_request(:get, %r{/puppet/v3/file_metadatas?/pluginfacts}).to_return(:status => 404)
662
+
663
+ catalog.add_resource(Puppet::Resource.new('notify', 'from apply'))
664
+ configurer.run(catalog: catalog.to_ral)
665
+
666
+ # make sure cache class is not set to avoid surprises later
667
+ expect(Puppet::Resource::Catalog.indirection).to_not be_cache
668
+ expect(@logs).to include(an_object_having_attributes(level: :notice, message: /defined 'message' as 'from apply'/))
669
+ end
670
+
671
+ it "applies the cached catalog when the catalog cache terminus is set, ignoring the catalog passed as options" do
672
+ Puppet::Resource::Catalog.indirection.cache_class = :json
673
+
674
+ cached_catalog = Puppet::Resource::Catalog.new(Puppet[:node_name_value], Puppet[:environment])
675
+ cached_catalog.add_resource(Puppet::Resource.new('notify', 'from cache'))
676
+
677
+ # update cached catalog
678
+ Puppet.settings.use(:main, :agent)
679
+ path = Puppet::Resource::Catalog.indirection.cache.path(cached_catalog.name)
680
+ FileUtils.mkdir(File.dirname(path))
681
+ File.write(path, cached_catalog.render(:json))
682
+
683
+ configurer.run(catalog: catalog.to_ral)
684
+
685
+ expect(@logs).to include(an_object_having_attributes(level: :notice, message: /defined 'message' as 'from cache'/))
738
686
  end
739
687
  end
740
688
 
741
689
  describe "and strict environment mode is set" do
742
690
  before do
743
- allow(@catalog).to receive(:to_ral).and_return(@catalog)
744
- allow(@catalog).to receive(:write_class_file)
745
- allow(@catalog).to receive(:write_resource_file)
746
- allow(@agent).to receive(:send_report)
747
- allow(@agent).to receive(:save_last_run_summary)
748
691
  Puppet.settings[:strict_environment_mode] = true
749
692
  end
750
693
 
751
694
  it "should not make a node request" do
695
+ stub_request(:get, %r{/puppet/v3/file_metadatas?/plugins}).to_return(:status => 404)
696
+ stub_request(:get, %r{/puppet/v3/file_metadatas?/pluginfacts}).to_return(:status => 404)
697
+ expects_new_catalog_only(catalog)
698
+
752
699
  expect(Puppet::Node.indirection).not_to receive(:find)
753
700
 
754
- @agent.run
701
+ configurer.run
755
702
  end
756
703
 
757
704
  it "should return nil when the catalog's environment doesn't match the agent specified environment" do
758
- @agent.instance_variable_set(:@environment, 'second_env')
759
- expects_new_catalog_only(@catalog)
705
+ Puppet[:environment] = 'second_env'
706
+ configurer = Puppet::Configurer.new
707
+
708
+ catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote("production"))
709
+ expects_new_catalog_only(catalog)
760
710
 
761
711
  expect(Puppet).to receive(:err).with("Not using catalog because its environment 'production' does not match agent specified environment 'second_env' and strict_environment_mode is set")
762
- expect(@agent.run).to be_nil
712
+ expect(configurer.run).to be_nil
763
713
  end
764
714
 
765
- it "should not return nil when the catalog's environment matches the agent specified environment" do
766
- @agent.instance_variable_set(:@environment, 'production')
767
- expects_new_catalog_only(@catalog)
715
+ it "should return 0 when the catalog's environment matches the agent specified environment" do
716
+ expects_new_catalog_only(catalog)
768
717
 
769
- expect(@agent.run).to eq(0)
718
+ expect(configurer.run).to eq(0)
770
719
  end
771
720
 
772
721
  describe "and a cached catalog is explicitly requested" do
@@ -775,83 +724,81 @@ describe Puppet::Configurer do
775
724
  end
776
725
 
777
726
  it "should return nil when the cached catalog's environment doesn't match the agent specified environment" do
778
- @agent.instance_variable_set(:@environment, 'second_env')
779
- expects_cached_catalog_only(@catalog)
727
+ Puppet[:environment] = 'second_env'
728
+ configurer = Puppet::Configurer.new
729
+
730
+ catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote("production"))
731
+ expects_cached_catalog_only(catalog)
780
732
 
781
733
  expect(Puppet).to receive(:err).with("Not using catalog because its environment 'production' does not match agent specified environment 'second_env' and strict_environment_mode is set")
782
- expect(@agent.run).to be_nil
734
+ expect(configurer.run).to be_nil
783
735
  end
784
736
 
785
737
  it "should proceed with the cached catalog if its environment matchs the local environment" do
786
- Puppet.settings[:use_cached_catalog] = true
787
- @agent.instance_variable_set(:@environment, 'production')
788
- expects_cached_catalog_only(@catalog)
738
+ expects_cached_catalog_only(catalog)
789
739
 
790
- expect(@agent.run).to eq(0)
740
+ expect(configurer.run).to eq(0)
791
741
  end
792
742
  end
793
743
  end
794
744
 
795
- it "should use the Catalog class to get its catalog" do
796
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(@catalog)
797
-
798
- @agent.retrieve_catalog({})
799
- end
800
-
801
745
  it "should set its cached_catalog_status to 'not_used' when downloading a new catalog" do
802
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_return(@catalog)
746
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_return(catalog)
803
747
 
804
- @agent.retrieve_catalog({})
805
- expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('not_used')
748
+ options = {}
749
+ configurer.run(options)
750
+
751
+ expect(options[:report].cached_catalog_status).to eq('not_used')
806
752
  end
807
753
 
808
754
  it "should use its node_name_value to retrieve the catalog" do
809
- allow(Facter).to receive(:value).and_return("eh")
810
- Puppet.settings[:node_name_value] = "myhost.domain.com"
811
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with("myhost.domain.com", anything).and_return(@catalog)
755
+ myhost_facts = Puppet::Node::Facts.new("myhost.domain.com")
756
+ Puppet::Node::Facts.indirection.save(myhost_facts)
812
757
 
813
- @agent.retrieve_catalog({})
814
- end
815
-
816
- it "should default to returning a catalog retrieved directly from the server, skipping the cache" do
817
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_return(@catalog)
758
+ Puppet.settings[:node_name_value] = "myhost.domain.com"
759
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with("myhost.domain.com", anything).and_return(catalog)
818
760
 
819
- expect(@agent.retrieve_catalog({})).to eq(@catalog)
761
+ configurer.run
820
762
  end
821
763
 
822
- it "should log and return the cached catalog when no catalog can be retrieved from the server" do
823
- expects_fallback_to_cached_catalog(@catalog)
764
+ it "should log when no catalog can be retrieved from the server" do
765
+ expects_fallback_to_cached_catalog(catalog)
824
766
 
767
+ allow(Puppet).to receive(:info)
825
768
  expect(Puppet).to receive(:info).with("Using cached catalog from environment 'production'")
826
- expect(@agent.retrieve_catalog({})).to eq(@catalog)
769
+ configurer.run
827
770
  end
828
771
 
829
772
  it "should set its cached_catalog_status to 'on_failure' when no catalog can be retrieved from the server" do
830
- expects_fallback_to_cached_catalog(@catalog)
773
+ expects_fallback_to_cached_catalog(catalog)
831
774
 
832
- @agent.retrieve_catalog({})
833
- expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('on_failure')
775
+ options = {}
776
+ configurer.run(options)
777
+
778
+ expect(options[:report].cached_catalog_status).to eq('on_failure')
834
779
  end
835
780
 
836
781
  it "should not look in the cache for a catalog if one is returned from the server" do
837
- expects_new_catalog_only(@catalog)
782
+ expects_new_catalog_only(catalog)
838
783
 
839
- expect(@agent.retrieve_catalog({})).to eq(@catalog)
784
+ configurer.run
840
785
  end
841
786
 
842
787
  it "should return the cached catalog when retrieving the remote catalog throws an exception" do
843
788
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_raise("eh")
844
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_terminus: true)).and_return(@catalog)
789
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_terminus: true)).and_return(catalog)
845
790
 
846
- expect(@agent.retrieve_catalog({})).to eq(@catalog)
791
+ configurer.run
847
792
  end
848
793
 
849
794
  it "should set its cached_catalog_status to 'on_failure' when retrieving the remote catalog throws an exception" do
850
795
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_raise("eh")
851
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_terminus: true)).and_return(@catalog)
796
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_terminus: true)).and_return(catalog)
797
+
798
+ options = {}
799
+ configurer.run(options)
852
800
 
853
- @agent.retrieve_catalog({})
854
- expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('on_failure')
801
+ expect(options[:report].cached_catalog_status).to eq('on_failure')
855
802
  end
856
803
 
857
804
  it "should log and return nil if no catalog can be retrieved from the server and :usecacheonfailure is disabled" do
@@ -860,120 +807,173 @@ describe Puppet::Configurer do
860
807
 
861
808
  expect(Puppet).to receive(:warning).with('Not using cache on failed catalog')
862
809
 
863
- expect(@agent.retrieve_catalog({})).to be_nil
810
+ expect(configurer.run).to be_nil
864
811
  end
865
812
 
866
813
  it "should set its cached_catalog_status to 'not_used' if no catalog can be retrieved from the server and :usecacheonfailure is disabled or fails to retrieve a catalog" do
867
814
  Puppet[:usecacheonfailure] = false
868
815
  expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true)).and_return(nil)
869
816
 
870
- @agent.retrieve_catalog({})
871
- expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('not_used')
817
+ options = {}
818
+ configurer.run(options)
819
+
820
+ expect(options[:report].cached_catalog_status).to eq('not_used')
872
821
  end
873
822
 
874
823
  it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do
875
824
  expects_neither_new_or_cached_catalog
876
825
 
877
- expect(@agent.retrieve_catalog({})).to be_nil
826
+ expect(configurer.run).to be_nil
878
827
  end
879
828
 
880
829
  it "should return nil if its cached catalog environment doesn't match server-specified environment" do
881
830
  cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
882
- @agent.instance_variable_set(:@node_environment, 'production')
883
831
 
884
832
  expects_fallback_to_cached_catalog(cached_catalog)
885
833
 
834
+ allow(Puppet).to receive(:err)
886
835
  expect(Puppet).to receive(:err).with("Not using cached catalog because its environment 'second_env' does not match 'production'")
887
- expect(@agent.retrieve_catalog({})).to be_nil
836
+ expect(configurer.run).to be_nil
888
837
  end
889
838
 
890
839
  it "should set its cached_catalog_status to 'not_used' if the cached catalog environment doesn't match server-specified environment" do
891
840
  cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote('second_env'))
892
- @agent.instance_variable_set(:@node_environment, 'production')
893
841
 
894
842
  expects_fallback_to_cached_catalog(cached_catalog)
895
843
 
896
- @agent.retrieve_catalog({})
897
- expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('not_used')
898
- end
899
-
900
- it "should return its cached catalog if the environment matches the server-specified environment" do
901
- cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment]))
902
- @agent.instance_variable_set(:@node_environment, cached_catalog.environment)
903
-
904
- expects_fallback_to_cached_catalog(cached_catalog)
905
-
906
- expect(@agent.retrieve_catalog({})).to eq(cached_catalog)
844
+ options = {}
845
+ configurer.run(options)
846
+ expect(options[:report].cached_catalog_status).to eq('not_used')
907
847
  end
908
848
 
909
849
  it "should set its cached_catalog_status to 'on_failure' if the cached catalog environment matches server-specified environment" do
910
- cached_catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment]))
911
- @agent.instance_variable_set(:@node_environment, cached_catalog.environment)
912
-
913
- expects_fallback_to_cached_catalog(cached_catalog)
850
+ expects_fallback_to_cached_catalog(catalog)
914
851
 
915
- @agent.retrieve_catalog({})
916
- expect(@agent.instance_variable_get(:@cached_catalog_status)).to eq('on_failure')
852
+ options = {}
853
+ configurer.run(options)
854
+ expect(options[:report].cached_catalog_status).to eq('on_failure')
917
855
  end
918
856
 
919
857
  it "should not update the cached catalog in noop mode" do
920
858
  Puppet[:noop] = true
921
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true, ignore_cache_save: true)).and_return(@catalog)
922
859
 
923
- @agent.retrieve_catalog({})
860
+ stub_request(:get, %r{/puppet/v3/catalog}).to_return(:status => 200, :body => catalog.render(:json), :headers => {'Content-Type' => 'application/json'})
861
+
862
+ Puppet::Resource::Catalog.indirection.cache_class = :json
863
+ path = Puppet::Resource::Catalog.indirection.cache.path(catalog.name)
864
+
865
+ expect(File).to_not be_exist(path)
866
+ configurer.run
867
+ expect(File).to_not be_exist(path)
924
868
  end
925
869
 
926
870
  it "should update the cached catalog when not in noop mode" do
927
871
  Puppet[:noop] = false
928
- expect(Puppet::Resource::Catalog.indirection).to receive(:find).with(anything, hash_including(ignore_cache: true, ignore_cache_save: false)).and_return(@catalog)
872
+ Puppet[:log_level] = 'info'
873
+
874
+ stub_request(:get, %r{/puppet/v3/catalog}).to_return(:status => 200, :body => catalog.render(:json), :headers => {'Content-Type' => 'application/json'})
875
+
876
+ Puppet::Resource::Catalog.indirection.cache_class = :json
877
+ cache_path = Puppet::Resource::Catalog.indirection.cache.path(Puppet[:node_name_value])
878
+
879
+ expect(File).to_not be_exist(cache_path)
880
+ configurer.run
881
+ expect(File).to be_exist(cache_path)
882
+
883
+ expect(@logs).to include(an_object_having_attributes(level: :info, message: "Caching catalog for #{Puppet[:node_name_value]}"))
884
+ end
885
+
886
+ it "successfully applies the catalog without a cache" do
887
+ stub_request(:get, %r{/puppet/v3/catalog}).to_return(:status => 200, :body => catalog.render(:json), :headers => {'Content-Type' => 'application/json'})
888
+
889
+ Puppet::Resource::Catalog.indirection.cache_class = nil
890
+
891
+ expect(configurer.run).to eq(0)
892
+ end
893
+
894
+ it "should not update the cached catalog when running puppet apply" do
895
+ Puppet::Resource::Catalog.indirection.cache_class = :json
896
+ path = Puppet::Resource::Catalog.indirection.cache.path(catalog.name)
929
897
 
930
- @agent.retrieve_catalog({})
898
+ expect(File).to_not be_exist(path)
899
+ configurer.run(catalog: catalog)
900
+ expect(File).to_not be_exist(path)
931
901
  end
932
902
  end
933
903
 
934
- describe "when converting the catalog" do
935
- before do
936
- allow(Puppet.settings).to receive(:use).and_return(true)
904
+ describe "when converging the environment" do
905
+ let(:apple) { Puppet::Resource::Catalog.new(Puppet[:node_name_value], Puppet::Node::Environment.remote('apple')) }
906
+ let(:banana) { Puppet::Resource::Catalog.new(Puppet[:node_name_value], Puppet::Node::Environment.remote('banana')) }
937
907
 
938
- allow(catalog).to receive(:to_ral).and_return(ral_catalog)
908
+ before :each do
909
+ apple.add_resource(resource)
910
+ banana.add_resource(resource)
939
911
  end
940
912
 
941
- let (:catalog) { Puppet::Resource::Catalog.new('tester', Puppet::Node::Environment.remote(Puppet[:environment].to_sym)) }
942
- let (:ral_catalog) { Puppet::Resource::Catalog.new('tester', Puppet::Node::Environment.remote(Puppet[:environment].to_sym)) }
913
+ it "converges after multiple attempts" do
914
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(apple, banana, banana)
915
+
916
+ allow(Puppet).to receive(:notice)
917
+ expect(Puppet).to receive(:notice).with("Local environment: 'production' doesn't match server specified environment 'apple', restarting agent run with environment 'apple'")
918
+ expect(Puppet).to receive(:notice).with("Local environment: 'apple' doesn't match server specified environment 'banana', restarting agent run with environment 'banana'")
943
919
 
944
- it "should convert the catalog to a RAL-formed catalog" do
945
- expect(@agent.convert_catalog(catalog, 10)).to equal(ral_catalog)
920
+ configurer.run
946
921
  end
947
922
 
948
- it "should finalize the catalog" do
949
- expect(ral_catalog).to receive(:finalize)
923
+ it "raises if it can't converge after 4 tries after the initial catalog request" do
924
+ expect(Puppet::Resource::Catalog.indirection).to receive(:find).and_return(apple, banana, apple, banana, apple)
950
925
 
951
- @agent.convert_catalog(catalog, 10)
926
+ configurer.run
927
+
928
+ expect(@logs).to include(an_object_having_attributes(level: :err, message: "Failed to apply catalog: Catalog environment didn't stabilize after 4 fetches, aborting run"))
952
929
  end
930
+ end
953
931
 
954
- it "should record the passed retrieval time with the RAL catalog" do
955
- expect(ral_catalog).to receive(:retrieval_duration=).with(10)
932
+ describe "when converting the catalog" do
933
+ it "converts Puppet::Resource into Puppet::Type::Notify" do
934
+ expect(configurer).to receive(:apply_catalog) do |ral, _|
935
+ expect(ral.resources).to contain(an_instance_of(Puppet::Type::Notify))
936
+ end
956
937
 
957
- @agent.convert_catalog(catalog, 10)
938
+ configurer.run(catalog: catalog)
958
939
  end
959
940
 
960
- it "should write the RAL catalog's class file" do
961
- expect(ral_catalog).to receive(:write_class_file)
941
+ it "adds default schedules" do
942
+ expect(configurer).to receive(:apply_catalog) do |ral, _|
943
+ expect(ral.resources.map(&:to_ref)).to contain(%w{Schedule[puppet] Schedule[hourly] Schedule[daily] Schedule[weekly] Schedule[monthly] Schedule[never]})
944
+ end
945
+
946
+ configurer.run
947
+ end
948
+
949
+ it "records the retrieval duration to the catalog" do
950
+ expect(configurer).to receive(:apply_catalog) do |ral, _|
951
+ expect(ral.retrieval_duration).to be_an_instance_of(Float)
952
+ end
962
953
 
963
- @agent.convert_catalog(catalog, 10)
954
+ configurer.run
964
955
  end
965
956
 
966
- it "should write the RAL catalog's resource file" do
967
- expect(ral_catalog).to receive(:write_resource_file)
957
+ it "writes the class file containing applied settings classes" do
958
+ expect(File).to_not be_exist(Puppet[:classfile])
959
+
960
+ configurer.run
968
961
 
969
- @agent.convert_catalog(catalog, 10)
962
+ expect(File.read(Puppet[:classfile]).chomp).to eq('settings')
970
963
  end
971
964
 
972
- it "should set catalog conversion time on the report" do
973
- report = Puppet::Transaction::Report.new
965
+ it "writes an empty resource file since no resources are 'managed'" do
966
+ expect(File).to_not be_exist(Puppet[:resourcefile])
974
967
 
975
- expect(report).to receive(:add_times).with(:convert_catalog, kind_of(Numeric))
976
- @agent.convert_catalog(catalog, 10, {:report => report})
968
+ configurer.run
969
+
970
+ expect(File.read(Puppet[:resourcefile]).chomp).to eq("")
971
+ end
972
+
973
+ it "adds the conversion time to the report" do
974
+ configurer.run(report: report)
975
+
976
+ expect(report.metrics['time']['convert_catalog']).to be_an_instance_of(Float)
977
977
  end
978
978
  end
979
979
 
@@ -994,66 +994,62 @@ describe Puppet::Configurer do
994
994
  describe "when attempting failover" do
995
995
  it "should not failover if server_list is not set" do
996
996
  Puppet.settings[:server_list] = []
997
- expect(@agent).not_to receive(:find_functional_server)
998
- @agent.run
997
+ configurer.run
999
998
  end
1000
999
 
1001
1000
  it "should not failover during an apply run" do
1002
1001
  Puppet.settings[:server_list] = ["myserver:123"]
1003
- expect(@agent).not_to receive(:find_functional_server)
1004
1002
  catalog = Puppet::Resource::Catalog.new("tester", Puppet::Node::Environment.remote(Puppet[:environment].to_sym))
1005
- @agent.run :catalog => catalog
1003
+ configurer.run(catalog: catalog)
1006
1004
  end
1007
1005
 
1008
1006
  it "should select a server when it receives 200 OK response" do
1009
1007
  Puppet.settings[:server_list] = ["myserver:123"]
1010
- response = Net::HTTPOK.new(nil, 200, 'OK')
1011
- allow(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(double('request', get: response))
1012
- allow(@agent).to receive(:run_internal)
1008
+
1009
+ stub_request(:get, 'https://myserver:123/status/v1/simple/master').to_return(status: 200)
1013
1010
 
1014
1011
  options = {}
1015
- @agent.run(options)
1012
+ configurer.run(options)
1016
1013
  expect(options[:report].master_used).to eq('myserver:123')
1017
1014
  end
1018
1015
 
1019
- it "queries the simple status for the 'master' service" do
1020
- Puppet.settings[:server_list] = ["myserver:123"]
1021
- response = Net::HTTPOK.new(nil, 200, 'OK')
1022
- http = double('request')
1023
- expect(http).to receive(:get).with('/status/v1/simple/master').and_return(response)
1024
- allow(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(http)
1025
- allow(@agent).to receive(:run_internal)
1026
-
1027
- @agent.run
1028
- end
1029
-
1030
1016
  it "should report when a server is unavailable" do
1031
1017
  Puppet.settings[:server_list] = ["myserver:123"]
1032
- response = Net::HTTPInternalServerError.new(nil, 500, 'Internal Server Error')
1033
- allow(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(double('request', get: response))
1034
1018
 
1019
+ stub_request(:get, 'https://myserver:123/status/v1/simple/master').to_return(status: [500, "Internal Server Error"])
1020
+
1021
+ allow(Puppet).to receive(:debug)
1035
1022
  expect(Puppet).to receive(:debug).with("Puppet server myserver:123 is unavailable: 500 Internal Server Error")
1036
- expect{ @agent.run }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list/)
1023
+
1024
+ expect {
1025
+ configurer.run
1026
+ }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list:/)
1037
1027
  end
1038
1028
 
1039
1029
  it "should error when no servers in 'server_list' are reachable" do
1040
- Puppet.settings[:server_list] = ["myserver:123"]
1041
- error = Net::HTTPError.new(400, 'dummy server communication error')
1042
- allow(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(double('request', get: error))
1030
+ Puppet.settings[:server_list] = "myserver:123,someotherservername"
1043
1031
 
1044
- options = {}
1045
- expect{ @agent.run(options) }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list/)
1046
- expect(options[:report].master_used).to be_nil
1032
+ stub_request(:get, 'https://myserver:123/status/v1/simple/master').to_return(status: 400)
1033
+ stub_request(:get, 'https://someotherservername:8140/status/v1/simple/master').to_return(status: 400)
1034
+
1035
+ expect{
1036
+ configurer.run
1037
+ }.to raise_error(Puppet::Error, /Could not select a functional puppet master from server_list: 'myserver:123,someotherservername'/)
1047
1038
  end
1048
1039
 
1049
1040
  it "should not make multiple node requests when the server is found" do
1050
1041
  Puppet.settings[:server_list] = ["myserver:123"]
1051
- response = Net::HTTPOK.new(nil, 200, 'OK')
1052
1042
 
1053
- expect(Puppet::Network::HttpPool).to receive(:connection).with('myserver', 123, anything).and_return(double('request', get: response))
1054
- allow(@agent).to receive(:run_internal)
1043
+ Puppet::Node.indirection.terminus_class = :rest
1044
+ Puppet::Resource::Catalog.indirection.terminus_class = :rest
1045
+
1046
+ stub_request(:get, 'https://myserver:123/status/v1/simple/master').to_return(status: 200)
1047
+ stub_request(:get, %r{https://myserver:123/puppet/v3/catalog}).to_return(status: 200)
1048
+ node_request = stub_request(:get, %r{https://myserver:123/puppet/v3/node/}).to_return(status: 200)
1049
+
1050
+ configurer.run
1055
1051
 
1056
- @agent.run
1052
+ expect(node_request).to have_been_requested.once
1057
1053
  end
1058
1054
  end
1059
1055
  end