diff --git a/changelog/30715.txt b/changelog/30715.txt new file mode 100644 index 0000000000..bc42839685 --- /dev/null +++ b/changelog/30715.txt @@ -0,0 +1,3 @@ +```release-note:bug +openapi: fix missing request schema for custom plugins +``` diff --git a/sdk/framework/openapi.go b/sdk/framework/openapi.go index d31c0107f9..d8be668288 100644 --- a/sdk/framework/openapi.go +++ b/sdk/framework/openapi.go @@ -64,10 +64,20 @@ func NewOASDocumentFromMap(input map[string]interface{}) (*OASDocument, error) { return inputRaw, nil } + // mapstructure does a strings.EqualFold check between a struct key and a map key. + // This does not work for $ref key, a custom match is needed to cover this edge case. + matchName := func(mapKey, fieldName string) bool { + if strings.HasPrefix(mapKey, "$") { + return strings.EqualFold(mapKey[1:], fieldName) + } + return strings.EqualFold(mapKey, fieldName) + } + doc := new(OASDocument) config := &mapstructure.DecoderConfig{ DecodeHook: decodeHook, + MatchName: matchName, Result: doc, } diff --git a/sdk/framework/openapi_test.go b/sdk/framework/openapi_test.go index e5e0142303..e3b8faec20 100644 --- a/sdk/framework/openapi_test.go +++ b/sdk/framework/openapi_test.go @@ -744,6 +744,52 @@ func TestOpenAPI_CustomDecoder(t *testing.T) { } } +func TestOpenAPI_CustomNameMatcher(t *testing.T) { + p := &Path{ + Pattern: "foo", + HelpSynopsis: "Synopsis", + Fields: map[string]*FieldSchema{ + "foo": { + Type: TypeString, + Description: "foo description", + }, + "bar": { + Type: TypeString, + Description: "bar description", + }, + }, + Operations: map[logical.Operation]OperationHandler{ + logical.UpdateOperation: &PathOperation{ + Summary: "My Summary", + }, + }, + } + + docOrig := NewOASDocument("version") + err := documentPath(p, &Backend{BackendType: logical.TypeLogical}, "kv", docOrig) + if err != nil { + t.Fatal(err) + } + + docJSON := mustJSONMarshal(t, docOrig) + + var intermediate map[string]interface{} + if err := jsonutil.DecodeJSON(docJSON, &intermediate); err != nil { + t.Fatal(err) + } + + docNew, err := NewOASDocumentFromMap(intermediate) + if err != nil { + t.Fatal(err) + } + + docNewJSON := mustJSONMarshal(t, docNew) + + if diff := deep.Equal(docJSON, docNewJSON); diff != nil { + t.Fatal(diff) + } +} + func TestOpenAPI_CleanResponse(t *testing.T) { // Verify that an all-null input results in empty JSON orig := &logical.Response{}