diff --git a/sdk/framework/openapi.go b/sdk/framework/openapi.go index 663386a179..6ef8a8414d 100644 --- a/sdk/framework/openapi.go +++ b/sdk/framework/openapi.go @@ -208,7 +208,7 @@ var ( // documentPaths parses all paths in a framework.Backend into OpenAPI paths. func documentPaths(backend *Backend, requestResponsePrefix string, doc *OASDocument) error { for _, p := range backend.Paths { - if err := documentPath(p, backend.SpecialPaths(), requestResponsePrefix, backend.BackendType, doc); err != nil { + if err := documentPath(p, backend, requestResponsePrefix, doc); err != nil { return err } } @@ -217,13 +217,13 @@ func documentPaths(backend *Backend, requestResponsePrefix string, doc *OASDocum } // documentPath parses a framework.Path into one or more OpenAPI paths. -func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix string, backendType logical.BackendType, doc *OASDocument) error { +func documentPath(p *Path, backend *Backend, requestResponsePrefix string, doc *OASDocument) error { var sudoPaths []string var unauthPaths []string - if specialPaths != nil { - sudoPaths = specialPaths.Root - unauthPaths = specialPaths.Unauthenticated + if backend.PathsSpecial != nil { + sudoPaths = backend.PathsSpecial.Root + unauthPaths = backend.PathsSpecial.Unauthenticated } // Convert optional parameters into distinct patterns to be processed independently. @@ -430,7 +430,7 @@ func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix st // Add tags based on backend type var tags []string - switch backendType { + switch backend.BackendType { case logical.TypeLogical: tags = []string{"secrets"} case logical.TypeCredential: @@ -528,7 +528,11 @@ func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix st } } - doc.Paths["/"+path] = &pi + openAPIPath := "/" + path + if doc.Paths[openAPIPath] != nil { + backend.Logger().Warn("OpenAPI spec generation: multiple framework.Path instances generated the same path; last processed wins", "path", openAPIPath) + } + doc.Paths[openAPIPath] = &pi } return nil diff --git a/sdk/framework/openapi_test.go b/sdk/framework/openapi_test.go index 9e2763f124..e37d5f5119 100644 --- a/sdk/framework/openapi_test.go +++ b/sdk/framework/openapi_test.go @@ -324,12 +324,15 @@ func TestOpenAPI_SpecialPaths(t *testing.T) { path := Path{ Pattern: test.pattern, } - specialPaths := &logical.Paths{ - Root: test.rootPaths, - Unauthenticated: test.unauthenticatedPaths, + backend := &Backend{ + PathsSpecial: &logical.Paths{ + Root: test.rootPaths, + Unauthenticated: test.unauthenticatedPaths, + }, + BackendType: logical.TypeLogical, } - if err := documentPath(&path, specialPaths, "kv", logical.TypeLogical, doc); err != nil { + if err := documentPath(&path, backend, "kv", doc); err != nil { t.Fatal(err) } @@ -593,7 +596,7 @@ func TestOpenAPI_CustomDecoder(t *testing.T) { } docOrig := NewOASDocument("version") - err := documentPath(p, nil, "kv", logical.TypeLogical, docOrig) + err := documentPath(p, &Backend{BackendType: logical.TypeLogical}, "kv", docOrig) if err != nil { t.Fatal(err) } @@ -866,7 +869,10 @@ func testPath(t *testing.T, path *Path, sp *logical.Paths, expectedJSON string) t.Helper() doc := NewOASDocument("dummyversion") - if err := documentPath(path, sp, "kv", logical.TypeLogical, doc); err != nil { + if err := documentPath(path, &Backend{ + PathsSpecial: sp, + BackendType: logical.TypeLogical, + }, "kv", doc); err != nil { t.Fatal(err) } doc.CreateOperationIDs("") diff --git a/sdk/framework/path.go b/sdk/framework/path.go index e96ba4c41b..932172fb28 100644 --- a/sdk/framework/path.go +++ b/sdk/framework/path.go @@ -374,7 +374,7 @@ func (p *Path) helpCallback(b *Backend) OperationFunc { } } doc := NewOASDocument(vaultVersion) - if err := documentPath(p, b.SpecialPaths(), requestResponsePrefix, b.BackendType, doc); err != nil { + if err := documentPath(p, b, requestResponsePrefix, doc); err != nil { b.Logger().Warn("error generating OpenAPI", "error", err) }