mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-19 05:31:10 +02:00
parent
de1fa7a467
commit
ffb61ea5f7
@ -119,6 +119,7 @@ func NewOASOperation() *OASOperation {
|
|||||||
type OASOperation struct {
|
type OASOperation struct {
|
||||||
Summary string `json:"summary,omitempty"`
|
Summary string `json:"summary,omitempty"`
|
||||||
Description string `json:"description,omitempty"`
|
Description string `json:"description,omitempty"`
|
||||||
|
OperationID string `json:"operationId,omitempty"`
|
||||||
Tags []string `json:"tags,omitempty"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
Parameters []OASParameter `json:"parameters,omitempty"`
|
Parameters []OASParameter `json:"parameters,omitempty"`
|
||||||
RequestBody *OASRequestBody `json:"requestBody,omitempty"`
|
RequestBody *OASRequestBody `json:"requestBody,omitempty"`
|
||||||
@ -185,6 +186,7 @@ var cleanSuffixRe = regexp.MustCompile(`/\?\$?$`) // Path suf
|
|||||||
var wsRe = regexp.MustCompile(`\s+`) // Match whitespace, to be compressed during cleaning
|
var wsRe = regexp.MustCompile(`\s+`) // Match whitespace, to be compressed during cleaning
|
||||||
var altFieldsGroupRe = regexp.MustCompile(`\(\?P<\w+>\w+(\|\w+)+\)`) // Match named groups that limit options, e.g. "(?<foo>a|b|c)"
|
var altFieldsGroupRe = regexp.MustCompile(`\(\?P<\w+>\w+(\|\w+)+\)`) // Match named groups that limit options, e.g. "(?<foo>a|b|c)"
|
||||||
var altFieldsRe = regexp.MustCompile(`\w+(\|\w+)+`) // Match an options set, e.g. "a|b|c"
|
var altFieldsRe = regexp.MustCompile(`\w+(\|\w+)+`) // Match an options set, e.g. "a|b|c"
|
||||||
|
var nonWordRe = regexp.MustCompile(`[^\w]+`) // Match a sequence of non-word characters
|
||||||
|
|
||||||
// documentPaths parses all paths in a framework.Backend into OpenAPI paths.
|
// documentPaths parses all paths in a framework.Backend into OpenAPI paths.
|
||||||
func documentPaths(backend *Backend, doc *OASDocument) error {
|
func documentPaths(backend *Backend, doc *OASDocument) error {
|
||||||
@ -611,3 +613,52 @@ func cleanResponse(resp *logical.Response) (*cleanedResponse, error) {
|
|||||||
|
|
||||||
return &r, nil
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateOperationIDs generates unique operationIds for all paths/methods.
|
||||||
|
// The transform will convert path/method into camelcase. e.g.:
|
||||||
|
//
|
||||||
|
// /sys/tools/random/{urlbytes} -> postSysToolsRandomUrlbytes
|
||||||
|
//
|
||||||
|
// In the unlikely case of a duplicate ids, a numeric suffix is added:
|
||||||
|
// postSysToolsRandomUrlbytes_2
|
||||||
|
//
|
||||||
|
// An optional user-provided suffix ("context") may also be appended.
|
||||||
|
func (d *OASDocument) CreateOperationIDs(context string) {
|
||||||
|
opIDCount := make(map[string]int)
|
||||||
|
|
||||||
|
for path, pi := range d.Paths {
|
||||||
|
for _, method := range []string{"get", "post", "delete"} {
|
||||||
|
var oasOperation *OASOperation
|
||||||
|
switch method {
|
||||||
|
case "get":
|
||||||
|
oasOperation = pi.Get
|
||||||
|
case "post":
|
||||||
|
oasOperation = pi.Post
|
||||||
|
case "delete":
|
||||||
|
oasOperation = pi.Delete
|
||||||
|
}
|
||||||
|
|
||||||
|
if oasOperation == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Space-split on non-words, title case everything, recombine
|
||||||
|
opID := nonWordRe.ReplaceAllString(strings.ToLower(path), " ")
|
||||||
|
opID = strings.Title(opID)
|
||||||
|
opID = method + strings.Replace(opID, " ", "", -1)
|
||||||
|
|
||||||
|
// deduplicate operationIds. This is a safeguard, since generated IDs should
|
||||||
|
// already be unique given our current path naming conventions.
|
||||||
|
opIDCount[opID]++
|
||||||
|
if opIDCount[opID] > 1 {
|
||||||
|
opID = fmt.Sprintf("%s_%d", opID, opIDCount[opID])
|
||||||
|
}
|
||||||
|
|
||||||
|
if context != "" {
|
||||||
|
opID += "_" + context
|
||||||
|
}
|
||||||
|
|
||||||
|
oasOperation.OperationID = opID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3064,6 +3064,8 @@ func (b *SystemBackend) pathInternalOpenAPI(ctx context.Context, req *logical.Re
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context := d.Get("context").(string)
|
||||||
|
|
||||||
// Set up target document and convert to map[string]interface{} which is what will
|
// Set up target document and convert to map[string]interface{} which is what will
|
||||||
// be received from plugin backends.
|
// be received from plugin backends.
|
||||||
doc := framework.NewOASDocument()
|
doc := framework.NewOASDocument()
|
||||||
@ -3144,6 +3146,8 @@ func (b *SystemBackend) pathInternalOpenAPI(ctx context.Context, req *logical.Re
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doc.CreateOperationIDs(context)
|
||||||
|
|
||||||
buf, err := json.Marshal(doc)
|
buf, err := json.Marshal(doc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -754,8 +754,15 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
|
|||||||
return []*framework.Path{
|
return []*framework.Path{
|
||||||
{
|
{
|
||||||
Pattern: "internal/specs/openapi",
|
Pattern: "internal/specs/openapi",
|
||||||
|
Fields: map[string]*framework.FieldSchema{
|
||||||
|
"context": &framework.FieldSchema{
|
||||||
|
Type: framework.TypeString,
|
||||||
|
Description: "Context string appended to every operationId",
|
||||||
|
},
|
||||||
|
},
|
||||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||||
logical.ReadOperation: b.pathInternalOpenAPI,
|
logical.ReadOperation: b.pathInternalOpenAPI,
|
||||||
|
logical.UpdateOperation: b.pathInternalOpenAPI,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user