Add a new log message, reporting collisions between OpenAPI paths (#20873)

Vault API endpoints are defined using regexes in instances of the SDK's
framework.Path structure. However, OpenAPI does not use regexes, so a
translation is performed. It is technically possible that this
translation produces colliding OpenAPI paths from multiple
framework.Path structures. When this happens, there has formerly been no
diagnostic, and one result silently overwrites the other in a map.

As a result of this, several operations are currently accidentally
missing from the Vault OpenAPI, which is also the trigger for
https://github.com/hashicorp/vault-client-go/issues/180.

This PR adds a log message, to help catch such accidents so that they
can be fixed. Much of the PR is propagating a logger to the point where
it is needed, and adjusting tests for the API change.

With current Vault, this will result in the following being logged each
time a request is made which triggers OpenAPI generation:
```
[WARN]  secrets.identity.identity_0cd35e4d: OpenAPI spec generation: multiple framework.Path instances generated the same path; last processed wins: path=/mfa/method
[WARN]  secrets.identity.identity_0cd35e4d: OpenAPI spec generation: multiple framework.Path instances generated the same path; last processed wins: path=/mfa/method/totp
[WARN]  secrets.identity.identity_0cd35e4d: OpenAPI spec generation: multiple framework.Path instances generated the same path; last processed wins: path=/mfa/method/okta
[WARN]  secrets.identity.identity_0cd35e4d: OpenAPI spec generation: multiple framework.Path instances generated the same path; last processed wins: path=/mfa/method/duo
[WARN]  secrets.identity.identity_0cd35e4d: OpenAPI spec generation: multiple framework.Path instances generated the same path; last processed wins: path=/mfa/method/pingid
```

I will submit a further PR to fix the issue - this one is just to add
the diagnostic.
This commit is contained in:
Max Bowsher
2023-06-23 18:36:11 +01:00
committed by GitHub
parent 43ae739971
commit 5ebda5d8f4
3 changed files with 24 additions and 14 deletions

View File

@@ -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