Wire action-group variables, sudo, and command path resolution through the API and UI.
Completes run-if/set_variable and requires_sudo editing, sudoers path resolve helpers, and execute permission checks so node action groups can gate upgrades and elevate safely.
This commit is contained in:
@@ -357,6 +357,63 @@ func TestNodesTestSSHReportsFailureForUnreachableHost(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNodesResolveCommandsRejectsInvalidNames(t *testing.T) {
|
||||
configDir := t.TempDir()
|
||||
cookie := seedCompletedSetup(t, configDir)
|
||||
router := NewRouter(configDir)
|
||||
|
||||
createBody := []byte(`{
|
||||
"id":"dddddddd-bbbb-4ccc-8ddd-eeeeeeeeeeee",
|
||||
"kind":"container",
|
||||
"name":"resolve-test",
|
||||
"host_ip":"127.0.0.1",
|
||||
"group_name":"Administrators",
|
||||
"generate":{"algorithm":"ed25519"}
|
||||
}`)
|
||||
createRequest := withSession(
|
||||
httptest.NewRequest(http.MethodPost, "/api/v1/nodes", bytes.NewReader(createBody)),
|
||||
cookie,
|
||||
)
|
||||
createRecorder := httptest.NewRecorder()
|
||||
router.ServeHTTP(createRecorder, createRequest)
|
||||
if createRecorder.Code != http.StatusCreated {
|
||||
t.Fatalf("create status = %d body=%s", createRecorder.Code, createRecorder.Body.String())
|
||||
}
|
||||
|
||||
badBody := []byte(`{"names":["/usr/bin/apt"]}`)
|
||||
badRequest := withSession(
|
||||
httptest.NewRequest(
|
||||
http.MethodPost,
|
||||
"/api/v1/nodes/dddddddd-bbbb-4ccc-8ddd-eeeeeeeeeeee/resolve-commands",
|
||||
bytes.NewReader(badBody),
|
||||
),
|
||||
cookie,
|
||||
)
|
||||
badRecorder := httptest.NewRecorder()
|
||||
router.ServeHTTP(badRecorder, badRequest)
|
||||
if badRecorder.Code != http.StatusBadRequest {
|
||||
t.Fatalf("status = %d body=%s", badRecorder.Code, badRecorder.Body.String())
|
||||
}
|
||||
if !strings.Contains(badRecorder.Body.String(), "basename") {
|
||||
t.Fatalf("expected basename error, got %s", badRecorder.Body.String())
|
||||
}
|
||||
|
||||
emptyBody := []byte(`{"names":[]}`)
|
||||
emptyRequest := withSession(
|
||||
httptest.NewRequest(
|
||||
http.MethodPost,
|
||||
"/api/v1/nodes/dddddddd-bbbb-4ccc-8ddd-eeeeeeeeeeee/resolve-commands",
|
||||
bytes.NewReader(emptyBody),
|
||||
),
|
||||
cookie,
|
||||
)
|
||||
emptyRecorder := httptest.NewRecorder()
|
||||
router.ServeHTTP(emptyRecorder, emptyRequest)
|
||||
if emptyRecorder.Code != http.StatusBadRequest {
|
||||
t.Fatalf("empty status = %d body=%s", emptyRecorder.Code, emptyRecorder.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestNodesDeleteRequiresPermissionAndInlineReauth(t *testing.T) {
|
||||
configDir := t.TempDir()
|
||||
cookie := seedCompletedSetup(t, configDir)
|
||||
|
||||
Reference in New Issue
Block a user