TakesArbitraryInput fixes (#22027)

Update the OpenAPI generation code to render TakesArbitraryInput
appropriately.

Mark the cubbyhole write operation as TakesArbitraryInput.

Contributes to fixing
https://github.com/hashicorp/vault-client-go/issues/201.

We will also need
https://github.com/hashicorp/vault-plugin-secrets-kv/pull/114 merged and
a new version of that plugin brought into Vault.
This commit is contained in:
Max Bowsher
2023-07-24 23:33:55 +01:00
committed by GitHub
parent ae34d344b6
commit 9352dc5579
2 changed files with 28 additions and 1 deletions

View File

@@ -164,6 +164,8 @@ type OASSchema struct {
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
Properties map[string]*OASSchema `json:"properties,omitempty"` Properties map[string]*OASSchema `json:"properties,omitempty"`
AdditionalProperties interface{} `json:"additionalProperties,omitempty"`
// Required is a list of keys in Properties that are required to be present. This is a different // Required is a list of keys in Properties that are required to be present. This is a different
// approach than OASParameter (unfortunately), but is how JSONSchema handles 'required'. // approach than OASParameter (unfortunately), but is how JSONSchema handles 'required'.
Required []string `json:"required,omitempty"` Required []string `json:"required,omitempty"`
@@ -388,8 +390,20 @@ func documentPath(p *Path, backend *Backend, requestResponsePrefix string, doc *
s.Example = props.Examples[0].Data s.Example = props.Examples[0].Data
} }
// TakesArbitraryInput is a case like writing to:
// - sys/wrapping/wrap
// - kv-v1/{path}
// - cubbyhole/{path}
// where the entire request body is an arbitrary JSON object used directly as input.
if p.TakesArbitraryInput {
// Whilst the default value of additionalProperties is true according to the JSON Schema standard,
// making this explicit helps communicate this to humans, and also tools such as
// https://openapi-generator.tech/ which treat it as defaulting to false.
s.AdditionalProperties = true
}
// Set the final request body. Only JSON request data is supported. // Set the final request body. Only JSON request data is supported.
if len(s.Properties) > 0 || s.Example != nil { if len(s.Properties) > 0 {
requestName := hyphenatedToTitleCase(operationID) + "Request" requestName := hyphenatedToTitleCase(operationID) + "Request"
doc.Components.Schemas[requestName] = s doc.Components.Schemas[requestName] = s
op.RequestBody = &OASRequestBody{ op.RequestBody = &OASRequestBody{
@@ -400,6 +414,17 @@ func documentPath(p *Path, backend *Backend, requestResponsePrefix string, doc *
}, },
}, },
} }
} else if p.TakesArbitraryInput {
// When there are no properties, the schema is trivial enough that it makes more sense to write it
// inline, rather than as a named component.
op.RequestBody = &OASRequestBody{
Required: true,
Content: OASContent{
"application/json": &OASMediaTypeObject{
Schema: s,
},
},
}
} }
} }

View File

@@ -61,6 +61,8 @@ func (b *CubbyholeBackend) paths() []*framework.Path {
}, },
}, },
TakesArbitraryInput: true,
Operations: map[logical.Operation]framework.OperationHandler{ Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{ logical.ReadOperation: &framework.PathOperation{
Callback: b.handleRead, Callback: b.handleRead,