puppet 6.19.0-x64-mingw32 → 6.22.1-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 (212) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -16
  3. data/Gemfile +3 -1
  4. data/Gemfile.lock +50 -39
  5. data/ext/project_data.yaml +2 -2
  6. data/lib/puppet/application.rb +10 -6
  7. data/lib/puppet/application/agent.rb +1 -0
  8. data/lib/puppet/application/apply.rb +3 -2
  9. data/lib/puppet/application/device.rb +1 -0
  10. data/lib/puppet/application/filebucket.rb +2 -2
  11. data/lib/puppet/application/script.rb +1 -0
  12. data/lib/puppet/application/ssl.rb +11 -0
  13. data/lib/puppet/application_support.rb +7 -0
  14. data/lib/puppet/configurer.rb +28 -18
  15. data/lib/puppet/defaults.rb +46 -20
  16. data/lib/puppet/environments.rb +54 -55
  17. data/lib/puppet/face/config.rb +10 -0
  18. data/lib/puppet/face/epp.rb +12 -2
  19. data/lib/puppet/face/facts.rb +158 -0
  20. data/lib/puppet/ffi/posix.rb +10 -0
  21. data/lib/puppet/ffi/posix/constants.rb +14 -0
  22. data/lib/puppet/ffi/posix/functions.rb +24 -0
  23. data/lib/puppet/file_system/memory_file.rb +8 -1
  24. data/lib/puppet/file_system/windows.rb +2 -0
  25. data/lib/puppet/functions/epp.rb +1 -0
  26. data/lib/puppet/functions/inline_epp.rb +1 -0
  27. data/lib/puppet/functions/partition.rb +8 -0
  28. data/lib/puppet/indirector/fact_search.rb +60 -0
  29. data/lib/puppet/indirector/facts/facter.rb +24 -3
  30. data/lib/puppet/indirector/facts/json.rb +27 -0
  31. data/lib/puppet/indirector/facts/yaml.rb +3 -58
  32. data/lib/puppet/indirector/json.rb +5 -1
  33. data/lib/puppet/indirector/node/json.rb +8 -0
  34. data/lib/puppet/indirector/report/json.rb +34 -0
  35. data/lib/puppet/module_tool/applications/installer.rb +48 -2
  36. data/lib/puppet/module_tool/errors/shared.rb +17 -2
  37. data/lib/puppet/network/formats.rb +69 -1
  38. data/lib/puppet/network/http/factory.rb +4 -0
  39. data/lib/puppet/pal/pal_impl.rb +70 -17
  40. data/lib/puppet/parser/ast/leaf.rb +3 -2
  41. data/lib/puppet/parser/templatewrapper.rb +1 -1
  42. data/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  43. data/lib/puppet/pops/evaluator/evaluator_impl.rb +22 -3
  44. data/lib/puppet/pops/model/ast_transformer.rb +1 -1
  45. data/lib/puppet/property/list.rb +1 -1
  46. data/lib/puppet/provider/group/groupadd.rb +13 -8
  47. data/lib/puppet/provider/package/apt.rb +34 -2
  48. data/lib/puppet/provider/package/aptitude.rb +6 -0
  49. data/lib/puppet/provider/package/dnfmodule.rb +1 -1
  50. data/lib/puppet/provider/service/debian.rb +2 -0
  51. data/lib/puppet/provider/service/systemd.rb +1 -1
  52. data/lib/puppet/provider/user/aix.rb +2 -2
  53. data/lib/puppet/provider/user/useradd.rb +62 -8
  54. data/lib/puppet/reference/configuration.rb +6 -5
  55. data/lib/puppet/settings.rb +43 -15
  56. data/lib/puppet/settings/alias_setting.rb +37 -0
  57. data/lib/puppet/settings/base_setting.rb +26 -2
  58. data/lib/puppet/settings/environment_conf.rb +1 -0
  59. data/lib/puppet/type/package.rb +3 -3
  60. data/lib/puppet/util/autoload.rb +1 -8
  61. data/lib/puppet/util/fact_dif.rb +81 -0
  62. data/lib/puppet/util/monkey_patches.rb +7 -0
  63. data/lib/puppet/util/posix.rb +54 -5
  64. data/lib/puppet/util/rubygems.rb +5 -1
  65. data/lib/puppet/util/windows/adsi.rb +46 -0
  66. data/lib/puppet/util/windows/api_types.rb +1 -1
  67. data/lib/puppet/util/windows/principal.rb +9 -2
  68. data/lib/puppet/util/windows/service.rb +1 -1
  69. data/lib/puppet/util/windows/sid.rb +4 -2
  70. data/lib/puppet/version.rb +1 -1
  71. data/locales/puppet.pot +295 -219
  72. data/man/man5/puppet.conf.5 +15 -7
  73. data/man/man8/puppet-agent.8 +2 -2
  74. data/man/man8/puppet-apply.8 +2 -2
  75. data/man/man8/puppet-catalog.8 +1 -1
  76. data/man/man8/puppet-config.8 +1 -1
  77. data/man/man8/puppet-describe.8 +1 -1
  78. data/man/man8/puppet-device.8 +2 -2
  79. data/man/man8/puppet-doc.8 +1 -1
  80. data/man/man8/puppet-epp.8 +1 -1
  81. data/man/man8/puppet-facts.8 +90 -1
  82. data/man/man8/puppet-filebucket.8 +3 -3
  83. data/man/man8/puppet-generate.8 +1 -1
  84. data/man/man8/puppet-help.8 +1 -1
  85. data/man/man8/puppet-key.8 +1 -1
  86. data/man/man8/puppet-lookup.8 +1 -1
  87. data/man/man8/puppet-man.8 +1 -1
  88. data/man/man8/puppet-module.8 +1 -1
  89. data/man/man8/puppet-node.8 +4 -1
  90. data/man/man8/puppet-parser.8 +1 -1
  91. data/man/man8/puppet-plugin.8 +1 -1
  92. data/man/man8/puppet-report.8 +4 -1
  93. data/man/man8/puppet-resource.8 +1 -1
  94. data/man/man8/puppet-script.8 +2 -2
  95. data/man/man8/puppet-ssl.8 +5 -1
  96. data/man/man8/puppet-status.8 +1 -1
  97. data/man/man8/puppet.8 +2 -2
  98. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +91 -0
  99. data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services_vendor_preset +9 -0
  100. data/spec/fixtures/unit/provider/user/aix/aix_passwd_file.out +4 -0
  101. data/spec/integration/application/agent_spec.rb +160 -3
  102. data/spec/integration/application/apply_spec.rb +19 -0
  103. data/spec/integration/application/plugin_spec.rb +1 -1
  104. data/spec/integration/defaults_spec.rb +0 -7
  105. data/spec/integration/environments/setting_hooks_spec.rb +1 -1
  106. data/spec/integration/http/client_spec.rb +12 -0
  107. data/spec/integration/indirector/direct_file_server_spec.rb +1 -3
  108. data/spec/integration/resource/type_collection_spec.rb +2 -6
  109. data/spec/integration/transaction_spec.rb +4 -9
  110. data/spec/integration/util/windows/adsi_spec.rb +21 -1
  111. data/spec/integration/util/windows/principal_spec.rb +21 -0
  112. data/spec/integration/util/windows/registry_spec.rb +6 -10
  113. data/spec/lib/puppet_spec/settings.rb +6 -1
  114. data/spec/spec_helper.rb +12 -5
  115. data/spec/unit/agent_spec.rb +8 -6
  116. data/spec/unit/application/agent_spec.rb +0 -1
  117. data/spec/unit/application/config_spec.rb +224 -4
  118. data/spec/unit/application/facts_spec.rb +482 -3
  119. data/spec/unit/application/filebucket_spec.rb +0 -2
  120. data/spec/unit/application/ssl_spec.rb +23 -0
  121. data/spec/unit/application_spec.rb +51 -9
  122. data/spec/unit/confine/feature_spec.rb +1 -1
  123. data/spec/unit/confine_spec.rb +8 -2
  124. data/spec/unit/defaults_spec.rb +36 -1
  125. data/spec/unit/environments_spec.rb +221 -68
  126. data/spec/unit/face/config_spec.rb +27 -32
  127. data/spec/unit/face/facts_spec.rb +4 -0
  128. data/spec/unit/face/node_spec.rb +0 -11
  129. data/spec/unit/file_serving/configuration/parser_spec.rb +0 -1
  130. data/spec/unit/file_serving/metadata_spec.rb +3 -3
  131. data/spec/unit/file_serving/terminus_helper_spec.rb +11 -4
  132. data/spec/unit/file_system_spec.rb +9 -0
  133. data/spec/unit/forge/module_release_spec.rb +2 -7
  134. data/spec/unit/functions/inline_epp_spec.rb +26 -1
  135. data/spec/unit/http/service/compiler_spec.rb +49 -0
  136. data/spec/unit/http/service_spec.rb +1 -1
  137. data/spec/unit/indirector/face_spec.rb +0 -1
  138. data/spec/unit/indirector/facts/facter_spec.rb +95 -1
  139. data/spec/unit/indirector/facts/json_spec.rb +255 -0
  140. data/spec/unit/indirector/file_bucket_file/selector_spec.rb +26 -8
  141. data/spec/unit/indirector/indirection_spec.rb +8 -12
  142. data/spec/unit/indirector/key/file_spec.rb +0 -1
  143. data/spec/unit/indirector/node/json_spec.rb +33 -0
  144. data/spec/{integration/indirector/report/yaml.rb → unit/indirector/report/json_spec.rb} +13 -24
  145. data/spec/unit/indirector/report/yaml_spec.rb +72 -8
  146. data/spec/unit/indirector_spec.rb +2 -2
  147. data/spec/unit/module_tool/applications/installer_spec.rb +66 -0
  148. data/spec/unit/network/authconfig_spec.rb +0 -3
  149. data/spec/unit/network/formats_spec.rb +41 -0
  150. data/spec/unit/network/http/api/indirected_routes_spec.rb +0 -9
  151. data/spec/unit/network/http/factory_spec.rb +19 -0
  152. data/spec/unit/network/http/handler_spec.rb +0 -5
  153. data/spec/unit/parser/compiler_spec.rb +3 -19
  154. data/spec/unit/parser/resource_spec.rb +14 -8
  155. data/spec/unit/parser/templatewrapper_spec.rb +4 -3
  156. data/spec/unit/pops/evaluator/deferred_resolver_spec.rb +20 -0
  157. data/spec/unit/property_spec.rb +1 -0
  158. data/spec/unit/provider/group/groupadd_spec.rb +5 -2
  159. data/spec/unit/provider/nameservice_spec.rb +66 -65
  160. data/spec/unit/provider/package/apt_spec.rb +28 -23
  161. data/spec/unit/provider/package/aptitude_spec.rb +1 -1
  162. data/spec/unit/provider/package/base_spec.rb +6 -5
  163. data/spec/unit/provider/package/dnfmodule_spec.rb +10 -1
  164. data/spec/unit/provider/package/pacman_spec.rb +18 -12
  165. data/spec/unit/provider/package/pip_spec.rb +6 -11
  166. data/spec/unit/provider/package/pkgdmg_spec.rb +0 -4
  167. data/spec/unit/provider/service/systemd_spec.rb +11 -0
  168. data/spec/unit/provider/user/aix_spec.rb +5 -0
  169. data/spec/unit/provider/user/hpux_spec.rb +1 -1
  170. data/spec/unit/provider/user/pw_spec.rb +2 -0
  171. data/spec/unit/provider/user/useradd_spec.rb +71 -3
  172. data/spec/unit/provider_spec.rb +8 -10
  173. data/spec/unit/puppet_pal_catalog_spec.rb +45 -0
  174. data/spec/unit/resource/capability_finder_spec.rb +6 -1
  175. data/spec/unit/resource/catalog_spec.rb +1 -1
  176. data/spec/unit/resource/type_spec.rb +1 -1
  177. data/spec/unit/resource_spec.rb +11 -10
  178. data/spec/unit/settings_spec.rb +543 -228
  179. data/spec/unit/ssl/base_spec.rb +0 -1
  180. data/spec/unit/ssl/host_spec.rb +0 -5
  181. data/spec/unit/ssl/ssl_provider_spec.rb +14 -8
  182. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -7
  183. data/spec/unit/transaction/event_manager_spec.rb +14 -11
  184. data/spec/unit/transaction_spec.rb +13 -4
  185. data/spec/unit/type/file/content_spec.rb +0 -1
  186. data/spec/unit/type/file/selinux_spec.rb +0 -2
  187. data/spec/unit/type/file_spec.rb +0 -6
  188. data/spec/unit/type/group_spec.rb +13 -6
  189. data/spec/unit/type/resources_spec.rb +7 -7
  190. data/spec/unit/type/service_spec.rb +1 -1
  191. data/spec/unit/type/tidy_spec.rb +0 -1
  192. data/spec/unit/type_spec.rb +2 -2
  193. data/spec/unit/util/at_fork_spec.rb +2 -2
  194. data/spec/unit/util/autoload_spec.rb +5 -1
  195. data/spec/unit/util/backups_spec.rb +1 -2
  196. data/spec/unit/util/execution_spec.rb +15 -11
  197. data/spec/unit/util/inifile_spec.rb +6 -14
  198. data/spec/unit/util/log_spec.rb +8 -7
  199. data/spec/unit/util/logging_spec.rb +3 -3
  200. data/spec/unit/util/posix_spec.rb +363 -15
  201. data/spec/unit/util/rubygems_spec.rb +2 -2
  202. data/spec/unit/util/selinux_spec.rb +76 -52
  203. data/spec/unit/util/storage_spec.rb +3 -1
  204. data/spec/unit/util/suidmanager_spec.rb +44 -41
  205. data/spec/unit/util/windows/sid_spec.rb +6 -0
  206. data/spec/unit/util_spec.rb +13 -6
  207. metadata +31 -16
  208. data/spec/integration/application/config_spec.rb +0 -74
  209. data/spec/lib/matchers/include.rb +0 -27
  210. data/spec/lib/matchers/include_spec.rb +0 -32
  211. data/spec/unit/face/catalog_spec.rb +0 -6
  212. data/spec/unit/face/module_spec.rb +0 -3
@@ -58,6 +58,18 @@ module Puppet
58
58
  end
59
59
  end
60
60
 
61
+ def self.default_cadir
62
+ return "" if Puppet::Util::Platform.windows?
63
+ old_ca_dir = "#{Puppet[:ssldir]}/ca"
64
+ new_ca_dir = '/etc/puppetlabs/puppetserver/ca'
65
+
66
+ if File.exist?("#{new_ca_dir}/ca_crt.pem")
67
+ new_ca_dir
68
+ else
69
+ old_ca_dir
70
+ end
71
+ end
72
+
61
73
  ############################################################################################
62
74
  # NOTE: For information about the available values for the ":type" property of settings,
63
75
  # see the docs for Settings.define_settings
@@ -77,7 +89,8 @@ module Puppet
77
89
  the "facter-ng" gem). This is not necessary if Facter 3.x or later is installed.
78
90
  This setting is still experimental.',
79
91
  :hook => proc do |value|
80
- if value
92
+ value = munge(value)
93
+ if value && Puppet::Util::Package.versioncmp(Facter.value('facterversion'), '4.0.0') < 0
81
94
  begin
82
95
  original_facter = Object.const_get(:Facter)
83
96
  Object.send(:remove_const, :Facter)
@@ -632,7 +645,7 @@ module Puppet
632
645
  :http_proxy_password =>{
633
646
  :default => "none",
634
647
  :hook => proc do |value|
635
- if settings[:http_proxy_password] =~ /[@!# \/]/
648
+ if value =~ /[@!# \/]/
636
649
  raise "Passwords set in the http_proxy_password setting must be valid as part of a URL, and any reserved characters must be URL-encoded. We received: #{value}"
637
650
  end
638
651
  end,
@@ -841,7 +854,10 @@ Valid values are 0 (never cache) and 15 (15 second minimum wait time).
841
854
  **Note:** You must set the certname in the main section of the puppet.conf file. Setting it in a different section causes errors.
842
855
 
843
856
  Defaults to the node's fully qualified domain name.",
844
- :hook => proc { |value| raise(ArgumentError, _("Certificate names must be lower case")) unless value == value.downcase }},
857
+ :call_hook => :on_initialize_and_write,
858
+ :hook => proc { |value|
859
+ raise(ArgumentError, _("Certificate names must be lower case")) unless value == value.downcase
860
+ }},
845
861
  :dns_alt_names => {
846
862
  :default => '',
847
863
  :desc => <<EOT,
@@ -1081,6 +1097,14 @@ EOT
1081
1097
  certificate revocation checking and does not attempt to download the CRL.
1082
1098
  EOT
1083
1099
  },
1100
+ :ciphers => {
1101
+ :default => 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256',
1102
+ :type => :string,
1103
+ :desc => "The list of ciphersuites for TLS connections initiated by puppet. The
1104
+ default value is chosen to support TLS 1.0 and up, but can be made
1105
+ more restrictive if needed. The ciphersuites must be specified in OpenSSL
1106
+ format, not IANA."
1107
+ },
1084
1108
  :key_type => {
1085
1109
  :default => 'rsa',
1086
1110
  :type => :enum,
@@ -1124,7 +1148,7 @@ EOT
1124
1148
  :type => :string,
1125
1149
  :desc => "Where to send log messages. Choose between 'syslog' (the POSIX syslog
1126
1150
  service), 'eventlog' (the Windows Event Log), 'console', or the path to a log
1127
- file."
1151
+ file. Multiple destinations can be set using a comma separated list (eg: `/path/file1,console,/path/file2`)"
1128
1152
  # Sure would be nice to set the Puppet::Util::Log destination here in an :on_initialize_and_write hook,
1129
1153
  # unfortunately we have a large number of tests that rely on the logging not resetting itself when the
1130
1154
  # settings are initialized as they test what gets logged during settings initialization.
@@ -1138,7 +1162,7 @@ EOT
1138
1162
  :desc => "The name to use the Certificate Authority certificate.",
1139
1163
  },
1140
1164
  :cadir => {
1141
- :default => "$ssldir/ca",
1165
+ :default => lambda { default_cadir },
1142
1166
  :type => :directory,
1143
1167
  :desc => "The root directory for the certificate authority.",
1144
1168
  },
@@ -1367,23 +1391,15 @@ EOT
1367
1391
  by `puppet`, and should only be set if you're writing your own Puppet
1368
1392
  executable.",
1369
1393
  },
1370
- :serverport => {
1371
- :default => 8140,
1372
- :desc => "The default port puppet subcommands use to communicate
1373
- with Puppet Server. (eg `puppet facts upload`, `puppet agent`). May be
1374
- overridden by more specific settings (see `ca_port`, `report_port`).",
1375
- :hook => proc do |value|
1376
- Puppet[:masterport] = value unless Puppet.settings.set_by_config?(:masterport)
1377
- end
1378
- },
1379
1394
  :masterport => {
1380
1395
  :default => 8140,
1381
1396
  :desc => "The default port puppet subcommands use to communicate
1382
1397
  with Puppet Server. (eg `puppet facts upload`, `puppet agent`). May be
1383
1398
  overridden by more specific settings (see `ca_port`, `report_port`).",
1384
- :hook => proc do |value|
1385
- Puppet[:serverport] = value unless Puppet.settings.set_by_config?(:serverport)
1386
- end
1399
+ },
1400
+ :serverport => {
1401
+ :type => :alias,
1402
+ :alias_for => :masterport
1387
1403
  },
1388
1404
  :node_name => {
1389
1405
  :default => 'cert',
@@ -1764,7 +1780,7 @@ EOT
1764
1780
  },
1765
1781
  :agent_disabled_lockfile => {
1766
1782
  :default => "$statedir/agent_disabled.lock",
1767
- :type => :file,
1783
+ :type => :string,
1768
1784
  :desc => "A lock file to indicate that puppet agent runs have been administratively
1769
1785
  disabled. File contains a JSON object with state information.",
1770
1786
  },
@@ -1874,7 +1890,11 @@ EOT
1874
1890
  :default => "$statedir/last_run_report.yaml",
1875
1891
  :type => :file,
1876
1892
  :mode => "0640",
1877
- :desc => "Where puppet agent stores the last run report in yaml format."
1893
+ :desc => "Where Puppet Agent stores the last run report, by default, in yaml format.
1894
+ The format of the report can be changed by setting the `cache` key of the `report` terminus
1895
+ in the [routes.yaml](https://puppet.com/docs/puppet/latest/config_file_routes.html) file.
1896
+ To avoid mismatches between content and file extension, this setting needs to be
1897
+ manually updated to reflect the terminus changes."
1878
1898
  },
1879
1899
  :graph => {
1880
1900
  :default => false,
@@ -2218,12 +2238,18 @@ EOT
2218
2238
  :func3x_check => {
2219
2239
  :default => true,
2220
2240
  :type => :boolean,
2221
- :desc => <<-'EOT'
2241
+ :desc => <<-'EOT',
2222
2242
  Causes validation of loaded legacy Ruby functions (3x API) to raise errors about illegal constructs that
2223
2243
  could cause harm or that simply does not work. This flag is on by default. This flag is made available
2224
2244
  so that the validation can be turned off in case the method of validation is faulty - if encountered, please
2225
2245
  file a bug report.
2226
2246
  EOT
2247
+ :call_hook => :on_initialize_and_write,
2248
+ :hook => proc do |value|
2249
+ unless value
2250
+ Puppet.deprecation_warning(_("The 'func3x_check' setting is deprecated and will be removed in a future release."))
2251
+ end
2252
+ end
2227
2253
  },
2228
2254
  :tasks => {
2229
2255
  :default => false,
@@ -225,6 +225,9 @@ module Puppet::Environments
225
225
  private
226
226
 
227
227
  def create_environment(name)
228
+ # interpolated modulepaths may be cached from prior environment instances
229
+ Puppet.settings.clear_environment_settings(name)
230
+
228
231
  env_symbol = name.intern
229
232
  setting_values = Puppet.settings.values(env_symbol, Puppet.settings.preferred_run_mode)
230
233
  env = Puppet::Node::Environment.create(
@@ -346,17 +349,23 @@ module Puppet::Environments
346
349
  @loader = loader
347
350
  @cache_expiration_service = Puppet::Environments::Cached.cache_expiration_service
348
351
  @cache = {}
349
-
350
- # Holds expiration times in sorted order - next to expire is first
351
- @expirations = SortedSet.new
352
-
353
- # Infinity since it there are no entries, this is a cache of the first to expire time
354
- @next_expiration = END_OF_TIME
355
352
  end
356
353
 
357
354
  # @!macro loader_list
358
355
  def list
359
- @loader.list
356
+ # Evict all that have expired, in the same way as `get`
357
+ clear_all_expired
358
+
359
+ @loader.list.map do |env|
360
+ name = env.name
361
+ old_entry = @cache[name]
362
+ if old_entry
363
+ old_entry.value
364
+ else
365
+ add_entry(name, entry(env))
366
+ env
367
+ end
368
+ end
360
369
  end
361
370
 
362
371
  # @!macro loader_search_paths
@@ -379,7 +388,6 @@ module Puppet::Environments
379
388
  elsif (result = @loader.get(name))
380
389
  # environment loaded, cache it
381
390
  cache_entry = entry(result)
382
- @cache_expiration_service.created(result)
383
391
  add_entry(name, cache_entry)
384
392
  result
385
393
  end
@@ -389,28 +397,36 @@ module Puppet::Environments
389
397
  def add_entry(name, cache_entry)
390
398
  Puppet.debug {"Caching environment '#{name}' #{cache_entry.label}"}
391
399
  @cache[name] = cache_entry
392
- expires = cache_entry.expires
393
- @expirations.add(expires)
394
- if @next_expiration > expires
395
- @next_expiration = expires
396
- end
400
+ @cache_expiration_service.created(cache_entry.value)
397
401
  end
398
402
  private :add_entry
399
403
 
404
+ def clear_entry(name, entry)
405
+ @cache.delete(name)
406
+ Puppet.debug {"Evicting cache entry for environment '#{name}'"}
407
+ @cache_expiration_service.evicted(name.to_sym)
408
+ Puppet::GettextConfig.delete_text_domain(name)
409
+ Puppet.settings.clear_environment_settings(name)
410
+ end
411
+ private :clear_entry
412
+
400
413
  # Clears the cache of the environment with the given name.
401
414
  # (The intention is that this could be used from a MANUAL cache eviction command (TBD)
402
415
  def clear(name)
403
- @cache.delete(name)
404
- Puppet::GettextConfig.delete_text_domain(name)
416
+ entry = @cache[name]
417
+ clear_entry(name, entry) if entry
405
418
  end
406
419
 
407
420
  # Clears all cached environments.
408
421
  # (The intention is that this could be used from a MANUAL cache eviction command (TBD)
409
- def clear_all()
422
+ def clear_all
410
423
  super
424
+
425
+ @cache.each_pair do |name, entry|
426
+ clear_entry(name, entry)
427
+ end
428
+
411
429
  @cache = {}
412
- @expirations.clear
413
- @next_expiration = END_OF_TIME
414
430
  Puppet::GettextConfig.delete_environment_text_domains
415
431
  end
416
432
 
@@ -419,18 +435,24 @@ module Puppet::Environments
419
435
  #
420
436
  def clear_all_expired()
421
437
  t = Time.now
422
- return if t < @next_expiration && ! @cache.any? {|name, _| @cache_expiration_service.expired?(name.to_sym) }
423
- to_expire = @cache.select { |name, entry| entry.expires < t || @cache_expiration_service.expired?(name.to_sym) }
424
- to_expire.each do |name, entry|
425
- Puppet.debug {"Evicting cache entry for environment '#{name}'"}
426
- @cache_expiration_service.evicted(name.to_sym)
427
- clear(name)
428
- @expirations.delete(entry.expires)
429
- Puppet.settings.clear_environment_settings(name)
438
+
439
+ @cache.each_pair do |name, entry|
440
+ clear_if_expired(name, entry, t)
430
441
  end
431
- @next_expiration = @expirations.first || END_OF_TIME
432
442
  end
433
443
 
444
+ # Clear an environment if it is expired, either by exceeding its time to live, or
445
+ # through an explicit eviction determined by the cache expiration service.
446
+ #
447
+ def clear_if_expired(name, entry, t = Time.now)
448
+ return unless entry
449
+
450
+ if entry.expired?(t) || @cache_expiration_service.expired?(name.to_sym)
451
+ clear_entry(name, entry)
452
+ end
453
+ end
454
+ private :clear_if_expired
455
+
434
456
  # This implementation evicts the cache, and always gets the current
435
457
  # configuration of the environment
436
458
  #
@@ -440,7 +462,7 @@ module Puppet::Environments
440
462
  #
441
463
  # @!macro loader_get_conf
442
464
  def get_conf(name)
443
- evict_if_expired(name)
465
+ clear_if_expired(name, @cache[name])
444
466
  @loader.get_conf(name)
445
467
  end
446
468
 
@@ -467,17 +489,6 @@ module Puppet::Environments
467
489
  end
468
490
  end
469
491
 
470
- # Evicts the entry if it has expired
471
- # Also clears caches in Settings that may prevent the entry from being updated
472
- def evict_if_expired(name)
473
- if (result = @cache[name]) && (result.expired? || @cache_expiration_service.expired?(name.to_sym))
474
- Puppet.debug {"Evicting cache entry for environment '#{name}'"}
475
- @cache_expiration_service.evicted(name.to_sym)
476
- clear(name)
477
- Puppet.settings.clear_environment_settings(name)
478
- end
479
- end
480
-
481
492
  # Never evicting entry
482
493
  class Entry
483
494
  attr_reader :value
@@ -489,32 +500,24 @@ module Puppet::Environments
489
500
  def touch
490
501
  end
491
502
 
492
- def expired?
503
+ def expired?(now)
493
504
  false
494
505
  end
495
506
 
496
507
  def label
497
508
  ""
498
509
  end
499
-
500
- def expires
501
- END_OF_TIME
502
- end
503
510
  end
504
511
 
505
512
  # Always evicting entry
506
513
  class NotCachedEntry < Entry
507
- def expired?
514
+ def expired?(now)
508
515
  true
509
516
  end
510
517
 
511
518
  def label
512
519
  "(ttl = 0 sec)"
513
520
  end
514
-
515
- def expires
516
- START_OF_TIME
517
- end
518
521
  end
519
522
 
520
523
  # Policy that expires in ttl_seconds from when it was created
@@ -525,17 +528,13 @@ module Puppet::Environments
525
528
  @ttl_seconds = ttl_seconds
526
529
  end
527
530
 
528
- def expired?
529
- Time.now > @ttl
531
+ def expired?(now)
532
+ now > @ttl
530
533
  end
531
534
 
532
535
  def label
533
536
  "(ttl = #{@ttl_seconds} sec)"
534
537
  end
535
-
536
- def expires
537
- @ttl
538
- end
539
538
  end
540
539
 
541
540
  # Policy that expires if it hasn't been touched within ttl_seconds
@@ -159,6 +159,16 @@ https://puppet.com/docs/puppet/latest/configuration.html#environment
159
159
  report_section_and_environment(options[:section], Puppet.settings[:environment])
160
160
  end
161
161
 
162
+ # only validate settings we recognize
163
+ setting = Puppet.settings.setting(name.to_sym)
164
+ if setting
165
+ # set the value, which will call `on_*_and_write` hooks, if any
166
+ Puppet.settings[setting.name] = value
167
+
168
+ # read the value to trigger interpolation and munge validation logic
169
+ Puppet.settings[setting.name]
170
+ end
171
+
162
172
  path = Puppet::FileSystem.pathname(Puppet.settings.which_configuration_file)
163
173
  Puppet::FileSystem.touch(path)
164
174
  Puppet::FileSystem.open(path, nil, 'r+:UTF-8') do |file|
@@ -440,7 +440,12 @@ Puppet::Face.define(:epp, '0.0.1') do
440
440
 
441
441
  def render_inline(epp_source, compiler, options)
442
442
  template_args = get_values(compiler, options)
443
- Puppet::Pops::Evaluator::EppEvaluator.inline_epp(compiler.topscope, epp_source, template_args)
443
+ result = Puppet::Pops::Evaluator::EppEvaluator.inline_epp(compiler.topscope, epp_source, template_args)
444
+ if result.instance_of?(Puppet::Pops::Types::PSensitiveType::Sensitive)
445
+ result.unwrap
446
+ else
447
+ result
448
+ end
444
449
  end
445
450
 
446
451
  def render_file(epp_template_name, compiler, options, show_filename, file_nbr)
@@ -457,7 +462,12 @@ Puppet::Face.define(:epp, '0.0.1') do
457
462
  if template_file.nil? && Puppet::FileSystem.exist?(epp_template_name)
458
463
  epp_template_name = File.expand_path(epp_template_name)
459
464
  end
460
- output << Puppet::Pops::Evaluator::EppEvaluator.epp(compiler.topscope, epp_template_name, compiler.environment, template_args)
465
+ result = Puppet::Pops::Evaluator::EppEvaluator.epp(compiler.topscope, epp_template_name, compiler.environment, template_args)
466
+ if result.instance_of?(Puppet::Pops::Types::PSensitiveType::Sensitive)
467
+ output << result.unwrap
468
+ else
469
+ output << result
470
+ end
461
471
  rescue Puppet::ParseError => detail
462
472
  Puppet.err("--- #{epp_template_name}") if show_filename
463
473
  raise detail
@@ -1,5 +1,21 @@
1
1
  require 'puppet/indirector/face'
2
2
  require 'puppet/node/facts'
3
+ require 'puppet/util/fact_dif'
4
+
5
+ EXCLUDE_LIST = %w[ ^facterversion$
6
+ ^load_averages\..*$
7
+ ^processors\.speed$
8
+ ^swapfree$ ^swapfree_mb$
9
+ ^memoryfree$ ^memoryfree_mb$
10
+ ^memory\.swap\.available_bytes$ ^memory\.swap\.used_bytes$
11
+ ^memory\.swap\.available$ ^memory\.swap\.capacity$ ^memory\.swap\.used$
12
+ ^memory\.system\.available_bytes$ ^memory\.system\.used_bytes$
13
+ ^memory\.system\.available$ ^memory\.system\.capacity$ ^memory\.system\.used$
14
+ ^mountpoints\..*\.available.*$ ^mountpoints\..*\.capacity$ ^mountpoints\..*\.used.*$
15
+ ^sp_uptime$ ^system_profiler\.uptime$
16
+ ^uptime$ ^uptime_days$ ^uptime_hours$ ^uptime_seconds$
17
+ ^system_uptime\.uptime$ ^system_uptime\.days$ ^system_uptime\.hours$ ^system_uptime\.seconds$
18
+ ]
3
19
 
4
20
  Puppet::Indirector::Face.define(:facts, '0.0.1') do
5
21
  copyright "Puppet Inc.", 2011
@@ -87,4 +103,146 @@ Puppet::Indirector::Face.define(:facts, '0.0.1') do
87
103
  nil
88
104
  end
89
105
  end
106
+
107
+ action(:diff) do
108
+ summary _("Compare Facter 3 output with Facter 4 output")
109
+ description <<-'EOT'
110
+ Compares output from facter 3 with Facter 4 and prints the differences
111
+ EOT
112
+ returns "Differences between Facter 3 and Facter 4 output as an array."
113
+ notes <<-'EOT'
114
+ EOT
115
+ examples <<-'EOT'
116
+ get differences between facter versions:
117
+ $ puppet facts diff
118
+ EOT
119
+
120
+ option("--structured") do
121
+ default_to { false }
122
+ summary _("Render the different facts as structured.")
123
+ end
124
+
125
+ option("--exclude " + _("<regex>")) do
126
+ summary _("Regex used to exclude specific facts from diff.")
127
+ end
128
+
129
+ when_invoked do |*args|
130
+ options = args.pop
131
+
132
+ Puppet.settings.preferred_run_mode = :agent
133
+ Puppet::Node::Facts.indirection.terminus_class = :facter
134
+
135
+ if Puppet::Util::Package.versioncmp(Facter.value('facterversion'), '4.0.0') < 0
136
+ cmd_flags = '--render-as json --show-legacy'
137
+
138
+ # puppet/ruby are in PATH since it was updated in the wrapper script
139
+ puppet_show_cmd = "puppet facts show"
140
+ if Puppet::Util::Platform.windows?
141
+ puppet_show_cmd = "ruby -S -- #{puppet_show_cmd}"
142
+ end
143
+
144
+ facter_3_result = Puppet::Util::Execution.execute("#{puppet_show_cmd} --no-facterng #{cmd_flags}", combine: false)
145
+ facter_ng_result = Puppet::Util::Execution.execute("#{puppet_show_cmd} --facterng #{cmd_flags}", combine: false)
146
+
147
+ exclude_list = options[:exclude].nil? ? EXCLUDE_LIST : EXCLUDE_LIST + [ options[:exclude] ]
148
+ fact_diff = FactDif.new(facter_3_result, facter_ng_result, exclude_list, options[:structured])
149
+ fact_diff.difs
150
+ else
151
+ Puppet.warning _("Already using Facter 4. To use `puppet facts diff` remove facterng from the .conf file or run `puppet config set facterng false`.")
152
+ exit 0
153
+ end
154
+ end
155
+
156
+ when_rendering :console do |result|
157
+ case result
158
+ when Array, Hash
159
+ Puppet::Util::Json.dump(result, :pretty => true)
160
+ else
161
+ result
162
+ end
163
+ end
164
+ end
165
+
166
+ action(:show) do
167
+ summary _("Retrieve current node's facts.")
168
+ arguments _("[<facts>]")
169
+ description <<-'EOT'
170
+ Reads facts from the local system using `facter` terminus.
171
+ A query can be provided to retrieve just a specific fact or a set of facts.
172
+ EOT
173
+ returns "The output of facter with added puppet specific facts."
174
+ notes <<-'EOT'
175
+
176
+ EOT
177
+ examples <<-'EOT'
178
+ retrieve facts:
179
+
180
+ $ puppet facts show os
181
+ EOT
182
+
183
+ option("--config-file " + _("<path>")) do
184
+ default_to { nil }
185
+ summary _("The location of the config file for Facter.")
186
+ end
187
+
188
+ option("--custom-dir " + _("<path>")) do
189
+ default_to { nil }
190
+ summary _("The path to a directory that contains custom facts.")
191
+ end
192
+
193
+ option("--external-dir " + _("<path>")) do
194
+ default_to { nil }
195
+ summary _("The path to a directory that contains external facts.")
196
+ end
197
+
198
+ option("--no-block") do
199
+ summary _("Disable fact blocking mechanism.")
200
+ end
201
+
202
+ option("--no-cache") do
203
+ summary _("Disable fact caching mechanism.")
204
+ end
205
+
206
+ option("--show-legacy") do
207
+ summary _("Show legacy facts when querying all facts.")
208
+ end
209
+
210
+ option("--value-only") do
211
+ summary _("Show only the value when the action is called with a single query")
212
+ end
213
+
214
+ when_invoked do |*args|
215
+ options = args.pop
216
+
217
+ Puppet.settings.preferred_run_mode = :agent
218
+ Puppet::Node::Facts.indirection.terminus_class = :facter
219
+
220
+ if options[:value_only] && !args.count.eql?(1)
221
+ options[:value_only] = nil
222
+ Puppet.warning("Incorrect use of --value-only argument; it can only be used when querying for a single fact!")
223
+ end
224
+
225
+ options[:user_query] = args
226
+ options[:resolve_options] = true
227
+ result = Puppet::Node::Facts.indirection.find(Puppet.settings[:certname], options)
228
+
229
+ if options[:value_only]
230
+ result.values.values.first
231
+ else
232
+ result.values
233
+ end
234
+ end
235
+
236
+ when_rendering :console do |result|
237
+ # VALID_TYPES = [Integer, Float, TrueClass, FalseClass, NilClass, Symbol, String, Array, Hash].freeze
238
+ # from https://github.com/puppetlabs/facter/blob/4.0.49/lib/facter/custom_facts/util/normalization.rb#L8
239
+
240
+ case result
241
+ when Array, Hash
242
+ Puppet::Util::Json.dump(result, :pretty => true)
243
+ else # one of VALID_TYPES above
244
+ result
245
+ end
246
+ end
247
+ end
90
248
  end