mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-13 01:57:03 +02:00
* CreateOperation should only be implemented alongside ExistenceCheck Closes #12329 Vault treats all POST or PUT HTTP requests equally - they default to being treated as UpdateOperations, but, if a backend implements an ExistenceCheck function, CreateOperations can be separated out when the existence check returns false. It follows, then, that if a CreateOperation handler is implemented without an ExistenceCheck function, this is unreachable code - a coding error. It's a fairly minor error in the grand scheme of things, but it causes the generated OpenAPI spec to include x-vault-createSupported for operations on which create can never actually be invoked - and promotes muddled understanding of the create/update feature. In this PR: 1) Implement a new test, which checks all builtin auth methods and secrets engines can be successfully initialized. (This is important to validate the next part.) 2) Expand upon the existing coding error checks built in to framework.Backend, adding a check for this misuse of CreateOperation. 3) Fix up instances of improper CreateOperation within the Vault repository - just two, transit and mock. Note: At this point, the newly added test will **fail**. There are improper uses of CreateOperation in all of the following: vault-plugin-auth-cf vault-plugin-auth-kerberos vault-plugin-auth-kubernetes vault-plugin-secrets-ad vault-plugin-secrets-gcpkms vault-plugin-secrets-kubernetes vault-plugin-secrets-kv vault-plugin-secrets-openldap vault-plugin-secrets-terraform each of which needs to be fixed and updated in go.mod here, before this new check can be added. * Add subtests * Add in testing of KV v2, which otherwise doesn't get tested This is a surprisingly complicated special case * The database plugin needs special handling as well, and add in help invocations of the builtin backends too * Fix extra package prefix * Add changelog * Update 6 out of 9 plugins to needed new versions Note, this IS an upgrade despite the apparent version numbers going down. (That's a consequence of slightly odd release management occurring in the plugin repositories.) * Update to deal with code changes since branch originally created * Perform necessary update of vault-plugin-secrets-kubernetes so that CI checks on PR can run * Fix another instance of incorrect CreateOperation, for a test-only endpoint By being hidden behind a Go build constraint, it had evaded notice until now. * Add an opportunistic test of sys/internal/specs/openapi too
77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package mock
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/rpc"
|
|
|
|
"github.com/hashicorp/vault/sdk/framework"
|
|
"github.com/hashicorp/vault/sdk/helper/errutil"
|
|
"github.com/hashicorp/vault/sdk/logical"
|
|
"github.com/hashicorp/vault/sdk/plugin/pb"
|
|
)
|
|
|
|
// pathInternal is used to test viewing internal backend values. In this case,
|
|
// it is used to test the invalidate func.
|
|
func errorPaths(b *backend) []*framework.Path {
|
|
return []*framework.Path{
|
|
{
|
|
Pattern: "errors/rpc",
|
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
|
logical.ReadOperation: b.pathErrorRPCRead,
|
|
},
|
|
},
|
|
{
|
|
Pattern: "errors/kill",
|
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
|
logical.ReadOperation: b.pathErrorRPCRead,
|
|
},
|
|
},
|
|
{
|
|
Pattern: "errors/type",
|
|
Fields: map[string]*framework.FieldSchema{
|
|
"err_type": {Type: framework.TypeInt},
|
|
},
|
|
Callbacks: map[logical.Operation]framework.OperationFunc{
|
|
logical.UpdateOperation: b.pathErrorRPCRead,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (b *backend) pathErrorRPCRead(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
|
errTypeRaw, ok := data.GetOk("err_type")
|
|
if !ok {
|
|
return nil, rpc.ErrShutdown
|
|
}
|
|
|
|
var err error
|
|
switch uint32(errTypeRaw.(int)) {
|
|
case pb.ErrTypeUnknown:
|
|
err = errors.New("test")
|
|
case pb.ErrTypeUserError:
|
|
err = errutil.UserError{Err: "test"}
|
|
case pb.ErrTypeInternalError:
|
|
err = errutil.InternalError{Err: "test"}
|
|
case pb.ErrTypeCodedError:
|
|
err = logical.CodedError(403, "test")
|
|
case pb.ErrTypeStatusBadRequest:
|
|
err = &logical.StatusBadRequest{Err: "test"}
|
|
case pb.ErrTypeUnsupportedOperation:
|
|
err = logical.ErrUnsupportedOperation
|
|
case pb.ErrTypeUnsupportedPath:
|
|
err = logical.ErrUnsupportedPath
|
|
case pb.ErrTypeInvalidRequest:
|
|
err = logical.ErrInvalidRequest
|
|
case pb.ErrTypePermissionDenied:
|
|
err = logical.ErrPermissionDenied
|
|
case pb.ErrTypeMultiAuthzPending:
|
|
err = logical.ErrMultiAuthzPending
|
|
}
|
|
|
|
return nil, err
|
|
}
|