mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-24 04:33:17 +00:00
Keep PBS setup safety checks aligned with secure installation (#2367)
## What changed and why PBS setup safety checks now match the credential-safe guide without treating explanatory TLS warnings as executable commands. The checks retain read-only API identities, private token-file permissions, inspected HTTPS downloads and failure-stop requirements; they cover bash, sh and shell examples. The synthetic TLS server explicitly requires TLS 1.2 and has a regression assertion for that floor. This reconciles reviewed fixture repairs with the previously published safe guidance. No product runtime, dependency, version or release metadata changes are included. ## Included source Complete `pulse` range `a7a4a9aa417a1cd73e016d7448b8d2428bbfba00..cafe38823f6db9864bb671c0ab3ea3a87cf887ba`: - Reviewed Delivery candidate `0955ddf9e0b48b9571771c04a27aa354db796055`, containing TLS fixture `ff3d05be49a3b067637107f83298066745dc5a1e` and bootstrap guards `2a8134035846a3bb3e0097a921a0f068edee1394` / `0955ddf9e0b48b9571771c04a27aa354db796055`. - Additive integration `ac34b6f4618161485df40fb7bb12d4c2bf949cf7` retains the stronger canonical safety assertions; upstream reconciliation `cafe38823f6db9864bb671c0ab3ea3a87cf887ba` retains the current published main frontier. Every reviewed commit identity is preserved. ## Validation and limits Recorded candidate evidence includes ten executable PBS controls (`source-ozwv0j9x`); final candidate `source-rf2cmnzr` passed the selected Go packages and PBS cases before failing a renderer import invocation. Corrected renderer-only `source-h5pd_tbz` passed 44 cases on the same candidate; the failed wrapper is not an overall pass. Fresh publication provenance, whitespace and all three non-merge per-commit completion/browser guards pass; browser checks skip correctly because no frontend source changed. All 62 shipped-document mirrors and 211 public Markdown checks pass. A fresh broad repoctl attempt (`source-axg1lvbp`) failed two cross-repository evidence tests because the single-module disposable guest has no Pro/Enterprise sibling checkout; its chained Python phase did not run. It is retained as failed evidence, not a complete suite pass. The narrowed reconciliation proof below tests the actual changed assertions and TLS recipes without bypassing those cross-repository checks. Exact-head required checks and independent review still govern landing. Synthetic credentials and guest-local TLS are not actual PBS installation, reporter acceptance, release qualification or availability in a release. Fresh exact integrated-head reconciliation `source-nr9x7ary` passes both changed Go assertion tests and all ten executable PBS recipe/TLS controls (exit 0) at `cafe38823f6db9864bb671c0ab3ea3a87cf887ba` in the standard offline source-proof VM. [How Pulse handles triage](https://github.com/rcourtman/Pulse/blob/main/docs/AI_TRANSPARENCY.md)
This commit is contained in:
@@ -1,11 +1,32 @@
|
||||
package repoctl
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func pbsShellExamples(document string) string {
|
||||
var examples []string
|
||||
blocks := strings.Split(document, "```")
|
||||
for i := 1; i < len(blocks); i += 2 {
|
||||
language, body, _ := strings.Cut(blocks[i], "\n")
|
||||
switch strings.TrimSpace(language) {
|
||||
case "bash", "sh", "shell":
|
||||
examples = append(examples, body)
|
||||
}
|
||||
}
|
||||
return strings.Join(examples, "\n")
|
||||
}
|
||||
|
||||
func TestPBSShellExamplesKeepWarningsSeparateFromCommands(t *testing.T) {
|
||||
document := "Do not use `--insecure` or `-k`.\n```bash\ncurl --fail https://pbs.example.com\n```\n" +
|
||||
"```sh\ncurl --insecure https://pbs.example.com\n```\n"
|
||||
examples := pbsShellExamples(document)
|
||||
if examples != "curl --fail https://pbs.example.com\n\ncurl --insecure https://pbs.example.com\n" {
|
||||
t.Fatalf("unexpected shell examples: %q", examples)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetupBootstrapDocsStayOnCanonicalArtifactContract(t *testing.T) {
|
||||
apiRel := "docs/API.md"
|
||||
apiDoc := readRepoFile(t, apiRel)
|
||||
@@ -24,21 +45,33 @@ func TestSetupBootstrapDocsStayOnCanonicalArtifactContract(t *testing.T) {
|
||||
"### Method 1: API-Only Connection (Recommended)",
|
||||
"proxmox-backup-manager acl update / Audit --auth-id pulse-monitor@pbs",
|
||||
"proxmox-backup-manager acl update / Audit --auth-id 'pulse-monitor@pbs!pulse-token'",
|
||||
`chmod 600 "$HOME/.config/pulse/pbs-agent-token"`,
|
||||
`--output "$HOME/.config/pulse/pbs-agent-install.sh"`,
|
||||
"https://pulse.example.com/install.sh",
|
||||
`--token-file "$HOME/.config/pulse/pbs-agent-token"`,
|
||||
"Stop if the download fails",
|
||||
"Create a separate Pulse token in **API Access**",
|
||||
"enter an administrator root shell",
|
||||
`chmod 700 "$HOME/.config/pulse"`,
|
||||
`chmod 600 "$HOME/.config/pulse/pbs-agent-token"`,
|
||||
`vi "$HOME/.config/pulse/pbs-agent-token"`,
|
||||
`curl --fail --silent --show-error`,
|
||||
`--output "$HOME/.config/pulse/pbs-agent-install.sh"`,
|
||||
`https://pulse.example.com/install.sh`,
|
||||
"successful download and inspection",
|
||||
`bash "$HOME/.config/pulse/pbs-agent-install.sh"`,
|
||||
`--token-file "$HOME/.config/pulse/pbs-agent-token"`,
|
||||
`--enable-proxmox --proxmox-type pbs --enable-docker=false`,
|
||||
"Do not bypass certificate checks",
|
||||
})
|
||||
// Inspect executable fences, not prose that warns against unsafe flags.
|
||||
commands := strings.Join(regexp.MustCompile("(?s)```bash\n(.*?)```").FindAllString(pbsDoc, -1), "\n")
|
||||
assertContainsNone(t, pbsRel, commands, []string{
|
||||
"PULSE_SETUP_TOKEN=",
|
||||
"sudo env PULSE_SETUP_TOKEN=",
|
||||
"curl -k",
|
||||
"--insecure",
|
||||
shellExamples := pbsShellExamples(pbsDoc)
|
||||
if shellExamples == "" {
|
||||
t.Fatal("PBS guide must retain executable shell examples")
|
||||
}
|
||||
assertContainsNone(t, pbsRel, shellExamples, []string{
|
||||
`curl -sSL "http://<pulse-ip>:7655/api/setup-script?type=pbs&host=https://<pbs-ip>:8007&pulse_url=http://<pulse-ip>:7655" | bash`,
|
||||
`PULSE_SETUP_TOKEN=`,
|
||||
`sudo env PULSE_SETUP_TOKEN=`,
|
||||
`--insecure`,
|
||||
` -k`,
|
||||
`curl -k`,
|
||||
`--token "`,
|
||||
"| bash",
|
||||
`| bash`,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -62,6 +62,13 @@ def certificate(directory, name):
|
||||
return certificate, key
|
||||
|
||||
|
||||
def server_context(cert, key):
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||
context.minimum_version = ssl.TLSVersion.TLSv1_2
|
||||
context.load_cert_chain(str(cert), str(key))
|
||||
return context
|
||||
|
||||
|
||||
@contextmanager
|
||||
def server(cert, key, status=200, installer=None, installer_path="/install.sh"):
|
||||
requests = []
|
||||
@@ -78,9 +85,7 @@ def server(cert, key, status=200, installer=None, installer_path="/install.sh"):
|
||||
pass
|
||||
|
||||
http = HTTPServer(("127.0.0.1", 0), Handler)
|
||||
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||
context.minimum_version = ssl.TLSVersion.TLSv1_2
|
||||
context.load_cert_chain(str(cert), str(key))
|
||||
context = server_context(cert, key)
|
||||
http.socket = context.wrap_socket(http.socket, server_side=True)
|
||||
thread = threading.Thread(target=http.serve_forever, daemon=True)
|
||||
thread.start()
|
||||
@@ -103,6 +108,10 @@ class PBSDocsTest(unittest.TestCase):
|
||||
def tearDownClass(cls):
|
||||
cls.temporary.cleanup()
|
||||
|
||||
def test_tls_fixture_explicitly_rejects_legacy_protocols(self):
|
||||
self.assertEqual(server_context(self.cert, self.key).minimum_version,
|
||||
ssl.TLSVersion.TLSv1_2)
|
||||
|
||||
def test_shipped_copy_and_safe_scope(self):
|
||||
self.assertEqual(DOC.read_bytes(), (ROOT / "frontend-modern/public/docs/PBS.md").read_bytes())
|
||||
text = DOC.read_text()
|
||||
|
||||
Reference in New Issue
Block a user