puppet 6.25.1 → 6.28.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.
- checksums.yaml +4 -4
- data/CODEOWNERS +1 -1
- data/Gemfile +2 -2
- data/Gemfile.lock +101 -34
- data/lib/puppet/agent.rb +47 -11
- data/lib/puppet/application/agent.rb +2 -12
- data/lib/puppet/application/lookup.rb +74 -24
- data/lib/puppet/concurrent/thread_local_singleton.rb +5 -3
- data/lib/puppet/configurer.rb +8 -14
- data/lib/puppet/defaults.rb +13 -3
- data/lib/puppet/face/generate.rb +2 -0
- data/lib/puppet/file_serving/metadata.rb +3 -0
- data/lib/puppet/file_system/file_impl.rb +7 -7
- data/lib/puppet/file_system/jruby.rb +1 -1
- data/lib/puppet/file_system/windows.rb +4 -4
- data/lib/puppet/file_system.rb +1 -1
- data/lib/puppet/functions/next.rb +18 -1
- data/lib/puppet/functions/tree_each.rb +0 -1
- data/lib/puppet/functions/versioncmp.rb +6 -2
- data/lib/puppet/generate/type.rb +9 -0
- data/lib/puppet/http/client.rb +22 -2
- data/lib/puppet/node.rb +1 -1
- data/lib/puppet/pops/parser/code_merger.rb +4 -4
- data/lib/puppet/pops/parser/egrammar.ra +2 -0
- data/lib/puppet/pops/parser/eparser.rb +813 -794
- data/lib/puppet/pops/serialization/to_data_converter.rb +6 -18
- data/lib/puppet/provider/package/puppetserver_gem.rb +7 -16
- data/lib/puppet/provider/package/windows/exe_package.rb +30 -1
- data/lib/puppet/provider/package/windows/package.rb +2 -1
- data/lib/puppet/provider/package/windows.rb +14 -1
- data/lib/puppet/provider/service/init.rb +5 -4
- data/lib/puppet/provider/user/directoryservice.rb +5 -0
- data/lib/puppet/ssl/ssl_provider.rb +75 -19
- data/lib/puppet/ssl/state_machine.rb +13 -17
- data/lib/puppet/ssl/verifier.rb +6 -0
- data/lib/puppet/transaction/persistence.rb +22 -12
- data/lib/puppet/type/exec.rb +1 -1
- data/lib/puppet/type/file/data_sync.rb +1 -1
- data/lib/puppet/type/user.rb +43 -38
- data/lib/puppet/util/json.rb +17 -0
- data/lib/puppet/util/log.rb +7 -2
- data/lib/puppet/util/monkey_patches.rb +6 -2
- data/lib/puppet/util/package.rb +25 -16
- data/lib/puppet/util/yaml.rb +21 -2
- data/lib/puppet/util.rb +1 -2
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet.rb +2 -14
- data/locales/puppet.pot +5 -10454
- data/man/man5/puppet.conf.5 +21 -2
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +9 -6
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +1 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/unit/forge/bacula.json +1 -1
- data/spec/integration/application/agent_spec.rb +108 -0
- data/spec/integration/application/lookup_spec.rb +81 -50
- data/spec/integration/application/resource_spec.rb +6 -2
- data/spec/integration/http/client_spec.rb +51 -4
- data/spec/lib/puppet_spec/https.rb +1 -1
- data/spec/lib/puppet_spec/puppetserver.rb +39 -2
- data/spec/shared_contexts/l10n.rb +5 -0
- data/spec/unit/agent_spec.rb +28 -2
- data/spec/unit/application/agent_spec.rb +26 -16
- data/spec/unit/application/lookup_spec.rb +131 -10
- data/spec/unit/concurrent/thread_local_singleton_spec.rb +39 -0
- data/spec/unit/configurer_spec.rb +124 -61
- data/spec/unit/daemon_spec.rb +2 -11
- data/spec/unit/face/generate_spec.rb +64 -0
- data/spec/unit/file_system_spec.rb +34 -4
- data/spec/unit/forge/module_release_spec.rb +3 -3
- data/spec/unit/functions/versioncmp_spec.rb +40 -4
- data/spec/unit/http/client_spec.rb +18 -0
- data/spec/unit/node_spec.rb +6 -0
- data/spec/unit/pops/parser/parse_containers_spec.rb +2 -2
- data/spec/unit/pops/serialization/to_from_hr_spec.rb +0 -58
- data/spec/unit/pops/validator/validator_spec.rb +5 -0
- data/spec/unit/provider/package/puppetserver_gem_spec.rb +2 -2
- data/spec/unit/provider/package/windows/exe_package_spec.rb +17 -0
- data/spec/unit/provider/service/gentoo_spec.rb +6 -5
- data/spec/unit/provider/service/init_spec.rb +15 -9
- data/spec/unit/provider/service/openwrt_spec.rb +21 -29
- data/spec/unit/provider/service/redhat_spec.rb +3 -2
- data/spec/unit/ssl/ssl_provider_spec.rb +75 -1
- data/spec/unit/ssl/state_machine_spec.rb +1 -0
- data/spec/unit/transaction/persistence_spec.rb +51 -0
- data/spec/unit/type/user_spec.rb +0 -45
- data/spec/unit/util/json_spec.rb +126 -0
- data/spec/unit/util/windows_spec.rb +23 -0
- data/spec/unit/util/yaml_spec.rb +54 -29
- data/tasks/generate_cert_fixtures.rake +5 -4
- metadata +9 -3
data/lib/puppet/type/user.rb
CHANGED
@@ -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
|
@@ -228,6 +227,9 @@ module Puppet
|
|
228
227
|
* OS X 10.8 and higher use salted SHA512 PBKDF2 hashes. When managing passwords
|
229
228
|
on these systems, the `salt` and `iterations` attributes need to be specified as
|
230
229
|
well as the password.
|
230
|
+
* macOS 10.15 and higher require the salt to be 32-bytes. Since Puppet's user
|
231
|
+
resource requires the value to be hex encoded, the length of the salt's
|
232
|
+
string must be 64.
|
231
233
|
* Windows passwords can be managed only in cleartext, because there is no Windows
|
232
234
|
API for setting the password hash.
|
233
235
|
|
@@ -695,7 +697,6 @@ module Puppet
|
|
695
697
|
|
696
698
|
def generate
|
697
699
|
if !self[:purge_ssh_keys].empty?
|
698
|
-
return [] if self[:ensure] == :present && !provider.exists?
|
699
700
|
if Puppet::Type.type(:ssh_authorized_key).nil?
|
700
701
|
warning _("Ssh_authorized_key type is not available. Cannot purge SSH keys.")
|
701
702
|
else
|
@@ -744,6 +745,45 @@ module Puppet
|
|
744
745
|
end
|
745
746
|
raise ArgumentError, _("purge_ssh_keys must be true, false, or an array of file names, not %{value}") % { value: value.inspect }
|
746
747
|
end
|
748
|
+
|
749
|
+
munge do |value|
|
750
|
+
# Resolve string, boolean and symbol forms of true and false to a
|
751
|
+
# single representation.
|
752
|
+
case value
|
753
|
+
when :false, false, "false"
|
754
|
+
[]
|
755
|
+
when :true, true, "true"
|
756
|
+
home = homedir
|
757
|
+
home ? [ "#{home}/.ssh/authorized_keys" ] : []
|
758
|
+
else
|
759
|
+
# value can be a string or array - munge each value
|
760
|
+
[ value ].flatten.map do |entry|
|
761
|
+
authorized_keys_path(entry)
|
762
|
+
end.compact
|
763
|
+
end
|
764
|
+
end
|
765
|
+
|
766
|
+
private
|
767
|
+
|
768
|
+
def homedir
|
769
|
+
resource[:home] || Dir.home(resource[:name])
|
770
|
+
rescue ArgumentError
|
771
|
+
Puppet.debug("User '#{resource[:name]}' does not exist")
|
772
|
+
nil
|
773
|
+
end
|
774
|
+
|
775
|
+
def authorized_keys_path(entry)
|
776
|
+
return entry unless entry.match?(%r{^(?:~|%h)/})
|
777
|
+
|
778
|
+
# if user doesn't exist (yet), ignore nonexistent homedir
|
779
|
+
home = homedir
|
780
|
+
return nil unless home
|
781
|
+
|
782
|
+
# compiler freezes "value" so duplicate using a gsub, second mutating gsub! is then ok
|
783
|
+
entry = entry.gsub(%r{^~/}, "#{home}/")
|
784
|
+
entry.gsub!(%r{^%h/}, "#{home}/")
|
785
|
+
entry
|
786
|
+
end
|
747
787
|
end
|
748
788
|
|
749
789
|
newproperty(:loginclass, :required_features => :manages_loginclass) do
|
@@ -765,7 +805,7 @@ module Puppet
|
|
765
805
|
# @see generate
|
766
806
|
# @api private
|
767
807
|
def find_unmanaged_keys
|
768
|
-
|
808
|
+
self[:purge_ssh_keys].
|
769
809
|
select { |f| File.readable?(f) }.
|
770
810
|
map { |f| unknown_keys_in_file(f) }.
|
771
811
|
flatten.each do |res|
|
@@ -777,41 +817,6 @@ module Puppet
|
|
777
817
|
end
|
778
818
|
end
|
779
819
|
|
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
820
|
# Parse an ssh authorized keys file superficially, extract the comments
|
816
821
|
# on the keys. These are considered names of possible ssh_authorized_keys
|
817
822
|
# resources. Keys that are managed by the present catalog are ignored.
|
data/lib/puppet/util/json.rb
CHANGED
@@ -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.
|
data/lib/puppet/util/log.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
@@ -64,8 +70,6 @@ unless Puppet::Util::Platform.jruby_fips?
|
|
64
70
|
end
|
65
71
|
|
66
72
|
if Puppet::Util::Platform.windows?
|
67
|
-
require 'puppet/util/windows'
|
68
|
-
|
69
73
|
class OpenSSL::X509::Store
|
70
74
|
@puppet_certs_loaded = false
|
71
75
|
alias __original_set_default_paths set_default_paths
|
data/lib/puppet/util/package.rb
CHANGED
@@ -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
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
data/lib/puppet/util/yaml.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
data/lib/puppet/util.rb
CHANGED
@@ -7,6 +7,7 @@ require 'uri'
|
|
7
7
|
require 'pathname'
|
8
8
|
require 'ostruct'
|
9
9
|
require 'puppet/util/platform'
|
10
|
+
require 'puppet/util/windows'
|
10
11
|
require 'puppet/util/symbolic_file_mode'
|
11
12
|
require 'puppet/file_system/uniquefile'
|
12
13
|
require 'securerandom'
|
@@ -22,8 +23,6 @@ module Util
|
|
22
23
|
require 'puppet/util/posix'
|
23
24
|
extend Puppet::Util::POSIX
|
24
25
|
|
25
|
-
require 'puppet/util/windows/process' if Puppet::Util::Platform.windows?
|
26
|
-
|
27
26
|
extend Puppet::Util::SymbolicFileMode
|
28
27
|
|
29
28
|
def default_env
|
data/lib/puppet/version.rb
CHANGED
data/lib/puppet.rb
CHANGED
@@ -242,20 +242,7 @@ module Puppet
|
|
242
242
|
{
|
243
243
|
:environments => Puppet::Environments::Cached.new(Puppet::Environments::Combined.new(*loaders)),
|
244
244
|
:http_pool => proc { Puppet.runtime[:http].pool },
|
245
|
-
:ssl_context => proc {
|
246
|
-
begin
|
247
|
-
cert = Puppet::X509::CertProvider.new
|
248
|
-
password = cert.load_private_key_password
|
249
|
-
ssl = Puppet::SSL::SSLProvider.new
|
250
|
-
ssl.load_context(certname: Puppet[:certname], password: password)
|
251
|
-
rescue => e
|
252
|
-
# TRANSLATORS: `message` is an already translated string of why SSL failed to initialize
|
253
|
-
Puppet.log_exception(e, _("Failed to initialize SSL: %{message}") % { message: e.message })
|
254
|
-
# TRANSLATORS: `puppet agent -t` is a command and should not be translated
|
255
|
-
Puppet.err(_("Run `puppet agent -t`"))
|
256
|
-
raise e
|
257
|
-
end
|
258
|
-
},
|
245
|
+
:ssl_context => proc { Puppet.runtime[:http].default_ssl_context },
|
259
246
|
:ssl_host => proc { Puppet::SSL::Host.localhost(true) },
|
260
247
|
:http_session => proc { Puppet.runtime[:http].create_session },
|
261
248
|
:plugins => proc { Puppet::Plugins::Configuration.load_plugins },
|
@@ -364,3 +351,4 @@ require 'puppet/status'
|
|
364
351
|
require 'puppet/file_bucket/file'
|
365
352
|
require 'puppet/plugins/configuration'
|
366
353
|
require 'puppet/pal/pal_api'
|
354
|
+
require 'puppet/node/facts'
|