puppet 6.19.1-x64-mingw32 → 6.23.0-x64-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 (293) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -16
  3. data/Gemfile +3 -1
  4. data/Gemfile.lock +51 -40
  5. data/ext/osx/puppet.plist +2 -0
  6. data/ext/project_data.yaml +2 -2
  7. data/lib/puppet/application.rb +10 -6
  8. data/lib/puppet/application/agent.rb +12 -4
  9. data/lib/puppet/application/apply.rb +4 -2
  10. data/lib/puppet/application/device.rb +2 -0
  11. data/lib/puppet/application/filebucket.rb +2 -2
  12. data/lib/puppet/application/resource.rb +2 -1
  13. data/lib/puppet/application/script.rb +2 -0
  14. data/lib/puppet/application/ssl.rb +11 -0
  15. data/lib/puppet/application_support.rb +7 -0
  16. data/lib/puppet/configurer.rb +28 -18
  17. data/lib/puppet/configurer/downloader.rb +2 -1
  18. data/lib/puppet/defaults.rb +51 -23
  19. data/lib/puppet/environments.rb +54 -55
  20. data/lib/puppet/face/config.rb +10 -0
  21. data/lib/puppet/face/epp.rb +12 -2
  22. data/lib/puppet/face/facts.rb +158 -0
  23. data/lib/puppet/ffi/posix.rb +10 -0
  24. data/lib/puppet/ffi/posix/constants.rb +14 -0
  25. data/lib/puppet/ffi/posix/functions.rb +24 -0
  26. data/lib/puppet/file_serving/fileset.rb +14 -2
  27. data/lib/puppet/file_system/memory_file.rb +8 -1
  28. data/lib/puppet/file_system/windows.rb +2 -0
  29. data/lib/puppet/functions/all.rb +1 -1
  30. data/lib/puppet/functions/camelcase.rb +1 -1
  31. data/lib/puppet/functions/capitalize.rb +2 -2
  32. data/lib/puppet/functions/downcase.rb +2 -2
  33. data/lib/puppet/functions/epp.rb +1 -0
  34. data/lib/puppet/functions/get.rb +5 -5
  35. data/lib/puppet/functions/group_by.rb +13 -5
  36. data/lib/puppet/functions/inline_epp.rb +1 -0
  37. data/lib/puppet/functions/lest.rb +1 -1
  38. data/lib/puppet/functions/new.rb +100 -100
  39. data/lib/puppet/functions/partition.rb +12 -4
  40. data/lib/puppet/functions/require.rb +5 -5
  41. data/lib/puppet/functions/sort.rb +3 -3
  42. data/lib/puppet/functions/tree_each.rb +7 -9
  43. data/lib/puppet/functions/type.rb +4 -4
  44. data/lib/puppet/functions/upcase.rb +2 -2
  45. data/lib/puppet/http/resolver/server_list.rb +15 -4
  46. data/lib/puppet/http/service/compiler.rb +69 -0
  47. data/lib/puppet/http/service/file_server.rb +2 -1
  48. data/lib/puppet/indirector/catalog/compiler.rb +1 -0
  49. data/lib/puppet/indirector/fact_search.rb +60 -0
  50. data/lib/puppet/indirector/facts/facter.rb +24 -3
  51. data/lib/puppet/indirector/facts/json.rb +27 -0
  52. data/lib/puppet/indirector/facts/yaml.rb +3 -58
  53. data/lib/puppet/indirector/file_metadata/rest.rb +1 -0
  54. data/lib/puppet/indirector/json.rb +5 -1
  55. data/lib/puppet/indirector/node/json.rb +8 -0
  56. data/lib/puppet/indirector/report/json.rb +34 -0
  57. data/lib/puppet/module_tool/applications/installer.rb +48 -2
  58. data/lib/puppet/module_tool/errors/shared.rb +17 -2
  59. data/lib/puppet/network/formats.rb +69 -1
  60. data/lib/puppet/network/http/factory.rb +4 -0
  61. data/lib/puppet/pal/pal_impl.rb +70 -17
  62. data/lib/puppet/parser/ast/leaf.rb +3 -2
  63. data/lib/puppet/parser/functions/fqdn_rand.rb +14 -6
  64. data/lib/puppet/parser/templatewrapper.rb +1 -1
  65. data/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  66. data/lib/puppet/pops/evaluator/evaluator_impl.rb +22 -3
  67. data/lib/puppet/pops/model/ast_transformer.rb +1 -1
  68. data/lib/puppet/pops/types/p_sem_ver_type.rb +8 -2
  69. data/lib/puppet/pops/types/p_sensitive_type.rb +10 -0
  70. data/lib/puppet/property/list.rb +1 -1
  71. data/lib/puppet/provider/group/groupadd.rb +13 -8
  72. data/lib/puppet/provider/package/apt.rb +34 -2
  73. data/lib/puppet/provider/package/aptitude.rb +6 -0
  74. data/lib/puppet/provider/package/dnfmodule.rb +1 -1
  75. data/lib/puppet/provider/package/nim.rb +11 -6
  76. data/lib/puppet/provider/service/debian.rb +2 -0
  77. data/lib/puppet/provider/service/systemd.rb +14 -4
  78. data/lib/puppet/provider/service/windows.rb +38 -0
  79. data/lib/puppet/provider/user/aix.rb +2 -2
  80. data/lib/puppet/provider/user/directoryservice.rb +25 -12
  81. data/lib/puppet/provider/user/useradd.rb +62 -8
  82. data/lib/puppet/reference/configuration.rb +7 -6
  83. data/lib/puppet/settings.rb +33 -28
  84. data/lib/puppet/settings/alias_setting.rb +37 -0
  85. data/lib/puppet/settings/base_setting.rb +26 -2
  86. data/lib/puppet/settings/environment_conf.rb +1 -0
  87. data/lib/puppet/transaction/additional_resource_generator.rb +1 -1
  88. data/lib/puppet/type/file.rb +19 -1
  89. data/lib/puppet/type/file/selcontext.rb +1 -1
  90. data/lib/puppet/type/package.rb +3 -3
  91. data/lib/puppet/type/service.rb +18 -38
  92. data/lib/puppet/type/tidy.rb +21 -2
  93. data/lib/puppet/type/user.rb +38 -20
  94. data/lib/puppet/util/autoload.rb +1 -8
  95. data/lib/puppet/util/fact_dif.rb +81 -0
  96. data/lib/puppet/util/monkey_patches.rb +7 -0
  97. data/lib/puppet/util/posix.rb +54 -5
  98. data/lib/puppet/util/rubygems.rb +5 -1
  99. data/lib/puppet/util/selinux.rb +30 -4
  100. data/lib/puppet/util/windows/adsi.rb +46 -0
  101. data/lib/puppet/util/windows/api_types.rb +1 -1
  102. data/lib/puppet/util/windows/principal.rb +9 -2
  103. data/lib/puppet/util/windows/service.rb +1 -1
  104. data/lib/puppet/util/windows/sid.rb +4 -2
  105. data/lib/puppet/version.rb +1 -1
  106. data/locales/puppet.pot +372 -288
  107. data/man/man5/puppet.conf.5 +282 -254
  108. data/man/man8/puppet-agent.8 +2 -2
  109. data/man/man8/puppet-apply.8 +2 -2
  110. data/man/man8/puppet-catalog.8 +1 -1
  111. data/man/man8/puppet-config.8 +1 -1
  112. data/man/man8/puppet-describe.8 +1 -1
  113. data/man/man8/puppet-device.8 +2 -2
  114. data/man/man8/puppet-doc.8 +1 -1
  115. data/man/man8/puppet-epp.8 +1 -1
  116. data/man/man8/puppet-facts.8 +90 -1
  117. data/man/man8/puppet-filebucket.8 +3 -3
  118. data/man/man8/puppet-generate.8 +1 -1
  119. data/man/man8/puppet-help.8 +1 -1
  120. data/man/man8/puppet-key.8 +1 -1
  121. data/man/man8/puppet-lookup.8 +1 -1
  122. data/man/man8/puppet-man.8 +1 -1
  123. data/man/man8/puppet-module.8 +1 -1
  124. data/man/man8/puppet-node.8 +4 -1
  125. data/man/man8/puppet-parser.8 +1 -1
  126. data/man/man8/puppet-plugin.8 +1 -1
  127. data/man/man8/puppet-report.8 +4 -1
  128. data/man/man8/puppet-resource.8 +1 -1
  129. data/man/man8/puppet-script.8 +2 -2
  130. data/man/man8/puppet-ssl.8 +5 -1
  131. data/man/man8/puppet-status.8 +1 -1
  132. data/man/man8/puppet.8 +2 -2
  133. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +91 -0
  134. data/spec/fixtures/ssl/127.0.0.1-key.pem +107 -57
  135. data/spec/fixtures/ssl/127.0.0.1.pem +52 -31
  136. data/spec/fixtures/ssl/bad-basic-constraints.pem +57 -35
  137. data/spec/fixtures/ssl/bad-int-basic-constraints.pem +57 -35
  138. data/spec/fixtures/ssl/ca.pem +57 -35
  139. data/spec/fixtures/ssl/crl.pem +28 -18
  140. data/spec/fixtures/ssl/ec-key.pem +11 -11
  141. data/spec/fixtures/ssl/ec.pem +33 -24
  142. data/spec/fixtures/ssl/encrypted-ec-key.pem +12 -12
  143. data/spec/fixtures/ssl/encrypted-key.pem +108 -58
  144. data/spec/fixtures/ssl/intermediate-agent-crl.pem +28 -19
  145. data/spec/fixtures/ssl/intermediate-agent.pem +57 -36
  146. data/spec/fixtures/ssl/intermediate-crl.pem +31 -21
  147. data/spec/fixtures/ssl/intermediate.pem +57 -36
  148. data/spec/fixtures/ssl/pluto-key.pem +107 -57
  149. data/spec/fixtures/ssl/pluto.pem +52 -30
  150. data/spec/fixtures/ssl/request-key.pem +107 -57
  151. data/spec/fixtures/ssl/request.pem +47 -26
  152. data/spec/fixtures/ssl/revoked-key.pem +107 -57
  153. data/spec/fixtures/ssl/revoked.pem +52 -30
  154. data/spec/fixtures/ssl/signed-key.pem +107 -57
  155. data/spec/fixtures/ssl/signed.pem +52 -30
  156. data/spec/fixtures/ssl/tampered-cert.pem +52 -30
  157. data/spec/fixtures/ssl/tampered-csr.pem +47 -26
  158. data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +107 -57
  159. data/spec/fixtures/ssl/unknown-127.0.0.1.pem +50 -29
  160. data/spec/fixtures/ssl/unknown-ca-key.pem +107 -57
  161. data/spec/fixtures/ssl/unknown-ca.pem +55 -33
  162. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services_vendor_preset +9 -0
  163. data/spec/fixtures/unit/provider/user/aix/aix_passwd_file.out +4 -0
  164. data/spec/integration/application/agent_spec.rb +160 -3
  165. data/spec/integration/application/apply_spec.rb +19 -0
  166. data/spec/integration/application/plugin_spec.rb +1 -1
  167. data/spec/integration/application/resource_spec.rb +30 -0
  168. data/spec/integration/defaults_spec.rb +0 -7
  169. data/spec/integration/environments/setting_hooks_spec.rb +1 -1
  170. data/spec/integration/http/client_spec.rb +12 -0
  171. data/spec/integration/indirector/direct_file_server_spec.rb +1 -3
  172. data/spec/integration/resource/type_collection_spec.rb +2 -6
  173. data/spec/integration/transaction_spec.rb +4 -9
  174. data/spec/integration/util/windows/adsi_spec.rb +21 -1
  175. data/spec/integration/util/windows/principal_spec.rb +21 -0
  176. data/spec/integration/util/windows/registry_spec.rb +6 -10
  177. data/spec/lib/puppet/test_ca.rb +2 -2
  178. data/spec/lib/puppet_spec/settings.rb +6 -1
  179. data/spec/spec_helper.rb +12 -5
  180. data/spec/unit/agent_spec.rb +8 -6
  181. data/spec/unit/application/agent_spec.rb +7 -3
  182. data/spec/unit/application/config_spec.rb +224 -4
  183. data/spec/unit/application/facts_spec.rb +482 -3
  184. data/spec/unit/application/filebucket_spec.rb +0 -2
  185. data/spec/unit/application/ssl_spec.rb +23 -0
  186. data/spec/unit/application_spec.rb +51 -9
  187. data/spec/unit/configurer/downloader_spec.rb +6 -0
  188. data/spec/unit/configurer_spec.rb +23 -0
  189. data/spec/unit/confine/feature_spec.rb +1 -1
  190. data/spec/unit/confine_spec.rb +8 -2
  191. data/spec/unit/defaults_spec.rb +36 -1
  192. data/spec/unit/environments_spec.rb +221 -68
  193. data/spec/unit/face/config_spec.rb +27 -32
  194. data/spec/unit/face/facts_spec.rb +4 -0
  195. data/spec/unit/face/node_spec.rb +0 -11
  196. data/spec/unit/file_serving/configuration/parser_spec.rb +0 -1
  197. data/spec/unit/file_serving/fileset_spec.rb +60 -0
  198. data/spec/unit/file_serving/metadata_spec.rb +3 -3
  199. data/spec/unit/file_serving/terminus_helper_spec.rb +11 -4
  200. data/spec/unit/file_system_spec.rb +9 -0
  201. data/spec/unit/forge/module_release_spec.rb +2 -7
  202. data/spec/unit/functions/inline_epp_spec.rb +26 -1
  203. data/spec/unit/gettext/config_spec.rb +12 -0
  204. data/spec/unit/http/service/compiler_spec.rb +172 -0
  205. data/spec/unit/http/service_spec.rb +1 -1
  206. data/spec/unit/indirector/catalog/compiler_spec.rb +14 -10
  207. data/spec/unit/indirector/face_spec.rb +0 -1
  208. data/spec/unit/indirector/facts/facter_spec.rb +95 -1
  209. data/spec/unit/indirector/facts/json_spec.rb +255 -0
  210. data/spec/unit/indirector/file_bucket_file/selector_spec.rb +26 -8
  211. data/spec/unit/indirector/indirection_spec.rb +8 -12
  212. data/spec/unit/indirector/key/file_spec.rb +0 -1
  213. data/spec/unit/indirector/node/json_spec.rb +33 -0
  214. data/spec/{integration/indirector/report/yaml.rb → unit/indirector/report/json_spec.rb} +13 -24
  215. data/spec/unit/indirector/report/yaml_spec.rb +72 -8
  216. data/spec/unit/indirector_spec.rb +2 -2
  217. data/spec/unit/module_tool/applications/installer_spec.rb +66 -0
  218. data/spec/unit/network/authconfig_spec.rb +0 -3
  219. data/spec/unit/network/formats_spec.rb +41 -0
  220. data/spec/unit/network/http/api/indirected_routes_spec.rb +0 -9
  221. data/spec/unit/network/http/factory_spec.rb +19 -0
  222. data/spec/unit/network/http/handler_spec.rb +0 -5
  223. data/spec/unit/parser/compiler_spec.rb +3 -19
  224. data/spec/unit/parser/functions/fqdn_rand_spec.rb +15 -1
  225. data/spec/unit/parser/resource_spec.rb +14 -8
  226. data/spec/unit/parser/templatewrapper_spec.rb +4 -3
  227. data/spec/unit/pops/evaluator/deferred_resolver_spec.rb +20 -0
  228. data/spec/unit/pops/types/p_sem_ver_type_spec.rb +18 -0
  229. data/spec/unit/pops/types/p_sensitive_type_spec.rb +18 -0
  230. data/spec/unit/property_spec.rb +1 -0
  231. data/spec/unit/provider/group/groupadd_spec.rb +5 -2
  232. data/spec/unit/provider/nameservice_spec.rb +66 -65
  233. data/spec/unit/provider/package/apt_spec.rb +28 -23
  234. data/spec/unit/provider/package/aptitude_spec.rb +1 -1
  235. data/spec/unit/provider/package/base_spec.rb +6 -5
  236. data/spec/unit/provider/package/dnfmodule_spec.rb +10 -1
  237. data/spec/unit/provider/package/nim_spec.rb +42 -0
  238. data/spec/unit/provider/package/pacman_spec.rb +18 -12
  239. data/spec/unit/provider/package/pip_spec.rb +6 -11
  240. data/spec/unit/provider/package/pkgdmg_spec.rb +0 -4
  241. data/spec/unit/provider/service/init_spec.rb +1 -0
  242. data/spec/unit/provider/service/openwrt_spec.rb +3 -1
  243. data/spec/unit/provider/service/systemd_spec.rb +53 -8
  244. data/spec/unit/provider/service/windows_spec.rb +202 -0
  245. data/spec/unit/provider/user/aix_spec.rb +5 -0
  246. data/spec/unit/provider/user/directoryservice_spec.rb +67 -35
  247. data/spec/unit/provider/user/hpux_spec.rb +1 -1
  248. data/spec/unit/provider/user/pw_spec.rb +2 -0
  249. data/spec/unit/provider/user/useradd_spec.rb +71 -3
  250. data/spec/unit/provider_spec.rb +8 -10
  251. data/spec/unit/puppet_pal_catalog_spec.rb +45 -0
  252. data/spec/unit/resource/capability_finder_spec.rb +6 -1
  253. data/spec/unit/resource/catalog_spec.rb +1 -1
  254. data/spec/unit/resource/type_spec.rb +1 -1
  255. data/spec/unit/resource_spec.rb +11 -10
  256. data/spec/unit/settings_spec.rb +419 -242
  257. data/spec/unit/ssl/base_spec.rb +0 -1
  258. data/spec/unit/ssl/host_spec.rb +0 -5
  259. data/spec/unit/ssl/ssl_provider_spec.rb +14 -8
  260. data/spec/unit/ssl/state_machine_spec.rb +19 -5
  261. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -9
  262. data/spec/unit/transaction/event_manager_spec.rb +14 -11
  263. data/spec/unit/transaction_spec.rb +18 -11
  264. data/spec/unit/type/file/content_spec.rb +0 -1
  265. data/spec/unit/type/file/selinux_spec.rb +3 -5
  266. data/spec/unit/type/file_spec.rb +0 -6
  267. data/spec/unit/type/group_spec.rb +13 -6
  268. data/spec/unit/type/resources_spec.rb +7 -7
  269. data/spec/unit/type/service_spec.rb +60 -189
  270. data/spec/unit/type/tidy_spec.rb +17 -8
  271. data/spec/unit/type/user_spec.rb +45 -0
  272. data/spec/unit/type_spec.rb +2 -2
  273. data/spec/unit/util/at_fork_spec.rb +2 -2
  274. data/spec/unit/util/autoload_spec.rb +5 -1
  275. data/spec/unit/util/backups_spec.rb +1 -2
  276. data/spec/unit/util/execution_spec.rb +15 -11
  277. data/spec/unit/util/inifile_spec.rb +6 -14
  278. data/spec/unit/util/log_spec.rb +8 -7
  279. data/spec/unit/util/logging_spec.rb +3 -3
  280. data/spec/unit/util/posix_spec.rb +363 -15
  281. data/spec/unit/util/rubygems_spec.rb +2 -2
  282. data/spec/unit/util/selinux_spec.rb +163 -68
  283. data/spec/unit/util/storage_spec.rb +3 -1
  284. data/spec/unit/util/suidmanager_spec.rb +44 -41
  285. data/spec/unit/util/windows/sid_spec.rb +6 -0
  286. data/spec/unit/util_spec.rb +13 -6
  287. data/tasks/generate_cert_fixtures.rake +2 -2
  288. metadata +33 -16
  289. data/spec/integration/application/config_spec.rb +0 -74
  290. data/spec/lib/matchers/include.rb +0 -27
  291. data/spec/lib/matchers/include_spec.rb +0 -32
  292. data/spec/unit/face/catalog_spec.rb +0 -6
  293. data/spec/unit/face/module_spec.rb +0 -3
@@ -138,7 +138,7 @@ trace = true
138
138
  Puppet[:log_level] = 'info'
139
139
  allow(Puppet::FileSystem).to receive(:open).with(path, anything, anything).and_yield(StringIO.new)
140
140
  expect {
141
- subject.set('foo', 'bar')
141
+ subject.set('certname', 'bar')
142
142
  }.to output("\e[1;33mResolving settings from section 'main' in environment 'production'\e[0m\n").to_stderr
143
143
  end
144
144
 
@@ -146,19 +146,19 @@ trace = true
146
146
  Puppet[:log_level] = 'info'
147
147
  allow(Puppet::FileSystem).to receive(:open).with(path, anything, anything).and_yield(StringIO.new)
148
148
  expect {
149
- subject.set('foo', 'bar', {:section => "baz"})
149
+ subject.set('certname', 'bar', {:section => "baz"})
150
150
  }.to output("\e[1;33mResolving settings from section 'baz' in environment 'production'\e[0m\n").to_stderr
151
151
  end
152
152
 
153
153
  it "writes to the correct puppet config file" do
154
154
  expect(Puppet::FileSystem).to receive(:open).with(path, anything, anything)
155
- subject.set('foo', 'bar')
155
+ subject.set('certname', 'bar')
156
156
  end
157
157
 
158
158
  it "creates a config file if one does not exist" do
159
159
  allow(Puppet::FileSystem).to receive(:open).with(path, anything, anything).and_yield(StringIO.new)
160
160
  expect(Puppet::FileSystem).to receive(:touch).with(path)
161
- subject.set('foo', 'bar')
161
+ subject.set('certname', 'bar')
162
162
  end
163
163
 
164
164
  it "sets the supplied config/value in the default section (main)" do
@@ -167,8 +167,8 @@ trace = true
167
167
  manipulator = Puppet::Settings::IniFile::Manipulator.new(config)
168
168
  allow(Puppet::Settings::IniFile::Manipulator).to receive(:new).and_return(manipulator)
169
169
 
170
- expect(manipulator).to receive(:set).with("main", "foo", "bar")
171
- subject.set('foo', 'bar')
170
+ expect(manipulator).to receive(:set).with("main", "certname", "bar")
171
+ subject.set('certname', 'bar')
172
172
  end
173
173
 
174
174
  it "sets the value in the supplied section" do
@@ -177,8 +177,8 @@ trace = true
177
177
  manipulator = Puppet::Settings::IniFile::Manipulator.new(config)
178
178
  allow(Puppet::Settings::IniFile::Manipulator).to receive(:new).and_return(manipulator)
179
179
 
180
- expect(manipulator).to receive(:set).with("baz", "foo", "bar")
181
- subject.set('foo', 'bar', {:section => "baz"})
180
+ expect(manipulator).to receive(:set).with("baz", "certname", "bar")
181
+ subject.set('certname', 'bar', {:section => "baz"})
182
182
  end
183
183
 
184
184
  it "does not duplicate an existing default section when a section is not specified" do
@@ -190,53 +190,48 @@ trace = true
190
190
  myfile = StringIO.new(contents)
191
191
  allow(Puppet::FileSystem).to receive(:open).with(path, anything, anything).and_yield(myfile)
192
192
 
193
- subject.set('foo', 'bar')
193
+ subject.set('certname', 'bar')
194
194
 
195
- expect(myfile.string).to match(/foo = bar/)
195
+ expect(myfile.string).to match(/certname = bar/)
196
196
  expect(myfile.string).not_to match(/main.*main/)
197
197
  end
198
198
 
199
199
  it "opens the file with UTF-8 encoding" do
200
200
  expect(Puppet::FileSystem).to receive(:open).with(path, nil, 'r+:UTF-8')
201
- subject.set('foo', 'bar')
201
+ subject.set('certname', 'bar')
202
202
  end
203
203
 
204
204
  it "sets settings into the [server] section when setting [master] section settings" do
205
- initial_contents = <<-CONFIG
206
- [master]
207
- setting = old_setting_value
208
- untouched_setting = value
205
+ initial_contents = <<~CONFIG
206
+ [master]
207
+ node_terminus = none
208
+ reports = log
209
209
  CONFIG
210
210
 
211
211
  myinitialfile = StringIO.new(initial_contents)
212
212
  allow(Puppet::FileSystem).to receive(:open).with(path, anything, anything).and_yield(myinitialfile)
213
213
 
214
214
  expect {
215
- subject.set('setting', 'new_setting_value', {:section => 'master'})
216
- }.to output("Deleted setting from 'master': 'setting = old_setting_value', and adding it to 'server' section\n").to_stdout
217
- modified_content = <<-CONFIG
218
- [master]
219
- untouched_setting = value
220
- [server]
221
- setting = new_setting_value
222
- CONFIG
215
+ subject.set('node_terminus', 'exec', {:section => 'master'})
216
+ }.to output("Deleted setting from 'master': 'node_terminus = none', and adding it to 'server' section\n").to_stdout
223
217
 
224
- mymodifiedfile = StringIO.new(modified_content)
225
- expect(myinitialfile.string).to match(mymodifiedfile.string)
218
+ expect(myinitialfile.string).to match(<<~CONFIG)
219
+ [master]
220
+ reports = log
221
+ [server]
222
+ node_terminus = exec
223
+ CONFIG
226
224
  end
227
225
 
228
226
  it "setting [master] section settings, sets settings into [server] section instead" do
229
227
  myinitialfile = StringIO.new("")
230
228
  allow(Puppet::FileSystem).to receive(:open).with(path, anything, anything).and_yield(myinitialfile)
231
- subject.set('setting_name', 'value', {:section => 'master'})
229
+ subject.set('node_terminus', 'exec', {:section => 'master'})
232
230
 
233
- expected_content = <<-CONFIG
234
- [server]
235
- setting_name = value
231
+ expect(myinitialfile.string).to match(<<~CONFIG)
232
+ [server]
233
+ node_terminus = exec
236
234
  CONFIG
237
-
238
- myexpectedfile = StringIO.new(expected_content)
239
- expect(myinitialfile.string).to match(myexpectedfile.string)
240
235
  end
241
236
  end
242
237
 
@@ -71,4 +71,8 @@ CONF
71
71
  log.message =~ /Uploading facts for '.*' to 'puppet\.server\.test'/}
72
72
  end
73
73
  end
74
+
75
+ describe "#show" do
76
+ it { is_expected.to be_action :show }
77
+ end
74
78
  end
@@ -15,13 +15,6 @@ describe Puppet::Face[:node, '0.0.1'] do
15
15
  end
16
16
 
17
17
  describe 'when running #clean' do
18
- before :each do
19
- allow(Puppet::Node::Facts.indirection).to receive(:terminus_class=)
20
- allow(Puppet::Node::Facts.indirection).to receive(:cache_class=)
21
- allow(Puppet::Node).to receive(:terminus_class=)
22
- allow(Puppet::Node).to receive(:cache_class=)
23
- end
24
-
25
18
  it 'should invoke #cleanup' do
26
19
  expect(subject).to receive(:cleanup).with('hostname')
27
20
  subject.clean('hostname')
@@ -30,10 +23,6 @@ describe Puppet::Face[:node, '0.0.1'] do
30
23
 
31
24
  describe "clean action" do
32
25
  before :each do
33
- allow(Puppet::Node::Facts.indirection).to receive(:terminus_class=)
34
- allow(Puppet::Node::Facts.indirection).to receive(:cache_class=)
35
- allow(Puppet::Node).to receive(:terminus_class=)
36
- allow(Puppet::Node).to receive(:cache_class=)
37
26
  allow(subject).to receive(:cleanup)
38
27
  end
39
28
 
@@ -87,7 +87,6 @@ describe Puppet::FileServing::Configuration::Parser do
87
87
  before do
88
88
  @mount = double('testmount', :name => "one", :validate => true)
89
89
  expect(Puppet::FileServing::Mount::File).to receive(:new).with("one").and_return(@mount)
90
- allow(@parser).to receive(:add_modules_mount)
91
90
  end
92
91
 
93
92
  it "should set the mount path to the path attribute from that section" do
@@ -46,6 +46,13 @@ describe Puppet::FileServing::Fileset do
46
46
  expect(set.recurselimit).to eq(3)
47
47
  end
48
48
 
49
+ it "accepts a 'max_files' option" do
50
+ expect(Puppet::FileSystem).to receive(:lstat).with(somefile).and_return(double('stat'))
51
+ set = Puppet::FileServing::Fileset.new(somefile, :recurselimit => 3, :max_files => 100)
52
+ expect(set.recurselimit).to eq(3)
53
+ expect(set.max_files).to eq(100)
54
+ end
55
+
49
56
  it "accepts an 'ignore' option" do
50
57
  expect(Puppet::FileSystem).to receive(:lstat).with(somefile).and_return(double('stat'))
51
58
  set = Puppet::FileServing::Fileset.new(somefile, :ignore => ".svn")
@@ -160,6 +167,29 @@ describe Puppet::FileServing::Fileset do
160
167
  end
161
168
  end
162
169
 
170
+ def mock_big_dir_structure(path, stat_method = :lstat)
171
+ allow(Puppet::FileSystem).to receive(stat_method).with(path).and_return(@dirstat)
172
+
173
+ # Keep track of the files we're stubbing.
174
+ @files = %w{.}
175
+
176
+ top_names = (1..10).map {|i| "dir_#{i}" }
177
+ sub_names = (1..100).map {|i| "file__#{i}" }
178
+
179
+ allow(Dir).to receive(:entries).with(path, encoding: Encoding::UTF_8).and_return(top_names)
180
+ top_names.each do |subdir|
181
+ @files << subdir # relative path
182
+ subpath = File.join(path, subdir)
183
+ allow(Puppet::FileSystem).to receive(stat_method).with(subpath).and_return(@dirstat)
184
+ allow(Dir).to receive(:entries).with(subpath, encoding: Encoding::UTF_8).and_return(sub_names)
185
+ sub_names.each do |file|
186
+ @files << File.join(subdir, file) # relative path
187
+ subfile_path = File.join(subpath, file)
188
+ allow(Puppet::FileSystem).to receive(stat_method).with(subfile_path).and_return(@filestat)
189
+ end
190
+ end
191
+ end
192
+
163
193
  def setup_mocks_for_dir(mock_dir, base_path)
164
194
  path = File.join(base_path, mock_dir.name)
165
195
  allow(Puppet::FileSystem).to receive(:lstat).with(path).and_return(MockStat.new(path, true))
@@ -258,6 +288,36 @@ describe Puppet::FileServing::Fileset do
258
288
  expect(@fileset.files.find { |file| file.include?("0") }).to be_nil
259
289
  end
260
290
 
291
+ it "raises exception if number of files is greater than :max_files" do
292
+ mock_dir_structure(@path)
293
+ @fileset.recurse = true
294
+ @fileset.max_files = 22
295
+ expect { @fileset.files }.to raise_error(Puppet::Error, "The directory '#{@path}' contains 28 entries, which exceeds the limit of 22 specified by the max_files parameter for this resource. The limit may be increased, but be aware that large number of file resources can result in excessive resource consumption and degraded performance. Consider using an alternate method to manage large directory trees")
296
+ end
297
+
298
+ it "logs a warning if number of files is greater than soft max_files limit of 1000" do
299
+ mock_big_dir_structure(@path)
300
+ @fileset.recurse = true
301
+ expect(Puppet).to receive(:warning).with("The directory '#{@path}' contains 1010 entries, which exceeds the default soft limit 1000 and may cause excessive resource consumption and degraded performance. To remove this warning set a value for `max_files` parameter or consider using an alternate method to manage large directory trees")
302
+ expect { @fileset.files }.to_not raise_error
303
+ end
304
+
305
+ it "does not emit a warning if max_files is -1" do
306
+ mock_big_dir_structure(@path)
307
+ @fileset.recurse = true
308
+ @fileset.max_files = -1
309
+ expect(Puppet).to receive(:warning).never
310
+ @fileset.files
311
+ end
312
+
313
+ it "does not emit a warning if max_files is `-1`(string)" do
314
+ mock_big_dir_structure(@path)
315
+ @fileset.recurse = true
316
+ @fileset.max_files = '-1'
317
+ expect(Puppet).to receive(:warning).never
318
+ @fileset.files
319
+ end
320
+
261
321
  it "ignores files that match a pattern given as a boolean" do
262
322
  mock_dir_structure(@path)
263
323
  @fileset.recurse = true
@@ -266,9 +266,9 @@ describe Puppet::FileServing::Metadata, :uses_checksums => true do
266
266
  path = tmpfile('bar')
267
267
  FileUtils.touch(path)
268
268
 
269
- allow(Puppet::Util::Windows::Security).to receive(:get_owner).with(path, :use).and_raise(invalid_error)
270
- allow(Puppet::Util::Windows::Security).to receive(:get_group).with(path, :use).and_raise(invalid_error)
271
- allow(Puppet::Util::Windows::Security).to receive(:get_mode).with(path, :use).and_raise(invalid_error)
269
+ allow(Puppet::Util::Windows::Security).to receive(:get_owner).with(path).and_raise(invalid_error)
270
+ allow(Puppet::Util::Windows::Security).to receive(:get_group).with(path).and_raise(invalid_error)
271
+ allow(Puppet::Util::Windows::Security).to receive(:get_mode).with(path).and_raise(invalid_error)
272
272
 
273
273
  stat = Puppet::FileSystem.stat(path)
274
274
 
@@ -2,13 +2,20 @@ require 'spec_helper'
2
2
 
3
3
  require 'puppet/file_serving/terminus_helper'
4
4
 
5
+ class Puppet::FileServing::TestHelper
6
+ include Puppet::FileServing::TerminusHelper
7
+
8
+ attr_reader :model
9
+
10
+ def initialize(model)
11
+ @model = model
12
+ end
13
+ end
14
+
5
15
  describe Puppet::FileServing::TerminusHelper do
6
16
  before do
7
- @helper = Object.new
8
- @helper.extend(Puppet::FileServing::TerminusHelper)
9
-
10
17
  @model = double('model')
11
- allow(@helper).to receive(:model).and_return(@model)
18
+ @helper = Puppet::FileServing::TestHelper.new(@model)
12
19
 
13
20
  @request = double('request', :key => "url", :options => {})
14
21
 
@@ -999,6 +999,15 @@ describe "Puppet::FileSystem" do
999
999
  Puppet::FileSystem.replace_file(dest, 0755) { |_| }
1000
1000
  }.to raise_error(ArgumentError, /Only modes 0644, 0640, 0660, and 0440 are allowed/)
1001
1001
  end
1002
+
1003
+ it 'falls back to fully qualified user name when sid retrieval fails' do
1004
+ current_user_sid = Puppet::Util::Windows::SID.name_to_sid(Puppet::Util::Windows::ADSI::User.current_user_name)
1005
+ allow(Puppet::Util::Windows::SID).to receive(:name_to_sid).with(Puppet::Util::Windows::ADSI::User.current_user_name).and_return(nil, current_user_sid)
1006
+ allow(Puppet::Util::Windows::SID).to receive(:name_to_sid).with(Puppet::Util::Windows::ADSI::User.current_sam_compatible_user_name).and_call_original
1007
+
1008
+ Puppet::FileSystem.replace_file(dest, 0644) { |f| f.write(content) }
1009
+ expects_public_file(dest)
1010
+ end
1002
1011
  end
1003
1012
  end
1004
1013
 
@@ -22,13 +22,8 @@ describe Puppet::Forge::ModuleRelease do
22
22
  let(:uri) { " "}
23
23
  let(:release) { Puppet::Forge::ModuleRelease.new(ssl_repository, JSON.parse(release_json)) }
24
24
 
25
- let(:mock_file) {
26
- mock_io = StringIO.new
27
- allow(mock_io).to receive(:path).and_return('/dev/null')
28
- mock_io
29
- }
30
-
31
- let(:mock_dir) { '/tmp' }
25
+ let(:mock_file) { double('file', path: '/dev/null') }
26
+ let(:mock_dir) { tmpdir('dir') }
32
27
 
33
28
  let(:destination) { tmpfile('forge_module_release') }
34
29
 
@@ -1,8 +1,10 @@
1
-
2
1
  require 'spec_helper'
3
2
 
3
+ require 'puppet_spec/compiler'
4
+
4
5
  describe "the inline_epp function" do
5
6
  include PuppetSpec::Files
7
+ include PuppetSpec::Compiler
6
8
 
7
9
  let :node do Puppet::Node.new('localhost') end
8
10
  let :compiler do Puppet::Parser::Compiler.new(node) end
@@ -73,6 +75,29 @@ describe "the inline_epp function" do
73
75
  expect(eval_template("string was: <%= $string %>")).to eq("string was: the string value")
74
76
  end
75
77
 
78
+ context "when using Sensitive" do
79
+ it "returns an unwrapped sensitive value as a String" do
80
+ expect(eval_and_collect_notices(<<~END)).to eq(["opensesame"])
81
+ notice(inline_epp("<%= Sensitive('opensesame').unwrap %>"))
82
+ END
83
+ end
84
+
85
+ it "rewraps a sensitive value" do
86
+ # note entire result is redacted, not just sensitive part
87
+ expect(eval_and_collect_notices(<<~END)).to eq(["Sensitive [value redacted]"])
88
+ notice(inline_epp("This is sensitive <%= Sensitive('opensesame') %>"))
89
+ END
90
+ end
91
+
92
+ it "can be double wrapped" do
93
+ catalog = compile_to_catalog(<<~END)
94
+ notify { 'title':
95
+ message => Sensitive(inline_epp("<%= Sensitive('opensesame') %>"))
96
+ }
97
+ END
98
+ expect(catalog.resource(:notify, 'title')['message']).to eq('opensesame')
99
+ end
100
+ end
76
101
 
77
102
  def eval_template_with_args(content, args_hash)
78
103
  epp_function.call(scope, content, args_hash)
@@ -27,6 +27,18 @@ describe Puppet::GettextConfig do
27
27
  Puppet::GettextConfig.delete_all_text_domains
28
28
  end
29
29
 
30
+ # These tests assume gettext is enabled, but it will be disabled when the
31
+ # first time the `Puppet[:disable_i18n]` setting is resolved
32
+ around(:each) do |example|
33
+ disabled = Puppet::GettextConfig.instance_variable_get(:@gettext_disabled)
34
+ Puppet::GettextConfig.instance_variable_set(:@gettext_disabled, false)
35
+ begin
36
+ example.run
37
+ ensure
38
+ Puppet::GettextConfig.instance_variable_set(:@gettext_disabled, disabled)
39
+ end
40
+ end
41
+
30
42
  describe 'setting and getting the locale' do
31
43
  it 'should return "en" when gettext is unavailable' do
32
44
  allow(Puppet::GettextConfig).to receive(:gettext_loaded?).and_return(false)
@@ -1,3 +1,4 @@
1
+
1
2
  # coding: utf-8
2
3
  require 'spec_helper'
3
4
  require 'puppet/http'
@@ -131,6 +132,26 @@ describe Puppet::HTTP::Service::Compiler do
131
132
  subject.post_catalog(certname, environment: 'production', facts: facts, checksum_type: %w[sha256 sha384])
132
133
  end
133
134
 
135
+ it 'does not accept msgpack by default' do
136
+ stub_request(:post, uri)
137
+ .with(headers: {'Accept' => 'application/vnd.puppet.rich+json, application/json, text/pson'})
138
+ .to_return(**catalog_response)
139
+
140
+ allow(Puppet.features).to receive(:msgpack?).and_return(false)
141
+
142
+ subject.post_catalog(certname, environment: environment, facts: facts)
143
+ end
144
+
145
+ it 'accepts msgpack & rich_json_msgpack if the gem is present' do
146
+ stub_request(:post, uri)
147
+ .with(headers: {'Accept' => 'application/vnd.puppet.rich+json, application/json, application/vnd.puppet.rich+msgpack, application/x-msgpack, text/pson'})
148
+ .to_return(**catalog_response)
149
+
150
+ allow(Puppet.features).to receive(:msgpack?).and_return(true)
151
+
152
+ subject.post_catalog(certname, environment: environment, facts: facts)
153
+ end
154
+
134
155
  it 'returns a deserialized catalog' do
135
156
  stub_request(:post, uri)
136
157
  .to_return(**catalog_response)
@@ -140,6 +161,35 @@ describe Puppet::HTTP::Service::Compiler do
140
161
  expect(cat.name).to eq(certname)
141
162
  end
142
163
 
164
+ it 'deserializes the catalog from msgpack', if: Puppet.features.msgpack? do
165
+ body = catalog.to_msgpack
166
+ formatter = Puppet::Network::FormatHandler.format(:msgpack)
167
+ catalog_response = { body: body, headers: {'Content-Type' => formatter.mime }}
168
+
169
+ stub_request(:post, uri)
170
+ .to_return(**catalog_response)
171
+
172
+ _, cat = subject.post_catalog(certname, environment: 'production', facts: facts)
173
+ expect(cat).to be_a(Puppet::Resource::Catalog)
174
+ expect(cat.name).to eq(certname)
175
+ end
176
+
177
+ it 'deserializes the catalog from rich msgpack', if: Puppet.features.msgpack? do
178
+ body = Puppet.override(rich_data: true) do
179
+ catalog.to_msgpack
180
+ end
181
+
182
+ formatter = Puppet::Network::FormatHandler.format(:rich_data_msgpack)
183
+ catalog_response = { body: body, headers: {'Content-Type' => formatter.mime }}
184
+
185
+ stub_request(:post, uri)
186
+ .to_return(**catalog_response)
187
+
188
+ _, cat = subject.post_catalog(certname, environment: 'production', facts: facts)
189
+ expect(cat).to be_a(Puppet::Resource::Catalog)
190
+ expect(cat.name).to eq(certname)
191
+ end
192
+
143
193
  it 'returns the request response' do
144
194
  stub_request(:post, uri)
145
195
  .to_return(**catalog_response)
@@ -209,6 +259,128 @@ describe Puppet::HTTP::Service::Compiler do
209
259
  end
210
260
  end
211
261
 
262
+ context 'when posting for a v4 catalog' do
263
+ let(:uri) {"https://compiler.example.com:8140/puppet/v4/catalog"}
264
+ let(:persistence) {{ facts: true, catalog: true }}
265
+ let(:facts) {{ 'foo' => 'bar' }}
266
+ let(:trusted_facts) {{}}
267
+ let(:uuid) { "ec3d2844-b236-4287-b0ad-632fbb4d1ff0" }
268
+ let(:job_id) { "1" }
269
+ let(:payload) {{
270
+ environment: environment,
271
+ persistence: persistence,
272
+ facts: facts,
273
+ trusted_facts: trusted_facts,
274
+ transaction_uuid: uuid,
275
+ job_id: job_id,
276
+ options: {
277
+ prefer_requested_environment: false,
278
+ capture_logs: false
279
+ }
280
+ }}
281
+ let(:serialized_catalog) {{ 'catalog' => catalog.to_data_hash }.to_json}
282
+ let(:catalog_response) {{ body: serialized_catalog, headers: {'Content-Type' => formatter.mime }}}
283
+
284
+ it 'includes default HTTP headers' do
285
+ stub_request(:post, uri).with do |request|
286
+ expect(request.headers).to include({'X-Puppet-Version' => /./, 'User-Agent' => /./})
287
+ expect(request.headers).to_not include('X-Puppet-Profiling')
288
+ end.to_return(**catalog_response)
289
+
290
+ subject.post_catalog4(certname, **payload)
291
+ end
292
+
293
+ it 'defaults the server and port based on settings' do
294
+ Puppet[:server] = 'compiler2.example.com'
295
+ Puppet[:serverport] = 8141
296
+
297
+ stub_request(:post, "https://compiler2.example.com:8141/puppet/v4/catalog")
298
+ .to_return(**catalog_response)
299
+
300
+ subject.post_catalog4(certname, **payload)
301
+ end
302
+
303
+ it 'includes puppet headers set via the :http_extra_headers and :profile settings' do
304
+ stub_request(:post, uri).with(headers: {'Example-Header' => 'real-thing', 'another' => 'thing', 'X-Puppet-Profiling' => 'true'}).
305
+ to_return(**catalog_response)
306
+
307
+ Puppet[:http_extra_headers] = 'Example-Header:real-thing,another:thing'
308
+ Puppet[:profile] = true
309
+
310
+ subject.post_catalog4(certname, **payload)
311
+ end
312
+
313
+ it 'returns a deserialized catalog' do
314
+ stub_request(:post, uri)
315
+ .to_return(**catalog_response)
316
+
317
+ _, cat, _ = subject.post_catalog4(certname, **payload)
318
+ expect(cat).to be_a(Puppet::Resource::Catalog)
319
+ expect(cat.name).to eq(certname)
320
+ end
321
+
322
+ it 'returns the request response' do
323
+ stub_request(:post, uri)
324
+ .to_return(**catalog_response)
325
+
326
+ resp, _, _ = subject.post_catalog4(certname, **payload)
327
+ expect(resp).to be_a(Puppet::HTTP::Response)
328
+ end
329
+
330
+ it 'raises a response error if unsuccessful' do
331
+ stub_request(:post, uri)
332
+ .to_return(status: [500, "Server Error"])
333
+
334
+ expect {
335
+ subject.post_catalog4(certname, **payload)
336
+ }.to raise_error do |err|
337
+ expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
338
+ expect(err.message).to eq('Server Error')
339
+ expect(err.response.code).to eq(500)
340
+ end
341
+ end
342
+
343
+ it 'raises a response error when server response is not JSON' do
344
+ stub_request(:post, uri)
345
+ .to_return(body: "this isn't valid JSON", headers: {'Content-Type' => 'application/json'})
346
+
347
+ expect {
348
+ subject.post_catalog4(certname, **payload)
349
+ }.to raise_error do |err|
350
+ expect(err).to be_an_instance_of(Puppet::HTTP::SerializationError)
351
+ expect(err.message).to match(/Failed to deserialize catalog from puppetserver response/)
352
+ end
353
+ end
354
+
355
+ it 'raises a response error when server response a JSON serialized catalog' do
356
+ stub_request(:post, uri)
357
+ .to_return(body: {oops: 'bad response data'}.to_json, headers: {'Content-Type' => 'application/json'})
358
+
359
+ expect {
360
+ subject.post_catalog4(certname, **payload)
361
+ }.to raise_error do |err|
362
+ expect(err).to be_an_instance_of(Puppet::HTTP::SerializationError)
363
+ expect(err.message).to match(/Failed to deserialize catalog from puppetserver response/)
364
+ end
365
+ end
366
+
367
+ it 'raises ArgumentError when the `persistence` hash does not contain required keys' do
368
+ payload[:persistence].delete(:facts)
369
+ expect { subject.post_catalog4(certname, **payload) }.to raise_error do |err|
370
+ expect(err).to be_an_instance_of(ArgumentError)
371
+ expect(err.message).to match(/The 'persistence' hash is missing the keys: facts/)
372
+ end
373
+ end
374
+
375
+ it 'raises ArgumentError when `facts` are not a Hash' do
376
+ payload[:facts] = Puppet::Node::Facts.new(certname)
377
+ expect { subject.post_catalog4(certname, **payload) }.to raise_error do |err|
378
+ expect(err).to be_an_instance_of(ArgumentError)
379
+ expect(err.message).to match(/Facts must be a Hash not a Puppet::Node::Facts/)
380
+ end
381
+ end
382
+ end
383
+
212
384
  context 'when getting a node' do
213
385
  let(:uri) { %r{/puppet/v3/node/ziggy} }
214
386
  let(:node_response) { { body: formatter.render(node), headers: {'Content-Type' => formatter.mime } } }