-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d8bb708
Showing
1,304 changed files
with
456,127 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# If you prefer the allow list template instead of the deny list, see community template: | ||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore | ||
# | ||
# Binaries for programs and plugins | ||
*.exe | ||
*.exe~ | ||
*.dll | ||
*.so | ||
*.dylib | ||
|
||
# Test binary, built with `go test -c` | ||
*.test | ||
|
||
# Output of the go coverage tool, specifically when used with LiteIDE | ||
*.out | ||
|
||
# Dependency directories (remove the comment below to include it) | ||
# vendor/ | ||
|
||
# Go workspace file | ||
go.work |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
GOARCH = amd64 | ||
|
||
UNAME = $(shell uname -s) | ||
|
||
ifndef OS | ||
ifeq ($(UNAME), Linux) | ||
OS = linux | ||
else ifeq ($(UNAME), Darwin) | ||
OS = darwin | ||
endif | ||
endif | ||
|
||
.DEFAULT_GOAL := all | ||
|
||
all: fmt build start | ||
|
||
build: | ||
GOOS=$(OS) GOARCH="$(GOARCH)" go build -o vault/plugins/vault-plugin-secrets-nats cmd/vault-plugin-secrets-nats/main.go | ||
|
||
start: | ||
vault server -dev -dev-root-token-id=root -dev-plugin-dir=./vault/plugins | ||
|
||
enable: | ||
vault secrets enable -path=nats-secrets vault-plugin-secrets-nats | ||
|
||
clean: | ||
rm -f ./vault/plugins/vault-plugin-secrets-nats | ||
|
||
fmt: | ||
go fmt $$(go list ./...) | ||
|
||
.PHONY: build clean fmt start enable |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Vault Plugin Secrets Nats | ||
|
||
## Usage | ||
|
||
## License |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package natssecretsengine | ||
|
||
import ( | ||
"context" | ||
"strings" | ||
"sync" | ||
|
||
"github.com/hashicorp/vault/sdk/framework" | ||
"github.com/hashicorp/vault/sdk/logical" | ||
) | ||
|
||
func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) { | ||
b := backend() | ||
if err := b.Setup(ctx, conf); err != nil { | ||
return nil, err | ||
} | ||
return b, nil | ||
} | ||
|
||
// natsBackend defines an object that | ||
// extends the Vault backend and stores the | ||
// target API's client. | ||
type natsBackend struct { | ||
*framework.Backend | ||
lock sync.RWMutex | ||
client *natsClient | ||
} | ||
|
||
// backend defines the target API backend | ||
// for Vault. It must include each path | ||
// and the secrets it will store. | ||
func backend() *natsBackend { | ||
var b = natsBackend{} | ||
|
||
b.Backend = &framework.Backend{ | ||
Help: strings.TrimSpace(backendHelp), | ||
PathsSpecial: &logical.Paths{ | ||
LocalStorage: []string{}, | ||
SealWrapStorage: []string{ | ||
"config", | ||
"role/*", | ||
}, | ||
}, | ||
Paths: framework.PathAppend( | ||
pathOperator(&b), | ||
[]*framework.Path{}, | ||
), | ||
Secrets: []*framework.Secret{ | ||
// b.hashiCupsToken(), | ||
}, | ||
BackendType: logical.TypeLogical, | ||
Invalidate: b.invalidate, | ||
} | ||
return &b | ||
} | ||
|
||
// reset clears any client configuration for a new | ||
// backend to be configured | ||
func (b *natsBackend) reset() { | ||
b.lock.Lock() | ||
defer b.lock.Unlock() | ||
b.client = nil | ||
} | ||
|
||
// invalidate clears an existing client configuration in | ||
// the backend | ||
func (b *natsBackend) invalidate(ctx context.Context, key string) { | ||
if key == "config" { | ||
b.reset() | ||
} | ||
} | ||
|
||
// getClient locks the backend as it configures and creates a | ||
// a new client for the target API | ||
func (b *natsBackend) getClient(ctx context.Context, s logical.Storage) (*natsClient, error) { | ||
b.lock.RLock() | ||
unlockFunc := b.lock.RUnlock | ||
defer func() { unlockFunc() }() | ||
|
||
if b.client != nil { | ||
return b.client, nil | ||
} | ||
|
||
b.lock.RUnlock() | ||
b.lock.Lock() | ||
unlockFunc = b.lock.Unlock | ||
return b.client, nil | ||
} | ||
|
||
// backendHelp should contain help information for the backend | ||
const backendHelp = ` | ||
The HashiCups secrets backend dynamically generates user tokens. | ||
After mounting this backend, credentials to manage HashiCups user tokens | ||
must be configured with the "config/" endpoints. | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package natssecretsengine | ||
|
||
import ( | ||
"context" | ||
"os" | ||
"testing" | ||
|
||
"github.com/hashicorp/go-hclog" | ||
"github.com/hashicorp/vault/sdk/logical" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
const ( | ||
envVarRunAccTests = "VAULT_ACC" | ||
envVarHashiCupsUsername = "TEST_HASHICUPS_USERNAME" | ||
envVarHashiCupsPassword = "TEST_HASHICUPS_PASSWORD" | ||
envVarHashiCupsURL = "TEST_HASHICUPS_URL" | ||
) | ||
|
||
// getTestBackend will help you construct a test backend object. | ||
// Update this function with your target backend. | ||
func getTestBackend(tb testing.TB) (*natsBackend, logical.Storage) { | ||
tb.Helper() | ||
|
||
config := logical.TestBackendConfig() | ||
config.StorageView = new(logical.InmemStorage) | ||
config.Logger = hclog.NewNullLogger() | ||
config.System = logical.TestSystemView() | ||
|
||
b, err := Factory(context.Background(), config) | ||
if err != nil { | ||
tb.Fatal(err) | ||
} | ||
|
||
return b.(*natsBackend), config.StorageView | ||
} | ||
|
||
// runAcceptanceTests will separate unit tests from | ||
// acceptance tests, which will make active requests | ||
// to your target API. | ||
var runAcceptanceTests = os.Getenv(envVarRunAccTests) == "1" | ||
|
||
// testEnv creates an object to store and track testing environment | ||
// resources | ||
type testEnv struct { | ||
Username string | ||
Password string | ||
URL string | ||
|
||
Backend logical.Backend | ||
Context context.Context | ||
Storage logical.Storage | ||
|
||
// SecretToken tracks the API token, for checking rotations | ||
SecretToken string | ||
|
||
// Tokens tracks the generated tokens, to make sure we clean up | ||
Tokens []string | ||
} | ||
|
||
// AddConfig adds the configuration to the test backend. | ||
// Make sure data includes all of the configuration | ||
// attributes you need and the `config` path! | ||
func (e *testEnv) AddConfig(t *testing.T) { | ||
req := &logical.Request{ | ||
Operation: logical.CreateOperation, | ||
Path: "config", | ||
Storage: e.Storage, | ||
Data: map[string]interface{}{ | ||
"username": e.Username, | ||
"password": e.Password, | ||
"url": e.URL, | ||
}, | ||
} | ||
resp, err := e.Backend.HandleRequest(e.Context, req) | ||
require.Nil(t, resp) | ||
require.Nil(t, err) | ||
} | ||
|
||
// AddUserTokenRole adds a role for the HashiCups | ||
// user token. | ||
func (e *testEnv) AddUserTokenRole(t *testing.T) { | ||
req := &logical.Request{ | ||
Operation: logical.UpdateOperation, | ||
Path: "role/test-user-token", | ||
Storage: e.Storage, | ||
Data: map[string]interface{}{ | ||
"username": e.Username, | ||
}, | ||
} | ||
resp, err := e.Backend.HandleRequest(e.Context, req) | ||
require.Nil(t, resp) | ||
require.Nil(t, err) | ||
} | ||
|
||
// ReadUserToken retrieves the user token | ||
// based on a Vault role. | ||
func (e *testEnv) ReadUserToken(t *testing.T) { | ||
req := &logical.Request{ | ||
Operation: logical.ReadOperation, | ||
Path: "creds/test-user-token", | ||
Storage: e.Storage, | ||
} | ||
resp, err := e.Backend.HandleRequest(e.Context, req) | ||
require.Nil(t, err) | ||
require.NotNil(t, resp) | ||
|
||
if t, ok := resp.Data["token"]; ok { | ||
e.Tokens = append(e.Tokens, t.(string)) | ||
} | ||
require.NotEmpty(t, resp.Data["token"]) | ||
|
||
if e.SecretToken != "" { | ||
require.NotEqual(t, e.SecretToken, resp.Data["token"]) | ||
} | ||
|
||
// collect secret IDs to revoke at end of test | ||
require.NotNil(t, resp.Secret) | ||
if t, ok := resp.Secret.InternalData["token"]; ok { | ||
e.SecretToken = t.(string) | ||
} | ||
} | ||
|
||
// CleanupUserTokens removes the tokens | ||
// when the test completes. | ||
func (e *testEnv) CleanupUserTokens(t *testing.T) { | ||
if len(e.Tokens) == 0 { | ||
t.Fatalf("expected 2 tokens, got: %d", len(e.Tokens)) | ||
} | ||
|
||
// for _, token := range e.Tokens { | ||
// b := e.Backend.(*natsBackend) | ||
// client, err := b.getClient(e.Context, e.Storage) | ||
// if err != nil { | ||
// t.Fatal("fatal getting client") | ||
// } | ||
// // client.Client.Token = string(token) | ||
// // if err := client.SignOut(); err != nil { | ||
// // t.Fatalf("unexpected error deleting user token: %s", err) | ||
// // } | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package natssecretsengine | ||
|
||
import ( | ||
nats "github.com/nats-io/nats.go" | ||
) | ||
|
||
// natsClient creates an object storing | ||
// the client. | ||
type natsClient struct { | ||
*nats.Conn | ||
} | ||
|
||
// // newClient creates a new client to access HashiCups | ||
// // and exposes it for any secrets or roles to use. | ||
// func newClient(config *natsConfig) (*natsClient, error) { | ||
// if config == nil { | ||
// return nil, errors.New("client configuration was nil") | ||
// } | ||
|
||
// if config.Username == "" { | ||
// return nil, errors.New("client username was not defined") | ||
// } | ||
|
||
// if config.Password == "" { | ||
// return nil, errors.New("client password was not defined") | ||
// } | ||
|
||
// if config.URL == "" { | ||
// return nil, errors.New("client URL was not defined") | ||
// } | ||
|
||
// // c, err := hashicups.NewClient(&config.URL, &config.Username, &config.Password) | ||
// nc, err := nats.Connect(nats.DefaultURL) | ||
// if err != nil { | ||
// return nil, err | ||
// } | ||
// return &natsClient{nc}, nil | ||
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
|
||
nats "github.com/edgefarm/vault-plugin-secrets-nats" | ||
"github.com/hashicorp/go-hclog" | ||
"github.com/hashicorp/vault/api" | ||
"github.com/hashicorp/vault/sdk/plugin" | ||
) | ||
|
||
func main() { | ||
apiClientMeta := &api.PluginAPIClientMeta{} | ||
flags := apiClientMeta.FlagSet() | ||
flags.Parse(os.Args[1:]) | ||
|
||
tlsConfig := apiClientMeta.GetTLSConfig() | ||
tlsProviderFunc := api.VaultPluginTLSProvider(tlsConfig) | ||
|
||
err := plugin.Serve(&plugin.ServeOpts{ | ||
BackendFactoryFunc: nats.Factory, | ||
TLSProviderFunc: tlsProviderFunc, | ||
}) | ||
if err != nil { | ||
logger := hclog.New(&hclog.LoggerOptions{}) | ||
|
||
logger.Error("plugin shutting down", "error", err) | ||
os.Exit(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
version: '3.7' | ||
services: | ||
nats: | ||
image: nats:2.9.0-alpine | ||
ports: | ||
- "8222:8222" | ||
command: "--http_port 8222 --config /server.conf" | ||
networks: ["nats"] | ||
volumes: | ||
- $PWD/server.conf:/server.conf | ||
networks: | ||
nats: | ||
name: nats | ||
|
||
|
||
# db: | ||
# image: "hashicorpdemoapp/product-api-db:v0.0.17" | ||
# ports: | ||
# - "15432:5432" | ||
# environment: | ||
# POSTGRES_DB: 'products' | ||
# POSTGRES_USER: 'postgres' | ||
# POSTGRES_PASSWORD: 'password' |
Oops, something went wrong.