diff --git a/changelog/18468.txt b/changelog/18468.txt new file mode 100644 index 000000000..362bf0501 --- /dev/null +++ b/changelog/18468.txt @@ -0,0 +1,3 @@ +```release-note:improvement +openapi: add openapi response defintions to /sys/capabilities endpoints +``` \ No newline at end of file diff --git a/vault/logical_system_paths.go b/vault/logical_system_paths.go index e09e485b4..4fffcdd30 100644 --- a/vault/logical_system_paths.go +++ b/vault/logical_system_paths.go @@ -1520,8 +1520,17 @@ func (b *SystemBackend) capabilitiesPaths() []*framework.Path { }, }, - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.UpdateOperation: b.handleCapabilitiesAccessor, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.UpdateOperation: &framework.PathOperation{ + Callback: b.handleCapabilitiesAccessor, + Responses: map[int][]framework.Response{ + http.StatusOK: {{ + Description: "OK", + // response keys are dynamic + Fields: nil, + }}, + }, + }, }, HelpSynopsis: strings.TrimSpace(sysHelp["capabilities_accessor"][0]), @@ -1547,8 +1556,17 @@ func (b *SystemBackend) capabilitiesPaths() []*framework.Path { }, }, - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.UpdateOperation: b.handleCapabilities, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.UpdateOperation: &framework.PathOperation{ + Callback: b.handleCapabilities, + Responses: map[int][]framework.Response{ + http.StatusOK: {{ + Description: "OK", + // response keys are dynamic + Fields: nil, + }}, + }, + }, }, HelpSynopsis: strings.TrimSpace(sysHelp["capabilities"][0]), @@ -1574,8 +1592,17 @@ func (b *SystemBackend) capabilitiesPaths() []*framework.Path { }, }, - Callbacks: map[logical.Operation]framework.OperationFunc{ - logical.UpdateOperation: b.handleCapabilities, + Operations: map[logical.Operation]framework.OperationHandler{ + logical.UpdateOperation: &framework.PathOperation{ + Callback: b.handleCapabilities, + Responses: map[int][]framework.Response{ + http.StatusOK: {{ + Description: "OK", + // response keys are dynamic + Fields: nil, + }}, + }, + }, }, HelpSynopsis: strings.TrimSpace(sysHelp["capabilities_self"][0]), diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index 4f18c3a9a..68e6b50a1 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -501,31 +501,45 @@ func TestSystemBackend_PathCapabilities(t *testing.T) { } // Check the capabilities using the root token - resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ + req := &logical.Request{ Path: "capabilities", Operation: logical.UpdateOperation, Data: map[string]interface{}{ "paths": []string{path1, path2, path3, path4}, "token": rootToken, }, - }) + } + resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) rootCheckFunc(t, resp) // Check the capabilities using capabilities-self - resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ + req = &logical.Request{ ClientToken: rootToken, Path: "capabilities-self", Operation: logical.UpdateOperation, Data: map[string]interface{}{ "paths": []string{path1, path2, path3, path4}, }, - }) + } + resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) rootCheckFunc(t, resp) // Lookup the accessor of the root token @@ -535,17 +549,24 @@ func TestSystemBackend_PathCapabilities(t *testing.T) { } // Check the capabilities using capabilities-accessor endpoint - resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ + req = &logical.Request{ Path: "capabilities-accessor", Operation: logical.UpdateOperation, Data: map[string]interface{}{ "paths": []string{path1, path2, path3, path4}, "accessor": te.Accessor, }, - }) + } + resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) rootCheckFunc(t, resp) // Create a non-root token @@ -566,32 +587,46 @@ func TestSystemBackend_PathCapabilities(t *testing.T) { } // Check the capabilities using a non-root token - resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ + req = &logical.Request{ Path: "capabilities", Operation: logical.UpdateOperation, Data: map[string]interface{}{ "paths": []string{path1, path2, path3, path4}, "token": "tokenid", }, - }) + } + resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) nonRootCheckFunc(t, resp) // Check the capabilities of a non-root token using capabilities-self // endpoint - resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ + req = &logical.Request{ ClientToken: "tokenid", Path: "capabilities-self", Operation: logical.UpdateOperation, Data: map[string]interface{}{ "paths": []string{path1, path2, path3, path4}, }, - }) + } + resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) nonRootCheckFunc(t, resp) // Lookup the accessor of the non-root token @@ -602,17 +637,24 @@ func TestSystemBackend_PathCapabilities(t *testing.T) { // Check the capabilities using a non-root token using // capabilities-accessor endpoint - resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{ + req = &logical.Request{ Path: "capabilities-accessor", Operation: logical.UpdateOperation, Data: map[string]interface{}{ "paths": []string{path1, path2, path3, path4}, "accessor": te.Accessor, }, - }) + } + resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || (resp != nil && resp.IsError()) { t.Fatalf("bad: resp: %#v\nerr: %v", resp, err) } + schema.ValidateResponse( + t, + schema.GetResponseSchema(t, b.(*SystemBackend).Route(req.Path), req.Operation), + resp, + true, + ) nonRootCheckFunc(t, resp) }