puppet 6.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (259) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +20 -20
  4. data/Guardfile.example +76 -0
  5. data/LICENSE +189 -4
  6. data/README.md +3 -3
  7. data/Rakefile +5 -2
  8. data/ext/solaris/smf/svc-puppetd +8 -1
  9. data/ext/solaris/smf/svc-puppetmasterd +8 -1
  10. data/lib/puppet/application/apply.rb +100 -59
  11. data/lib/puppet/application/cert.rb +4 -114
  12. data/lib/puppet/application/device.rb +48 -32
  13. data/lib/puppet/application/script.rb +1 -1
  14. data/lib/puppet/application/ssl.rb +135 -51
  15. data/lib/puppet/application.rb +5 -0
  16. data/lib/puppet/configurer.rb +2 -3
  17. data/lib/puppet/defaults.rb +33 -49
  18. data/lib/puppet/etc.rb +20 -0
  19. data/lib/puppet/face/config.rb +3 -3
  20. data/lib/puppet/face/key.rb +1 -1
  21. data/lib/puppet/face/node/clean.rb +0 -1
  22. data/lib/puppet/feature/base.rb +1 -1
  23. data/lib/puppet/file_bucket/dipper.rb +1 -1
  24. data/lib/puppet/file_serving/fileset.rb +1 -1
  25. data/lib/puppet/functions/abs.rb +1 -1
  26. data/lib/puppet/functions/new.rb +1 -1
  27. data/lib/puppet/module/task.rb +29 -38
  28. data/lib/puppet/pal/catalog_compiler.rb +96 -0
  29. data/lib/puppet/pal/compiler.rb +221 -0
  30. data/lib/puppet/pal/function_signature.rb +52 -0
  31. data/lib/puppet/pal/json_catalog_encoder.rb +67 -0
  32. data/lib/puppet/pal/pal_api.rb +15 -0
  33. data/lib/puppet/pal/pal_impl.rb +523 -0
  34. data/lib/puppet/pal/plan_signature.rb +71 -0
  35. data/lib/puppet/pal/script_compiler.rb +71 -0
  36. data/lib/puppet/pal/task_signature.rb +58 -0
  37. data/lib/puppet/parser/catalog_compiler.rb +24 -0
  38. data/lib/puppet/parser/compiler.rb +3 -1
  39. data/lib/puppet/parser/functions/generate.rb +7 -6
  40. data/lib/puppet/plugins/configuration.rb +5 -1
  41. data/lib/puppet/pops/evaluator/collectors/abstract_collector.rb +3 -1
  42. data/lib/puppet/pops/evaluator/deferred_resolver.rb +3 -0
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +5 -1
  44. data/lib/puppet/pops/evaluator/external_syntax_support.rb +3 -3
  45. data/lib/puppet/pops/evaluator/runtime3_converter.rb +2 -2
  46. data/lib/puppet/pops/loader/ruby_legacy_function_instantiator.rb +19 -10
  47. data/lib/puppet/pops/loader/task_instantiator.rb +13 -70
  48. data/lib/puppet/pops/parser/heredoc_support.rb +1 -2
  49. data/lib/puppet/pops/parser/lexer2.rb +1 -1
  50. data/lib/puppet/pops/pcore.rb +10 -33
  51. data/lib/puppet/pops/serialization/to_data_converter.rb +9 -1
  52. data/lib/puppet/pops/serialization.rb +1 -0
  53. data/lib/puppet/pops/types/p_timespan_type.rb +2 -2
  54. data/lib/puppet/pops/types/string_converter.rb +18 -4
  55. data/lib/puppet/pops/validation/checker4_0.rb +17 -2
  56. data/lib/puppet/provider/exec.rb +59 -57
  57. data/lib/puppet/provider/group/aix.rb +18 -2
  58. data/lib/puppet/provider/group/windows_adsi.rb +7 -3
  59. data/lib/puppet/provider/nameservice.rb +1 -25
  60. data/lib/puppet/provider/package/dnf.rb +2 -0
  61. data/lib/puppet/provider/package/pkgng.rb +37 -21
  62. data/lib/puppet/provider/package/portage.rb +2 -2
  63. data/lib/puppet/provider/package/windows/exe_package.rb +16 -10
  64. data/lib/puppet/provider/package/windows/msi_package.rb +8 -0
  65. data/lib/puppet/provider/package/windows/package.rb +9 -1
  66. data/lib/puppet/provider/package/windows.rb +2 -2
  67. data/lib/puppet/provider/package/yum.rb +1 -1
  68. data/lib/puppet/provider/parsedfile.rb +25 -4
  69. data/lib/puppet/provider/service/launchd.rb +19 -3
  70. data/lib/puppet/provider/service/smf.rb +54 -0
  71. data/lib/puppet/provider/service/systemd.rb +19 -0
  72. data/lib/puppet/provider/service/upstart.rb +1 -0
  73. data/lib/puppet/provider/service/windows.rb +22 -5
  74. data/lib/puppet/provider/user/aix.rb +48 -2
  75. data/lib/puppet/provider/user/useradd.rb +2 -10
  76. data/lib/puppet/provider/user/windows_adsi.rb +9 -1
  77. data/lib/puppet/resource/catalog.rb +1 -5
  78. data/lib/puppet/resource.rb +3 -1
  79. data/lib/puppet/ssl/host.rb +26 -16
  80. data/lib/puppet/syntax_checkers/epp.rb +34 -0
  81. data/lib/puppet/syntax_checkers/pp.rb +34 -0
  82. data/lib/puppet/transaction/event_manager.rb +13 -1
  83. data/lib/puppet/transaction/persistence.rb +1 -1
  84. data/lib/puppet/transaction/resource_harness.rb +3 -1
  85. data/lib/puppet/type/group.rb +29 -1
  86. data/lib/puppet/type/package.rb +5 -1
  87. data/lib/puppet/type/resources.rb +12 -2
  88. data/lib/puppet/type/schedule.rb +7 -0
  89. data/lib/puppet/type/service.rb +12 -0
  90. data/lib/puppet/type/user.rb +5 -2
  91. data/lib/puppet/type.rb +6 -0
  92. data/lib/puppet/util/command_line.rb +2 -3
  93. data/lib/puppet/util/execution.rb +15 -1
  94. data/lib/puppet/util/filetype.rb +56 -8
  95. data/lib/puppet/util/log/destinations.rb +3 -2
  96. data/lib/puppet/util/logging.rb +3 -2
  97. data/lib/puppet/util/posix.rb +15 -0
  98. data/lib/puppet/util/selinux.rb +1 -1
  99. data/lib/puppet/util/storage.rb +12 -0
  100. data/lib/puppet/util/windows/adsi.rb +79 -2
  101. data/lib/puppet/util/windows/api_types.rb +1 -1
  102. data/lib/puppet/util/windows/process.rb +23 -3
  103. data/lib/puppet/util/windows/registry.rb +29 -5
  104. data/lib/puppet/util/windows/security.rb +14 -0
  105. data/lib/puppet/util/windows/service.rb +294 -74
  106. data/lib/puppet/util/windows/user.rb +3 -5
  107. data/lib/puppet/util.rb +7 -3
  108. data/lib/puppet/version.rb +1 -1
  109. data/lib/puppet.rb +1 -0
  110. data/lib/puppet_pal.rb +5 -1099
  111. data/locales/ja/puppet.po +952 -986
  112. data/locales/puppet.pot +592 -347
  113. data/man/man5/puppet.conf.5 +26 -31
  114. data/man/man8/puppet-agent.8 +1 -1
  115. data/man/man8/puppet-apply.8 +1 -1
  116. data/man/man8/puppet-catalog.8 +1 -1
  117. data/man/man8/puppet-config.8 +4 -4
  118. data/man/man8/puppet-describe.8 +1 -1
  119. data/man/man8/puppet-device.8 +23 -19
  120. data/man/man8/puppet-doc.8 +1 -1
  121. data/man/man8/puppet-epp.8 +1 -1
  122. data/man/man8/puppet-facts.8 +1 -1
  123. data/man/man8/puppet-filebucket.8 +1 -1
  124. data/man/man8/puppet-generate.8 +1 -1
  125. data/man/man8/puppet-help.8 +1 -1
  126. data/man/man8/puppet-key.8 +2 -2
  127. data/man/man8/puppet-lookup.8 +1 -1
  128. data/man/man8/puppet-man.8 +1 -1
  129. data/man/man8/puppet-module.8 +1 -1
  130. data/man/man8/puppet-node.8 +1 -1
  131. data/man/man8/puppet-parser.8 +1 -1
  132. data/man/man8/puppet-plugin.8 +1 -1
  133. data/man/man8/puppet-report.8 +1 -1
  134. data/man/man8/puppet-resource.8 +1 -1
  135. data/man/man8/puppet-script.8 +1 -1
  136. data/man/man8/puppet-ssl.8 +26 -3
  137. data/man/man8/puppet-status.8 +1 -1
  138. data/man/man8/puppet.8 +2 -2
  139. data/spec/fixtures/unit/pops/loaders/loaders/mix_4x_and_3x_functions/usee/lib/puppet/parser/functions/bad_func_load.rb +11 -0
  140. data/spec/fixtures/unit/provider/package/pkgng/pkg.query +7 -1
  141. data/spec/fixtures/unit/provider/package/pkgng/pkg.query.zsh +1 -0
  142. data/spec/fixtures/unit/provider/service/smf/svcs_fmri.out +6 -0
  143. data/spec/fixtures/unit/provider/service/smf/svcs_multiple_fmris.out +13 -0
  144. data/spec/integration/application/apply_spec.rb +4 -1
  145. data/spec/integration/parser/collection_spec.rb +4 -8
  146. data/spec/integration/provider/service/windows_spec.rb +5 -5
  147. data/spec/integration/ssl/key_spec.rb +0 -4
  148. data/spec/integration/transaction_spec.rb +559 -0
  149. data/spec/integration/type/file_spec.rb +6 -6
  150. data/spec/integration/util/windows/registry_spec.rb +39 -0
  151. data/spec/integration/util/windows/security_spec.rb +10 -7
  152. data/spec/integration/util/windows/user_spec.rb +37 -17
  153. data/spec/lib/puppet/test_ca.rb +1 -1
  154. data/spec/spec_helper.rb +1 -1
  155. data/spec/unit/agent_spec.rb +2 -2
  156. data/spec/unit/application/apply_spec.rb +55 -2
  157. data/spec/unit/application/device_spec.rb +10 -7
  158. data/spec/unit/application/face_base_spec.rb +1 -1
  159. data/spec/unit/application/lookup_spec.rb +2 -1
  160. data/spec/unit/application/ssl_spec.rb +178 -109
  161. data/spec/unit/application_spec.rb +29 -11
  162. data/spec/unit/configurer/downloader_spec.rb +1 -1
  163. data/spec/unit/configurer_spec.rb +16 -5
  164. data/spec/unit/etc_spec.rb +25 -0
  165. data/spec/unit/face/node_spec.rb +1 -3
  166. data/spec/unit/face/parser_spec.rb +15 -0
  167. data/spec/unit/file_serving/fileset_spec.rb +11 -11
  168. data/spec/unit/functions/logging_spec.rb +10 -3
  169. data/spec/unit/indirector/catalog/json_spec.rb +9 -3
  170. data/spec/unit/indirector/yaml_spec.rb +1 -1
  171. data/spec/unit/network/http/connection_spec.rb +2 -2
  172. data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +36 -0
  173. data/spec/unit/pops/evaluator/runtime3_converter_spec.rb +22 -4
  174. data/spec/unit/pops/loaders/loader_spec.rb +9 -17
  175. data/spec/unit/pops/loaders/loaders_spec.rb +48 -0
  176. data/spec/unit/pops/loaders/module_loaders_spec.rb +7 -7
  177. data/spec/unit/pops/parser/parse_heredoc_spec.rb +16 -0
  178. data/spec/unit/pops/serialization/to_from_hr_spec.rb +9 -0
  179. data/spec/unit/pops/types/p_timespan_type_spec.rb +22 -0
  180. data/spec/unit/pops/types/p_timestamp_type_spec.rb +19 -0
  181. data/spec/unit/pops/types/string_converter_spec.rb +25 -1
  182. data/spec/unit/pops/types/task_spec.rb +42 -116
  183. data/spec/unit/pops/validator/validator_spec.rb +24 -10
  184. data/spec/unit/provider/exec/posix_spec.rb +24 -0
  185. data/spec/unit/provider/group/aix_spec.rb +20 -6
  186. data/spec/unit/provider/group/ldap_spec.rb +22 -25
  187. data/spec/unit/provider/group/pw_spec.rb +7 -10
  188. data/spec/unit/provider/group/windows_adsi_spec.rb +42 -33
  189. data/spec/unit/provider/nameservice/directoryservice_spec.rb +97 -103
  190. data/spec/unit/provider/package/aix_spec.rb +5 -8
  191. data/spec/unit/provider/package/apt_spec.rb +3 -6
  192. data/spec/unit/provider/package/dnf_spec.rb +38 -25
  193. data/spec/unit/provider/package/dpkg_spec.rb +18 -21
  194. data/spec/unit/provider/package/freebsd_spec.rb +4 -7
  195. data/spec/unit/provider/package/gem_spec.rb +41 -41
  196. data/spec/unit/provider/package/hpux_spec.rb +7 -10
  197. data/spec/unit/provider/package/macports_spec.rb +13 -15
  198. data/spec/unit/provider/package/nim_spec.rb +3 -10
  199. data/spec/unit/provider/package/openbsd_spec.rb +14 -17
  200. data/spec/unit/provider/package/pip3_spec.rb +3 -6
  201. data/spec/unit/provider/package/pip_spec.rb +45 -49
  202. data/spec/unit/provider/package/pkgin_spec.rb +13 -18
  203. data/spec/unit/provider/package/pkgng_spec.rb +32 -27
  204. data/spec/unit/provider/package/puppet_gem_spec.rb +6 -9
  205. data/spec/unit/provider/package/tdnf_spec.rb +9 -12
  206. data/spec/unit/provider/package/windows/exe_package_spec.rb +3 -3
  207. data/spec/unit/provider/package/windows_spec.rb +4 -4
  208. data/spec/unit/provider/package/yum_spec.rb +30 -16
  209. data/spec/unit/provider/package/zypper_spec.rb +17 -19
  210. data/spec/unit/provider/service/bsd_spec.rb +7 -9
  211. data/spec/unit/provider/service/daemontools_spec.rb +12 -16
  212. data/spec/unit/provider/service/debian_spec.rb +6 -10
  213. data/spec/unit/provider/service/freebsd_spec.rb +2 -2
  214. data/spec/unit/provider/service/launchd_spec.rb +19 -0
  215. data/spec/unit/provider/service/openbsd_spec.rb +13 -17
  216. data/spec/unit/provider/service/rcng_spec.rb +2 -4
  217. data/spec/unit/provider/service/redhat_spec.rb +12 -11
  218. data/spec/unit/provider/service/runit_spec.rb +7 -14
  219. data/spec/unit/provider/service/smf_spec.rb +77 -13
  220. data/spec/unit/provider/service/src_spec.rb +11 -16
  221. data/spec/unit/provider/service/systemd_spec.rb +39 -1
  222. data/spec/unit/provider/service/windows_spec.rb +39 -7
  223. data/spec/unit/provider/user/aix_spec.rb +43 -2
  224. data/spec/unit/provider/user/hpux_spec.rb +3 -5
  225. data/spec/unit/provider/user/ldap_spec.rb +29 -32
  226. data/spec/unit/provider/user/pw_spec.rb +10 -13
  227. data/spec/unit/provider/user/useradd_spec.rb +2 -2
  228. data/spec/unit/provider/user/windows_adsi_spec.rb +4 -4
  229. data/spec/unit/puppet_pal_2pec.rb +6 -6
  230. data/spec/unit/puppet_pal_catalog_spec.rb +58 -0
  231. data/spec/unit/resource/catalog_spec.rb +2 -2
  232. data/spec/unit/resource_spec.rb +31 -0
  233. data/spec/unit/ssl/host_spec.rb +22 -1
  234. data/spec/unit/ssl/key_spec.rb +2 -4
  235. data/spec/unit/task_spec.rb +50 -5
  236. data/spec/unit/transaction/event_manager_spec.rb +12 -1
  237. data/spec/unit/transaction/persistence_spec.rb +4 -4
  238. data/spec/unit/transaction/resource_harness_spec.rb +18 -0
  239. data/spec/unit/type/group_spec.rb +11 -3
  240. data/spec/unit/type/resources_spec.rb +18 -0
  241. data/spec/unit/type/service_spec.rb +27 -1
  242. data/spec/unit/util/execution_spec.rb +77 -0
  243. data/spec/unit/util/filetype_spec.rb +13 -5
  244. data/spec/unit/util/log/destinations_spec.rb +10 -0
  245. data/spec/unit/util/logging_spec.rb +58 -41
  246. data/spec/unit/util/monkey_patches_spec.rb +18 -5
  247. data/spec/unit/util/posix_spec.rb +28 -0
  248. data/spec/unit/util/selinux_spec.rb +4 -0
  249. data/spec/unit/util/storage_spec.rb +107 -0
  250. data/spec/unit/util/suidmanager_spec.rb +1 -3
  251. data/spec/unit/util/windows/adsi_spec.rb +95 -0
  252. data/spec/unit/util/windows/service_spec.rb +377 -131
  253. metadata +24 -11
  254. data/ext/autotest/Rakefile +0 -8
  255. data/ext/autotest/config +0 -43
  256. data/ext/autotest/readme.rst +0 -16
  257. data/spec/fixtures/unit/provider/package/pkgng/pkg.info +0 -7
  258. data/spec/fixtures/unit/provider/package/pkgng/pkg.query_absent +0 -1
  259. data/spec/watchr.rb +0 -137
@@ -2,88 +2,24 @@ require 'spec_helper'
2
2
  require 'puppet/application/ssl'
3
3
  require 'webmock/rspec'
4
4
  require 'openssl'
5
+ require 'puppet/test_ca'
5
6
 
6
7
  describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
7
- let(:ssl) { Puppet::Application[:ssl] }
8
- let(:name) { 'ssl-client' }
9
-
10
- def generate_cert(name, issuer = nil, issuer_key = nil)
11
- # generate CA key pair
12
- private_key = OpenSSL::PKey::RSA.new(512)
13
- public_key = private_key.public_key
14
-
15
- # generate CSR
16
- csr = OpenSSL::X509::Request.new
17
- csr.version = 0
18
- csr.subject = OpenSSL::X509::Name.new([["CN", name]])
19
- csr.public_key = public_key
20
- csr.sign(private_key, OpenSSL::Digest::SHA256.new)
21
-
22
- # is it self-signed?
23
- issuer ||= csr.subject
24
- issuer_key ||= private_key
25
-
26
- # issue cert
27
- cert = OpenSSL::X509::Certificate.new
28
- cert.version = 2 # X509v3
29
- cert.subject = csr.subject
30
- cert.issuer = issuer
31
- cert.public_key = csr.public_key
32
- cert.serial = 1
33
- cert.not_before = Time.now - (60*60*24)
34
- cert.not_after = Time.now + (60*60*24)
35
-
36
- # Ugly hack, but we need to make sure the CA cert has the proper
37
- # X509v3 Basic Constraints to be a valid CA certificate.
38
- if name == 'ca'
39
- extension_factory = OpenSSL::X509::ExtensionFactory.new
40
- extension_factory.subject_certificate = cert
41
- extension_factory.issuer_certificate = cert
42
-
43
- extensions = {
44
- "keyUsage" => [%w{cRLSign keyCertSign}, true],
45
- "basicConstraints" => ["CA:TRUE", true],
46
- }
47
-
48
- cert.extensions = extensions.map do |oid, (val, crit)|
49
- val = val.join(', ') unless val.is_a? String
50
-
51
- if Puppet::SSL::Oids.subtree_of?('id-ce', oid) or Puppet::SSL::Oids.subtree_of?('id-pkix', oid)
52
- # Attempt to create a X509v3 certificate extension. Standard certificate
53
- # extensions may need access to the associated subject certificate and
54
- # issuing certificate, so must be created by the OpenSSL::X509::ExtensionFactory
55
- # which provides that context.
56
- extension_factory.create_ext(oid, val, crit)
57
- else
58
- # This is not an X509v3 extension which means that the extension
59
- # factory cannot generate it. We need to generate the extension
60
- # manually.
61
- OpenSSL::X509::Extension.new(oid, OpenSSL::ASN1::UTF8String.new(val).to_der, crit)
62
- end
63
- end
64
- end
65
-
66
- cert.sign(issuer_key, OpenSSL::Digest::SHA256.new)
8
+ include PuppetSpec::Files
67
9
 
68
- {:private_key => private_key, :csr => csr, :cert => cert}
69
- end
70
-
71
- def generate_crl(name, issuer, issuer_key)
72
- crl = OpenSSL::X509::CRL.new
73
- crl.version = 1
74
- crl.issuer = issuer
75
- crl.last_update = Time.now - (60*60*24)
76
- crl.next_update = Time.now + (60*60*24)
77
- crl.extensions = [OpenSSL::X509::Extension.new('crlNumber', OpenSSL::ASN1::Integer(0))]
78
- crl.sign(issuer_key, OpenSSL::Digest::SHA256.new)
79
-
80
- crl
10
+ let(:ssl) do
11
+ app = Puppet::Application[:ssl]
12
+ app.options[:verbose] = true
13
+ app.setup_logs
14
+ app
81
15
  end
16
+ let(:name) { 'ssl-client' }
82
17
 
83
18
  before :all do
84
- @ca = generate_cert('ca')
85
- @crl = generate_crl('ca', @ca[:cert].subject, @ca[:private_key])
86
- @host = generate_cert('ssl-client', @ca[:cert].subject, @ca[:private_key])
19
+ @ca = Puppet::TestCa.new
20
+ @ca_cert = @ca.ca_cert
21
+ @crl = @ca.ca_crl
22
+ @host = @ca.generate('ssl-client', {})
87
23
  end
88
24
 
89
25
  before do
@@ -91,9 +27,10 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
91
27
 
92
28
  Puppet.settings.use(:main)
93
29
  Puppet[:certname] = name
30
+ Puppet[:vardir] = tmpdir("ssl_testing")
94
31
 
95
32
  # Host assumes ca cert and crl are present
96
- File.open(Puppet[:localcacert], 'w') { |f| f.write(@ca[:cert].to_pem) }
33
+ File.open(Puppet[:localcacert], 'w') { |f| f.write(@ca_cert.to_pem) }
97
34
  File.open(Puppet[:hostcrl], 'w') { |f| f.write(@crl.to_pem) }
98
35
 
99
36
  # Setup our ssl client
@@ -101,25 +38,31 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
101
38
  File.open(Puppet[:hostpubkey], 'w') { |f| f.write(@host[:private_key].public_key.to_pem) }
102
39
  end
103
40
 
104
- def expects_command_to_output(expected_message = nil, code = 0)
41
+ def expects_command_to_pass(expected_output = nil)
42
+ expect {
43
+ ssl.run_command
44
+ }.to have_printed(expected_output)
45
+ end
46
+
47
+ def expects_command_to_fail(message)
105
48
  expect {
106
49
  expect {
107
50
  ssl.run_command
108
- }.to exit_with(code)
109
- }.to output(expected_message).to_stdout
51
+ }.to raise_error(Puppet::Error, message)
52
+ }.to have_printed(/.*/) # ignore output
110
53
  end
111
54
 
112
55
  shared_examples_for 'an ssl action' do
113
56
  it 'downloads the CA bundle first when missing' do
114
57
  File.delete(Puppet[:localcacert])
115
- stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: @ca[:cert].to_pem)
58
+ stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: @ca.ca_cert.to_pem)
116
59
  stub_request(:get, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 404)
117
60
  stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
118
- stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
61
+ stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 200, body: @host[:cert].to_pem)
119
62
 
120
- expects_command_to_output
63
+ expects_command_to_pass
121
64
 
122
- expect(File.read(Puppet[:localcacert])).to eq(@ca[:cert].to_pem)
65
+ expect(File.read(Puppet[:localcacert])).to eq(@ca.ca_cert.to_pem)
123
66
  end
124
67
 
125
68
  it 'downloads the CRL bundle first when missing' do
@@ -127,23 +70,29 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
127
70
  stub_request(:get, %r{puppet-ca/v1/certificate_revocation_list/ca}).to_return(status: 200, body: @crl.to_pem)
128
71
  stub_request(:get, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 404)
129
72
  stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
130
- stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
73
+ stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 200, body: @host[:cert].to_pem)
131
74
 
132
- expects_command_to_output
75
+ expects_command_to_pass
133
76
 
134
77
  expect(File.read(Puppet[:hostcrl])).to eq(@crl.to_pem)
135
78
  end
136
79
  end
137
80
 
81
+ it 'uses the agent run mode' do
82
+ # make sure the ssl app resolves certname, server, etc
83
+ # the same way the agent application does
84
+ expect(ssl.class.run_mode.name).to eq(:agent)
85
+ end
86
+
138
87
  context 'when generating help' do
139
- it 'prints usage when no arguments are specified' do
88
+ it 'prints a message when an unknown action is specified' do
140
89
  ssl.command_line.args << 'whoops'
141
90
 
142
- expects_command_to_output(/Unknown action 'whoops'/, 1)
91
+ expects_command_to_fail(/Unknown action 'whoops'/)
143
92
  end
144
93
 
145
- it 'rejects unknown actions' do
146
- expects_command_to_output(/^puppet-ssl.*SYNOPSIS/m, 1)
94
+ it 'prints a message requiring an action to be specified' do
95
+ expects_command_to_fail(/An action must be specified/)
147
96
  end
148
97
  end
149
98
 
@@ -161,7 +110,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
161
110
  stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
162
111
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
163
112
 
164
- expects_command_to_output(%r{Submitted certificate request for '#{name}' to https://.*}, 0)
113
+ expects_command_to_pass(%r{Submitted certificate request for '#{name}' to https://.*})
165
114
 
166
115
  expect(Puppet::FileSystem).to be_exist(csr_path)
167
116
  end
@@ -171,13 +120,13 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
171
120
  stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
172
121
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
173
122
 
174
- expects_command_to_output(%r{Submitted certificate request for '#{name}' to https://.*}, 0)
123
+ expects_command_to_pass(%r{Submitted certificate request for '#{name}' to https://.*})
175
124
 
176
125
  stub_request(:get, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200, body: @host[:csr].to_pem)
177
126
  # we skip :put
178
127
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
179
128
 
180
- expects_command_to_output
129
+ expects_command_to_pass
181
130
  end
182
131
 
183
132
  it "warns if the local CSR doesn't match the local public key, and submits a new CSR" do
@@ -199,7 +148,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
199
148
 
200
149
  Puppet.stubs(:warning) # ignore unrelated warnings
201
150
  Puppet.expects(:warning).with("The local CSR does not match the agent's public key. Generating a new CSR.")
202
- expects_command_to_output(%r{Submitted certificate request for '#{name}' to https://.*}, 0)
151
+ expects_command_to_pass(%r{Submitted certificate request for '#{name}' to https://.*})
203
152
  end
204
153
 
205
154
  it 'downloads the certificate when autosigning is enabled' do
@@ -207,7 +156,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
207
156
  stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
208
157
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 200, body: @host[:cert].to_pem)
209
158
 
210
- expects_command_to_output(%r{Submitted certificate request for '#{name}' to https://.*}, 0)
159
+ expects_command_to_pass(%r{Submitted certificate request for '#{name}' to https://.*})
211
160
 
212
161
  expect(Puppet::FileSystem).to be_exist(Puppet[:hostcert])
213
162
  end
@@ -219,7 +168,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
219
168
  stub_request(:put, %r{puppet-ca/v1/certificate_request/#{name}}).to_return(status: 200)
220
169
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
221
170
 
222
- expects_command_to_output
171
+ expects_command_to_pass
223
172
 
224
173
  csr = Puppet::SSL::CertificateRequest.new(name)
225
174
  csr.read(csr_path)
@@ -237,7 +186,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
237
186
  it 'downloads a new cert' do
238
187
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 200, body: @host[:cert].to_pem)
239
188
 
240
- expects_command_to_output(%r{Downloaded certificate '#{name}' with fingerprint .*})
189
+ expects_command_to_pass(%r{Downloaded certificate '#{name}' with fingerprint .*})
241
190
 
242
191
  expect(File.read(Puppet[:hostcert])).to eq(@host[:cert].to_pem)
243
192
  end
@@ -247,7 +196,7 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
247
196
 
248
197
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 200, body: @host[:cert].to_pem)
249
198
 
250
- expects_command_to_output(%r{Downloaded certificate '#{name}' with fingerprint .*})
199
+ expects_command_to_pass(%r{Downloaded certificate '#{name}' with fingerprint .*})
251
200
 
252
201
  expect(File.read(Puppet[:hostcert])).to eq(@host[:cert].to_pem)
253
202
  end
@@ -262,13 +211,15 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
262
211
 
263
212
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 200, body: @host[:cert].to_pem)
264
213
 
265
- expects_command_to_output(%r{^Failed to download certificate: The certificate retrieved from the master does not match the agent's private key. Did you forget to run as root?}, 1)
214
+ expects_command_to_fail(
215
+ %r{^Failed to download certificate: The certificate retrieved from the master does not match the agent's private key. Did you forget to run as root?}
216
+ )
266
217
  end
267
218
 
268
219
  it "prints a message if there isn't a cert to download" do
269
220
  stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_return(status: 404)
270
221
 
271
- expects_command_to_output(/No certificate for '#{name}' on CA/)
222
+ expects_command_to_fail(/The certificate for '#{name}' has not yet been signed/)
272
223
  end
273
224
  end
274
225
 
@@ -282,13 +233,13 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
282
233
  it 'reports if the key is missing' do
283
234
  File.delete(Puppet[:hostprivkey])
284
235
 
285
- expects_command_to_output(/The host's private key is missing/, 1)
236
+ expects_command_to_fail(/The host's private key is missing/)
286
237
  end
287
238
 
288
239
  it 'reports if the cert is missing' do
289
240
  File.delete(Puppet[:hostcert])
290
241
 
291
- expects_command_to_output(/The host's certificate is missing/, 1)
242
+ expects_command_to_fail(/The host's certificate is missing/)
292
243
  end
293
244
 
294
245
  it 'reports if the key and cert are mismatched' do
@@ -298,25 +249,143 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
298
249
  File.open(Puppet[:hostprivkey], 'w') { |f| f.write(private_key.to_pem) }
299
250
  File.open(Puppet[:hostpubkey], 'w') { |f| f.write(public_key.to_pem) }
300
251
 
301
- expects_command_to_output(/The host's key does not match the certificate/, 1)
252
+ expects_command_to_fail(/The host's key does not match the certificate/)
302
253
  end
303
254
 
304
255
  it 'reports if the cert verification fails' do
305
256
  # generate a new CA to force an error
306
- ca = generate_cert('ca')
307
- File.open(Puppet[:localcacert], 'w') { |f| f.write(ca[:cert].to_pem) }
257
+ new_ca = Puppet::TestCa.new
258
+ File.open(Puppet[:localcacert], 'w') { |f| f.write(new_ca.ca_cert.to_pem) }
308
259
 
309
260
  # and CRL for that CA
310
- crl = generate_crl('ca', ca[:cert].subject, ca[:private_key])
311
- File.open(Puppet[:hostcrl], 'w') { |f| f.write(crl.to_pem) }
261
+ File.open(Puppet[:hostcrl], 'w') { |f| f.write(new_ca.ca_crl.to_pem) }
312
262
 
313
- expects_command_to_output(/Failed to verify certificate '#{name}': certificate signature failure \(7\)/, 1)
263
+ expects_command_to_fail(
264
+ /Failed to verify certificate '#{name}': certificate signature failure \(7\)/
265
+ )
314
266
  end
315
267
 
316
268
  it 'reports when verification succeeds' do
317
269
  OpenSSL::X509::Store.any_instance.stubs(:verify).returns(true)
318
270
 
319
- expects_command_to_output(/Verified certificate '#{name}'/, 0)
271
+ expects_command_to_pass(/Verified certificate '#{name}'/)
272
+ end
273
+ end
274
+
275
+ context 'when cleaning' do
276
+ before do
277
+ ssl.command_line.args << 'clean'
278
+ end
279
+
280
+ it 'deletes the hostcert' do
281
+ File.open(Puppet[:hostcert], 'w') { |f| f.write(@host[:cert].to_pem) }
282
+
283
+ expects_command_to_pass(%r{Removed certificate #{Puppet[:cert]}})
284
+ end
285
+
286
+ it 'deletes the private key' do
287
+ File.open(Puppet[:hostprivkey], 'w') { |f| f.write(@host[:private_key].to_pem) }
288
+
289
+ expects_command_to_pass(%r{Removed private key #{Puppet[:hostprivkey]}})
290
+ end
291
+
292
+ it 'deletes the public key' do
293
+ File.open(Puppet[:hostpubkey], 'w') { |f| f.write(@host[:private_key].public_key.to_pem) }
294
+
295
+ expects_command_to_pass(%r{Removed public key #{Puppet[:hostpubkey]}})
296
+ end
297
+
298
+ it 'deletes the request' do
299
+ path = File.join(Puppet[:requestdir], "#{Puppet[:certname]}.pem")
300
+ File.open(path, 'w') { |f| f.write(@host[:csr].to_pem) }
301
+
302
+ expects_command_to_pass(%r{Removed certificate request #{path}})
303
+ end
304
+
305
+ it 'deletes the passfile' do
306
+ File.open(Puppet[:passfile], 'w') { |_| }
307
+
308
+ expects_command_to_pass(%r{Removed private key password file #{Puppet[:passfile]}})
320
309
  end
310
+
311
+ it 'skips files that do not exist' do
312
+ File.delete(Puppet[:hostprivkey])
313
+
314
+ expect {
315
+ ssl.run_command
316
+ }.to_not output(%r{Removed private key #{Puppet[:hostprivkey]}}).to_stdout
317
+ end
318
+
319
+ it "raises if we fail to retrieve server's cert that we're about to clean" do
320
+ Puppet[:certname] = name
321
+ Puppet[:server] = name
322
+
323
+ stub_request(:get, %r{puppet-ca/v1/certificate/#{name}}).to_raise(Errno::ECONNREFUSED)
324
+
325
+ expects_command_to_fail(%r{Failed to connect to the CA to determine if certificate #{name} has been cleaned})
326
+ end
327
+
328
+ context 'when deleting local CA' do
329
+ before do
330
+ ssl.command_line.args << '--localca'
331
+ ssl.parse_options
332
+ end
333
+
334
+ it 'deletes the local CA cert' do
335
+ File.open(Puppet[:localcacert], 'w') { |f| f.write(@ca_cert.to_pem) }
336
+
337
+ expects_command_to_pass(%r{Removed local CA certificate #{Puppet[:localcacert]}})
338
+ end
339
+
340
+ it 'deletes the local CRL' do
341
+ File.open(Puppet[:hostcrl], 'w') { |f| f.write(@crl.to_pem) }
342
+
343
+ expects_command_to_pass(%r{Removed local CRL #{Puppet[:hostcrl]}})
344
+ end
345
+ end
346
+
347
+ context 'on the puppetserver host' do
348
+ before :each do
349
+ Puppet[:certname] = 'puppetserver'
350
+ Puppet[:server] = 'puppetserver'
351
+ end
352
+
353
+ it "prints an error when the CA is local and the CA has not cleaned its cert" do
354
+ stub_request(:get, %r{puppet-ca/v1/certificate/puppetserver}).to_return(status: 200, body: @host[:cert].to_pem)
355
+
356
+ expects_command_to_fail(%r{The certificate puppetserver must be cleaned from the CA first})
357
+ end
358
+
359
+ it "cleans the cert when the CA is local and the CA has already cleaned its cert" do
360
+ File.open(Puppet[:hostcert], 'w') { |f| f.write(@host[:cert].to_pem) }
361
+
362
+ stub_request(:get, %r{puppet-ca/v1/certificate/puppetserver}).to_return(status: 404)
363
+
364
+ expects_command_to_pass(%r{Removed certificate .*puppetserver.pem})
365
+ end
366
+
367
+ it "cleans the cert when run on a puppetserver that isn't the CA" do
368
+ File.open(Puppet[:hostcert], 'w') { |f| f.write(@host[:cert].to_pem) }
369
+
370
+ Puppet[:ca_server] = 'caserver'
371
+
372
+ expects_command_to_pass(%r{Removed certificate .*puppetserver.pem})
373
+ end
374
+ end
375
+
376
+ context 'when cleaning a device' do
377
+ before do
378
+ ssl.command_line.args = ['clean', '--target', 'device.example.com']
379
+ ssl.parse_options
380
+ end
381
+
382
+ it 'deletes the device certificate' do
383
+ device_cert_path = File.join(Puppet[:devicedir], 'device.example.com', 'ssl', 'certs')
384
+ device_cert_file = File.join(device_cert_path, 'device.example.com.pem')
385
+ FileUtils.mkdir_p(device_cert_path)
386
+ File.open(device_cert_file, 'w') { |f| f.write('device.example.com') }
387
+ expects_command_to_pass(%r{Removed certificate #{device_cert_file}})
388
+ end
389
+ end
321
390
  end
322
391
  end
@@ -33,7 +33,7 @@ describe Puppet::Application do
33
33
  describe "application defaults" do
34
34
  it "should fail if required app default values are missing" do
35
35
  @app.stubs(:app_defaults).returns({ :foo => 'bar' })
36
- Puppet.expects(:err).with(regexp_matches(/missing required app default setting/))
36
+ Puppet.expects(:send_log).with(:err, regexp_matches(/missing required app default setting/))
37
37
  expect {
38
38
  @app.run
39
39
  }.to exit_with(1)
@@ -55,10 +55,10 @@ describe Puppet::Application do
55
55
  end
56
56
 
57
57
  it "should error if it can't find a class" do
58
- Puppet.expects(:err).with do |value|
59
- value =~ /Unable to find application 'ThisShallNeverEverEverExist'/ and
60
- value =~ /puppet\/application\/thisshallneverevereverexist/ and
61
- value =~ /no such file to load|cannot load such file/
58
+ Puppet.expects(:send_log).with do |_level, message|
59
+ message =~ /Unable to find application 'ThisShallNeverEverEverExist'/ and
60
+ message =~ /puppet\/application\/thisshallneverevereverexist/ and
61
+ message =~ /no such file to load|cannot load such file/
62
62
  end
63
63
 
64
64
  expect {
@@ -422,7 +422,6 @@ describe Puppet::Application do
422
422
  end
423
423
 
424
424
  describe "when calling default setup" do
425
-
426
425
  before :each do
427
426
  @app.options.stubs(:[])
428
427
  end
@@ -443,6 +442,14 @@ describe Puppet::Application do
443
442
 
444
443
  @app.setup
445
444
  end
445
+
446
+ it "sets the log destination if provided via settings" do
447
+ @app.options.unstub(:[])
448
+ Puppet[:logdest] = "set_via_config"
449
+ Puppet::Util::Log.expects(:newdestination).with("set_via_config")
450
+
451
+ @app.setup
452
+ end
446
453
 
447
454
  it "does not downgrade the loglevel when --verbose is specified" do
448
455
  Puppet[:log_level] = :debug
@@ -553,19 +560,19 @@ describe Puppet::Application do
553
560
  end
554
561
 
555
562
  it "should warn and exit if no command can be called" do
556
- Puppet.expects(:err)
563
+ Puppet.expects(:send_log).with(:err, "Could not run: No valid command or main")
557
564
  expect { @app.run }.to exit_with 1
558
565
  end
559
566
 
560
567
  it "should raise an error if dispatch returns no command" do
561
568
  @app.stubs(:get_command).returns(nil)
562
- Puppet.expects(:err)
569
+ Puppet.expects(:send_log).with(:err, "Could not run: No valid command or main")
563
570
  expect { @app.run }.to exit_with 1
564
571
  end
565
572
 
566
573
  it "should raise an error if dispatch returns an invalid command" do
567
574
  @app.stubs(:get_command).returns(:this_function_doesnt_exist)
568
- Puppet.expects(:err)
575
+ Puppet.expects(:send_log).with(:err, "Could not run: No valid command or main")
569
576
  expect { @app.run }.to exit_with 1
570
577
  end
571
578
  end
@@ -652,7 +659,6 @@ describe Puppet::Application do
652
659
  end
653
660
 
654
661
  describe "#handle_logdest_arg" do
655
-
656
662
  let(:test_arg) { "arg_test_logdest" }
657
663
 
658
664
  it "should log an exception that is raised" do
@@ -672,6 +678,18 @@ describe Puppet::Application do
672
678
  @app.handle_logdest_arg(test_arg)
673
679
  expect(@app.options[:setdest]).to be_truthy
674
680
  end
675
- end
676
681
 
682
+ it "does not set the log destination if setdest is true" do
683
+ Puppet::Util::Log.expects(:newdestination).never
684
+ @app.options[:setdest] = true
685
+
686
+ @app.handle_logdest_arg(test_arg)
687
+ end
688
+
689
+ it "does not set the log destination if arg is nil" do
690
+ Puppet::Util::Log.expects(:newdestination).never
691
+
692
+ @app.handle_logdest_arg(nil)
693
+ end
694
+ end
677
695
  end
@@ -222,7 +222,7 @@ describe Puppet::Configurer::Downloader do
222
222
  end
223
223
 
224
224
  it "should catch and log exceptions" do
225
- Puppet.expects(:err)
225
+ Puppet.expects(:log_exception)
226
226
  # The downloader creates a new catalog for each apply, and really the only object
227
227
  # that it is possible to stub for the purpose of generating a puppet error
228
228
  Puppet::Resource::Catalog.any_instance.stubs(:apply).raises(Puppet::Error, "testing")
@@ -551,8 +551,8 @@ describe Puppet::Configurer do
551
551
 
552
552
  Puppet::Transaction::Report.indirection.expects(:save).raises("whatever")
553
553
 
554
- Puppet.expects(:err)
555
- expect { @configurer.send_report(@report) }.not_to raise_error
554
+ Puppet.expects(:send_log).with(:err, 'Could not send report: whatever')
555
+ @configurer.send_report(@report)
556
556
  end
557
557
  end
558
558
 
@@ -590,8 +590,8 @@ describe Puppet::Configurer do
590
590
 
591
591
  Puppet::Util.expects(:replace_file).yields(fh)
592
592
 
593
- Puppet.expects(:err)
594
- expect { @configurer.save_last_run_summary(@report) }.to_not raise_error
593
+ Puppet.expects(:send_log).with(:err, 'Could not save last run local report: failed to do print')
594
+ @configurer.save_last_run_summary(@report)
595
595
  end
596
596
 
597
597
  it "should create the last run file with the correct mode" do
@@ -609,7 +609,7 @@ describe Puppet::Configurer do
609
609
 
610
610
  it "should report invalid last run file permissions" do
611
611
  Puppet.settings.setting(:lastrunfile).expects(:mode).returns('892')
612
- Puppet.expects(:err).with(regexp_matches(/Could not save last run local report.*892 is invalid/))
612
+ Puppet.expects(:send_log).with(:err, regexp_matches(/Could not save last run local report.*892 is invalid/))
613
613
  @configurer.save_last_run_summary(@report)
614
614
  end
615
615
  end
@@ -1019,6 +1019,17 @@ describe Puppet::Configurer do
1019
1019
  expect(options[:report].master_used).to eq('myserver:123')
1020
1020
  end
1021
1021
 
1022
+ it "queries the simple status for the 'master' service" do
1023
+ Puppet.settings[:server_list] = ["myserver:123"]
1024
+ response = Net::HTTPOK.new(nil, 200, 'OK')
1025
+ http = mock('request')
1026
+ http.expects(:get).with('/status/v1/simple/master').returns(response)
1027
+ Puppet::Network::HttpPool.stubs(:http_ssl_instance).with('myserver', '123').returns(http)
1028
+ @agent.stubs(:run_internal)
1029
+
1030
+ @agent.run
1031
+ end
1032
+
1022
1033
  it "should report when a server is unavailable" do
1023
1034
  Puppet.settings[:server_list] = ["myserver:123"]
1024
1035
  response = Net::HTTPInternalServerError.new(nil, 500, 'Internal Server Error')
@@ -412,6 +412,31 @@ describe Puppet::Etc, :if => !Puppet::Util::Platform.windows? do
412
412
  end
413
413
  end
414
414
 
415
+ describe :group do
416
+ it 'should return the next group struct if a block is not provided' do
417
+ Puppet::Etc.expects(:getgrent).returns(ascii_group_struct)
418
+
419
+ expect(Puppet::Etc.group).to eql(ascii_group_struct)
420
+ end
421
+
422
+ it 'should iterate over the available groups if a block is provided' do
423
+ expected_groups = [
424
+ utf_8_group_struct,
425
+ euc_kr_group_struct,
426
+ ascii_group_struct
427
+ ]
428
+ Puppet::Etc.stubs(:getgrent).returns(*(expected_groups + [nil]))
429
+
430
+ Puppet::Etc.expects(:setgrent)
431
+ Puppet::Etc.expects(:endgrent)
432
+
433
+ actual_groups = []
434
+ Puppet::Etc.group { |group| actual_groups << group }
435
+
436
+ expect(actual_groups).to eql(expected_groups)
437
+ end
438
+ end
439
+
415
440
  describe "endgrent" do
416
441
  it "should call Etc.getgrent" do
417
442
  Etc.expects(:getgrent)
@@ -2,8 +2,6 @@
2
2
  require 'spec_helper'
3
3
  require 'puppet/face'
4
4
 
5
- require 'puppetserver/ca/cli'
6
-
7
5
  describe Puppet::Face[:node, '0.0.1'] do
8
6
  describe '#cleanup' do
9
7
  it "should clean everything" do
@@ -90,7 +88,7 @@ describe Puppet::Face[:node, '0.0.1'] do
90
88
  end
91
89
  end
92
90
 
93
- describe "when cleaning certificate" do
91
+ describe "when cleaning certificate", :if => Puppet.features.puppetserver_ca? do
94
92
  it "should call the CA CLI gem's clean action" do
95
93
  Puppetserver::Ca::Action::Clean.any_instance.expects(:run).with({ 'certnames' => ['hostname'] }).returns(0)
96
94
  subject.clean_cert('hostname')
@@ -35,6 +35,21 @@ describe Puppet::Face[:parser, :current] do
35
35
  expect { parser.validate(manifest) }.to exit_with(1)
36
36
  end
37
37
 
38
+ it "validates static heredoc with specified syntax" do
39
+ manifest = file_containing('site.pp', "@(EOT:pp)
40
+ { invalid =>
41
+ EOT
42
+ ")
43
+ expect { parser.validate(manifest) }.to exit_with(1)
44
+ end
45
+
46
+ it "does not validates dynamic heredoc with specified syntax" do
47
+ manifest = file_containing('site.pp', "@(\"EOT\":pp)
48
+ {invalid => ${1+1}
49
+ EOT")
50
+ expect { parser.validate(manifest) }.to_not exit_with(1)
51
+ end
52
+
38
53
  it "runs error free when there are no validation errors" do
39
54
  expect {
40
55
  manifest = file_containing('site.pp', "notify { valid: }")