http: help
This commit is contained in:
parent
eec6c27fae
commit
020af2fac2
11
api/SPEC.md
11
api/SPEC.md
|
@ -56,6 +56,17 @@ that can be enabled (see
|
|||
Authentication is done with the login endpoint. The login endpoint
|
||||
returns an access token that is set as the `token` cookie.
|
||||
|
||||
## Help
|
||||
|
||||
To retrieve the help for any API within Vault, including mounted
|
||||
backends, credential providers, etc. then append `?help=1` to any
|
||||
URL. If you have valid permission to access the path, then the help text
|
||||
will be returned with the following structure:
|
||||
|
||||
{
|
||||
"help": "help text"
|
||||
}
|
||||
|
||||
## Error Response
|
||||
|
||||
A common JSON structure is always returned to return errors:
|
||||
|
|
6
api/help.go
Normal file
6
api/help.go
Normal file
|
@ -0,0 +1,6 @@
|
|||
package api
|
||||
|
||||
// Help reads the help information for the given path.
|
||||
func (c *Client) Help(path string) (string, error) {
|
||||
return "", nil
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/vault"
|
||||
|
@ -15,6 +16,7 @@ const AuthCookieName = "token"
|
|||
// Handler returns an http.Handler for the API. This can be used on
|
||||
// its own to mount the Vault API within another web server.
|
||||
func Handler(core *vault.Core) http.Handler {
|
||||
// Create the muxer to handle the actual endpoints
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/v1/sys/init", handleSysInit(core))
|
||||
mux.Handle("/v1/sys/seal-status", handleSysSealStatus(core))
|
||||
|
@ -29,7 +31,26 @@ func Handler(core *vault.Core) http.Handler {
|
|||
mux.Handle("/v1/sys/audit", handleSysListAudit(core))
|
||||
mux.Handle("/v1/sys/audit/", handleSysAudit(core))
|
||||
mux.Handle("/v1/", handleLogical(core))
|
||||
return mux
|
||||
|
||||
// Wrap the handler in another handler to trigger all help paths.
|
||||
handler := handleHelpHandler(mux, core)
|
||||
|
||||
return handler
|
||||
}
|
||||
|
||||
// stripPrefix is a helper to strip a prefix from the path. It will
|
||||
// return false from the second return value if it the prefix doesn't exist.
|
||||
func stripPrefix(prefix, path string) (string, bool) {
|
||||
if !strings.HasPrefix(path, prefix) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
path = path[len(prefix):]
|
||||
if path == "" {
|
||||
return "", false
|
||||
}
|
||||
|
||||
return path, true
|
||||
}
|
||||
|
||||
func parseRequest(r *http.Request, out interface{}) error {
|
||||
|
|
40
http/help.go
Normal file
40
http/help.go
Normal file
|
@ -0,0 +1,40 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/vault"
|
||||
)
|
||||
|
||||
func handleHelpHandler(h http.Handler, core *vault.Core) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
// If the help parameter is not blank, then show the help
|
||||
if v := req.URL.Query().Get("help"); v != "" {
|
||||
handleHelp(core, w, req)
|
||||
return
|
||||
}
|
||||
|
||||
h.ServeHTTP(w, req)
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
func handleHelp(core *vault.Core, w http.ResponseWriter, req *http.Request) {
|
||||
path, ok := stripPrefix("/v1/", req.URL.Path)
|
||||
if !ok {
|
||||
respondError(w, http.StatusNotFound, nil)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := core.HandleRequest(requestAuth(req, &logical.Request{
|
||||
Operation: logical.HelpOperation,
|
||||
Path: path,
|
||||
}))
|
||||
if err != nil {
|
||||
respondError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
respondOk(w, resp.Data)
|
||||
}
|
27
http/help_test.go
Normal file
27
http/help_test.go
Normal file
|
@ -0,0 +1,27 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/vault"
|
||||
)
|
||||
|
||||
func TestHelp(t *testing.T) {
|
||||
core, _, token := vault.TestCoreUnsealed(t)
|
||||
ln, addr := TestServer(t, core)
|
||||
defer ln.Close()
|
||||
TestServerAuth(t, addr, token)
|
||||
|
||||
resp, err := http.Get(addr + "/v1/sys/mounts?help=1")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
var actual map[string]interface{}
|
||||
testResponseStatus(t, resp, 200)
|
||||
testResponseBody(t, resp, &actual)
|
||||
if _, ok := actual["help"]; !ok {
|
||||
t.Fatalf("bad: %#v", actual)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue