Skip to content

Commit

Permalink
VAULT-12112: add openapi responses for /sys/internal endpoints (#18542)
Browse files Browse the repository at this point in the history
* added responses for sys/internal/ui/mounts

Signed-off-by: Daniel Huckins <dhuckins@users.noreply.github.com>

* responses for internal paths

Signed-off-by: Daniel Huckins <dhuckins@users.noreply.github.com>

* added changelog

* add schema validation for internal/ui/mounts

Signed-off-by: Daniel Huckins <dhuckins@users.noreply.github.com>

* add counters test

Signed-off-by: Daniel Huckins <dhuckins@users.noreply.github.com>

* update test to use new method

Signed-off-by: Daniel Huckins <dhuckins@users.noreply.github.com>

* use new method in TestSystemBackend_InternalUIMounts

Signed-off-by: Daniel Huckins <dhuckins@users.noreply.github.com>

* :rage4: fixed test, diff between core.HandleRequest and backend.HandleRequest

Signed-off-by: Daniel Huckins <dhuckins@users.noreply.github.com>

* test feature flags

Signed-off-by: Daniel Huckins <dhuckins@users.noreply.github.com>

---------

Signed-off-by: Daniel Huckins <dhuckins@users.noreply.github.com>
  • Loading branch information
dhuckins authored Feb 24, 2023
1 parent e812d7b commit 6080a01
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 3 deletions.
3 changes: 3 additions & 0 deletions changelog/18542.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
openapi: add openapi response definitions to /sys/internal endpoints
```
13 changes: 11 additions & 2 deletions vault/counters_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/go-test/deep"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/sdk/helper/testhelpers/schema"
"github.com/hashicorp/vault/sdk/logical"
)

Expand All @@ -23,14 +24,22 @@ func testCountActiveTokens(t *testing.T, c *Core, root string) int {
t.Helper()

rootCtx := namespace.RootContext(nil)
resp, err := c.HandleRequest(rootCtx, &logical.Request{
req := &logical.Request{
ClientToken: root,
Operation: logical.ReadOperation,
Path: "sys/internal/counters/tokens",
})
}
resp, err := c.HandleRequest(rootCtx, req)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("bad: resp: %#v\n err: %v", resp, err)
}
schema.ValidateResponse(
t,
// we remove the `sys/` prefix b/c Core removes it before routing to the 'sys' backend
schema.GetResponseSchema(t, c.systemBackend.Route("internal/counters/tokens"), req.Operation),
resp,
true,
)

activeTokens := resp.Data["counters"].(*ActiveTokens)
return activeTokens.ServiceTokens.Total
Expand Down
4 changes: 3 additions & 1 deletion vault/external_tests/api/feature_flag_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import (

"github.com/hashicorp/go-cleanhttp"
vaulthttp "github.com/hashicorp/vault/http"
"github.com/hashicorp/vault/sdk/helper/testhelpers/schema"
"github.com/hashicorp/vault/vault"
"golang.org/x/net/http2"
)

func TestFeatureFlags(t *testing.T) {
cluster := vault.NewTestCluster(t, nil, &vault.TestClusterOptions{
HandlerFunc: vaulthttp.Handler,
HandlerFunc: vaulthttp.Handler,
RequestResponseCallback: schema.ResponseValidatingCallback(t),
})
cluster.Start()
defer cluster.Cleanup()
Expand Down
145 changes: 145 additions & 0 deletions vault/logical_system_paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -1612,6 +1612,17 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
logical.ReadOperation: &framework.PathOperation{
// callback is absent because this is an unauthenticated method
Summary: "Lists enabled feature flags.",
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"feature_flags": {
Type: framework.TypeCommaStringSlice,
Required: true,
},
},
}},
},
},
},
HelpSynopsis: strings.TrimSpace(sysHelp["internal-ui-feature-flags"][0]),
Expand All @@ -1623,6 +1634,23 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathInternalUIMountsRead,
Summary: "Lists all enabled and visible auth and secrets mounts.",
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"secret": {
Description: "secret mounts",
Type: framework.TypeMap,
Required: true,
},
"auth": {
Description: "auth mounts",
Type: framework.TypeMap,
Required: true,
},
},
}},
},
},
},
HelpSynopsis: strings.TrimSpace(sysHelp["internal-ui-mounts"][0]),
Expand All @@ -1640,6 +1668,65 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathInternalUIMountRead,
Summary: "Return information about the given mount.",
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"type": {
Type: framework.TypeString,
Required: true,
},
"description": {
Type: framework.TypeString,
Required: true,
},
"accessor": {
Type: framework.TypeString,
Required: true,
},
"local": {
Type: framework.TypeBool,
Required: true,
},
"seal_wrap": {
Type: framework.TypeBool,
Required: true,
},
"external_entropy_access": {
Type: framework.TypeBool,
Required: true,
},
"options": {
Type: framework.TypeMap,
Required: true,
},
"uuid": {
Type: framework.TypeString,
Required: true,
},
"plugin_version": {
Type: framework.TypeString,
Required: true,
},
"running_plugin_version": {
Type: framework.TypeString,
Required: true,
},
"running_sha256": {
Type: framework.TypeString,
Required: true,
},
"path": {
Type: framework.TypeString,
Required: true,
},
"config": {
Type: framework.TypeMap,
Required: true,
},
},
}},
},
},
},
HelpSynopsis: strings.TrimSpace(sysHelp["internal-ui-mounts"][0]),
Expand All @@ -1651,6 +1738,17 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
logical.ReadOperation: &framework.PathOperation{
Callback: pathInternalUINamespacesRead(b),
Summary: "Backwards compatibility is not guaranteed for this API",
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"keys": {
Type: framework.TypeCommaStringSlice,
Description: "field is only returned if there are one or more namespaces",
},
},
}},
},
},
},
HelpSynopsis: strings.TrimSpace(sysHelp["internal-ui-namespaces"][0]),
Expand All @@ -1662,6 +1760,29 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathInternalUIResultantACL,
Summary: "Backwards compatibility is not guaranteed for this API",
Responses: map[int][]framework.Response{
http.StatusNoContent: {{
Description: "empty response returned if no client token",
Fields: nil,
}},
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"root": {
Type: framework.TypeBool,
Required: true,
},
"exact_paths": {
Type: framework.TypeMap,
Required: false,
},
"glob_paths": {
Type: framework.TypeMap,
Required: false,
},
},
}},
},
},
},
HelpSynopsis: strings.TrimSpace(sysHelp["internal-ui-resultant-acl"][0]),
Expand All @@ -1673,6 +1794,8 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathInternalCountersRequests,
Summary: "Backwards compatibility is not guaranteed for this API",
// callback only returns errors
Responses: nil,
},
},
HelpSynopsis: strings.TrimSpace(sysHelp["internal-counters-requests"][0]),
Expand All @@ -1684,6 +1807,17 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathInternalCountersTokens,
Summary: "Backwards compatibility is not guaranteed for this API",
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"counters": {
Type: framework.TypeMap,
Required: true,
},
},
}},
},
},
},
HelpSynopsis: strings.TrimSpace(sysHelp["internal-counters-tokens"][0]),
Expand All @@ -1695,6 +1829,17 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathInternalCountersEntities,
Summary: "Backwards compatibility is not guaranteed for this API",
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"counters": {
Type: framework.TypeMap,
Required: true,
},
},
}},
},
},
},
HelpSynopsis: strings.TrimSpace(sysHelp["internal-counters-entities"][0]),
Expand Down
38 changes: 38 additions & 0 deletions vault/logical_system_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3630,13 +3630,20 @@ func TestSystemBackend_ToolsRandom(t *testing.T) {

func TestSystemBackend_InternalUIMounts(t *testing.T) {
_, b, rootToken := testCoreSystemBackend(t)
systemBackend := b.(*SystemBackend)

// Ensure no entries are in the endpoint as a starting point
req := logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts")
resp, err := b.HandleRequest(namespace.RootContext(nil), req)
if err != nil {
t.Fatalf("err: %v", err)
}
schema.ValidateResponse(
t,
schema.GetResponseSchema(t, systemBackend.Route(req.Path), req.Operation),
resp,
true,
)

exp := map[string]interface{}{
"secret": map[string]interface{}{},
Expand All @@ -3652,6 +3659,12 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
schema.ValidateResponse(
t,
schema.GetResponseSchema(t, systemBackend.Route(req.Path), req.Operation),
resp,
true,
)

exp = map[string]interface{}{
"secret": map[string]interface{}{
Expand Down Expand Up @@ -3787,6 +3800,12 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) {
if err != nil {
t.Fatalf("err: %v", err)
}
schema.ValidateResponse(
t,
schema.GetResponseSchema(t, systemBackend.Route(req.Path), req.Operation),
resp,
true,
)

exp = map[string]interface{}{
"secret": map[string]interface{}{
Expand All @@ -3811,6 +3830,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) {

func TestSystemBackend_InternalUIMount(t *testing.T) {
core, b, rootToken := testCoreSystemBackend(t)
systemBackend := b.(*SystemBackend)

req := logical.TestRequest(t, logical.UpdateOperation, "policy/secret")
req.ClientToken = rootToken
Expand Down Expand Up @@ -3840,6 +3860,12 @@ func TestSystemBackend_InternalUIMount(t *testing.T) {
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("Bad %#v %#v", err, resp)
}
schema.ValidateResponse(
t,
schema.GetResponseSchema(t, systemBackend.Route(req.Path), req.Operation),
resp,
true,
)
if resp.Data["type"] != "kv" {
t.Fatalf("Bad Response: %#v", resp)
}
Expand All @@ -3859,6 +3885,12 @@ func TestSystemBackend_InternalUIMount(t *testing.T) {
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("Bad %#v %#v", err, resp)
}
schema.ValidateResponse(
t,
schema.GetResponseSchema(t, systemBackend.Route(req.Path), req.Operation),
resp,
true,
)
if resp.Data["type"] != "kv" {
t.Fatalf("Bad Response: %#v", resp)
}
Expand All @@ -3869,6 +3901,12 @@ func TestSystemBackend_InternalUIMount(t *testing.T) {
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("Bad %#v %#v", err, resp)
}
schema.ValidateResponse(
t,
schema.GetResponseSchema(t, systemBackend.Route(req.Path), req.Operation),
resp,
true,
)
if resp.Data["type"] != "system" {
t.Fatalf("Bad Response: %#v", resp)
}
Expand Down

0 comments on commit 6080a01

Please sign in to comment.