logical/framework: support root help

This commit is contained in:
Mitchell Hashimoto
2015-04-03 20:36:47 -07:00
parent 1c6ed3494b
commit e56b16b6d7
4 changed files with 100 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
package aws
import (
"strings"
"time"
"github.com/hashicorp/vault/logical"
@@ -14,6 +15,8 @@ func Factory(map[string]string) (logical.Backend, error) {
func Backend() *framework.Backend {
var b backend
b.Backend = &framework.Backend{
Help: strings.TrimSpace(backendHelp),
PathsSpecial: &logical.Paths{
Root: []string{
"root",
@@ -41,3 +44,9 @@ func Backend() *framework.Backend {
type backend struct {
*framework.Backend
}
const backendHelp = `
The AWS backend dynamically generates AWS access keys for a set of
IAM policies. The AWS access keys have a configurable lease set and
are automatically revoked at the end of the lease.
`

View File

@@ -16,6 +16,11 @@ import (
//
// This is recommended over implementing logical.Backend directly.
type Backend struct {
// Help is the help text that is shown when a help request is made
// on the root of this resource. The root help is special since we
// show all the paths that can be requested.
Help string
// Paths are the various routes that the backend responds to.
// This cannot be modified after construction (i.e. dynamically changing
// paths, including adding or removing, is not allowed once the
@@ -54,6 +59,8 @@ type RollbackFunc func(*logical.Request, string, interface{}) error
// logical.Backend impl.
func (b *Backend) HandleRequest(req *logical.Request) (*logical.Response, error) {
b.once.Do(b.init)
// Check for special cased global operations. These don't route
// to a specific Path.
switch req.Operation {
@@ -65,6 +72,11 @@ func (b *Backend) HandleRequest(req *logical.Request) (*logical.Response, error)
return b.handleRollback(req)
}
// If the path is empty and it is a help operation, handle that.
if req.Path == "" && req.Operation == logical.HelpOperation {
return b.handleRootHelp()
}
// Find the matching route
path, captures := b.route(req.Path)
if path == nil {
@@ -171,6 +183,23 @@ func (b *Backend) route(path string) (*Path, map[string]string) {
return nil, nil
}
func (b *Backend) handleRootHelp() (*logical.Response, error) {
paths := make([]string, 0, len(b.Paths))
for _, p := range b.pathsRe {
paths = append(paths, p.String())
}
help, err := executeTemplate(rootHelpTemplate, &rootHelpTemplateData{
Help: b.Help,
Paths: paths,
})
if err != nil {
return nil, err
}
return logical.HelpResponse(help, nil), nil
}
func (b *Backend) handleRevokeRenew(
req *logical.Request) (*logical.Response, error) {
if req.Secret == nil {
@@ -295,3 +324,24 @@ func (t FieldType) Zero() interface{} {
panic("unknown type: " + t.String())
}
}
type rootHelpTemplateData struct {
Help string
Paths []string
}
const rootHelpTemplate = `
## DESCRIPTION
{{.Help}}
## PATHS
The following paths are supported by this backend. To view help for
any of the paths below, use the help command with any route matching
the path pattern.
{{range .Paths}} {{.}}
{{end}}
`

View File

@@ -137,6 +137,23 @@ func TestBackendHandleRequest_help(t *testing.T) {
}
}
func TestBackendHandleRequest_helpRoot(t *testing.T) {
b := &Backend{
Help: "42",
}
resp, err := b.HandleRequest(&logical.Request{
Operation: logical.HelpOperation,
Path: "",
})
if err != nil {
t.Fatalf("err: %s", err)
}
if resp.Data["help"] == nil {
t.Fatalf("bad: %#v", resp)
}
}
func TestBackendHandleRequest_renew(t *testing.T) {
var called uint32
callback := func(*logical.Request, *FieldData) (*logical.Response, error) {

View File

@@ -0,0 +1,24 @@
package framework
import (
"bytes"
"fmt"
"strings"
"text/template"
)
func executeTemplate(tpl string, data interface{}) (string, error) {
// Parse the help template
t, err := template.New("root").Parse(tpl)
if err != nil {
return "", fmt.Errorf("error parsing template: %s", err)
}
// Execute the template and store the output
var buf bytes.Buffer
if err := t.Execute(&buf, data); err != nil {
return "", fmt.Errorf("error executing template: %s", err)
}
return strings.TrimSpace(buf.String()), nil
}