beaker-puppet 4.4.2 → 4.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/beaker-puppet/helpers/puppet_helpers.rb +39 -27
- data/lib/beaker-puppet/version.rb +1 -1
- data/spec/beaker-puppet/helpers/puppet_helpers_spec.rb +77 -54
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e9d1aa526da4c8769497a59aabdbbe0ac613257a1821007382990de7c33c3894
|
|
4
|
+
data.tar.gz: 8a39103726db46e5321e805fda7925197a2011c96f027dbd4cc9b936abcafc40
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d71514b42d3f9aca125c68a7458a36c047a5a2a1214b5645acd0faba6274b3f30cc4e98de95526ce291318680a498491d977f8f150812a19a9f5f1c875b9d2db
|
|
7
|
+
data.tar.gz: 61fd33d1feff22ddbce4580e3865dc187d381eb125c8698e6b455f5abbc3ab46fe785152a94c49f2d71a5e7ca822fa6874290f3b31138e87fdbabd708be39093
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [4.4.3](https://github.com/puppetlabs/beaker-puppet/tree/4.4.3) (2026-08-17)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/puppetlabs/beaker-puppet/compare/4.4.2...4.4.3)
|
|
6
|
+
|
|
7
|
+
**Merged pull requests:**
|
|
8
|
+
|
|
9
|
+
- \(PE-45697\) Content-validate PuppetDB readiness over the ssl status port [\#280](https://github.com/puppetlabs/beaker-puppet/pull/280) ([steveax](https://github.com/steveax))
|
|
10
|
+
|
|
3
11
|
## [4.4.2](https://github.com/puppetlabs/beaker-puppet/tree/4.4.2) (2026-08-12)
|
|
4
12
|
|
|
5
13
|
[Full Changelog](https://github.com/puppetlabs/beaker-puppet/compare/4.4.1...4.4.2)
|
|
@@ -662,37 +662,49 @@ module Beaker
|
|
|
662
662
|
endpoint = 'status/v1/services/puppetdb-status'
|
|
663
663
|
expected_regex = '\"state\" \{0,\}: \{0,\}\"running\"'
|
|
664
664
|
end
|
|
665
|
-
#
|
|
666
|
-
#
|
|
667
|
-
#
|
|
668
|
-
#
|
|
669
|
-
#
|
|
670
|
-
#
|
|
671
|
-
#
|
|
672
|
-
#
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
#
|
|
677
|
-
#
|
|
678
|
-
|
|
679
|
-
# the cleartext listener disabled -- shouldn't fail this method.
|
|
680
|
-
nonssl_status_command = "curl -m 1 http://localhost:#{nonssl_port}/#{endpoint} | grep '#{expected_regex}'"
|
|
665
|
+
# Confirm readiness -- not just liveness -- over the ssl status port,
|
|
666
|
+
# which is always enabled. /status/v1/* (and the pre-4.0 /pdb/meta
|
|
667
|
+
# fallback) is allow-unauthenticated and PuppetDB's jetty listener is
|
|
668
|
+
# client-auth=want, so `curl -k` gets a real, content-validated body
|
|
669
|
+
# with no client cert, and it works even when the cleartext listener
|
|
670
|
+
# is disabled by default (PE-45384/PE-44906, SECVULN-1792).
|
|
671
|
+
#
|
|
672
|
+
# PE-45697 could no longer perform this running-state validation once
|
|
673
|
+
# it had to stop relying on the (now disabled-by-default) cleartext
|
|
674
|
+
# port: it fell back to a bare curl_with_retries liveness probe, which
|
|
675
|
+
# only confirms the tls port answers, not that puppetdb reports a
|
|
676
|
+
# running state -- reopening the "port up but not ready" race the
|
|
677
|
+
# nonssl content check used to guard. Restore that check over ssl.
|
|
678
|
+
ssl_status_command = "curl -m 1 -k https://localhost:#{ssl_port}/#{endpoint} | grep '#{expected_regex}'"
|
|
681
679
|
begin
|
|
682
|
-
retry_on(host,
|
|
680
|
+
result = retry_on(host, ssl_status_command, { max_retries: 60 })
|
|
683
681
|
rescue RuntimeError => e
|
|
684
682
|
# Only treat this as the known "exhausted all retries" failure
|
|
685
|
-
# retry_on itself raises for THIS command (a plain RuntimeError
|
|
686
|
-
#
|
|
683
|
+
# retry_on itself raises for THIS command (a plain RuntimeError with
|
|
684
|
+
# this exact templated message, see beaker's
|
|
687
685
|
# Beaker::DSL::Helpers::HostHelpers#retry_on) -- not any other
|
|
688
|
-
# RuntimeError, or a same-shaped error for a different command,
|
|
689
|
-
#
|
|
690
|
-
#
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
686
|
+
# RuntimeError, or a same-shaped error for a different command, that
|
|
687
|
+
# might surface from deeper in the retry loop (e.g. an SSH/connection
|
|
688
|
+
# error from the underlying on() call).
|
|
689
|
+
raise unless e.message == "Command `#{ssl_status_command}` failed."
|
|
690
|
+
|
|
691
|
+
# The ssl status endpoint didn't serve unauthenticated content
|
|
692
|
+
# (older or nonstandard config). Degrade to the previous behaviour
|
|
693
|
+
# rather than failing: a bare ssl liveness probe, plus a best-effort
|
|
694
|
+
# nonssl content check whose absence -- by design, on a host with the
|
|
695
|
+
# cleartext listener disabled -- must not fail this method.
|
|
696
|
+
logger.warn("sleep_until_puppetdb_started: ssl status content check did not confirm a running state (#{e.message}); falling back to an ssl liveness probe")
|
|
697
|
+
result = curl_with_retries('start puppetdb (ssl)',
|
|
698
|
+
host, "https://#{host.node_name}:#{ssl_port}", [35, 60])
|
|
699
|
+
|
|
700
|
+
nonssl_status_command = "curl -m 1 http://localhost:#{nonssl_port}/#{endpoint} | grep '#{expected_regex}'"
|
|
701
|
+
begin
|
|
702
|
+
retry_on(host, nonssl_status_command, { max_retries: 5 })
|
|
703
|
+
rescue RuntimeError => nonssl_error
|
|
704
|
+
raise unless nonssl_error.message == "Command `#{nonssl_status_command}` failed."
|
|
705
|
+
|
|
706
|
+
logger.warn("sleep_until_puppetdb_started: nonssl status check on port #{nonssl_port} did not succeed (#{nonssl_error.message}), but ssl liveness was confirmed")
|
|
707
|
+
end
|
|
696
708
|
end
|
|
697
709
|
|
|
698
710
|
result
|
|
@@ -1034,96 +1034,119 @@ describe ClassMixedWithDSLHelpers do
|
|
|
1034
1034
|
allow(subject).to receive(:version_is_less).and_return(true)
|
|
1035
1035
|
end
|
|
1036
1036
|
|
|
1037
|
-
it '
|
|
1037
|
+
it 'content-validates over the ssl status port and, on success, never touches the cleartext port' do
|
|
1038
1038
|
host = hosts[0]
|
|
1039
|
-
expect(subject).to receive(:
|
|
1040
|
-
expect(subject).
|
|
1041
|
-
subject.
|
|
1042
|
-
end
|
|
1043
|
-
|
|
1044
|
-
it 'allows setting the nonssl_port' do
|
|
1045
|
-
host = hosts[0]
|
|
1046
|
-
expect(subject).to receive(:curl_with_retries).with(anything, anything, /8081/, anything).once.ordered
|
|
1047
|
-
expect(subject).to receive(:retry_on).with(anything, /8084/, anything).once.ordered
|
|
1039
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8081/}, { max_retries: 60 }).once
|
|
1040
|
+
expect(subject).not_to receive(:curl_with_retries)
|
|
1041
|
+
expect(subject).not_to receive(:retry_on).with(anything, %r{http://localhost:8080/}, anything)
|
|
1048
1042
|
|
|
1049
|
-
subject.sleep_until_puppetdb_started(host
|
|
1043
|
+
subject.sleep_until_puppetdb_started(host)
|
|
1050
1044
|
end
|
|
1051
1045
|
|
|
1052
1046
|
it 'allows setting the ssl_port' do
|
|
1053
1047
|
host = hosts[0]
|
|
1054
|
-
expect(subject).to receive(:
|
|
1055
|
-
expect(subject).to receive(:retry_on).with(anything, /8080/, anything).once.ordered
|
|
1048
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8085/}, { max_retries: 60 }).once
|
|
1056
1049
|
|
|
1057
1050
|
subject.sleep_until_puppetdb_started(host, nil, 8085)
|
|
1058
1051
|
end
|
|
1059
1052
|
|
|
1060
|
-
context 'when
|
|
1061
|
-
it '
|
|
1053
|
+
context 'when pe_ver is less than 2016.1.0' do
|
|
1054
|
+
it 'content-validates the version endpoint over ssl' do
|
|
1062
1055
|
host = hosts[0]
|
|
1063
|
-
|
|
1064
|
-
expect(subject).to receive(:
|
|
1065
|
-
|
|
1066
|
-
|
|
1056
|
+
host['pe_ver'] = '2015.3.3'
|
|
1057
|
+
expect(subject).to receive(:version_is_less).with(host['pe_ver'], '2016.1.0').and_return(true)
|
|
1058
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8081/pdb/meta/v1/version},
|
|
1059
|
+
{ max_retries: 60 }).once
|
|
1067
1060
|
|
|
1068
|
-
|
|
1061
|
+
subject.sleep_until_puppetdb_started(host)
|
|
1069
1062
|
end
|
|
1070
1063
|
end
|
|
1071
1064
|
|
|
1072
|
-
context 'when
|
|
1073
|
-
it '
|
|
1065
|
+
context 'when pe_ver is greater than 2015.9.9' do
|
|
1066
|
+
it 'content-validates the status endpoint over ssl' do
|
|
1074
1067
|
host = hosts[0]
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
expect(subject).
|
|
1068
|
+
host['pe_ver'] = '2016.1.0'
|
|
1069
|
+
expect(subject).to receive(:version_is_less).with(host['pe_ver'], '2016.1.0').and_return(false)
|
|
1070
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8081/status/v1/services/puppetdb-status},
|
|
1071
|
+
{ max_retries: 60 }).once
|
|
1078
1072
|
|
|
1079
|
-
|
|
1073
|
+
subject.sleep_until_puppetdb_started(host)
|
|
1080
1074
|
end
|
|
1081
1075
|
end
|
|
1082
1076
|
|
|
1083
|
-
context 'when
|
|
1084
|
-
|
|
1077
|
+
context 'when the ssl status endpoint does not serve unauthenticated content' do
|
|
1078
|
+
# Older/nonstandard configs: degrade to the previous behaviour rather
|
|
1079
|
+
# than failing -- a bare ssl liveness probe plus a best-effort nonssl
|
|
1080
|
+
# content check.
|
|
1081
|
+
it 'falls back to an ssl liveness probe and a nonssl content check' do
|
|
1085
1082
|
host = hosts[0]
|
|
1086
|
-
expect(subject).to receive(:
|
|
1087
|
-
|
|
1088
|
-
|
|
1083
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8081/}, { max_retries: 60 }).once.ordered do |_host, command, _opts|
|
|
1084
|
+
raise "Command `#{command}` failed."
|
|
1085
|
+
end
|
|
1086
|
+
expect(subject).to receive(:curl_with_retries).with(anything, anything, %r{https://[^/]*:8081}, [35, 60]).once.ordered
|
|
1087
|
+
expect(subject).to receive(:retry_on).with(anything, %r{http://localhost:8080/}, { max_retries: 5 }).once.ordered
|
|
1089
1088
|
|
|
1090
|
-
expect { subject.sleep_until_puppetdb_started(host) }.
|
|
1089
|
+
expect { subject.sleep_until_puppetdb_started(host) }.not_to raise_error
|
|
1091
1090
|
end
|
|
1092
|
-
end
|
|
1093
1091
|
|
|
1094
|
-
|
|
1095
|
-
it 'propagates the error rather than treating it as a disabled port' do
|
|
1092
|
+
it 'allows setting the nonssl_port in the fallback path' do
|
|
1096
1093
|
host = hosts[0]
|
|
1097
|
-
expect(subject).to receive(:
|
|
1098
|
-
|
|
1099
|
-
|
|
1094
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8081/}, { max_retries: 60 }).once.ordered do |_host, command, _opts|
|
|
1095
|
+
raise "Command `#{command}` failed."
|
|
1096
|
+
end
|
|
1097
|
+
expect(subject).to receive(:curl_with_retries).with(anything, anything, /8081/, [35, 60]).once.ordered
|
|
1098
|
+
expect(subject).to receive(:retry_on).with(anything, %r{http://localhost:8084/}, { max_retries: 5 }).once.ordered
|
|
1100
1099
|
|
|
1101
|
-
|
|
1100
|
+
subject.sleep_until_puppetdb_started(host, 8084)
|
|
1101
|
+
end
|
|
1102
|
+
|
|
1103
|
+
context 'and the cleartext status port never responds (e.g. disabled by default)' do
|
|
1104
|
+
it 'swallows the nonssl failure once ssl liveness is confirmed' do
|
|
1105
|
+
host = hosts[0]
|
|
1106
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8081/}, { max_retries: 60 }).once.ordered do |_host, command, _opts|
|
|
1107
|
+
raise "Command `#{command}` failed."
|
|
1108
|
+
end
|
|
1109
|
+
expect(subject).to receive(:curl_with_retries).with(anything, anything, /8081/, [35, 60]).once.ordered
|
|
1110
|
+
expect(subject).to receive(:retry_on).with(anything, %r{http://localhost:8080/}, { max_retries: 5 }).once.ordered do |_host, command, _opts|
|
|
1111
|
+
raise "Command `#{command}` failed."
|
|
1112
|
+
end
|
|
1113
|
+
|
|
1114
|
+
expect { subject.sleep_until_puppetdb_started(host) }.not_to raise_error
|
|
1115
|
+
end
|
|
1116
|
+
|
|
1117
|
+
it 'propagates an unrelated RuntimeError from the nonssl check' do
|
|
1118
|
+
host = hosts[0]
|
|
1119
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8081/}, { max_retries: 60 }).once.ordered do |_host, command, _opts|
|
|
1120
|
+
raise "Command `#{command}` failed."
|
|
1121
|
+
end
|
|
1122
|
+
expect(subject).to receive(:curl_with_retries).with(anything, anything, /8081/, [35, 60]).once.ordered
|
|
1123
|
+
expect(subject).to receive(:retry_on).with(anything, %r{http://localhost:8080/}, { max_retries: 5 }).once.ordered
|
|
1124
|
+
.and_raise('Host unreachable: no route to host')
|
|
1125
|
+
|
|
1126
|
+
expect { subject.sleep_until_puppetdb_started(host) }.to raise_error(/Host unreachable/)
|
|
1127
|
+
end
|
|
1102
1128
|
end
|
|
1103
1129
|
end
|
|
1104
1130
|
|
|
1105
|
-
context 'when
|
|
1106
|
-
it '
|
|
1131
|
+
context 'when the ssl content check raises a RuntimeError unrelated to exhausted retries' do
|
|
1132
|
+
it 'propagates the error rather than falling back' do
|
|
1107
1133
|
host = hosts[0]
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
expect(subject).
|
|
1134
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8081/}, { max_retries: 60 }).once
|
|
1135
|
+
.and_raise('Host unreachable: no route to host')
|
|
1136
|
+
expect(subject).not_to receive(:curl_with_retries)
|
|
1111
1137
|
|
|
1112
|
-
expect(
|
|
1113
|
-
subject.sleep_until_puppetdb_started(host)
|
|
1138
|
+
expect { subject.sleep_until_puppetdb_started(host) }.to raise_error(/Host unreachable/)
|
|
1114
1139
|
end
|
|
1115
1140
|
end
|
|
1116
1141
|
|
|
1117
|
-
context 'when
|
|
1118
|
-
it '
|
|
1142
|
+
context 'when the ssl content check raises the templated failure but for a different command' do
|
|
1143
|
+
it 'propagates the error rather than falling back' do
|
|
1119
1144
|
host = hosts[0]
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
expect(subject).
|
|
1123
|
-
anything).once.ordered
|
|
1145
|
+
expect(subject).to receive(:retry_on).with(anything, %r{-k https://localhost:8081/}, { max_retries: 60 }).once
|
|
1146
|
+
.and_raise('Command `some other command` failed.')
|
|
1147
|
+
expect(subject).not_to receive(:curl_with_retries)
|
|
1124
1148
|
|
|
1125
|
-
expect(
|
|
1126
|
-
subject.sleep_until_puppetdb_started(host)
|
|
1149
|
+
expect { subject.sleep_until_puppetdb_started(host) }.to raise_error(/some other command/)
|
|
1127
1150
|
end
|
|
1128
1151
|
end
|
|
1129
1152
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: beaker-puppet
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.4.
|
|
4
|
+
version: 4.4.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vox Pupuli
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: fakefs
|