puppet 4.9.4 → 4.10.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 +7 -0
- data/Rakefile +6 -0
- data/ext/project_data.yaml +2 -2
- data/lib/hiera/puppet_function.rb +1 -1
- data/lib/puppet.rb +1 -0
- data/lib/puppet/application.rb +14 -0
- data/lib/puppet/application/inspect.rb +3 -0
- data/lib/puppet/defaults.rb +12 -2
- data/lib/puppet/etc.rb +125 -0
- data/lib/puppet/face/help.rb +1 -1
- data/lib/puppet/functions.rb +49 -4
- data/lib/puppet/functions/eyaml_lookup_key.rb +12 -3
- data/lib/puppet/functions/hocon_data.rb +9 -0
- data/lib/puppet/functions/json_data.rb +9 -0
- data/lib/puppet/functions/yaml_data.rb +9 -0
- data/lib/puppet/indirector/file_bucket_file/file.rb +69 -22
- data/lib/puppet/indirector/key/file.rb +2 -1
- data/lib/puppet/indirector/ssl_file.rb +24 -3
- data/lib/puppet/module.rb +28 -22
- data/lib/puppet/network/http/compression.rb +2 -1
- data/lib/puppet/parser/compiler.rb +15 -38
- data/lib/puppet/parser/functions/hiera.rb +1 -1
- data/lib/puppet/parser/functions/hiera_array.rb +1 -1
- data/lib/puppet/parser/functions/hiera_hash.rb +1 -1
- data/lib/puppet/parser/functions/hiera_include.rb +1 -1
- data/lib/puppet/parser/scope.rb +59 -17
- data/lib/puppet/pops/evaluator/callable_signature.rb +7 -0
- data/lib/puppet/pops/functions/dispatch.rb +18 -5
- data/lib/puppet/pops/functions/dispatcher.rb +7 -13
- data/lib/puppet/pops/issue_reporter.rb +1 -1
- data/lib/puppet/pops/issues.rb +84 -0
- data/lib/puppet/pops/loader/base_loader.rb +13 -5
- data/lib/puppet/pops/lookup/configured_data_provider.rb +8 -2
- data/lib/puppet/pops/lookup/data_dig_function_provider.rb +109 -19
- data/lib/puppet/pops/lookup/data_hash_function_provider.rb +19 -4
- data/lib/puppet/pops/lookup/data_provider.rb +43 -29
- data/lib/puppet/pops/lookup/environment_data_provider.rb +1 -1
- data/lib/puppet/pops/lookup/explainer.rb +1 -0
- data/lib/puppet/pops/lookup/function_provider.rb +36 -11
- data/lib/puppet/pops/lookup/global_data_provider.rb +18 -5
- data/lib/puppet/pops/lookup/hiera_config.rb +203 -84
- data/lib/puppet/pops/lookup/interpolation.rb +21 -6
- data/lib/puppet/pops/lookup/invocation.rb +14 -9
- data/lib/puppet/pops/lookup/location_resolver.rb +27 -0
- data/lib/puppet/pops/lookup/lookup_adapter.rb +59 -6
- data/lib/puppet/pops/lookup/lookup_key_function_provider.rb +9 -77
- data/lib/puppet/pops/lookup/module_data_provider.rb +27 -4
- data/lib/puppet/pops/parser/lexer2.rb +1 -1
- data/lib/puppet/pops/pcore.rb +3 -3
- data/lib/puppet/pops/types/p_object_type.rb +4 -6
- data/lib/puppet/pops/types/ruby_generator.rb +2 -2
- data/lib/puppet/pops/types/type_asserter.rb +3 -3
- data/lib/puppet/pops/types/type_mismatch_describer.rb +25 -7
- data/lib/puppet/pops/types/types.rb +20 -29
- data/lib/puppet/provider/exec.rb +4 -2
- data/lib/puppet/provider/nameservice.rb +8 -8
- data/lib/puppet/provider/selmodule/semodule.rb +20 -16
- data/lib/puppet/provider/service/src.rb +39 -39
- data/lib/puppet/provider/service/systemd.rb +1 -1
- data/lib/puppet/provider/user/aix.rb +7 -2
- data/lib/puppet/settings.rb +30 -17
- data/lib/puppet/ssl/base.rb +14 -1
- data/lib/puppet/ssl/certificate_authority.rb +4 -2
- data/lib/puppet/ssl/configuration.rb +4 -1
- data/lib/puppet/ssl/inventory.rb +10 -3
- data/lib/puppet/ssl/key.rb +7 -3
- data/lib/puppet/test/test_helper.rb +3 -0
- data/lib/puppet/type.rb +13 -1
- data/lib/puppet/type/exec.rb +16 -1
- data/lib/puppet/type/group.rb +17 -11
- data/lib/puppet/type/user.rb +3 -1
- data/lib/puppet/util.rb +1 -0
- data/lib/puppet/util/character_encoding.rb +95 -0
- data/lib/puppet/util/execution.rb +9 -6
- data/lib/puppet/util/reference.rb +4 -2
- data/lib/puppet/util/windows/file.rb +5 -1
- data/lib/puppet/version.rb +6 -2
- data/locales/config.yaml +1 -1
- data/locales/puppet.pot +18 -4
- data/spec/integration/ssl/autosign_spec.rb +18 -3
- data/spec/integration/ssl/key_spec.rb +104 -0
- data/spec/integration/type/user_spec.rb +13 -6
- data/spec/spec_helper.rb +7 -0
- data/spec/unit/application/inspect_spec.rb +9 -2
- data/spec/unit/data_providers/function_data_provider_spec.rb +2 -2
- data/spec/unit/etc_spec.rb +234 -0
- data/spec/unit/face/certificate_spec.rb +10 -2
- data/spec/unit/functions/dig_spec.rb +1 -1
- data/spec/unit/functions/hiera_spec.rb +40 -1
- data/spec/unit/functions/lookup_fixture_spec.rb +10 -10
- data/spec/unit/functions/lookup_spec.rb +1217 -357
- data/spec/unit/functions4_spec.rb +37 -1
- data/spec/unit/indirector/file_bucket_file/file_spec.rb +33 -2
- data/spec/unit/indirector/key/file_spec.rb +1 -1
- data/spec/unit/indirector/ssl_file_spec.rb +3 -3
- data/spec/unit/module_spec.rb +52 -59
- data/spec/unit/network/http/compression_spec.rb +39 -8
- data/spec/unit/parser/compiler_spec.rb +14 -0
- data/spec/unit/pops/loaders/loaders_spec.rb +21 -3
- data/spec/unit/pops/loaders/module_loaders_spec.rb +61 -0
- data/spec/unit/pops/lookup/context_spec.rb +56 -8
- data/spec/unit/pops/lookup/lookup_spec.rb +32 -1
- data/spec/unit/pops/parser/lexer2_spec.rb +8 -0
- data/spec/unit/pops/types/ruby_generator_spec.rb +48 -0
- data/spec/unit/pops/types/type_mismatch_describer_spec.rb +12 -3
- data/spec/unit/pops/types/types_spec.rb +6 -7
- data/spec/unit/provider/nameservice_spec.rb +12 -12
- data/spec/unit/provider/package/pkg_spec.rb +2 -0
- data/spec/unit/provider/service/src_spec.rb +5 -0
- data/spec/unit/ssl/base_spec.rb +9 -0
- data/spec/unit/ssl/certificate_authority_spec.rb +2 -2
- data/spec/unit/ssl/certificate_request_attributes_spec.rb +6 -0
- data/spec/unit/ssl/certificate_request_spec.rb +1 -1
- data/spec/unit/ssl/certificate_spec.rb +1 -1
- data/spec/unit/ssl/configuration_spec.rb +11 -2
- data/spec/unit/ssl/inventory_spec.rb +27 -3
- data/spec/unit/ssl/key_spec.rb +7 -7
- data/spec/unit/type/exec_spec.rb +41 -4
- data/spec/unit/type/file_spec.rb +4 -1
- data/spec/unit/util/character_encoding_spec.rb +88 -0
- data/spec/unit/util/execution_spec.rb +12 -0
- data/spec/unit/version_spec.rb +4 -0
- metadata +3803 -3808
- data/tasks/i18n.rake +0 -20
@@ -23,7 +23,7 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
|
|
23
23
|
defaultfor :osfamily => :redhat, :operatingsystem => :fedora
|
24
24
|
defaultfor :osfamily => :suse
|
25
25
|
defaultfor :osfamily => :coreos
|
26
|
-
defaultfor :operatingsystem => :debian, :operatingsystemmajrelease => "8"
|
26
|
+
defaultfor :operatingsystem => :debian, :operatingsystemmajrelease => ["8", "stretch/sid", "9", "buster/sid"]
|
27
27
|
defaultfor :operatingsystem => :ubuntu, :operatingsystemmajrelease => ["15.04","15.10","16.04","16.10"]
|
28
28
|
defaultfor :operatingsystem => :cumuluslinux, :operatingsystemmajrelease => ["3"]
|
29
29
|
|
@@ -216,7 +216,9 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
216
216
|
|
217
217
|
def open_security_passwd
|
218
218
|
# helper method for tests
|
219
|
-
|
219
|
+
# AIX reference indicates this file is ASCII
|
220
|
+
# https://www.ibm.com/support/knowledgecenter/en/ssw_aix_72/com.ibm.aix.files/passwd_security.htm
|
221
|
+
Puppet::FileSystem.open("/etc/security/passwd", nil, "r:ASCII")
|
220
222
|
end
|
221
223
|
|
222
224
|
#--------------------------------
|
@@ -255,7 +257,10 @@ Puppet::Type.type(:user).provide :aix, :parent => Puppet::Provider::AixObject do
|
|
255
257
|
user = @resource[:name]
|
256
258
|
|
257
259
|
# Puppet execute does not support strings as input, only files.
|
258
|
-
|
260
|
+
# The password is expected to be in an encrypted format given -e is specified:
|
261
|
+
# https://www.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.cmds1/chpasswd.htm
|
262
|
+
# /etc/security/passwd is specified as an ASCII file per the AIX documentation
|
263
|
+
tmpfile = Tempfile.new("puppet_#{user}_pw", :encoding => Encoding::ASCII)
|
259
264
|
tmpfile << "#{user}:#{value}\n"
|
260
265
|
tmpfile.close()
|
261
266
|
|
data/lib/puppet/settings.rb
CHANGED
@@ -44,6 +44,8 @@ class Puppet::Settings
|
|
44
44
|
# The acceptable sections of the puppet.conf configuration file.
|
45
45
|
ALLOWED_SECTION_NAMES = ['main', 'master', 'agent', 'user'].freeze
|
46
46
|
|
47
|
+
NONE = 'none'.freeze
|
48
|
+
|
47
49
|
# This method is intended for puppet internal use only; it is a convenience method that
|
48
50
|
# returns reasonable application default settings values for a given run_mode.
|
49
51
|
def self.app_defaults_for_run_mode(run_mode)
|
@@ -384,12 +386,12 @@ class Puppet::Settings
|
|
384
386
|
end
|
385
387
|
end
|
386
388
|
|
387
|
-
|
389
|
+
def_delegators :@config, :each, :each_pair, :each_key
|
388
390
|
|
389
391
|
# Iterate over each section name.
|
390
392
|
def eachsection
|
391
393
|
yielded = []
|
392
|
-
@config.
|
394
|
+
@config.each_value do |object|
|
393
395
|
section = object.section
|
394
396
|
unless yielded.include? section
|
395
397
|
yield section
|
@@ -549,7 +551,7 @@ class Puppet::Settings
|
|
549
551
|
if @config[:environment]
|
550
552
|
env = self.value(:environment).to_sym
|
551
553
|
else
|
552
|
-
env =
|
554
|
+
env = NONE
|
553
555
|
end
|
554
556
|
|
555
557
|
# Call any hooks we should be calling.
|
@@ -1046,26 +1048,37 @@ Generated on #{Time.now}.
|
|
1046
1048
|
#
|
1047
1049
|
# @raise [InterpolationError]
|
1048
1050
|
def value(param, environment = nil, bypass_interpolation = false)
|
1049
|
-
param = param.to_sym
|
1050
1051
|
environment &&= environment.to_sym
|
1052
|
+
value_sym(param.to_sym, environment, bypass_interpolation)
|
1053
|
+
end
|
1051
1054
|
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1055
|
+
# Find the correct value using symbols and our search path.
|
1056
|
+
#
|
1057
|
+
# @param param [Symbol] The value to look up
|
1058
|
+
# @param environment [Symbol] The environment to check for the value
|
1059
|
+
# @param bypass_interpolation [true, false] Whether to skip interpolation
|
1060
|
+
#
|
1061
|
+
# @return [Object] The looked up value
|
1062
|
+
#
|
1063
|
+
# @raise [InterpolationError]
|
1064
|
+
def value_sym(param, environment = nil, bypass_interpolation = false)
|
1057
1065
|
# Check the cache first. It needs to be a per-environment
|
1058
1066
|
# cache so that we don't spread values from one env
|
1059
1067
|
# to another.
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1068
|
+
cached_env = @cache[environment || NONE]
|
1069
|
+
|
1070
|
+
# Avoid two lookups in cache_env unless val is nil. When it is, it's important
|
1071
|
+
# to check if the key is included so that further processing (that will result
|
1072
|
+
# in nil again) is avoided.
|
1073
|
+
val = cached_env[param]
|
1074
|
+
return val if !val.nil? || cached_env.include?(param)
|
1075
|
+
|
1076
|
+
# Short circuit to nil for undefined settings.
|
1077
|
+
return nil unless @config.include?(param)
|
1067
1078
|
|
1068
|
-
|
1079
|
+
vals = values(environment, preferred_run_mode)
|
1080
|
+
val = bypass_interpolation ? vals.lookup(param) : vals.interpolate(param)
|
1081
|
+
cached_env[param] = val
|
1069
1082
|
val
|
1070
1083
|
end
|
1071
1084
|
|
data/lib/puppet/ssl/base.rb
CHANGED
@@ -81,7 +81,20 @@ class Puppet::SSL::Base
|
|
81
81
|
|
82
82
|
# Read content from disk appropriately.
|
83
83
|
def read(path)
|
84
|
-
|
84
|
+
# applies to Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest, Puppet::SSL::CertificateRevocationList
|
85
|
+
# Puppet::SSL::Key uses this, but also provides its own override
|
86
|
+
# nothing derives from Puppet::SSL::Certificate, but it is called by a number of other SSL Indirectors:
|
87
|
+
# Puppet::SSL::Certificate::DisabledCa (:find, :save, :destroy)
|
88
|
+
# Puppet::Indirector::CertificateStatus::File (.indirection.find)
|
89
|
+
# Puppet::Network::HTTP::WEBrick (.indirection.find)
|
90
|
+
# Puppet::Network::HTTP::RackREST (.from_instance)
|
91
|
+
# Puppet::Network::HTTP::WEBrickREST (.from_instance)
|
92
|
+
# Puppet::SSL::CertificateAuthority (.new, .indirection.find, .indirection.save)
|
93
|
+
# Puppet::SSL::Host (.indirection.find)
|
94
|
+
# Puppet::SSL::Inventory (.indirection.search, implements its own add / rebuild / serials with encoding UTF8)
|
95
|
+
# Puppet::SSL::CertificateAuthority::Interface (.indirection.find)
|
96
|
+
# Puppet::SSL::Validator::DefaultValidator (.from_instance) / Puppet::SSL::Validator::NoValidator does nothing
|
97
|
+
@content = wrapped_class.new(Puppet::FileSystem.read(path, :encoding => Encoding::ASCII))
|
85
98
|
end
|
86
99
|
|
87
100
|
# Convert our thing to pem.
|
@@ -173,7 +173,8 @@ class Puppet::SSL::CertificateAuthority
|
|
173
173
|
20.times { pass += (rand(74) + 48).chr }
|
174
174
|
|
175
175
|
begin
|
176
|
-
|
176
|
+
# random password is limited to ASCII characters 48 ('0') through 122 ('z')
|
177
|
+
Puppet.settings.setting(:capass).open('w:ASCII') { |f| f.print pass }
|
177
178
|
rescue Errno::EACCES => detail
|
178
179
|
raise Puppet::Error, "Could not write CA password: #{detail}", detail.backtrace
|
179
180
|
end
|
@@ -216,7 +217,8 @@ class Puppet::SSL::CertificateAuthority
|
|
216
217
|
# file so this one is considered used.
|
217
218
|
def next_serial
|
218
219
|
serial = 1
|
219
|
-
|
220
|
+
# the serial is 4 hex digits - limited to ASCII
|
221
|
+
Puppet.settings.setting(:serial).exclusive_open('a+:ASCII') do |f|
|
220
222
|
f.rewind
|
221
223
|
serial = f.read.chomp.hex
|
222
224
|
if serial == 0
|
@@ -50,7 +50,10 @@ class Configuration
|
|
50
50
|
|
51
51
|
# read_file makes testing easier.
|
52
52
|
def read_file(path)
|
53
|
-
|
53
|
+
# https://www.ietf.org/rfc/rfc2459.txt defines the x509 V3 certificate format
|
54
|
+
# CA bundles are concatenated X509 certificates, but may also include
|
55
|
+
# comments, which could have UTF-8 characters
|
56
|
+
Puppet::FileSystem.read(path, :encoding => Encoding::UTF_8)
|
54
57
|
end
|
55
58
|
private :read_file
|
56
59
|
end
|
data/lib/puppet/ssl/inventory.rb
CHANGED
@@ -8,7 +8,10 @@ class Puppet::SSL::Inventory
|
|
8
8
|
# Add a certificate to our inventory.
|
9
9
|
def add(cert)
|
10
10
|
cert = cert.content if cert.is_a?(Puppet::SSL::Certificate)
|
11
|
-
|
11
|
+
# RFC 5280 says the cert subject may contain UTF8 - https://www.ietf.org/rfc/rfc5280.txt
|
12
|
+
# Note however that Puppet generated SSL files must only contain ASCII characters
|
13
|
+
# based on the validate_certname method of Puppet::SSL::Base
|
14
|
+
Puppet.settings.setting(:cert_inventory).open('a:UTF-8') do |f|
|
12
15
|
f.print format(cert)
|
13
16
|
end
|
14
17
|
end
|
@@ -28,7 +31,8 @@ class Puppet::SSL::Inventory
|
|
28
31
|
def rebuild
|
29
32
|
Puppet.notice "Rebuilding inventory file"
|
30
33
|
|
31
|
-
|
34
|
+
# RFC 5280 says the cert subject may contain UTF8 - https://www.ietf.org/rfc/rfc5280.txt
|
35
|
+
Puppet.settings.setting(:cert_inventory).open('w:UTF-8') do |f|
|
32
36
|
Puppet::SSL::Certificate.indirection.search("*").each do |cert|
|
33
37
|
f.print format(cert.content)
|
34
38
|
end
|
@@ -40,7 +44,10 @@ class Puppet::SSL::Inventory
|
|
40
44
|
def serials(name)
|
41
45
|
return [] unless Puppet::FileSystem.exist?(@path)
|
42
46
|
|
43
|
-
|
47
|
+
# RFC 5280 says the cert subject may contain UTF8 - https://www.ietf.org/rfc/rfc5280.txt
|
48
|
+
# Note however that Puppet generated SSL files must only contain ASCII characters
|
49
|
+
# based on the validate_certname method of Puppet::SSL::Base
|
50
|
+
File.readlines(@path, :encoding => Encoding::UTF_8).collect do |line|
|
44
51
|
/^(\S+).+\/CN=#{name}$/.match(line)
|
45
52
|
end.compact.map { |m| Integer(m[1]) }
|
46
53
|
end
|
data/lib/puppet/ssl/key.rb
CHANGED
@@ -38,15 +38,19 @@ DOC
|
|
38
38
|
def password
|
39
39
|
return nil unless password_file and Puppet::FileSystem.exist?(password_file)
|
40
40
|
|
41
|
-
|
41
|
+
# Puppet generates files at the default Puppet[:capass] using ASCII
|
42
|
+
# User configured :passfile could be in any encoding
|
43
|
+
# Use BINARY given the string is passed to an OpenSSL API accepting bytes
|
44
|
+
# note this is only called internally
|
45
|
+
Puppet::FileSystem.read(password_file, :encoding => Encoding::BINARY)
|
42
46
|
end
|
43
47
|
|
44
48
|
# Optionally support specifying a password file.
|
45
49
|
def read(path)
|
46
50
|
return super unless password_file
|
47
51
|
|
48
|
-
|
49
|
-
@content = wrapped_class.new(::
|
52
|
+
# RFC 1421 states PEM is 7-bit ASCII https://tools.ietf.org/html/rfc1421
|
53
|
+
@content = wrapped_class.new(Puppet::FileSystem.read(path, :encoding => Encoding::ASCII), password)
|
50
54
|
end
|
51
55
|
|
52
56
|
def to_s
|
@@ -192,6 +192,9 @@ module Puppet::Test
|
|
192
192
|
$old_env.each {|k, v| Puppet::Util.set_env(k, v, mode) }
|
193
193
|
end
|
194
194
|
|
195
|
+
# Clear all environments
|
196
|
+
Puppet.lookup(:environments).clear_all
|
197
|
+
|
195
198
|
# Restore the load_path late, to avoid messing with stubs from the test.
|
196
199
|
$LOAD_PATH.clear
|
197
200
|
$old_load_path.each {|x| $LOAD_PATH << x }
|
data/lib/puppet/type.rb
CHANGED
@@ -1218,6 +1218,10 @@ class Type
|
|
1218
1218
|
resource = Puppet::Resource.new(self, title)
|
1219
1219
|
resource.catalog = hash.delete(:catalog)
|
1220
1220
|
|
1221
|
+
if sensitive = hash.delete(:sensitive_parameters)
|
1222
|
+
resource.sensitive_parameters = sensitive
|
1223
|
+
end
|
1224
|
+
|
1221
1225
|
hash.each do |param, value|
|
1222
1226
|
resource[param] = value
|
1223
1227
|
end
|
@@ -1291,7 +1295,9 @@ class Type
|
|
1291
1295
|
end
|
1292
1296
|
|
1293
1297
|
newmetaparam(:audit) do
|
1294
|
-
desc "
|
1298
|
+
desc "(This metaparameter is deprecated and will be ignored in a future release.)
|
1299
|
+
|
1300
|
+
Marks a subset of this resource's unmanaged attributes for auditing. Accepts an
|
1295
1301
|
attribute name, an array of attribute names, or `all`.
|
1296
1302
|
|
1297
1303
|
Auditing a resource attribute has two effects: First, whenever a catalog
|
@@ -1312,6 +1318,12 @@ class Type
|
|
1312
1318
|
and the second run will log the edit made by Puppet.)"
|
1313
1319
|
|
1314
1320
|
validate do |list|
|
1321
|
+
if Puppet.settings[:strict] != :off
|
1322
|
+
# Only warn if `audit` metaparam came from a manifest
|
1323
|
+
if file && line
|
1324
|
+
puppet_deprecation_warning(_("The `audit` metaparameter is deprecated and will be ignored in a future release."), { :line => line, :file => file })
|
1325
|
+
end
|
1326
|
+
end
|
1315
1327
|
list = Array(list).collect {|p| p.to_sym}
|
1316
1328
|
unless list == [:all]
|
1317
1329
|
list.each do |param|
|
data/lib/puppet/type/exec.rb
CHANGED
@@ -157,7 +157,12 @@ module Puppet
|
|
157
157
|
end
|
158
158
|
|
159
159
|
unless self.should.include?(@status.exitstatus.to_s)
|
160
|
-
|
160
|
+
if @resource.parameter(:command).sensitive
|
161
|
+
# Don't print sensitive commands in the clear
|
162
|
+
self.fail("[command redacted] returned #{@status.exitstatus} instead of one of [#{self.should.join(",")}]")
|
163
|
+
else
|
164
|
+
self.fail("'#{self.resource[:command]}' returned #{@status.exitstatus} instead of one of [#{self.should.join(",")}]")
|
165
|
+
end
|
161
166
|
end
|
162
167
|
|
163
168
|
event
|
@@ -597,5 +602,15 @@ module Puppet
|
|
597
602
|
def current_username
|
598
603
|
Etc.getpwuid(Process.uid).name
|
599
604
|
end
|
605
|
+
|
606
|
+
private
|
607
|
+
def set_sensitive_parameters(sensitive_parameters)
|
608
|
+
# Respect sensitive commands
|
609
|
+
if sensitive_parameters.include?(:command)
|
610
|
+
sensitive_parameters.delete(:command)
|
611
|
+
parameter(:command).sensitive = true
|
612
|
+
end
|
613
|
+
super(sensitive_parameters)
|
614
|
+
end
|
600
615
|
end
|
601
616
|
end
|
data/lib/puppet/type/group.rb
CHANGED
@@ -79,10 +79,9 @@ module Puppet
|
|
79
79
|
end
|
80
80
|
|
81
81
|
newproperty(:members, :array_matching => :all, :required_features => :manages_members) do
|
82
|
-
desc "The members of the group. For directory services where group
|
83
|
-
|
84
|
-
|
85
|
-
are inclusive or the minimum."
|
82
|
+
desc "The members of the group. For platforms or directory services where group
|
83
|
+
membership is stored in the group objects, not the users. This parameter's
|
84
|
+
behavior can be configured with `auth_membership`."
|
86
85
|
|
87
86
|
def change_to_s(currentvalue, newvalue)
|
88
87
|
currentvalue = currentvalue.join(",") if currentvalue != :absent
|
@@ -118,9 +117,12 @@ module Puppet
|
|
118
117
|
end
|
119
118
|
|
120
119
|
newparam(:auth_membership, :boolean => true, :parent => Puppet::Parameter::Boolean) do
|
121
|
-
desc "
|
122
|
-
|
123
|
-
`members
|
120
|
+
desc "Configures the behavior of the `members` parameter.
|
121
|
+
|
122
|
+
* `false` (default) --- The provided list of group members is partial,
|
123
|
+
and Puppet **ignores** any members that aren't listed there.
|
124
|
+
* `true` --- The provided list of of group members is comprehensive, and
|
125
|
+
Puppet **purges** any members that aren't listed there."
|
124
126
|
defaultto false
|
125
127
|
end
|
126
128
|
|
@@ -146,7 +148,8 @@ module Puppet
|
|
146
148
|
end
|
147
149
|
|
148
150
|
newproperty(:attributes, :parent => Puppet::Property::KeyValue, :required_features => :manages_aix_lam) do
|
149
|
-
desc "Specify group AIX attributes
|
151
|
+
desc "Specify group AIX attributes, as an array of `'key=value'` strings. This
|
152
|
+
parameter's behavior can be configured with `attribute_membership`."
|
150
153
|
|
151
154
|
def membership
|
152
155
|
:attribute_membership
|
@@ -162,9 +165,12 @@ module Puppet
|
|
162
165
|
end
|
163
166
|
|
164
167
|
newparam(:attribute_membership) do
|
165
|
-
desc "
|
166
|
-
|
167
|
-
|
168
|
+
desc "AIX only. Configures the behavior of the `attributes` parameter.
|
169
|
+
|
170
|
+
* `minimum` (default) --- The provided list of attributes is partial, and Puppet
|
171
|
+
**ignores** any attributes that aren't listed there.
|
172
|
+
* `inclusive` --- The provided list of attributes is comprehensive, and
|
173
|
+
Puppet **purges** any attributes that aren't listed there."
|
168
174
|
|
169
175
|
newvalues(:inclusive, :minimum)
|
170
176
|
|
data/lib/puppet/type/user.rb
CHANGED
@@ -739,7 +739,9 @@ module Puppet
|
|
739
739
|
def unknown_keys_in_file(keyfile)
|
740
740
|
names = []
|
741
741
|
name_index = 0
|
742
|
-
|
742
|
+
# RFC 4716 specifies UTF-8 allowed in public key files per https://www.ietf.org/rfc/rfc4716.txt
|
743
|
+
# the authorized_keys file may contain UTF-8 comments
|
744
|
+
Puppet::FileSystem.open(keyfile, nil, 'r:UTF-8').each do |line|
|
743
745
|
next unless line =~ Puppet::Type.type(:ssh_authorized_key).keyline_regex
|
744
746
|
# the name is stored in the 4th capture of the regex
|
745
747
|
name = $4
|
data/lib/puppet/util.rb
CHANGED
@@ -0,0 +1,95 @@
|
|
1
|
+
# A module to centralize heuristics/practices for managing character encoding in Puppet
|
2
|
+
|
3
|
+
module Puppet::Util::CharacterEncoding
|
4
|
+
class << self
|
5
|
+
# Warning! This is a destructive method - the string supplied is modified!
|
6
|
+
# @api public
|
7
|
+
# @param [String] string a string to transcode / force_encode to utf-8
|
8
|
+
# @return [String] string if already utf-8, OR
|
9
|
+
# the same string with external encoding set to utf-8 if bytes are valid utf-8 OR
|
10
|
+
# the same string transcoded to utf-8 OR
|
11
|
+
# nil upon a failure to legitimately set external encoding or transcode string
|
12
|
+
def convert_to_utf_8!(string)
|
13
|
+
currently_valid = string.valid_encoding?
|
14
|
+
|
15
|
+
begin
|
16
|
+
if string.encoding == Encoding::UTF_8
|
17
|
+
if currently_valid
|
18
|
+
return string
|
19
|
+
else
|
20
|
+
# If a string is currently believed to be UTF-8, but is also not
|
21
|
+
# valid_encoding?, we have no recourse but to fail because we have no
|
22
|
+
# idea what encoding this string originally came from where it *was*
|
23
|
+
# valid - all we know is it's not currently valid UTF-8.
|
24
|
+
raise EncodingError
|
25
|
+
end
|
26
|
+
elsif valid_utf_8_bytes?(string)
|
27
|
+
# Before we try to transcode the string, check if it is valid UTF-8 as
|
28
|
+
# currently constitued (in its non-UTF-8 encoding), and if it is, limit
|
29
|
+
# ourselves to setting the external encoding of the string to UTF-8
|
30
|
+
# rather than actually transcoding it. We do this to handle
|
31
|
+
# a couple scenarios:
|
32
|
+
|
33
|
+
# The first scenario is that the string was originally valid UTF-8 but
|
34
|
+
# the current puppet run is not in a UTF-8 environment. In this case,
|
35
|
+
# the string will likely have invalid byte sequences (i.e.,
|
36
|
+
# string.valid_encoding? == false), and attempting to transcode will
|
37
|
+
# fail with Encoding::InvalidByteSequenceError, referencing the
|
38
|
+
# invalid byte sequence in the original, pre-transcode, string. We
|
39
|
+
# might have gotten here, for example, if puppet is run first in a
|
40
|
+
# user context with UTF-8 encoding (setting the "is" value to UTF-8)
|
41
|
+
# and then later run via cron without UTF-8 specified, resulting in in
|
42
|
+
# EN_US (ISO-8859-1) on many systems. In this scenario we're
|
43
|
+
# effectively best-guessing this string originated as UTF-8 and only
|
44
|
+
# set external encoding to UTF-8 - transcoding would have failed
|
45
|
+
# anyway.
|
46
|
+
|
47
|
+
# The second scenario (more rare, I expect) is that this string does
|
48
|
+
# NOT have invalid byte sequences (string.valid_encoding? == true),
|
49
|
+
# but is *ALSO valid unicode*.
|
50
|
+
# Our example case is "\u16A0" - "RUNIC LETTER FEHU FEOH FE"
|
51
|
+
# http://www.fileformat.info/info/unicode/char/16A0/index.htm
|
52
|
+
# 0xE1 0x9A 0xA0 / 225 154 160
|
53
|
+
# These bytes are valid in ISO-8859-1 but the character they represent
|
54
|
+
# transcodes cleanly in ruby to *different* characters in UTF-8.
|
55
|
+
# That's not what we want if the user intended the original string as
|
56
|
+
# UTF-8. We can only guess, so if the string is valid UTF-8 as
|
57
|
+
# currently constituted, we default to assuming the string originated
|
58
|
+
# in UTF-8 and do not transcode it - we only set external encoding.
|
59
|
+
return string.force_encoding(Encoding::UTF_8)
|
60
|
+
elsif currently_valid
|
61
|
+
# If the string is not currently valid UTF-8 but it can be transcoded
|
62
|
+
# (it is valid in its current encoding), we can guess this string was
|
63
|
+
# not originally unicode. Transcode it to UTF-8. For strings with
|
64
|
+
# original encodings like SHIFT_JIS, this should be the final result.
|
65
|
+
return string.encode!(Encoding::UTF_8)
|
66
|
+
else
|
67
|
+
# If the string is neither valid UTF-8 as-is nor valid in its current
|
68
|
+
# encoding, fail. It requires user remediation.
|
69
|
+
raise EncodingError
|
70
|
+
end
|
71
|
+
rescue EncodingError => detail
|
72
|
+
# Catch both our own self-determined failure to transcode as well as any
|
73
|
+
# error on ruby's part, ie Encoding::UndefinedConversionError on a
|
74
|
+
# failure to encode!.
|
75
|
+
Puppet.debug(_("%{error}: %{value} is not valid UTF-8 and cannot be transcoded by Puppet.") %
|
76
|
+
{ error: detail.inspect, value: string.dump })
|
77
|
+
return nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
# Do our best to determine if a string is valid UTF-8 via String#valid_encoding? without permanently
|
84
|
+
# modifying or duplicating the string due to performance concerns
|
85
|
+
# @api private
|
86
|
+
# @param [String] string a string to test
|
87
|
+
# @return [Boolean] whether we think the string is UTF-8 or not
|
88
|
+
def valid_utf_8_bytes?(string)
|
89
|
+
original_encoding = string.encoding
|
90
|
+
valid = string.force_encoding(Encoding::UTF_8).valid_encoding?
|
91
|
+
string.force_encoding(original_encoding)
|
92
|
+
valid
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|