puppet 6.19.1 → 6.20.0

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

Potentially problematic release.


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

Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +2 -16
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +30 -25
  5. data/lib/puppet/application.rb +10 -6
  6. data/lib/puppet/application/agent.rb +1 -0
  7. data/lib/puppet/application/apply.rb +3 -2
  8. data/lib/puppet/application/device.rb +1 -0
  9. data/lib/puppet/application/filebucket.rb +2 -2
  10. data/lib/puppet/application/script.rb +1 -0
  11. data/lib/puppet/application_support.rb +7 -0
  12. data/lib/puppet/configurer.rb +28 -18
  13. data/lib/puppet/defaults.rb +24 -18
  14. data/lib/puppet/environments.rb +38 -54
  15. data/lib/puppet/face/config.rb +10 -0
  16. data/lib/puppet/face/epp.rb +12 -2
  17. data/lib/puppet/face/facts.rb +60 -0
  18. data/lib/puppet/ffi/posix.rb +10 -0
  19. data/lib/puppet/ffi/posix/constants.rb +14 -0
  20. data/lib/puppet/ffi/posix/functions.rb +24 -0
  21. data/lib/puppet/functions/epp.rb +1 -0
  22. data/lib/puppet/functions/inline_epp.rb +1 -0
  23. data/lib/puppet/indirector/fact_search.rb +60 -0
  24. data/lib/puppet/indirector/facts/json.rb +27 -0
  25. data/lib/puppet/indirector/facts/yaml.rb +3 -58
  26. data/lib/puppet/indirector/json.rb +5 -1
  27. data/lib/puppet/indirector/node/json.rb +8 -0
  28. data/lib/puppet/indirector/report/json.rb +34 -0
  29. data/lib/puppet/module_tool/applications/installer.rb +48 -2
  30. data/lib/puppet/module_tool/errors/shared.rb +17 -2
  31. data/lib/puppet/network/formats.rb +2 -1
  32. data/lib/puppet/pal/pal_impl.rb +70 -17
  33. data/lib/puppet/parser/ast/leaf.rb +3 -2
  34. data/lib/puppet/parser/templatewrapper.rb +1 -1
  35. data/lib/puppet/pops/evaluator/deferred_resolver.rb +5 -3
  36. data/lib/puppet/pops/evaluator/evaluator_impl.rb +22 -3
  37. data/lib/puppet/pops/model/ast_transformer.rb +1 -1
  38. data/lib/puppet/provider/package/apt.rb +4 -0
  39. data/lib/puppet/provider/user/aix.rb +2 -2
  40. data/lib/puppet/reference/configuration.rb +6 -5
  41. data/lib/puppet/settings.rb +33 -28
  42. data/lib/puppet/settings/alias_setting.rb +37 -0
  43. data/lib/puppet/settings/base_setting.rb +26 -2
  44. data/lib/puppet/util/autoload.rb +1 -8
  45. data/lib/puppet/util/fact_dif.rb +62 -0
  46. data/lib/puppet/util/posix.rb +54 -5
  47. data/lib/puppet/util/rubygems.rb +5 -1
  48. data/lib/puppet/version.rb +1 -1
  49. data/locales/puppet.pot +188 -164
  50. data/man/man5/puppet.conf.5 +6 -6
  51. data/man/man8/puppet-agent.8 +2 -2
  52. data/man/man8/puppet-apply.8 +2 -2
  53. data/man/man8/puppet-catalog.8 +1 -1
  54. data/man/man8/puppet-config.8 +1 -1
  55. data/man/man8/puppet-describe.8 +1 -1
  56. data/man/man8/puppet-device.8 +2 -2
  57. data/man/man8/puppet-doc.8 +1 -1
  58. data/man/man8/puppet-epp.8 +1 -1
  59. data/man/man8/puppet-facts.8 +32 -1
  60. data/man/man8/puppet-filebucket.8 +3 -3
  61. data/man/man8/puppet-generate.8 +1 -1
  62. data/man/man8/puppet-help.8 +1 -1
  63. data/man/man8/puppet-key.8 +1 -1
  64. data/man/man8/puppet-lookup.8 +1 -1
  65. data/man/man8/puppet-man.8 +1 -1
  66. data/man/man8/puppet-module.8 +1 -1
  67. data/man/man8/puppet-node.8 +4 -1
  68. data/man/man8/puppet-parser.8 +1 -1
  69. data/man/man8/puppet-plugin.8 +1 -1
  70. data/man/man8/puppet-report.8 +4 -1
  71. data/man/man8/puppet-resource.8 +1 -1
  72. data/man/man8/puppet-script.8 +2 -2
  73. data/man/man8/puppet-ssl.8 +1 -1
  74. data/man/man8/puppet-status.8 +1 -1
  75. data/man/man8/puppet.8 +2 -2
  76. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +91 -0
  77. data/spec/fixtures/unit/provider/user/aix/aix_passwd_file.out +4 -0
  78. data/spec/integration/application/agent_spec.rb +127 -3
  79. data/spec/integration/application/apply_spec.rb +19 -0
  80. data/spec/integration/defaults_spec.rb +0 -7
  81. data/spec/integration/environments/setting_hooks_spec.rb +1 -1
  82. data/spec/integration/resource/type_collection_spec.rb +2 -6
  83. data/spec/integration/transaction_spec.rb +4 -9
  84. data/spec/integration/util/windows/adsi_spec.rb +3 -1
  85. data/spec/integration/util/windows/registry_spec.rb +0 -10
  86. data/spec/lib/puppet_spec/settings.rb +6 -1
  87. data/spec/spec_helper.rb +1 -4
  88. data/spec/unit/agent_spec.rb +8 -6
  89. data/spec/unit/application/agent_spec.rb +0 -1
  90. data/spec/unit/application/config_spec.rb +224 -4
  91. data/spec/unit/application/filebucket_spec.rb +0 -2
  92. data/spec/unit/application_spec.rb +51 -9
  93. data/spec/unit/confine/feature_spec.rb +1 -1
  94. data/spec/unit/confine_spec.rb +8 -2
  95. data/spec/unit/defaults_spec.rb +20 -1
  96. data/spec/unit/environments_spec.rb +96 -19
  97. data/spec/unit/face/config_spec.rb +27 -32
  98. data/spec/unit/face/node_spec.rb +0 -11
  99. data/spec/unit/file_serving/configuration/parser_spec.rb +0 -1
  100. data/spec/unit/file_serving/metadata_spec.rb +3 -3
  101. data/spec/unit/file_serving/terminus_helper_spec.rb +11 -4
  102. data/spec/unit/forge/module_release_spec.rb +2 -7
  103. data/spec/unit/functions/inline_epp_spec.rb +26 -1
  104. data/spec/unit/http/service/compiler_spec.rb +49 -0
  105. data/spec/unit/http/service_spec.rb +1 -1
  106. data/spec/unit/indirector/face_spec.rb +0 -1
  107. data/spec/unit/indirector/facts/facter_spec.rb +0 -1
  108. data/spec/unit/indirector/facts/json_spec.rb +255 -0
  109. data/spec/unit/indirector/file_bucket_file/selector_spec.rb +26 -8
  110. data/spec/unit/indirector/indirection_spec.rb +8 -12
  111. data/spec/unit/indirector/key/file_spec.rb +0 -1
  112. data/spec/unit/indirector/node/json_spec.rb +33 -0
  113. data/spec/{integration/indirector/report/yaml.rb → unit/indirector/report/json_spec.rb} +13 -24
  114. data/spec/unit/indirector/report/yaml_spec.rb +72 -8
  115. data/spec/unit/indirector_spec.rb +2 -2
  116. data/spec/unit/module_tool/applications/installer_spec.rb +66 -0
  117. data/spec/unit/network/authconfig_spec.rb +0 -3
  118. data/spec/unit/network/http/api/indirected_routes_spec.rb +0 -9
  119. data/spec/unit/network/http/handler_spec.rb +0 -5
  120. data/spec/unit/parser/compiler_spec.rb +3 -19
  121. data/spec/unit/parser/resource_spec.rb +14 -8
  122. data/spec/unit/parser/templatewrapper_spec.rb +4 -3
  123. data/spec/unit/pops/evaluator/deferred_resolver_spec.rb +20 -0
  124. data/spec/unit/property_spec.rb +1 -0
  125. data/spec/unit/provider/nameservice_spec.rb +66 -65
  126. data/spec/unit/provider/package/apt_spec.rb +4 -8
  127. data/spec/unit/provider/package/base_spec.rb +6 -5
  128. data/spec/unit/provider/package/pacman_spec.rb +18 -12
  129. data/spec/unit/provider/package/pip_spec.rb +6 -11
  130. data/spec/unit/provider/package/pkgdmg_spec.rb +0 -4
  131. data/spec/unit/provider/user/aix_spec.rb +5 -0
  132. data/spec/unit/provider/user/hpux_spec.rb +1 -1
  133. data/spec/unit/provider/user/pw_spec.rb +2 -0
  134. data/spec/unit/provider/user/useradd_spec.rb +1 -0
  135. data/spec/unit/provider_spec.rb +8 -10
  136. data/spec/unit/puppet_pal_catalog_spec.rb +45 -0
  137. data/spec/unit/resource/capability_finder_spec.rb +6 -1
  138. data/spec/unit/resource/type_spec.rb +1 -1
  139. data/spec/unit/resource_spec.rb +11 -10
  140. data/spec/unit/settings_spec.rb +419 -242
  141. data/spec/unit/ssl/base_spec.rb +0 -1
  142. data/spec/unit/ssl/host_spec.rb +0 -5
  143. data/spec/unit/ssl/ssl_provider_spec.rb +14 -8
  144. data/spec/unit/transaction/additional_resource_generator_spec.rb +3 -7
  145. data/spec/unit/transaction/event_manager_spec.rb +14 -11
  146. data/spec/unit/transaction_spec.rb +13 -4
  147. data/spec/unit/type/file/content_spec.rb +0 -1
  148. data/spec/unit/type/file/selinux_spec.rb +0 -2
  149. data/spec/unit/type/file_spec.rb +0 -6
  150. data/spec/unit/type/group_spec.rb +13 -6
  151. data/spec/unit/type/resources_spec.rb +7 -7
  152. data/spec/unit/type/service_spec.rb +1 -1
  153. data/spec/unit/type/tidy_spec.rb +0 -1
  154. data/spec/unit/type_spec.rb +2 -2
  155. data/spec/unit/util/at_fork_spec.rb +2 -2
  156. data/spec/unit/util/autoload_spec.rb +5 -1
  157. data/spec/unit/util/backups_spec.rb +1 -2
  158. data/spec/unit/util/execution_spec.rb +15 -11
  159. data/spec/unit/util/inifile_spec.rb +6 -14
  160. data/spec/unit/util/log_spec.rb +8 -7
  161. data/spec/unit/util/logging_spec.rb +3 -3
  162. data/spec/unit/util/posix_spec.rb +363 -15
  163. data/spec/unit/util/rubygems_spec.rb +2 -2
  164. data/spec/unit/util/selinux_spec.rb +76 -52
  165. data/spec/unit/util/storage_spec.rb +3 -1
  166. data/spec/unit/util/suidmanager_spec.rb +44 -41
  167. data/spec/unit/util_spec.rb +13 -6
  168. metadata +21 -10
  169. data/spec/integration/application/config_spec.rb +0 -74
  170. data/spec/unit/face/catalog_spec.rb +0 -6
  171. data/spec/unit/face/module_spec.rb +0 -3
@@ -346,12 +346,6 @@ module Puppet::Environments
346
346
  @loader = loader
347
347
  @cache_expiration_service = Puppet::Environments::Cached.cache_expiration_service
348
348
  @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
349
  end
356
350
 
357
351
  # @!macro loader_list
@@ -379,7 +373,6 @@ module Puppet::Environments
379
373
  elsif (result = @loader.get(name))
380
374
  # environment loaded, cache it
381
375
  cache_entry = entry(result)
382
- @cache_expiration_service.created(result)
383
376
  add_entry(name, cache_entry)
384
377
  result
385
378
  end
@@ -389,28 +382,36 @@ module Puppet::Environments
389
382
  def add_entry(name, cache_entry)
390
383
  Puppet.debug {"Caching environment '#{name}' #{cache_entry.label}"}
391
384
  @cache[name] = cache_entry
392
- expires = cache_entry.expires
393
- @expirations.add(expires)
394
- if @next_expiration > expires
395
- @next_expiration = expires
396
- end
385
+ @cache_expiration_service.created(cache_entry.value)
397
386
  end
398
387
  private :add_entry
399
388
 
389
+ def clear_entry(name, entry)
390
+ @cache.delete(name)
391
+ Puppet.debug {"Evicting cache entry for environment '#{name}'"}
392
+ @cache_expiration_service.evicted(name.to_sym)
393
+ Puppet::GettextConfig.delete_text_domain(name)
394
+ Puppet.settings.clear_environment_settings(name)
395
+ end
396
+ private :clear_entry
397
+
400
398
  # Clears the cache of the environment with the given name.
401
399
  # (The intention is that this could be used from a MANUAL cache eviction command (TBD)
402
400
  def clear(name)
403
- @cache.delete(name)
404
- Puppet::GettextConfig.delete_text_domain(name)
401
+ entry = @cache[name]
402
+ clear_entry(name, entry) if entry
405
403
  end
406
404
 
407
405
  # Clears all cached environments.
408
406
  # (The intention is that this could be used from a MANUAL cache eviction command (TBD)
409
- def clear_all()
407
+ def clear_all
410
408
  super
409
+
410
+ @cache.each_pair do |name, entry|
411
+ clear_entry(name, entry)
412
+ end
413
+
411
414
  @cache = {}
412
- @expirations.clear
413
- @next_expiration = END_OF_TIME
414
415
  Puppet::GettextConfig.delete_environment_text_domains
415
416
  end
416
417
 
@@ -419,18 +420,24 @@ module Puppet::Environments
419
420
  #
420
421
  def clear_all_expired()
421
422
  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)
423
+
424
+ @cache.each_pair do |name, entry|
425
+ clear_if_expired(name, entry, t)
430
426
  end
431
- @next_expiration = @expirations.first || END_OF_TIME
432
427
  end
433
428
 
429
+ # Clear an environment if it is expired, either by exceeding its time to live, or
430
+ # through an explicit eviction determined by the cache expiration service.
431
+ #
432
+ def clear_if_expired(name, entry, t = Time.now)
433
+ return unless entry
434
+
435
+ if entry.expired?(t) || @cache_expiration_service.expired?(name.to_sym)
436
+ clear_entry(name, entry)
437
+ end
438
+ end
439
+ private :clear_if_expired
440
+
434
441
  # This implementation evicts the cache, and always gets the current
435
442
  # configuration of the environment
436
443
  #
@@ -440,7 +447,7 @@ module Puppet::Environments
440
447
  #
441
448
  # @!macro loader_get_conf
442
449
  def get_conf(name)
443
- evict_if_expired(name)
450
+ clear_if_expired(name, @cache[name])
444
451
  @loader.get_conf(name)
445
452
  end
446
453
 
@@ -467,17 +474,6 @@ module Puppet::Environments
467
474
  end
468
475
  end
469
476
 
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
477
  # Never evicting entry
482
478
  class Entry
483
479
  attr_reader :value
@@ -489,32 +485,24 @@ module Puppet::Environments
489
485
  def touch
490
486
  end
491
487
 
492
- def expired?
488
+ def expired?(now)
493
489
  false
494
490
  end
495
491
 
496
492
  def label
497
493
  ""
498
494
  end
499
-
500
- def expires
501
- END_OF_TIME
502
- end
503
495
  end
504
496
 
505
497
  # Always evicting entry
506
498
  class NotCachedEntry < Entry
507
- def expired?
499
+ def expired?(now)
508
500
  true
509
501
  end
510
502
 
511
503
  def label
512
504
  "(ttl = 0 sec)"
513
505
  end
514
-
515
- def expires
516
- START_OF_TIME
517
- end
518
506
  end
519
507
 
520
508
  # Policy that expires in ttl_seconds from when it was created
@@ -525,17 +513,13 @@ module Puppet::Environments
525
513
  @ttl_seconds = ttl_seconds
526
514
  end
527
515
 
528
- def expired?
529
- Time.now > @ttl
516
+ def expired?(now)
517
+ now > @ttl
530
518
  end
531
519
 
532
520
  def label
533
521
  "(ttl = #{@ttl_seconds} sec)"
534
522
  end
535
-
536
- def expires
537
- @ttl
538
- end
539
523
  end
540
524
 
541
525
  # 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,29 @@
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
+ swapfree_mb swapsize_mb
7
+ load_averages\.*
8
+ memory\.swap\.available_bytes memory\.swap\.capacity memory\.swap\.total_bytes
9
+ memory\.swap\.used_bytes memory\.swap\.available
10
+ memory\.system\.available memory\.system\.available_bytes memory\.system\.capacity memory\.swap\.used
11
+ memory\.system\.total_bytes memory\.system\.used memory\.system\.used_bytes
12
+ memoryfree memoryfree_mb memorysize_mb
13
+ mountpoints\..* mtu_.* mountpoints\..*\.capacity
14
+ networking\.interfaces\..*\.mtu networking\.mtu partitions\..*\.filesystem
15
+ partitions\..*\.size_bytes partitions\..*\.mount partitions\..*\.uuid
16
+ disks\..*\.size_bytes
17
+ hypervisors\.lpar\.partition_number hypervisors\.xen\.privileged hypervisors\.zone\..* hypervisors\.ldom\..*
18
+ processors\.speed
19
+ ldom_.*
20
+ boardassettag dmi\.board\.asset_tag
21
+ blockdevice_.*_vendor blockdevice_.*_size
22
+ system_uptime\.days system_uptime\.hours system_uptime\.seconds system_uptime\.uptime
23
+ uptime_days uptime_hours uptime_seconds
24
+ system_profiler\.uptime
25
+ sp_uptime
26
+ uptime]
3
27
 
4
28
  Puppet::Indirector::Face.define(:facts, '0.0.1') do
5
29
  copyright "Puppet Inc.", 2011
@@ -87,4 +111,40 @@ Puppet::Indirector::Face.define(:facts, '0.0.1') do
87
111
  nil
88
112
  end
89
113
  end
114
+
115
+ action(:diff) do
116
+ summary _("Compare Facter 3 output with Facter 4 output")
117
+ description <<-'EOT'
118
+ Compares output from facter 3 with Facter 4 and prints the differences
119
+ EOT
120
+ returns "Differences between Facter 3 and Facter 4 output as an array."
121
+ notes <<-'EOT'
122
+ EOT
123
+ examples <<-'EOT'
124
+ get differences between facter versions:
125
+ $ puppet facts diff
126
+ EOT
127
+
128
+ render_as :json
129
+
130
+ when_invoked do |*args|
131
+ Puppet.settings.preferred_run_mode = :agent
132
+ Puppet::Node::Facts.indirection.terminus_class = :facter
133
+
134
+ if Puppet::Util::Package.versioncmp(Facter.value('facterversion'), '4.0.0') < 0
135
+ facter3_result = Puppet::Node::Facts.indirection.find(Puppet.settings[:certname])
136
+ begin
137
+ require 'facter-ng'
138
+ facter4_result = Puppet::Node::Facts.indirection.find(Puppet.settings[:certname])
139
+ rescue LoadError
140
+ raise ArgumentError, 'facter-ng could not be loaded'
141
+ end
142
+ fact_diff = FactDif.new(facter3_result.to_json, facter4_result.to_json, EXCLUDE_LIST)
143
+ fact_diff.difs
144
+ else
145
+ Puppet.warning _("Already using Facter 4. To use `puppet facts diff` remove facterng from the .conf file or run `puppet config set facterng false`.")
146
+ exit 0
147
+ end
148
+ end
149
+ end
90
150
  end
@@ -0,0 +1,10 @@
1
+ require 'ffi'
2
+
3
+ module Puppet
4
+ module FFI
5
+ module POSIX
6
+ require 'puppet/ffi/posix/functions'
7
+ require 'puppet/ffi/posix/constants'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ require 'puppet/ffi/posix'
2
+
3
+ module Puppet::FFI::POSIX
4
+ module Constants
5
+ extend FFI::Library
6
+
7
+ # Maximum number of supplementary groups (groups
8
+ # that a user can be in plus its primary group)
9
+ # (64 + 1 primary group)
10
+ # Chosen a reasonable middle number from the list
11
+ # https://www.j3e.de/ngroups.html
12
+ MAXIMUM_NUMBER_OF_GROUPS = 65
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ require 'puppet/ffi/posix'
2
+
3
+ module Puppet::FFI::POSIX
4
+ module Functions
5
+
6
+ extend FFI::Library
7
+
8
+ ffi_convention :stdcall
9
+
10
+ # https://man7.org/linux/man-pages/man3/getgrouplist.3.html
11
+ # int getgrouplist (
12
+ # const char *user,
13
+ # gid_t group,
14
+ # gid_t *groups,
15
+ # int *ngroups
16
+ # );
17
+ begin
18
+ ffi_lib FFI::Library::LIBC
19
+ attach_function :getgrouplist, [:string, :uint, :pointer, :pointer], :int
20
+ rescue FFI::NotFoundError
21
+ # Do nothing
22
+ end
23
+ end
24
+ end
@@ -40,6 +40,7 @@ Puppet::Functions.create_function(:epp, Puppet::Functions::InternalFunction) do
40
40
  scope_param
41
41
  param 'String', :path
42
42
  optional_param 'Hash[Pattern[/^\w+$/], Any]', :parameters
43
+ return_type 'Variant[String, Sensitive[String]]'
43
44
  end
44
45
 
45
46
  def epp(scope, path, parameters = nil)
@@ -51,6 +51,7 @@ Puppet::Functions.create_function(:inline_epp, Puppet::Functions::InternalFuncti
51
51
  scope_param()
52
52
  param 'String', :template
53
53
  optional_param 'Hash[Pattern[/^\w+$/], Any]', :parameters
54
+ return_type 'Variant[String, Sensitive[String]]'
54
55
  end
55
56
 
56
57
  def inline_epp(scope, template, parameters = nil)
@@ -0,0 +1,60 @@
1
+ # module containing common methods used by json and yaml facts indirection terminus
2
+ module Puppet::Indirector::FactSearch
3
+ def node_matches?(facts, options)
4
+ options.each do |key, value|
5
+ type, name, operator = key.to_s.split(".")
6
+ operator ||= 'eq'
7
+
8
+ return false unless node_matches_option?(type, name, operator, value, facts)
9
+ end
10
+ return true
11
+ end
12
+
13
+ def node_matches_option?(type, name, operator, value, facts)
14
+ case type
15
+ when "meta"
16
+ case name
17
+ when "timestamp"
18
+ compare_timestamp(operator, facts.timestamp, Time.parse(value))
19
+ end
20
+ when "facts"
21
+ compare_facts(operator, facts.values[name], value)
22
+ end
23
+ end
24
+
25
+ def compare_facts(operator, value1, value2)
26
+ return false unless value1
27
+
28
+ case operator
29
+ when "eq"
30
+ value1.to_s == value2.to_s
31
+ when "le"
32
+ value1.to_f <= value2.to_f
33
+ when "ge"
34
+ value1.to_f >= value2.to_f
35
+ when "lt"
36
+ value1.to_f < value2.to_f
37
+ when "gt"
38
+ value1.to_f > value2.to_f
39
+ when "ne"
40
+ value1.to_s != value2.to_s
41
+ end
42
+ end
43
+
44
+ def compare_timestamp(operator, value1, value2)
45
+ case operator
46
+ when "eq"
47
+ value1 == value2
48
+ when "le"
49
+ value1 <= value2
50
+ when "ge"
51
+ value1 >= value2
52
+ when "lt"
53
+ value1 < value2
54
+ when "gt"
55
+ value1 > value2
56
+ when "ne"
57
+ value1 != value2
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,27 @@
1
+ require 'puppet/node/facts'
2
+ require 'puppet/indirector/json'
3
+ require 'puppet/indirector/fact_search'
4
+
5
+ class Puppet::Node::Facts::Json < Puppet::Indirector::JSON
6
+ desc "Store client facts as flat files, serialized using JSON, or
7
+ return deserialized facts from disk."
8
+
9
+ include Puppet::Indirector::FactSearch
10
+
11
+ def search(request)
12
+ node_names = []
13
+ Dir.glob(json_dir_path).each do |file|
14
+ facts = load_json_from_file(file, '')
15
+ if facts && node_matches?(facts, request.options)
16
+ node_names << facts.name
17
+ end
18
+ end
19
+ node_names
20
+ end
21
+
22
+ private
23
+
24
+ def json_dir_path
25
+ self.path("*")
26
+ end
27
+ end