puppet 8.1.0-x86-mingw32 → 8.3.1-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +39 -45
- data/ext/project_data.yaml +2 -2
- data/lib/puppet/application/doc.rb +1 -1
- data/lib/puppet/application/ssl.rb +42 -7
- data/lib/puppet/application.rb +5 -1
- data/lib/puppet/defaults.rb +17 -5
- data/lib/puppet/face/config.rb +1 -1
- data/lib/puppet/face/epp.rb +2 -2
- data/lib/puppet/face/module/list.rb +2 -2
- data/lib/puppet/face/parser.rb +1 -1
- data/lib/puppet/functions/split.rb +28 -1
- data/lib/puppet/http/client.rb +12 -5
- data/lib/puppet/http/service/ca.rb +25 -0
- data/lib/puppet/indirector/facts/facter.rb +1 -1
- data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
- data/lib/puppet/indirector/indirection.rb +1 -1
- data/lib/puppet/info_service/task_information_service.rb +1 -1
- data/lib/puppet/module_tool.rb +1 -1
- data/lib/puppet/network/formats.rb +3 -3
- data/lib/puppet/network/http/memory_response.rb +1 -1
- data/lib/puppet/node/environment.rb +6 -4
- data/lib/puppet/parameter/value_collection.rb +1 -1
- data/lib/puppet/parser/files.rb +4 -3
- data/lib/puppet/parser/functions.rb +1 -1
- data/lib/puppet/pops/evaluator/deferred_resolver.rb +20 -3
- data/lib/puppet/pops/loader/loader_paths.rb +4 -4
- data/lib/puppet/pops/lookup/explainer.rb +1 -1
- data/lib/puppet/pops/lookup/hiera_config.rb +1 -1
- data/lib/puppet/pops/model/factory.rb +1 -1
- data/lib/puppet/pops/model/tree_dumper.rb +1 -1
- data/lib/puppet/pops/parser/epp_support.rb +1 -1
- data/lib/puppet/pops/parser/evaluating_parser.rb +1 -1
- data/lib/puppet/pops/parser/pn_parser.rb +1 -1
- data/lib/puppet/pops/pn.rb +1 -1
- data/lib/puppet/pops/serialization/json_path.rb +1 -1
- data/lib/puppet/pops/time/timespan.rb +4 -4
- data/lib/puppet/pops/types/ruby_generator.rb +2 -2
- data/lib/puppet/pops/types/string_converter.rb +6 -6
- data/lib/puppet/pops/types/type_formatter.rb +2 -2
- data/lib/puppet/pops/types/types.rb +1 -1
- data/lib/puppet/provider/nameservice/directoryservice.rb +2 -2
- data/lib/puppet/provider/package/apt.rb +1 -1
- data/lib/puppet/provider/package/dnf.rb +1 -1
- data/lib/puppet/provider/package/yum.rb +1 -1
- data/lib/puppet/provider/user/directoryservice.rb +1 -1
- data/lib/puppet/reference/configuration.rb +1 -1
- data/lib/puppet/reference/indirection.rb +1 -1
- data/lib/puppet/reports.rb +1 -1
- data/lib/puppet/ssl/oids.rb +2 -0
- data/lib/puppet/ssl/ssl_provider.rb +1 -1
- data/lib/puppet/ssl/state_machine.rb +60 -9
- data/lib/puppet/transaction/report.rb +1 -1
- data/lib/puppet/type/filebucket.rb +1 -1
- data/lib/puppet/util/diff.rb +1 -1
- data/lib/puppet/util/execution.rb +9 -4
- data/lib/puppet/util/inifile.rb +2 -2
- data/lib/puppet/util/monkey_patches.rb +18 -0
- data/lib/puppet/util/package/version/rpm.rb +1 -1
- data/lib/puppet/util/provider_features.rb +1 -1
- data/lib/puppet/util/selinux.rb +1 -1
- data/lib/puppet/util/windows/access_control_entry.rb +1 -1
- data/lib/puppet/util/windows/access_control_list.rb +1 -1
- data/lib/puppet/util/windows/adsi.rb +9 -2
- data/lib/puppet/util/windows/error.rb +1 -1
- data/lib/puppet/util/windows/file.rb +2 -2
- data/lib/puppet/util/windows/process.rb +1 -1
- data/lib/puppet/util/windows/sid.rb +4 -2
- data/lib/puppet/util.rb +2 -3
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet/x509/cert_provider.rb +13 -2
- data/locales/puppet.pot +106 -74
- data/man/man5/puppet.conf.5 +16 -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-lookup.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 +5 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/ssl/127.0.0.1-key.pem +107 -107
- data/spec/fixtures/ssl/127.0.0.1.pem +52 -51
- data/spec/fixtures/ssl/bad-basic-constraints.pem +56 -56
- data/spec/fixtures/ssl/bad-int-basic-constraints.pem +53 -53
- data/spec/fixtures/ssl/ca.pem +54 -54
- data/spec/fixtures/ssl/crl.pem +26 -26
- data/spec/fixtures/ssl/ec-key.pem +11 -11
- data/spec/fixtures/ssl/ec.pem +33 -32
- data/spec/fixtures/ssl/encrypted-ec-key.pem +12 -12
- data/spec/fixtures/ssl/encrypted-key.pem +108 -108
- data/spec/fixtures/ssl/intermediate-agent-crl.pem +26 -26
- data/spec/fixtures/ssl/intermediate-agent.pem +56 -56
- data/spec/fixtures/ssl/intermediate-crl.pem +29 -29
- data/spec/fixtures/ssl/intermediate.pem +53 -53
- data/spec/fixtures/ssl/oid-key.pem +107 -107
- data/spec/fixtures/ssl/oid.pem +51 -50
- data/spec/fixtures/ssl/pluto-key.pem +107 -107
- data/spec/fixtures/ssl/pluto.pem +52 -51
- data/spec/fixtures/ssl/renewed.pem +67 -0
- data/spec/fixtures/ssl/request-key.pem +107 -107
- data/spec/fixtures/ssl/request.pem +50 -48
- data/spec/fixtures/ssl/revoked-key.pem +107 -107
- data/spec/fixtures/ssl/revoked.pem +51 -50
- data/spec/fixtures/ssl/signed-key.pem +107 -107
- data/spec/fixtures/ssl/signed.pem +49 -48
- data/spec/fixtures/ssl/tampered-cert.pem +51 -50
- data/spec/fixtures/ssl/tampered-csr.pem +50 -48
- data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +107 -107
- data/spec/fixtures/ssl/unknown-127.0.0.1.pem +50 -49
- data/spec/fixtures/ssl/unknown-ca-key.pem +107 -107
- data/spec/fixtures/ssl/unknown-ca.pem +54 -54
- data/spec/integration/application/agent_spec.rb +27 -27
- data/spec/integration/application/apply_spec.rb +14 -0
- data/spec/integration/http/client_spec.rb +16 -0
- data/spec/integration/type/exec_spec.rb +13 -0
- data/spec/lib/puppet/test_ca.rb +3 -10
- data/spec/lib/puppet_spec/verbose.rb +10 -1
- data/spec/unit/agent_spec.rb +2 -9
- data/spec/unit/application/ssl_spec.rb +49 -0
- data/spec/unit/defaults_spec.rb +2 -40
- data/spec/unit/file_system/path_pattern_spec.rb +15 -0
- data/spec/unit/functions/split_spec.rb +6 -0
- data/spec/unit/http/service/ca_spec.rb +71 -0
- data/spec/unit/info_service_spec.rb +1 -1
- data/spec/unit/ssl/certificate_signer_spec.rb +17 -0
- data/spec/unit/ssl/ssl_provider_spec.rb +21 -1
- data/spec/unit/ssl/state_machine_spec.rb +75 -3
- data/spec/unit/util/execution_spec.rb +1 -0
- data/spec/unit/util/monkey_patches_spec.rb +42 -0
- data/spec/unit/util/windows/adsi_spec.rb +25 -0
- data/spec/unit/x509/cert_provider_spec.rb +23 -0
- data/tasks/generate_cert_fixtures.rake +4 -0
- metadata +11 -13
data/lib/puppet/parser/files.rb
CHANGED
@@ -29,9 +29,10 @@ module Puppet::Parser::Files
|
|
29
29
|
# * modulename/filename selector: a file is found in the file directory
|
30
30
|
# of the named module.
|
31
31
|
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
32
|
+
# The check for file existence is performed on the node compiling the
|
33
|
+
# manifest. A node running "puppet apply" compiles its own manifest, but
|
34
|
+
# a node running "puppet agent" depends on the configured puppetserver
|
35
|
+
# for compiling. In either case, a nil is returned if no file is found.
|
35
36
|
#
|
36
37
|
# @param template [String] the file selector
|
37
38
|
# @param environment [Puppet::Node::Environment] the environment in which to search
|
@@ -258,7 +258,7 @@ module Puppet::Parser::Functions
|
|
258
258
|
def self.functiondocs(environment = Puppet.lookup(:current_environment))
|
259
259
|
autoloader.delegatee.loadall(environment)
|
260
260
|
|
261
|
-
ret =
|
261
|
+
ret = ''.dup
|
262
262
|
|
263
263
|
merged_functions(environment).sort { |a,b| a[0].to_s <=> b[0].to_s }.each do |name, hash|
|
264
264
|
ret << "#{name}\n#{"-" * name.to_s.length}\n"
|
@@ -10,7 +10,13 @@ class DeferredValue
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def resolve
|
13
|
-
@proc.call
|
13
|
+
val = @proc.call
|
14
|
+
# Deferred sensitive values will be marked as such in resolve_futures()
|
15
|
+
if val.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
|
16
|
+
val.unwrap
|
17
|
+
else
|
18
|
+
val
|
19
|
+
end
|
14
20
|
end
|
15
21
|
end
|
16
22
|
|
@@ -88,8 +94,12 @@ class DeferredResolver
|
|
88
94
|
#
|
89
95
|
if resolved.is_a?(Puppet::Pops::Types::PSensitiveType::Sensitive)
|
90
96
|
resolved = resolved.unwrap
|
91
|
-
|
92
|
-
|
97
|
+
mark_sensitive_parameters(r, k)
|
98
|
+
# If the value is a DeferredValue and it has an argument of type PSensitiveType, mark it as sensitive
|
99
|
+
# The DeferredValue.resolve method will unwrap it during catalog application
|
100
|
+
elsif resolved.is_a?(Puppet::Pops::Evaluator::DeferredValue)
|
101
|
+
if v.arguments.any? {|arg| arg.is_a?(Puppet::Pops::Types::PSensitiveType)}
|
102
|
+
mark_sensitive_parameters(r, k)
|
93
103
|
end
|
94
104
|
end
|
95
105
|
overrides[ k ] = resolved
|
@@ -98,6 +108,13 @@ class DeferredResolver
|
|
98
108
|
end
|
99
109
|
end
|
100
110
|
|
111
|
+
def mark_sensitive_parameters(r, k)
|
112
|
+
unless r.sensitive_parameters.include?(k.to_sym)
|
113
|
+
r.sensitive_parameters = (r.sensitive_parameters + [k.to_sym]).freeze
|
114
|
+
end
|
115
|
+
end
|
116
|
+
private :mark_sensitive_parameters
|
117
|
+
|
101
118
|
def resolve(x)
|
102
119
|
if x.class == @deferred_class
|
103
120
|
resolve_future(x)
|
@@ -88,7 +88,7 @@ module LoaderPaths
|
|
88
88
|
|
89
89
|
def typed_name(type, name_authority, relative_path, module_name)
|
90
90
|
# Module name is assumed to be included in the path and therefore not added here
|
91
|
-
n =
|
91
|
+
n = ''.dup
|
92
92
|
unless extension.empty?
|
93
93
|
# Remove extension
|
94
94
|
relative_path = relative_path[0..-(extension.length+1)]
|
@@ -153,7 +153,7 @@ module LoaderPaths
|
|
153
153
|
end
|
154
154
|
|
155
155
|
def typed_name(type, name_authority, relative_path, module_name)
|
156
|
-
n =
|
156
|
+
n = ''.dup
|
157
157
|
n << module_name unless module_name.nil?
|
158
158
|
unless extension.empty?
|
159
159
|
# Remove extension
|
@@ -249,7 +249,7 @@ module LoaderPaths
|
|
249
249
|
end
|
250
250
|
|
251
251
|
def typed_name(type, name_authority, relative_path, module_name)
|
252
|
-
n =
|
252
|
+
n = ''.dup
|
253
253
|
n << module_name unless module_name.nil?
|
254
254
|
|
255
255
|
# Remove the file extension, defined as everything after the *last* dot.
|
@@ -351,7 +351,7 @@ module LoaderPaths
|
|
351
351
|
if @init_filenames.include?(relative_path) && !(module_name.nil? || module_name.empty?)
|
352
352
|
TypedName.new(type, module_name, name_authority)
|
353
353
|
else
|
354
|
-
n =
|
354
|
+
n = ''.dup
|
355
355
|
n << module_name unless module_name.nil?
|
356
356
|
ext = @extensions.find { |extension| relative_path.end_with?(extension) }
|
357
357
|
relative_path = relative_path[0..-(ext.length+1)]
|
data/lib/puppet/pops/pn.rb
CHANGED
@@ -545,7 +545,7 @@ module Time
|
|
545
545
|
end
|
546
546
|
|
547
547
|
def format(timespan)
|
548
|
-
bld =
|
548
|
+
bld = timespan.negative? ? '-'.dup : ''.dup
|
549
549
|
@segments.each { |segment| segment.append_to(bld, timespan) }
|
550
550
|
bld
|
551
551
|
end
|
@@ -575,7 +575,7 @@ module Time
|
|
575
575
|
end
|
576
576
|
|
577
577
|
def build_regexp
|
578
|
-
bld =
|
578
|
+
bld = '\A-?'.dup
|
579
579
|
@segments.each { |segment| segment.append_regexp(bld) }
|
580
580
|
bld << '\z'
|
581
581
|
Regexp.new(bld)
|
@@ -613,7 +613,7 @@ module Time
|
|
613
613
|
|
614
614
|
def append_literal(bld, codepoint)
|
615
615
|
if bld.empty? || !bld.last.is_a?(Format::LiteralSegment)
|
616
|
-
bld << Format::LiteralSegment.new(
|
616
|
+
bld << Format::LiteralSegment.new(''.dup.concat(codepoint))
|
617
617
|
else
|
618
618
|
bld.last.concat(codepoint)
|
619
619
|
end
|
@@ -634,7 +634,7 @@ module Time
|
|
634
634
|
position = -1
|
635
635
|
fstart = 0
|
636
636
|
|
637
|
-
str.
|
637
|
+
str.each_codepoint do |codepoint|
|
638
638
|
position += 1
|
639
639
|
if state == STATE_LITERAL
|
640
640
|
if codepoint == 0x25 # '%'
|
@@ -60,7 +60,7 @@ class RubyGenerator < TypeFormatter
|
|
60
60
|
if cls.nil?
|
61
61
|
rp = key.resolved_parent
|
62
62
|
parent_class = rp.is_a?(PObjectType) ? rp.implementation_class : Object
|
63
|
-
class_def =
|
63
|
+
class_def = ''.dup
|
64
64
|
class_body(key, EMPTY_ARRAY, class_def)
|
65
65
|
cls = Class.new(parent_class)
|
66
66
|
cls.class_eval(class_def)
|
@@ -109,7 +109,7 @@ class RubyGenerator < TypeFormatter
|
|
109
109
|
end
|
110
110
|
|
111
111
|
# Create class definition of all contained types
|
112
|
-
bld =
|
112
|
+
bld = ''.dup
|
113
113
|
start_module(common_prefix, comment, bld)
|
114
114
|
class_names = []
|
115
115
|
names_by_prefix.each_pair do |seg_array, index_and_name_array|
|
@@ -701,7 +701,7 @@ class StringConverter
|
|
701
701
|
# Performs post-processing of literals to apply width and precision flags
|
702
702
|
def apply_string_flags(f, literal_str)
|
703
703
|
if f.left || f.width || f.prec
|
704
|
-
fmt =
|
704
|
+
fmt = '%'.dup
|
705
705
|
fmt << '-' if f.left
|
706
706
|
fmt << f.width.to_s if f.width
|
707
707
|
fmt << '.' << f.prec.to_s if f.prec
|
@@ -853,7 +853,7 @@ class StringConverter
|
|
853
853
|
end
|
854
854
|
|
855
855
|
# Assume that the string can be single quoted
|
856
|
-
bld =
|
856
|
+
bld = "'".dup
|
857
857
|
bld.force_encoding(str.encoding)
|
858
858
|
escaped = false
|
859
859
|
str.each_codepoint do |codepoint|
|
@@ -879,12 +879,12 @@ class StringConverter
|
|
879
879
|
# If string ended with a backslash, then that backslash must be escaped
|
880
880
|
bld << 0x5c if escaped
|
881
881
|
|
882
|
-
bld << '
|
882
|
+
bld << "'"
|
883
883
|
bld
|
884
884
|
end
|
885
885
|
|
886
886
|
def puppet_double_quote(str)
|
887
|
-
bld =
|
887
|
+
bld = '"'.dup
|
888
888
|
str.each_codepoint do |codepoint|
|
889
889
|
case codepoint
|
890
890
|
when 0x09
|
@@ -940,7 +940,7 @@ class StringConverter
|
|
940
940
|
|
941
941
|
case format.format
|
942
942
|
when :a, :s, :p
|
943
|
-
buf =
|
943
|
+
buf = ''.dup
|
944
944
|
if indentation.breaks?
|
945
945
|
buf << "\n"
|
946
946
|
buf << indentation.padding
|
@@ -1055,7 +1055,7 @@ class StringConverter
|
|
1055
1055
|
|
1056
1056
|
when :h, :s, :p
|
1057
1057
|
indentation = indentation.indenting(format.alt? || indentation.is_indenting?)
|
1058
|
-
buf =
|
1058
|
+
buf = ''.dup
|
1059
1059
|
if indentation.breaks?
|
1060
1060
|
buf << "\n"
|
1061
1061
|
buf << indentation.padding
|
@@ -50,7 +50,7 @@ class TypeFormatter
|
|
50
50
|
# @api public
|
51
51
|
#
|
52
52
|
def string(t)
|
53
|
-
@bld =
|
53
|
+
@bld = ''.dup
|
54
54
|
append_string(t)
|
55
55
|
@bld
|
56
56
|
end
|
@@ -64,7 +64,7 @@ class TypeFormatter
|
|
64
64
|
#
|
65
65
|
# @api public
|
66
66
|
def indented_string(t, indent = 0, indent_width = 2)
|
67
|
-
@bld =
|
67
|
+
@bld = ''.dup
|
68
68
|
append_indented_string(t, indent, indent_width)
|
69
69
|
@bld
|
70
70
|
end
|
@@ -1713,7 +1713,7 @@ class PRegexpType < PScalarType
|
|
1713
1713
|
if options == 0
|
1714
1714
|
rx_string
|
1715
1715
|
else
|
1716
|
-
bld =
|
1716
|
+
bld = '(?'.dup
|
1717
1717
|
bld << 'i' if (options & Regexp::IGNORECASE) != 0
|
1718
1718
|
bld << 'm' if (options & Regexp::MULTILINE) != 0
|
1719
1719
|
bld << 'x' if (options & Regexp::EXTENDED) != 0
|
@@ -218,8 +218,8 @@ class Puppet::Provider::NameService::DirectoryService < Puppet::Provider::NameSe
|
|
218
218
|
password_hash_plist = users_plist['ShadowHashData'][0]
|
219
219
|
converted_hash_plist = convert_binary_to_hash(password_hash_plist)
|
220
220
|
else
|
221
|
-
users_plist['ShadowHashData'] =
|
222
|
-
converted_hash_plist = {'SALTED-SHA512' =>
|
221
|
+
users_plist['ShadowHashData'] = ''.dup
|
222
|
+
converted_hash_plist = {'SALTED-SHA512' => ''.dup}
|
223
223
|
end
|
224
224
|
|
225
225
|
# converted_hash_plist['SALTED-SHA512'] expects a Base64 encoded
|
@@ -13,7 +13,7 @@ Puppet::Type.type(:package).provide :apt, :parent => :dpkg, :source => :dpkg do
|
|
13
13
|
These options should be specified as an array where each element is either a
|
14
14
|
string or a hash."
|
15
15
|
|
16
|
-
has_feature :versionable, :install_options, :virtual_packages
|
16
|
+
has_feature :versionable, :install_options, :virtual_packages, :version_ranges
|
17
17
|
|
18
18
|
commands :aptget => "/usr/bin/apt-get"
|
19
19
|
commands :aptcache => "/usr/bin/apt-cache"
|
@@ -10,7 +10,7 @@ Puppet::Type.type(:package).provide :dnf, :parent => :yum do
|
|
10
10
|
These options should be specified as an array where each element is either
|
11
11
|
a string or a hash."
|
12
12
|
|
13
|
-
has_feature :install_options, :versionable, :virtual_packages, :install_only
|
13
|
+
has_feature :install_options, :versionable, :virtual_packages, :install_only, :version_ranges
|
14
14
|
|
15
15
|
commands :cmd => "dnf", :rpm => "rpm"
|
16
16
|
|
@@ -16,7 +16,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
|
|
16
16
|
This provider supports the `install_options` attribute, which allows command-line flags to be passed to yum.
|
17
17
|
These options should be specified as an array where each element is either a string or a hash."
|
18
18
|
|
19
|
-
has_feature :install_options, :versionable, :virtual_packages, :install_only
|
19
|
+
has_feature :install_options, :versionable, :virtual_packages, :install_only, :version_ranges
|
20
20
|
|
21
21
|
RPM_VERSION = Puppet::Util::Package::Version::Rpm
|
22
22
|
RPM_VERSION_RANGE = Puppet::Util::Package::Version::Range
|
@@ -637,7 +637,7 @@ Puppet::Type.type(:user).provide :directoryservice do
|
|
637
637
|
def set_salted_sha512(users_plist, shadow_hash_data, value)
|
638
638
|
unless shadow_hash_data
|
639
639
|
shadow_hash_data = Hash.new
|
640
|
-
shadow_hash_data['SALTED-SHA512'] =
|
640
|
+
shadow_hash_data['SALTED-SHA512'] = ''.dup
|
641
641
|
end
|
642
642
|
shadow_hash_data['SALTED-SHA512'] = base64_decode_string(value)
|
643
643
|
binary_plist = self.class.convert_hash_to_binary(shadow_hash_data)
|
@@ -5,7 +5,7 @@ require_relative '../../puppet/file_serving/content'
|
|
5
5
|
require_relative '../../puppet/file_serving/metadata'
|
6
6
|
|
7
7
|
reference = Puppet::Util::Reference.newreference :indirection, :doc => "Indirection types and their terminus classes" do
|
8
|
-
text =
|
8
|
+
text = ''.dup
|
9
9
|
Puppet::Indirector::Indirection.instances.sort_by(&:to_s).each do |indirection|
|
10
10
|
ind = Puppet::Indirector::Indirection.instance(indirection)
|
11
11
|
name = indirection.to_s.capitalize
|
data/lib/puppet/reports.rb
CHANGED
@@ -71,7 +71,7 @@ class Puppet::Reports
|
|
71
71
|
# Collects the docs for all reports.
|
72
72
|
# @api private
|
73
73
|
def self.reportdocs
|
74
|
-
docs =
|
74
|
+
docs = ''.dup
|
75
75
|
|
76
76
|
# Use this method so they all get loaded
|
77
77
|
instance_loader(:report).loadall(Puppet.lookup(:current_environment))
|
data/lib/puppet/ssl/oids.rb
CHANGED
@@ -71,7 +71,9 @@ module Puppet::SSL::Oids
|
|
71
71
|
["1.3.6.1.4.1.34380.1.3", 'ppAuthCertExt', 'Puppet Certificate Authorization Extension'],
|
72
72
|
|
73
73
|
["1.3.6.1.4.1.34380.1.3.1", 'pp_authorization', 'Certificate Extension Authorization'],
|
74
|
+
["1.3.6.1.4.1.34380.1.3.2", 'pp_auth_auto_renew', 'Auto-Renew Certificate Attribute'],
|
74
75
|
["1.3.6.1.4.1.34380.1.3.13", 'pp_auth_role', 'Puppet Node Role Name for Authorization'],
|
76
|
+
["1.3.6.1.4.1.34380.1.3.39", 'pp_cli_auth', 'Puppetserver CA CLI Authorization'],
|
75
77
|
]
|
76
78
|
|
77
79
|
@did_register_puppet_oids = false
|
@@ -225,7 +225,7 @@ class Puppet::SSL::SSLProvider
|
|
225
225
|
ssl_context.crls.each do |crl|
|
226
226
|
oid_values = Hash[crl.extensions.map { |ext| [ext.oid, ext.value] }]
|
227
227
|
crlNumber = oid_values['crlNumber'] || 'unknown'
|
228
|
-
authKeyId = (oid_values['authorityKeyIdentifier'] || 'unknown').chomp
|
228
|
+
authKeyId = (oid_values['authorityKeyIdentifier'] || 'unknown').chomp
|
229
229
|
Puppet.debug("Using CRL '#{crl.issuer.to_utf8}' authorityKeyIdentifier '#{authKeyId}' crlNumber '#{crlNumber }'")
|
230
230
|
end
|
231
231
|
end
|
@@ -59,9 +59,6 @@ class Puppet::SSL::StateMachine
|
|
59
59
|
now = Time.now
|
60
60
|
last_update = @cert_provider.ca_last_update
|
61
61
|
if needs_refresh?(now, last_update)
|
62
|
-
# set last updated time first, then make a best effort to refresh
|
63
|
-
@cert_provider.ca_last_update = now
|
64
|
-
|
65
62
|
# If we refresh the CA, then we need to force the CRL to be refreshed too,
|
66
63
|
# since if there is a new CA in the chain, then we need its CRL to check
|
67
64
|
# the full chain for revocation status.
|
@@ -114,7 +111,12 @@ class Puppet::SSL::StateMachine
|
|
114
111
|
Puppet.info(_("Refreshing CA certificate"))
|
115
112
|
|
116
113
|
# return the next_ctx containing the updated ca
|
117
|
-
[download_ca(ssl_ctx, last_update), true]
|
114
|
+
next_ctx = [download_ca(ssl_ctx, last_update), true]
|
115
|
+
|
116
|
+
# After a successful refresh, update ca_last_update
|
117
|
+
@cert_provider.ca_last_update = Time.now
|
118
|
+
|
119
|
+
next_ctx
|
118
120
|
rescue Puppet::HTTP::ResponseError => e
|
119
121
|
if e.response.code == 304
|
120
122
|
Puppet.info(_("CA certificate is unmodified, using existing CA certificate"))
|
@@ -171,8 +173,6 @@ class Puppet::SSL::StateMachine
|
|
171
173
|
now = Time.now
|
172
174
|
last_update = @cert_provider.crl_last_update
|
173
175
|
if needs_refresh?(now, last_update)
|
174
|
-
# set last updated time first, then make a best effort to refresh
|
175
|
-
@cert_provider.crl_last_update = now
|
176
176
|
next_ctx = refresh_crl(next_ctx, last_update)
|
177
177
|
end
|
178
178
|
else
|
@@ -209,7 +209,12 @@ class Puppet::SSL::StateMachine
|
|
209
209
|
Puppet.info(_("Refreshing CRL"))
|
210
210
|
|
211
211
|
# return the next_ctx containing the updated crl
|
212
|
-
download_crl(ssl_ctx, last_update)
|
212
|
+
next_ctx = download_crl(ssl_ctx, last_update)
|
213
|
+
|
214
|
+
# After a successful refresh, update crl_last_update
|
215
|
+
@cert_provider.crl_last_update = Time.now
|
216
|
+
|
217
|
+
next_ctx
|
213
218
|
rescue Puppet::HTTP::ResponseError => e
|
214
219
|
if e.response.code == 304
|
215
220
|
Puppet.info(_("CRL is unmodified, using existing CRL"))
|
@@ -257,7 +262,11 @@ class Puppet::SSL::StateMachine
|
|
257
262
|
next_ctx = @ssl_provider.create_context(
|
258
263
|
cacerts: @ssl_context.cacerts, crls: @ssl_context.crls, private_key: key, client_cert: cert
|
259
264
|
)
|
260
|
-
|
265
|
+
if needs_refresh?(cert)
|
266
|
+
return NeedRenewedCert.new(@machine, next_ctx, key)
|
267
|
+
else
|
268
|
+
return Done.new(@machine, next_ctx)
|
269
|
+
end
|
261
270
|
end
|
262
271
|
else
|
263
272
|
if Puppet[:key_type] == 'ec'
|
@@ -273,6 +282,15 @@ class Puppet::SSL::StateMachine
|
|
273
282
|
|
274
283
|
NeedSubmitCSR.new(@machine, @ssl_context, key)
|
275
284
|
end
|
285
|
+
|
286
|
+
private
|
287
|
+
|
288
|
+
def needs_refresh?(cert)
|
289
|
+
cert_ttl = Puppet[:hostcert_renewal_interval]
|
290
|
+
return false unless cert_ttl
|
291
|
+
|
292
|
+
Time.now.to_i >= (cert.not_after.to_i - cert_ttl)
|
293
|
+
end
|
276
294
|
end
|
277
295
|
|
278
296
|
# Base class for states with a private key.
|
@@ -344,6 +362,39 @@ class Puppet::SSL::StateMachine
|
|
344
362
|
end
|
345
363
|
end
|
346
364
|
|
365
|
+
# Class to renew a client/host certificate automatically.
|
366
|
+
#
|
367
|
+
class NeedRenewedCert < KeySSLState
|
368
|
+
def next_state
|
369
|
+
Puppet.debug(_("Renewing client certificate"))
|
370
|
+
|
371
|
+
route = @machine.session.route_to(:ca, ssl_context: @ssl_context)
|
372
|
+
cert = OpenSSL::X509::Certificate.new(
|
373
|
+
route.post_certificate_renewal(@ssl_context)[1]
|
374
|
+
)
|
375
|
+
|
376
|
+
# verify client cert before saving
|
377
|
+
next_ctx = @ssl_provider.create_context(
|
378
|
+
cacerts: @ssl_context.cacerts, crls: @ssl_context.crls, private_key: @private_key, client_cert: cert
|
379
|
+
)
|
380
|
+
@cert_provider.save_client_cert(Puppet[:certname], cert)
|
381
|
+
|
382
|
+
Puppet.info(_("Renewed client certificate: %{cert_digest}, not before '%{not_before}', not after '%{not_after}'") % { cert_digest: @machine.digest_as_hex(cert.to_pem), not_before: cert.not_before, not_after: cert.not_after })
|
383
|
+
|
384
|
+
Done.new(@machine, next_ctx)
|
385
|
+
rescue Puppet::HTTP::ResponseError => e
|
386
|
+
if e.response.code == 404
|
387
|
+
Puppet.info(_("Certificate autorenewal has not been enabled on the server."))
|
388
|
+
else
|
389
|
+
Puppet.warning(_("Failed to automatically renew certificate: %{code} %{reason}") % { code: e.response.code, reason: e.response.reason })
|
390
|
+
end
|
391
|
+
Done.new(@machine, @ssl_context)
|
392
|
+
rescue => e
|
393
|
+
Puppet.warning(_("Unable to automatically renew certificate: %{message}") % { message: e })
|
394
|
+
Done.new(@machine, @ssl_context)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
347
398
|
# We cannot make progress, so wait if allowed to do so, or exit.
|
348
399
|
#
|
349
400
|
class Wait < SSLState
|
@@ -495,7 +546,7 @@ class Puppet::SSL::StateMachine
|
|
495
546
|
final_state.ssl_context
|
496
547
|
end
|
497
548
|
|
498
|
-
# Run the state machine for
|
549
|
+
# Run the state machine for client certs.
|
499
550
|
#
|
500
551
|
# @return [Puppet::SSL::SSLContext] initialized SSLContext
|
501
552
|
# @raise [Puppet::Error] If we fail to generate an SSLContext
|
@@ -4,7 +4,7 @@ module Puppet
|
|
4
4
|
|
5
5
|
Type.newtype(:filebucket) do
|
6
6
|
@doc = <<-EOT
|
7
|
-
A repository for storing and retrieving file content by
|
7
|
+
A repository for storing and retrieving file content by cryptographic checksum. Can
|
8
8
|
be local to each agent node, or centralized on a primary Puppet server. All
|
9
9
|
puppet servers provide a filebucket service that agent nodes can access
|
10
10
|
via HTTP, but you must declare a filebucket resource before any agents
|
data/lib/puppet/util/diff.rb
CHANGED
@@ -34,7 +34,7 @@ module Puppet::Util::Diff
|
|
34
34
|
data_old = data_old.split(/\n/).map! { |e| e.chomp }
|
35
35
|
data_new = data_new.split(/\n/).map! { |e| e.chomp }
|
36
36
|
|
37
|
-
output =
|
37
|
+
output = ''.dup
|
38
38
|
|
39
39
|
diffs = ::Diff::LCS.diff(data_old, data_new)
|
40
40
|
return output if diffs.empty?
|
@@ -162,7 +162,7 @@ module Puppet::Util::Execution
|
|
162
162
|
# do this after processing 'command' array or string
|
163
163
|
command_str = '[redacted]' if options[:sensitive]
|
164
164
|
|
165
|
-
user_log_s =
|
165
|
+
user_log_s = ''.dup
|
166
166
|
if options[:uid]
|
167
167
|
user_log_s << " uid=#{options[:uid]}"
|
168
168
|
end
|
@@ -202,7 +202,7 @@ module Puppet::Util::Execution
|
|
202
202
|
stderr = options[:combine] ? stdout : Puppet::FileSystem.open(null_file, nil, 'w')
|
203
203
|
|
204
204
|
exec_args = [command, options, stdin, stdout, stderr]
|
205
|
-
output =
|
205
|
+
output = ''.dup
|
206
206
|
|
207
207
|
# We close stdin/stdout/stderr immediately after fork/exec as they're no longer needed by
|
208
208
|
# this process. In most cases they could be closed later, but when `stdout` is the "writer"
|
@@ -223,8 +223,12 @@ module Puppet::Util::Execution
|
|
223
223
|
# Use non-blocking read to check for data. After each attempt,
|
224
224
|
# check whether the child is done. This is done in case the child
|
225
225
|
# forks and inherits stdout, as happens in `foo &`.
|
226
|
-
|
227
|
-
|
226
|
+
# If we encounter EOF, though, then switch to a blocking wait for
|
227
|
+
# the child; after EOF, IO.select will never block and the loop
|
228
|
+
# below will use maximum CPU available.
|
229
|
+
|
230
|
+
wait_flags = Process::WNOHANG
|
231
|
+
until results = Process.waitpid2(child_pid, wait_flags) #rubocop:disable Lint/AssignmentInCondition
|
228
232
|
|
229
233
|
# If not done, wait for data to read with a timeout
|
230
234
|
# This timeout is selected to keep activity low while waiting on
|
@@ -235,6 +239,7 @@ module Puppet::Util::Execution
|
|
235
239
|
output << reader.read_nonblock(4096) if ready
|
236
240
|
rescue Errno::EAGAIN
|
237
241
|
rescue EOFError
|
242
|
+
wait_flags = 0
|
238
243
|
end
|
239
244
|
end
|
240
245
|
|