feat(auth): integrate authentication with installation lifecycle
This commit is contained in:
@@ -48,7 +48,7 @@ func TestActiveSessionsUsesInstallationScopedInventory(t *testing.T) {
|
||||
if active, err := activeSessions(context.Background(), runner); err != nil || active {
|
||||
t.Fatalf("activeSessions(%s) = %t, %v; want false, nil", scope, active, err)
|
||||
}
|
||||
if len(runner.calls) != 1 || !strings.Contains(runner.calls[0], "/sessions?scope="+scope) {
|
||||
if len(runner.calls) != 1 || !strings.Contains(runner.calls[0], "operator-command.js session-inventory "+scope) {
|
||||
t.Fatalf("activeSessions(%s) call = %v; want installation-scoped inventory", scope, runner.calls)
|
||||
}
|
||||
}
|
||||
@@ -250,7 +250,7 @@ func TestMaintenanceTransportLossAfterBackendRestartRequiresRecovery(t *testing.
|
||||
if fake.backendRestarts != 1 {
|
||||
t.Fatalf("backend restarts = %d, want 1", fake.backendRestarts)
|
||||
}
|
||||
assertCalled(t, fake.calls, "/internal/maintenance/status")
|
||||
assertCalled(t, fake.calls, "operator-command.js maintenance-status")
|
||||
for index, active := range fake.maintenanceAtRecreate {
|
||||
if !active {
|
||||
t.Fatalf("recreate %d started without durable maintenance", index+1)
|
||||
@@ -344,8 +344,8 @@ func TestCompensationReactivatesMaintenanceAndRescansBeforeRollback(t *testing.T
|
||||
t.Fatalf("calls %v contain no rollback", fake.calls)
|
||||
}
|
||||
recreate := callIndex(fake.calls, "force-recreate core")
|
||||
activate := lastCallIndexBefore(fake.calls, "/internal/maintenance/activate", rollback)
|
||||
scan := lastCallIndexBefore(fake.calls, "/sessions?scope=all", rollback)
|
||||
activate := lastCallIndexBefore(fake.calls, "operator-command.js maintenance-activate", rollback)
|
||||
scan := lastCallIndexBefore(fake.calls, "operator-command.js session-inventory all", rollback)
|
||||
if activate <= recreate || scan <= recreate {
|
||||
t.Fatalf("calls %v do not reactivate/confirm and rescan after candidate recreate before rollback", fake.calls)
|
||||
}
|
||||
@@ -599,7 +599,7 @@ func TestRecoverMaintenanceClearsOnlyAfterTerminalStateAndVerifiedSmoke(t *testi
|
||||
if selected := readSelectorReference(t, currentImageOverridePath(statePath)); selected != previous.Reference {
|
||||
t.Fatalf("maintenance cleanup changed durable selector to %q", selected)
|
||||
}
|
||||
assertCalled(t, fake.calls, "/pi-management/test")
|
||||
assertCalled(t, fake.calls, "operator-command.js pi-test")
|
||||
}
|
||||
|
||||
func TestRecoverMaintenanceRefusesPendingTransaction(t *testing.T) {
|
||||
@@ -774,12 +774,12 @@ func TestUpdateRequiresConfirmationAndDrainsActiveSessions(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("Update() with drain error = %v", err)
|
||||
}
|
||||
assertCalled(t, fake.calls, "http://127.0.0.1:8787/sessions?scope=all")
|
||||
assertCalled(t, fake.calls, "/internal/maintenance/activate")
|
||||
assertCalled(t, fake.calls, "/internal/maintenance/deactivate")
|
||||
assertCalled(t, fake.calls, "operator-command.js session-inventory all")
|
||||
assertCalled(t, fake.calls, "operator-command.js maintenance-activate")
|
||||
assertCalled(t, fake.calls, "operator-command.js maintenance-deactivate")
|
||||
}
|
||||
|
||||
func TestMaintenanceControlUsesExactLoopbackOperatorIdentity(t *testing.T) {
|
||||
func TestMaintenanceControlUsesOnlyTheScopedNonNetworkCommand(t *testing.T) {
|
||||
fake := newFakeRunner()
|
||||
if err := setMaintenance(context.Background(), fake, true); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -788,26 +788,15 @@ func TestMaintenanceControlUsesExactLoopbackOperatorIdentity(t *testing.T) {
|
||||
if _, err := MaintenanceStatus(context.Background(), fake); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, path := range []string{"/internal/maintenance/activate", "/internal/maintenance/status"} {
|
||||
found := false
|
||||
for _, call := range fake.calls {
|
||||
if !strings.Contains(call, path) {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
for _, header := range []string{
|
||||
"x-thoth-principal-issuer: tht",
|
||||
"x-thoth-principal-subject: tht-maintenance",
|
||||
"x-thoth-principal-display-name: Tht maintenance",
|
||||
"x-thoth-is-admin: 1",
|
||||
} {
|
||||
if !strings.Contains(call, header) {
|
||||
t.Fatalf("maintenance call %q lacks %q", call, header)
|
||||
}
|
||||
}
|
||||
joined := strings.Join(fake.calls, "\n")
|
||||
for _, action := range []string{"operator-command.js maintenance-activate", "operator-command.js maintenance-status"} {
|
||||
if !strings.Contains(joined, action) {
|
||||
t.Fatalf("maintenance action %q was not made: %s", action, joined)
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("maintenance call %q was not made", path)
|
||||
}
|
||||
for _, forbidden := range []string{"curl", "x-thoth-principal", "x-thoth-is-admin"} {
|
||||
if strings.Contains(joined, forbidden) {
|
||||
t.Fatalf("maintenance commands retained HTTP identity material %q: %s", forbidden, joined)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1074,7 +1063,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
if f.fail == "version" && (f.built || f.recreated) && strings.Contains(call, "pi --version") && strings.Contains(call, "exec") {
|
||||
return compose.Result{ExitCode: 1}, errors.New("version token=secret")
|
||||
}
|
||||
if f.fail == "smoke" && (f.built || f.recreated) && strings.Contains(call, "127.0.0.1:8787/pi-management/test") {
|
||||
if f.fail == "smoke" && (f.built || f.recreated) && strings.Contains(call, "operator-command.js pi-test") {
|
||||
return compose.Result{ExitCode: 1}, errors.New("smoke token=secret")
|
||||
}
|
||||
switch {
|
||||
@@ -1106,7 +1095,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{Stdout: f.mountsJSON}, nil
|
||||
}
|
||||
return compose.Result{Stdout: `[{"Type":"volume","Name":"settings","Source":"settings","Destination":"/data/settings","RW":true},{"Type":"volume","Name":"pi-state","Source":"pi-state","Destination":"/home/thoth/.pi","RW":true},{"Type":"volume","Name":"sessions","Source":"sessions","Destination":"/data/sessions","RW":true},{"Type":"volume","Name":"workspace-registry","Source":"workspace-registry","Destination":"/data/workspace-registry","RW":true}]`}, nil
|
||||
case strings.Contains(call, "/internal/maintenance/activate"):
|
||||
case strings.Contains(call, "operator-command.js maintenance-activate"):
|
||||
f.maintenance = true
|
||||
if f.fail == "maintenance-activate-durability" || f.fail == "maintenance-activate-durability-without-status-flag" {
|
||||
return compose.Result{ExitCode: 22}, errors.New("maintenance activation durability was not acknowledged")
|
||||
@@ -1119,7 +1108,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{ExitCode: 52}, errors.New("lost activation response")
|
||||
}
|
||||
return compose.Result{Stdout: `{"active":true,"admissions":0}`}, nil
|
||||
case strings.Contains(call, "/internal/maintenance/deactivate"):
|
||||
case strings.Contains(call, "operator-command.js maintenance-deactivate"):
|
||||
if f.fail == "maintenance-clear" {
|
||||
return compose.Result{ExitCode: 53}, errors.New("maintenance clear failure")
|
||||
}
|
||||
@@ -1138,7 +1127,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{ExitCode: 52}, errors.New("lost deactivation response")
|
||||
}
|
||||
return compose.Result{Stdout: `{"active":false,"admissions":0}`}, nil
|
||||
case strings.Contains(call, "/internal/maintenance/status"):
|
||||
case strings.Contains(call, "operator-command.js maintenance-status"):
|
||||
if f.fail == "maintenance-proof" && f.recreated {
|
||||
return compose.Result{Stdout: fmt.Sprintf(`{"active":%t,"admissions":0,"recoveryRequired":true}`, f.maintenance)}, nil
|
||||
}
|
||||
@@ -1149,7 +1138,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{Stdout: fmt.Sprintf(`{"active":%t,"admissions":0,"recoveryRequired":true}`, f.maintenance)}, nil
|
||||
}
|
||||
return compose.Result{Stdout: fmt.Sprintf(`{"active":%t,"admissions":0}`, f.maintenance)}, nil
|
||||
case strings.Contains(call, "/sessions?scope=all"):
|
||||
case strings.Contains(call, "operator-command.js session-inventory all"):
|
||||
if f.sessionsWire != "" {
|
||||
return compose.Result{Stdout: f.sessionsWire}, nil
|
||||
}
|
||||
@@ -1230,12 +1219,12 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{Stdout: f.version + "\n"}, nil
|
||||
case strings.Contains(call, "PI_VERSION"):
|
||||
return compose.Result{Stdout: f.expectedVersion + "\n"}, nil
|
||||
case strings.Contains(call, "/pi-management/options"):
|
||||
case strings.Contains(call, "operator-command.js pi-options"):
|
||||
if f.piManagementOptionsWire != "" {
|
||||
return compose.Result{Stdout: f.piManagementOptionsWire}, nil
|
||||
}
|
||||
return compose.Result{Stdout: `{"providers":["provider"],"models":[{"id":"model","provider":"provider"}],"reasoning":["low","medium","high"]}`}, nil
|
||||
case strings.Contains(call, "/pi-management/test"):
|
||||
case strings.Contains(call, "operator-command.js pi-test"):
|
||||
if f.currentImage == "sha256:old" {
|
||||
f.restoredProofComplete = true
|
||||
}
|
||||
@@ -1248,7 +1237,7 @@ func (f *fakeRunner) Run(_ context.Context, args []string, _ io.Reader) (compose
|
||||
return compose.Result{Stdout: f.modelsWire}, nil
|
||||
}
|
||||
return compose.Result{Stdout: `{"models":[{"id":"model","provider":"provider"}]}`}, nil
|
||||
case strings.Contains(call, "/settings"):
|
||||
case strings.Contains(call, "operator-command.js effective-settings"):
|
||||
if f.currentImage == "sha256:old" {
|
||||
f.restoredProofComplete = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user