From 3f85dcba10560d6fbbca35b2d17f47b0242d1aa3 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 16 Mar 2015 10:41:08 -0700 Subject: [PATCH] http: /v1/sys/mount DELETE --- http/handler.go | 2 +- http/http_test.go | 4 +++ http/sys_mount.go | 79 ++++++++++++++++++++++++++++++------------ http/sys_mount_test.go | 37 ++++++++++++++++++++ 4 files changed, 99 insertions(+), 23 deletions(-) diff --git a/http/handler.go b/http/handler.go index 2baf42a886..6eff998e38 100644 --- a/http/handler.go +++ b/http/handler.go @@ -16,7 +16,7 @@ func Handler(core *vault.Core) http.Handler { mux.Handle("/v1/sys/seal", handleSysSeal(core)) mux.Handle("/v1/sys/unseal", handleSysUnseal(core)) mux.Handle("/v1/sys/mounts", handleSysListMounts(core)) - mux.Handle("/v1/sys/mount/", handleSysMount(core)) + mux.Handle("/v1/sys/mount/", handleSysMountUnmount(core)) mux.Handle("/v1/", handleLogical(core)) return mux } diff --git a/http/http_test.go b/http/http_test.go index 06a4dc37a3..c5cbd30e6d 100644 --- a/http/http_test.go +++ b/http/http_test.go @@ -8,6 +8,10 @@ import ( "testing" ) +func testHttpDelete(t *testing.T, addr string) *http.Response { + return testHttpData(t, "DELETE", addr, nil) +} + func testHttpPost(t *testing.T, addr string, body interface{}) *http.Response { return testHttpData(t, "POST", addr, body) } diff --git a/http/sys_mount.go b/http/sys_mount.go index ec4a2657ed..c4b779cdc8 100644 --- a/http/sys_mount.go +++ b/http/sys_mount.go @@ -28,9 +28,12 @@ func handleSysListMounts(core *vault.Core) http.Handler { }) } -func handleSysMount(core *vault.Core) http.Handler { +func handleSysMountUnmount(core *vault.Core) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { + switch r.Method { + case "POST": + case "DELETE": + default: respondError(w, http.StatusMethodNotAllowed, nil) return } @@ -47,30 +50,62 @@ func handleSysMount(core *vault.Core) http.Handler { return } - // Parse the request if we can - var req MountRequest - if err := parseRequest(r, &req); err != nil { - respondError(w, http.StatusBadRequest, err) - return + switch r.Method { + case "POST": + handleSysMount(core, w, r, path) + case "DELETE": + handleSysUnmount(core, w, r, path) + default: + panic("should never happen") } - - _, err := core.HandleRequest(&logical.Request{ - Operation: logical.WriteOperation, - Path: "sys/mount/" + path, - Data: map[string]interface{}{ - "type": req.Type, - "description": req.Description, - }, - }) - if err != nil { - respondError(w, http.StatusInternalServerError, err) - return - } - - respondOk(w, nil) }) } +func handleSysMount( + core *vault.Core, + w http.ResponseWriter, + r *http.Request, + path string) { + // Parse the request if we can + var req MountRequest + if err := parseRequest(r, &req); err != nil { + respondError(w, http.StatusBadRequest, err) + return + } + + _, err := core.HandleRequest(&logical.Request{ + Operation: logical.WriteOperation, + Path: "sys/mount/" + path, + Data: map[string]interface{}{ + "type": req.Type, + "description": req.Description, + }, + }) + if err != nil { + respondError(w, http.StatusInternalServerError, err) + return + } + + respondOk(w, nil) +} + +func handleSysUnmount( + core *vault.Core, + w http.ResponseWriter, + r *http.Request, + path string) { + _, err := core.HandleRequest(&logical.Request{ + Operation: logical.DeleteOperation, + Path: "sys/mount/" + path, + }) + if err != nil { + respondError(w, http.StatusInternalServerError, err) + return + } + + respondOk(w, nil) +} + type MountRequest struct { Type string `json:"type"` Description string `json:"description"` diff --git a/http/sys_mount_test.go b/http/sys_mount_test.go index bf03611d00..d2d68d54db 100644 --- a/http/sys_mount_test.go +++ b/http/sys_mount_test.go @@ -73,3 +73,40 @@ func TestSysMount(t *testing.T) { t.Fatalf("bad: %#v", actual) } } + +func TestSysUnmount(t *testing.T) { + core, _ := vault.TestCoreUnsealed(t) + ln, addr := TestServer(t, core) + defer ln.Close() + + resp := testHttpPost(t, addr+"/v1/sys/mount/foo", map[string]interface{}{ + "type": "generic", + "description": "foo", + }) + testResponseStatus(t, resp, 204) + + resp = testHttpDelete(t, addr+"/v1/sys/mount/foo") + testResponseStatus(t, resp, 204) + + resp, err := http.Get(addr + "/v1/sys/mounts") + if err != nil { + t.Fatalf("err: %s", err) + } + + var actual map[string]interface{} + expected := map[string]interface{}{ + "secret/": map[string]interface{}{ + "description": "generic secret storage", + "type": "generic", + }, + "sys/": map[string]interface{}{ + "description": "system endpoints used for control, policy and debugging", + "type": "system", + }, + } + testResponseStatus(t, resp, 200) + testResponseBody(t, resp, &actual) + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: %#v", actual) + } +}