puppet 6.25.1 → 6.26.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/Gemfile.lock +24 -17
  4. data/lib/puppet/application/lookup.rb +78 -24
  5. data/lib/puppet/concurrent/thread_local_singleton.rb +5 -3
  6. data/lib/puppet/configurer.rb +2 -12
  7. data/lib/puppet/defaults.rb +14 -3
  8. data/lib/puppet/face/generate.rb +2 -0
  9. data/lib/puppet/file_serving/metadata.rb +3 -0
  10. data/lib/puppet/file_system/file_impl.rb +7 -7
  11. data/lib/puppet/file_system/jruby.rb +1 -1
  12. data/lib/puppet/file_system/windows.rb +4 -4
  13. data/lib/puppet/file_system.rb +1 -1
  14. data/lib/puppet/functions/versioncmp.rb +6 -2
  15. data/lib/puppet/generate/type.rb +9 -0
  16. data/lib/puppet/node.rb +1 -1
  17. data/lib/puppet/pops/parser/code_merger.rb +4 -4
  18. data/lib/puppet/pops/parser/egrammar.ra +2 -0
  19. data/lib/puppet/pops/parser/eparser.rb +813 -794
  20. data/lib/puppet/pops/serialization/to_data_converter.rb +6 -18
  21. data/lib/puppet/provider/service/init.rb +5 -4
  22. data/lib/puppet/ssl/verifier.rb +6 -0
  23. data/lib/puppet/transaction/persistence.rb +22 -12
  24. data/lib/puppet/type/file/data_sync.rb +1 -1
  25. data/lib/puppet/type/user.rb +40 -38
  26. data/lib/puppet/util/json.rb +17 -0
  27. data/lib/puppet/util/log.rb +7 -2
  28. data/lib/puppet/util/monkey_patches.rb +6 -0
  29. data/lib/puppet/util/package.rb +25 -16
  30. data/lib/puppet/util/yaml.rb +21 -2
  31. data/lib/puppet/version.rb +1 -1
  32. data/lib/puppet.rb +1 -0
  33. data/locales/puppet.pot +5 -10454
  34. data/man/man5/puppet.conf.5 +21 -2
  35. data/man/man8/puppet-agent.8 +1 -1
  36. data/man/man8/puppet-apply.8 +1 -1
  37. data/man/man8/puppet-catalog.8 +1 -1
  38. data/man/man8/puppet-config.8 +1 -1
  39. data/man/man8/puppet-describe.8 +1 -1
  40. data/man/man8/puppet-device.8 +1 -1
  41. data/man/man8/puppet-doc.8 +1 -1
  42. data/man/man8/puppet-epp.8 +1 -1
  43. data/man/man8/puppet-facts.8 +1 -1
  44. data/man/man8/puppet-filebucket.8 +1 -1
  45. data/man/man8/puppet-generate.8 +1 -1
  46. data/man/man8/puppet-help.8 +1 -1
  47. data/man/man8/puppet-key.8 +1 -1
  48. data/man/man8/puppet-lookup.8 +9 -6
  49. data/man/man8/puppet-man.8 +1 -1
  50. data/man/man8/puppet-module.8 +1 -1
  51. data/man/man8/puppet-node.8 +1 -1
  52. data/man/man8/puppet-parser.8 +1 -1
  53. data/man/man8/puppet-plugin.8 +1 -1
  54. data/man/man8/puppet-report.8 +1 -1
  55. data/man/man8/puppet-resource.8 +1 -1
  56. data/man/man8/puppet-script.8 +1 -1
  57. data/man/man8/puppet-ssl.8 +1 -1
  58. data/man/man8/puppet-status.8 +1 -1
  59. data/man/man8/puppet.8 +2 -2
  60. data/spec/fixtures/unit/forge/bacula.json +1 -1
  61. data/spec/integration/application/lookup_spec.rb +32 -6
  62. data/spec/shared_contexts/l10n.rb +5 -0
  63. data/spec/unit/application/lookup_spec.rb +131 -10
  64. data/spec/unit/concurrent/thread_local_singleton_spec.rb +39 -0
  65. data/spec/unit/configurer_spec.rb +90 -58
  66. data/spec/unit/face/generate_spec.rb +64 -0
  67. data/spec/unit/file_system_spec.rb +34 -4
  68. data/spec/unit/forge/module_release_spec.rb +3 -3
  69. data/spec/unit/functions/versioncmp_spec.rb +40 -4
  70. data/spec/unit/node_spec.rb +6 -0
  71. data/spec/unit/pops/parser/parse_containers_spec.rb +2 -2
  72. data/spec/unit/pops/serialization/to_from_hr_spec.rb +0 -58
  73. data/spec/unit/pops/validator/validator_spec.rb +5 -0
  74. data/spec/unit/provider/service/gentoo_spec.rb +6 -5
  75. data/spec/unit/provider/service/init_spec.rb +15 -9
  76. data/spec/unit/provider/service/openwrt_spec.rb +21 -29
  77. data/spec/unit/provider/service/redhat_spec.rb +3 -2
  78. data/spec/unit/transaction/persistence_spec.rb +51 -0
  79. data/spec/unit/type/user_spec.rb +0 -45
  80. data/spec/unit/util/json_spec.rb +126 -0
  81. data/spec/unit/util/yaml_spec.rb +54 -29
  82. metadata +7 -3
@@ -14,8 +14,6 @@ module Serialization
14
14
  # @option options [Boolean] :local_reference use local references instead of duplicating complex entries
15
15
  # @option options [Boolean] :type_by_reference `true` if Object types are converted to references rather than embedded.
16
16
  # @option options [Boolean] :symbol_as_string `true` if Symbols should be converted to strings (with type loss)
17
- # @option options [Boolean] :force_symbol `false` if Symbols should not be converted (rich_data and symbol_as_string must be false)
18
- # @option options [Boolean] :silence_warnings `false` if warnings should be silenced
19
17
  # @option options [String] :message_prefix String to prepend to in warnings and errors
20
18
  # @return [Data] the processed result. An object assignable to `Data`.
21
19
  #
@@ -43,12 +41,6 @@ module Serialization
43
41
  @symbol_as_string = options[:symbol_as_string]
44
42
  @symbol_as_string = false if @symbol_as_string.nil?
45
43
 
46
- @force_symbol = options[:force_symbol]
47
- @force_symbol = false if @force_symbol.nil?
48
-
49
- @silence_warnings = options[:silence_warnings]
50
- @silence_warnings = false if @silence_warnings.nil?
51
-
52
44
  @rich_data = options[:rich_data]
53
45
  @rich_data = false if @rich_data.nil?
54
46
 
@@ -100,11 +92,7 @@ module Serialization
100
92
  elsif @rich_data
101
93
  { PCORE_TYPE_KEY => PCORE_TYPE_SYMBOL, PCORE_VALUE_KEY => value.to_s }
102
94
  else
103
- if @force_symbol
104
- value
105
- else
106
- @silence_warnings ? unknown_to_string(value) : unknown_to_string_with_warning(value)
107
- end
95
+ unknown_to_string_with_warning(value)
108
96
  end
109
97
  elsif value.instance_of?(Array)
110
98
  process(value) do
@@ -129,11 +117,7 @@ module Serialization
129
117
  { PCORE_TYPE_KEY => PCORE_TYPE_SENSITIVE, PCORE_VALUE_KEY => to_data(value.unwrap) }
130
118
  end
131
119
  else
132
- if @rich_data
133
- value_to_data_hash(value)
134
- else
135
- @silence_warnings ? unknown_to_string(value) : unknown_to_string_with_warning(value)
136
- end
120
+ unknown_to_data(value)
137
121
  end
138
122
  end
139
123
 
@@ -207,6 +191,10 @@ module Serialization
207
191
  v
208
192
  end
209
193
 
194
+ def unknown_to_data(value)
195
+ @rich_data ? value_to_data_hash(value) : unknown_to_string_with_warning(value)
196
+ end
197
+
210
198
  def unknown_key_to_string_with_warning(value)
211
199
  str = unknown_to_string(value)
212
200
  serialization_issue(Issues::SERIALIZATION_UNKNOWN_KEY_CONVERTED_TO_STRING, :path => path_to_s, :klass => value.class, :value => str)
@@ -84,7 +84,7 @@ Puppet::Type.type(:service).provide :init, :parent => :base do
84
84
  defpath = [defpath] unless defpath.is_a? Array
85
85
  instances = []
86
86
  defpath.each do |path|
87
- unless FileTest.directory?(path)
87
+ unless Puppet::FileSystem.directory?(path)
88
88
  Puppet.debug "Service path #{path} does not exist"
89
89
  next
90
90
  end
@@ -97,8 +97,9 @@ Puppet::Type.type(:service).provide :init, :parent => :base do
97
97
  fullpath = File.join(path, name)
98
98
  next if name =~ /^\./
99
99
  next if exclude.include? name
100
- next if not FileTest.executable?(fullpath)
101
- next if not is_init?(fullpath)
100
+ next if Puppet::FileSystem.directory?(fullpath)
101
+ next unless Puppet::FileSystem.executable?(fullpath)
102
+ next unless is_init?(fullpath)
102
103
  instances << new(:name => name, :path => path, :hasstatus => true)
103
104
  end
104
105
  end
@@ -122,7 +123,7 @@ Puppet::Type.type(:service).provide :init, :parent => :base do
122
123
 
123
124
  def paths
124
125
  @paths ||= @resource[:path].find_all do |path|
125
- if File.directory?(path)
126
+ if Puppet::FileSystem.directory?(path)
126
127
  true
127
128
  else
128
129
  if Puppet::FileSystem.exist?(path)
@@ -115,6 +115,12 @@ class Puppet::SSL::Verifier
115
115
  return false
116
116
  end
117
117
 
118
+ # ruby-openssl#74ef8c0cc56b840b772240f2ee2b0fc0aafa2743 now sets the
119
+ # store_context error when the cert is mismatched
120
+ when OpenSSL::X509::V_ERR_HOSTNAME_MISMATCH
121
+ @last_error = Puppet::SSL::CertMismatchError.new(peer_cert, @hostname)
122
+ return false
123
+
118
124
  when OpenSSL::X509::V_ERR_CRL_NOT_YET_VALID
119
125
  crl = store_context.current_crl
120
126
  if crl && crl.last_update && crl.last_update < Time.now + FIVE_MINUTES_AS_SECONDS
@@ -6,6 +6,26 @@ require 'puppet/util/yaml'
6
6
  # as calculating corrective_change).
7
7
  # @api private
8
8
  class Puppet::Transaction::Persistence
9
+
10
+ def self.allowed_classes
11
+ @allowed_classes ||= [
12
+ Symbol,
13
+ Time,
14
+ Regexp,
15
+ # URI is excluded, because it serializes all instance variables including the
16
+ # URI parser. Better to serialize the URL encoded representation.
17
+ SemanticPuppet::Version,
18
+ # SemanticPuppet::VersionRange has many nested classes and is unlikely to be
19
+ # used directly, so ignore it
20
+ Puppet::Pops::Time::Timestamp,
21
+ Puppet::Pops::Time::TimeData,
22
+ Puppet::Pops::Time::Timespan,
23
+ Puppet::Pops::Types::PBinaryType::Binary,
24
+ # Puppet::Pops::Types::PSensitiveType::Sensitive values are excluded from
25
+ # the persistence store, ignore it.
26
+ ].freeze
27
+ end
28
+
9
29
  def initialize
10
30
  @old_data = {}
11
31
  @new_data = {"resources" => {}}
@@ -62,7 +82,7 @@ class Puppet::Transaction::Persistence
62
82
  result = nil
63
83
  Puppet::Util.benchmark(:debug, _("Loaded transaction store file in %{seconds} seconds")) do
64
84
  begin
65
- result = Puppet::Util::Yaml.safe_load_file(filename, [Symbol, Time])
85
+ result = Puppet::Util::Yaml.safe_load_file(filename, self.class.allowed_classes)
66
86
  rescue Puppet::Util::Yaml::YamlLoadError => detail
67
87
  Puppet.log_exception(detail, _("Transaction store file %{filename} is corrupt (%{detail}); replacing") % { filename: filename, detail: detail })
68
88
 
@@ -87,17 +107,7 @@ class Puppet::Transaction::Persistence
87
107
 
88
108
  # Save data from internal class to persistence store on disk.
89
109
  def save
90
- converted_data = Puppet::Pops::Serialization::ToDataConverter.convert(
91
- @new_data, {
92
- symbol_as_string: false,
93
- local_reference: false,
94
- type_by_reference: true,
95
- force_symbol: true,
96
- silence_warnings: true,
97
- message_prefix: to_s
98
- }
99
- )
100
- Puppet::Util::Yaml.dump(converted_data, Puppet[:transactionstorefile])
110
+ Puppet::Util::Yaml.dump(@new_data, Puppet[:transactionstorefile])
101
111
  end
102
112
 
103
113
  # Use the catalog and run_mode to determine if persistence should be enabled or not
@@ -79,7 +79,7 @@ module Puppet
79
79
  return :absent unless stat
80
80
  ftype = stat.ftype
81
81
  # Don't even try to manage the content on directories or links
82
- return nil if ["directory","link"].include?(ftype)
82
+ return nil if ['directory', 'link', 'fifo', 'socket'].include?(ftype)
83
83
 
84
84
  begin
85
85
  resource.parameter(:checksum).sum_file(resource[:path])
@@ -66,7 +66,6 @@ module Puppet
66
66
  newproperty(:ensure, :parent => Puppet::Property::Ensure) do
67
67
  newvalue(:present, :event => :user_created) do
68
68
  provider.create
69
- @resource.generate
70
69
  end
71
70
 
72
71
  newvalue(:absent, :event => :user_removed) do
@@ -695,7 +694,6 @@ module Puppet
695
694
 
696
695
  def generate
697
696
  if !self[:purge_ssh_keys].empty?
698
- return [] if self[:ensure] == :present && !provider.exists?
699
697
  if Puppet::Type.type(:ssh_authorized_key).nil?
700
698
  warning _("Ssh_authorized_key type is not available. Cannot purge SSH keys.")
701
699
  else
@@ -744,6 +742,45 @@ module Puppet
744
742
  end
745
743
  raise ArgumentError, _("purge_ssh_keys must be true, false, or an array of file names, not %{value}") % { value: value.inspect }
746
744
  end
745
+
746
+ munge do |value|
747
+ # Resolve string, boolean and symbol forms of true and false to a
748
+ # single representation.
749
+ case value
750
+ when :false, false, "false"
751
+ []
752
+ when :true, true, "true"
753
+ home = homedir
754
+ home ? [ "#{home}/.ssh/authorized_keys" ] : []
755
+ else
756
+ # value can be a string or array - munge each value
757
+ [ value ].flatten.map do |entry|
758
+ authorized_keys_path(entry)
759
+ end.compact
760
+ end
761
+ end
762
+
763
+ private
764
+
765
+ def homedir
766
+ resource[:home] || Dir.home(resource[:name])
767
+ rescue ArgumentError
768
+ Puppet.debug("User '#{resource[:name]}' does not exist")
769
+ nil
770
+ end
771
+
772
+ def authorized_keys_path(entry)
773
+ return entry unless entry.match?(%r{^(?:~|%h)/})
774
+
775
+ # if user doesn't exist (yet), ignore nonexistent homedir
776
+ home = homedir
777
+ return nil unless home
778
+
779
+ # compiler freezes "value" so duplicate using a gsub, second mutating gsub! is then ok
780
+ entry = entry.gsub(%r{^~/}, "#{home}/")
781
+ entry.gsub!(%r{^%h/}, "#{home}/")
782
+ entry
783
+ end
747
784
  end
748
785
 
749
786
  newproperty(:loginclass, :required_features => :manages_loginclass) do
@@ -765,7 +802,7 @@ module Puppet
765
802
  # @see generate
766
803
  # @api private
767
804
  def find_unmanaged_keys
768
- munged_unmanaged_keys.
805
+ self[:purge_ssh_keys].
769
806
  select { |f| File.readable?(f) }.
770
807
  map { |f| unknown_keys_in_file(f) }.
771
808
  flatten.each do |res|
@@ -777,41 +814,6 @@ module Puppet
777
814
  end
778
815
  end
779
816
 
780
- def munged_unmanaged_keys
781
- value = self[:purge_ssh_keys]
782
-
783
- # Resolve string, boolean and symbol forms of true and false to a
784
- # single representation.
785
- test_sym = value.to_s.intern
786
- value = test_sym if [:true, :false].include? test_sym
787
-
788
- return [] if value == :false
789
-
790
- home = self[:home]
791
- begin
792
- home ||= provider.home
793
- rescue
794
- Puppet.debug("User '#{self[:name]}' does not exist")
795
- end
796
-
797
- if home.to_s.empty? || !Dir.exist?(home.to_s)
798
- if value == :true || [ value ].flatten.any? { |v| v.start_with?('~/', '%h/') }
799
- Puppet.debug("User '#{self[:name]}' has no home directory set to purge ssh keys from.")
800
- return []
801
- end
802
- end
803
-
804
- return [ "#{home}/.ssh/authorized_keys" ] if value == :true
805
-
806
- # value is an array - munge each value
807
- [ value ].flatten.map do |entry|
808
- # make sure frozen value is duplicated by using a gsub, second mutating gsub! is then ok
809
- entry = entry.gsub(/^~\//, "#{home}/")
810
- entry.gsub!(/^%h\//, "#{home}/")
811
- entry
812
- end
813
- end
814
-
815
817
  # Parse an ssh authorized keys file superficially, extract the comments
816
818
  # on the keys. These are considered names of possible ssh_authorized_keys
817
819
  # resources. Keys that are managed by the present catalog are ignored.
@@ -26,6 +26,23 @@ module Puppet::Util
26
26
  require 'json'
27
27
  end
28
28
 
29
+ # Load the content from a file as JSON if
30
+ # contents are in valid format. This method does not
31
+ # raise error but returns `nil` when invalid file is
32
+ # given.
33
+ def self.load_file_if_valid(filename, options = {})
34
+ load_file(filename, options)
35
+ rescue Puppet::Util::Json::ParseError, ArgumentError, Errno::ENOENT => detail
36
+ Puppet.debug("Could not retrieve JSON content from '#{filename}': #{detail.message}")
37
+ nil
38
+ end
39
+
40
+ # Load the content from a file as JSON.
41
+ def self.load_file(filename, options = {})
42
+ json = Puppet::FileSystem.read(filename, :encoding => 'utf-8')
43
+ load(json, options)
44
+ end
45
+
29
46
  # These methods do similar processing to the fallback implemented by MultiJson
30
47
  # when using the built-in JSON backend, to ensure consistent behavior
31
48
  # whether or not MultiJson can be loaded.
@@ -105,9 +105,14 @@ class Puppet::Util::Log
105
105
  def Log.level=(level)
106
106
  level = level.intern unless level.is_a?(Symbol)
107
107
 
108
- raise Puppet::DevError, _("Invalid loglevel %{level}") % { level: level } unless @levels.include?(level)
108
+ # loglevel is a 0-based index
109
+ loglevel = @levels.index(level)
110
+ raise Puppet::DevError, _("Invalid loglevel %{level}") % { level: level } unless loglevel
109
111
 
110
- @loglevel = @levels.index(level)
112
+ return if @loglevel == loglevel
113
+
114
+ # loglevel changed
115
+ @loglevel = loglevel
111
116
 
112
117
  # Enable or disable Facter debugging
113
118
  Puppet.runtime[:facter].debugging(level == :debug)
@@ -39,6 +39,12 @@ unless Puppet::Util::Platform.jruby_fips?
39
39
  end
40
40
  end
41
41
 
42
+ unless defined?(OpenSSL::X509::V_ERR_HOSTNAME_MISMATCH)
43
+ module OpenSSL::X509
44
+ OpenSSL::X509::V_ERR_HOSTNAME_MISMATCH = 0x3E
45
+ end
46
+ end
47
+
42
48
  class OpenSSL::SSL::SSLContext
43
49
  if DEFAULT_PARAMS[:options]
44
50
  DEFAULT_PARAMS[:options] |= OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
@@ -1,6 +1,13 @@
1
+ # frozen_string_literal: true
1
2
  module Puppet::Util::Package
2
- def versioncmp(version_a, version_b)
3
+ def versioncmp(version_a, version_b, ignore_trailing_zeroes = false)
3
4
  vre = /[-.]|\d+|[^-.\d]+/
5
+
6
+ if ignore_trailing_zeroes
7
+ version_a = normalize(version_a)
8
+ version_b = normalize(version_b)
9
+ end
10
+
4
11
  ax = version_a.scan(vre)
5
12
  bx = version_b.scan(vre)
6
13
 
@@ -8,24 +15,26 @@ module Puppet::Util::Package
8
15
  a = ax.shift
9
16
  b = bx.shift
10
17
 
11
- if( a == b ) then next
12
- elsif (a == '-' && b == '-') then next
13
- elsif (a == '-') then return -1
14
- elsif (b == '-') then return 1
15
- elsif (a == '.' && b == '.') then next
16
- elsif (a == '.' ) then return -1
17
- elsif (b == '.' ) then return 1
18
- elsif (a =~ /^\d+$/ && b =~ /^\d+$/) then
19
- if( a =~ /^0/ or b =~ /^0/ ) then
20
- return a.to_s.upcase <=> b.to_s.upcase
21
- end
18
+ next if a == b
19
+ return -1 if a == '-'
20
+ return 1 if b == '-'
21
+ return -1 if a == '.'
22
+ return 1 if b == '.'
23
+ if a =~ /^\d+$/ && b =~ /^\d+$/
24
+ return a.to_s.upcase <=> b.to_s.upcase if a =~ /^0/ || b =~ /^0/
22
25
  return a.to_i <=> b.to_i
23
- else
24
- return a.upcase <=> b.upcase
25
26
  end
27
+ return a.upcase <=> b.upcase
26
28
  end
27
- version_a <=> version_b;
29
+ version_a <=> version_b
28
30
  end
29
-
30
31
  module_function :versioncmp
32
+
33
+ def self.normalize(version)
34
+ version = version.split('-')
35
+ version.first.sub!(/([\.0]+)$/, '')
36
+
37
+ version.join('-')
38
+ end
39
+ private_class_method :normalize
31
40
  end
@@ -24,7 +24,11 @@ module Puppet::Util::Yaml
24
24
  # @raise [YamlLoadException] If deserialization fails.
25
25
  # @return The parsed YAML, which can be Hash, Array or scalar types.
26
26
  def self.safe_load(yaml, allowed_classes = [], filename = nil)
27
- data = YAML.safe_load(yaml, allowed_classes, [], true, filename)
27
+ if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0')
28
+ data = YAML.safe_load(yaml, permitted_classes: allowed_classes, aliases: true, filename: filename)
29
+ else
30
+ data = YAML.safe_load(yaml, allowed_classes, [], true, filename)
31
+ end
28
32
  data = false if data.nil?
29
33
  data
30
34
  rescue ::Psych::DisallowedClass => detail
@@ -42,6 +46,17 @@ module Puppet::Util::Yaml
42
46
  safe_load(yaml, allowed_classes, filename)
43
47
  end
44
48
 
49
+ # Safely load the content from a file as YAML if
50
+ # contents are in valid format. This method does not
51
+ # raise error but returns `nil` when invalid file is
52
+ # given.
53
+ def self.safe_load_file_if_valid(filename, allowed_classes = [])
54
+ safe_load_file(filename, allowed_classes)
55
+ rescue YamlLoadError, ArgumentError, Errno::ENOENT => detail
56
+ Puppet.debug("Could not retrieve YAML content from '#{filename}': #{detail.message}")
57
+ nil
58
+ end
59
+
45
60
  # @deprecated Use {#safe_load_file} instead.
46
61
  def self.load_file(filename, default_value = false, strip_classes = false)
47
62
  Puppet.deprecation_warning(_("Puppet::Util::Yaml.load_file is deprecated. Use safe_load_file instead."))
@@ -57,7 +72,11 @@ module Puppet::Util::Yaml
57
72
  end
58
73
  data.to_ruby || default_value
59
74
  else
60
- yaml = YAML.load_file(filename)
75
+ if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.3.2')
76
+ yaml = YAML.unsafe_load_file(filename)
77
+ else
78
+ yaml = YAML.load_file(filename)
79
+ end
61
80
  yaml || default_value
62
81
  end
63
82
  rescue *YamlLoadExceptions => detail
@@ -6,7 +6,7 @@
6
6
  # Raketasks and such to set the version based on the output of `git describe`
7
7
 
8
8
  module Puppet
9
- PUPPETVERSION = '6.25.1'
9
+ PUPPETVERSION = '6.26.0'
10
10
 
11
11
  ##
12
12
  # version is a public API method intended to always provide a fast and
data/lib/puppet.rb CHANGED
@@ -364,3 +364,4 @@ require 'puppet/status'
364
364
  require 'puppet/file_bucket/file'
365
365
  require 'puppet/plugins/configuration'
366
366
  require 'puppet/pal/pal_api'
367
+ require 'puppet/node/facts'