fix server creation run binding

This commit is contained in:
npc0-hue
2026-08-04 17:14:28 +08:00
parent 980f1786dd
commit 5fbe8092b9
13 changed files with 80 additions and 53 deletions
+16 -10
View File
@@ -783,14 +783,22 @@ func TestServerLifecycleWorkflowAPI(t *testing.T) {
created := postOKJSONWithAuth[dto.ServerLifecycleResponse](t, router, "/api/v1/server-instances/workflows/create", dto.ServerLifecycleCreateRequest{
ID: "server-create",
PluginID: "server.scum",
RunEndpointID: "run-local",
Name: "SCUM Create",
IdempotencyKey: "idem-create",
ProfileKey: "local",
}, adminSession)
if created.Action != domain.ServerLifecycleActionCreate || created.Instance.State != domain.ServerInstanceStateInstalling || created.Job.Capability != domain.LifecycleCapabilityInstall {
if created.Action != domain.ServerLifecycleActionCreate || created.Instance.State != domain.ServerInstanceStateDraft || created.Job.ID != "" || created.Instance.RunEndpointID != "" {
t.Fatalf("expected create workflow response, got %+v", created)
}
legacyCreate := requestJSONWithAuth(t, router, http.MethodPost, "/api/v1/server-instances/workflows/create", dto.ServerLifecycleCreateRequest{
ID: "server-create-legacy",
PluginID: "server.scum",
RunEndpointID: "run-local",
Name: "SCUM Legacy Create",
IdempotencyKey: "idem-create-legacy",
ProfileKey: "local",
Bindings: map[string]string{"server-root": "runtime.server-root"},
}, adminSession)
assertErrorResponse(t, legacyCreate, http.StatusBadRequest, errorCodeValidation)
ready := postJSONWithAuth[dto.ServerInstanceResponse](t, router, "/api/v1/server-instances", dto.ServerInstanceCreateRequest{
ID: "server-ready",
@@ -844,7 +852,7 @@ func TestServerDeploymentRevealAPIIsExplicitAndOwnerScoped(t *testing.T) {
endpoint := validRunEndpointRequest()
endpoint.Capabilities = append(endpoint.Capabilities, domain.JobCapabilityDeploymentPlan)
postJSON[dto.RunEndpointResponse](t, router, "/api/v1/run/endpoints", endpoint)
created := postOKJSONWithAuth[dto.ServerLifecycleResponse](t, router, "/api/v1/server-instances/workflows/create", dto.ServerLifecycleCreateRequest{ID: "deployment-reveal", PluginID: "server.scum", RunEndpointID: "run-local", Name: "Reveal", IdempotencyKey: "deployment-reveal", ProfileKey: "local", Deployment: dto.ServerDeploymentRequest{Mode: domain.ServerDeploymentModeCustom, ServerRoot: "/srv/reveal", WorkingDirectory: "/srv/reveal", StartCommand: "./start-server"}}, adminSession)
postOKJSONWithAuth[dto.ServerLifecycleResponse](t, router, "/api/v1/server-instances/workflows/create", dto.ServerLifecycleCreateRequest{ID: "deployment-reveal", PluginID: "server.scum", Name: "Reveal", IdempotencyKey: "deployment-reveal", Deployment: dto.ServerDeploymentRequest{Mode: domain.ServerDeploymentModeCustom, ServerRoot: "/srv/reveal", WorkingDirectory: "/srv/reveal", StartCommand: "./start-server"}}, adminSession)
redactedRecorder := requestWithAuth(t, router, http.MethodGet, "/api/v1/server-instances/deployment-reveal/deployment", "", adminSession)
assertStatus(t, redactedRecorder, http.StatusOK)
@@ -852,8 +860,8 @@ func TestServerDeploymentRevealAPIIsExplicitAndOwnerScoped(t *testing.T) {
t.Fatalf("normal deployment view leaked protected inputs: %s", body)
}
redacted := decodeBody[dto.ServerDeploymentResponse](t, redactedRecorder)
if redacted.LatestDispatch == nil || !redacted.LatestDispatch.DeploymentDefinitionIncluded || redacted.LatestDispatch.JobID != created.Job.ID || redacted.LatestDispatch.DeploymentRevision != 1 {
t.Fatalf("expected safe deployment dispatch evidence, got %+v", redacted.LatestDispatch)
if redacted.LatestDispatch != nil {
t.Fatalf("create-time deployment settings must not dispatch to Run, got %+v", redacted.LatestDispatch)
}
revealed := getJSONWithAuth[dto.ServerDeploymentRevealResponse](t, router, "/api/v1/server-instances/deployment-reveal/deployment/reveal", adminSession)
@@ -1631,10 +1639,8 @@ func TestRuntimeBindingAPIIsAuthorizedValidatedAndRedacted(t *testing.T) {
undeclared := requestJSONWithAuth(t, router, http.MethodPut, "/api/v1/server-instances/"+server.ID+"/runtime-binding", dto.RuntimeBindingUpdateRequest{ProfileKey: "local", Bindings: map[string]string{"host.socket": "runtime.socket"}}, adminSession)
assertErrorResponse(t, undeclared, http.StatusBadRequest, errorCodeValidation)
created := postOKJSONWithAuth[dto.ServerLifecycleResponse](t, router, "/api/v1/server-instances/workflows/create", dto.ServerLifecycleCreateRequest{ID: "runtime-create-complete", PluginID: registration.Manifest.ID, RunEndpointID: "run-local", Name: "Runtime Create Complete", IdempotencyKey: "runtime-create-complete", ProfileKey: "local", Bindings: map[string]string{"server-root": "runtime.server-root", "rcon.password": "secret://runtime-create-complete/rcon"}}, adminSession)
if created.Job.TargetKey != "actions/install.json" {
t.Fatalf("create workflow did not dispatch selected profile: %+v", created.Job)
}
legacyCreate := requestJSONWithAuth(t, router, http.MethodPost, "/api/v1/server-instances/workflows/create", dto.ServerLifecycleCreateRequest{ID: "runtime-create-complete", PluginID: registration.Manifest.ID, RunEndpointID: "run-local", Name: "Runtime Create Complete", IdempotencyKey: "runtime-create-complete", ProfileKey: "local", Bindings: map[string]string{"server-root": "runtime.server-root", "rcon.password": "secret://runtime-create-complete/rcon"}}, adminSession)
assertErrorResponse(t, legacyCreate, http.StatusBadRequest, errorCodeValidation)
incompleteCreate := requestJSONWithAuth(t, router, http.MethodPost, "/api/v1/server-instances/workflows/create", dto.ServerLifecycleCreateRequest{ID: "runtime-create-incomplete", PluginID: registration.Manifest.ID, RunEndpointID: "run-local", Name: "Runtime Create Incomplete", IdempotencyKey: "runtime-create-incomplete", ProfileKey: "local", Bindings: map[string]string{"server-root": "runtime.server-root"}}, adminSession)
assertErrorResponse(t, incompleteCreate, http.StatusBadRequest, errorCodeValidation)
missingServer := requestWithAuth(t, router, http.MethodGet, "/api/v1/server-instances/runtime-create-incomplete", "", adminSession)