-
Notifications
You must be signed in to change notification settings - Fork 0
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
1 parent
8e43506
commit bb66231
Showing
14 changed files
with
1,205 additions
and
1 deletion.
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 @@ | ||
# TODO: automate generation of this file | ||
version: 2 | ||
updates: | ||
- package-ecosystem: github-actions | ||
directory: / | ||
labels: | ||
- dependencies | ||
- actions | ||
- Skip Changelog | ||
schedule: | ||
interval: weekly | ||
day: sunday | ||
- package-ecosystem: gomod | ||
directory: / | ||
labels: | ||
- dependencies | ||
- go | ||
- Skip Changelog | ||
schedule: | ||
interval: weekly | ||
day: sunday |
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 @@ | ||
name: Dependabot Pull Request Approve and Merge | ||
|
||
on: pull_request_target | ||
|
||
permissions: | ||
pull-requests: write | ||
contents: write | ||
|
||
jobs: | ||
dependabot: | ||
runs-on: ubuntu-latest | ||
if: ${{ github.actor == 'dependabot[bot]' }} | ||
steps: | ||
- name: Dependabot metadata | ||
id: dependabot-metadata | ||
uses: dependabot/[email protected] | ||
with: | ||
github-token: "${{ secrets.GITHUB_TOKEN }}" | ||
# Here the PR gets approved. | ||
- name: Approve a PR | ||
run: gh pr review --approve "$PR_URL" | ||
env: | ||
PR_URL: ${{ github.event.pull_request.html_url }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
# Finally, this sets the PR to allow auto-merging for patch and minor | ||
# updates if all checks pass | ||
- name: Enable auto-merge for Dependabot PRs | ||
if: ${{ steps.dependabot-metadata.outputs.update-type != 'version-update:semver-major' }} | ||
run: gh pr merge --auto --squash "$PR_URL" | ||
env: | ||
PR_URL: ${{ github.event.pull_request.html_url }} | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
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 @@ | ||
name: goreleaser | ||
|
||
on: | ||
push: | ||
tags: | ||
- "*" | ||
|
||
jobs: | ||
goreleaser: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v2 | ||
with: | ||
fetch-depth: 0 | ||
- name: Set up Go | ||
uses: actions/setup-go@v2 | ||
with: | ||
go-version: 1.18 | ||
- name: Run GoReleaser | ||
uses: goreleaser/goreleaser-action@v2 | ||
with: | ||
# either 'goreleaser' (default) or 'goreleaser-pro' | ||
distribution: goreleaser | ||
version: latest | ||
args: release --rm-dist | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
# Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution | ||
# GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }} |
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,20 @@ | ||
name: test | ||
|
||
on: | ||
push: | ||
branches: [main] | ||
pull_request: | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
go: ["1.17", "1.18"] | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: actions/setup-go@v3 | ||
with: | ||
go-version: ${{ matrix.go }} | ||
cache: true | ||
- run: go test ./... |
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 |
---|---|---|
|
@@ -13,3 +13,5 @@ | |
|
||
# Dependency directories (remove the comment below to include it) | ||
# vendor/ | ||
# | ||
bin |
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,33 @@ | ||
# This is an example .goreleaser.yml file with some sensible defaults. | ||
# Make sure to check the documentation at https://goreleaser.com | ||
before: | ||
hooks: | ||
# You may remove this if you don't use go modules. | ||
- go mod tidy | ||
# you may remove this if you don't need go generate | ||
- go generate ./... | ||
builds: | ||
- env: | ||
- CGO_ENABLED=0 | ||
goos: | ||
- linux | ||
- windows | ||
- darwin | ||
main: ./planetscale-database-plugin/ | ||
archives: | ||
- replacements: | ||
darwin: Darwin | ||
linux: Linux | ||
windows: Windows | ||
386: i386 | ||
amd64: x86_64 | ||
checksum: | ||
name_template: "checksums.txt" | ||
snapshot: | ||
name_template: "{{ incpatch .Version }}-next" | ||
changelog: | ||
sort: asc | ||
filters: | ||
exclude: | ||
- "^docs:" | ||
- "^test:" |
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,31 @@ | ||
VERSION 0.6 | ||
FROM golang:1.18 | ||
WORKDIR /vault-plugin-database-planetscale | ||
|
||
deps: | ||
COPY go.mod go.sum ./ | ||
RUN go mod download | ||
SAVE ARTIFACT go.mod AS LOCAL go.mod | ||
SAVE ARTIFACT go.sum AS LOCAL go.sum | ||
|
||
build: | ||
FROM +deps | ||
COPY *.go . | ||
COPY --dir ./planetscale-database-plugin . | ||
RUN CGO_ENABLED=0 go build -o bin/vault-plugin-database-planetscale planetscale-database-plugin/main.go | ||
SAVE ARTIFACT bin/vault-plugin-database-planetscale /auth0 AS LOCAL bin/vault-plugin-database-planetscale | ||
|
||
test: | ||
FROM +deps | ||
COPY *.go . | ||
ARG TEST_AUTH0_DOMAIN=https://test-stratos-host.us.auth0.com | ||
RUN --secret TEST_AUTH0_ACCESS_TOKEN TEST_AUTH0_DOMAIN=$TEST_AUTH0_DOMAIN CGO_ENABLED=0 go test github.com/bloominlabs/vault-plugin-database-planetscale | ||
|
||
dev: | ||
BUILD +build | ||
LOCALLY | ||
RUN bash ./scripts/dev.sh | ||
|
||
all: | ||
BUILD +build | ||
BUILD +test |
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 |
---|---|---|
@@ -1,2 +1,100 @@ | ||
# vault-plugin-database-planetscale | ||
generate @planetscale usernames and passwords using @vault | ||
|
||
Generate @planetscale usernames and passwords using vault. | ||
|
||
## Usage | ||
|
||
### Setup Endpoint | ||
|
||
1. Download and enable plugin locally | ||
|
||
```bash | ||
vault secrets enable database | ||
vault write sys/plugins/catalog/database/vault-plugin-database-planetscale \ | ||
sha256=<SHA256SUM of plugin> \ | ||
command="vault-plugin-database-planetscale" | ||
``` | ||
|
||
2. Configure a database the plugin | ||
|
||
```bash | ||
# you can generate a service token withhttps://docs.planetscale.com/concepts/service-tokens | ||
vault write database/config/planetscale \ | ||
plugin_name=vualt-plugin-database-planetscale \ | ||
allowed_roles="admin" \ | ||
organization="<your organization>" \ | ||
database="<your database>" \ | ||
service_token="<service_token>" \ | ||
service_token_id="<service_token_id>" | ||
|
||
``` | ||
|
||
3. Configure a role | ||
|
||
```bash | ||
vault write database/roles/admin \ | ||
db_name=$MNT_PATH \ | ||
creation_statements='{"branch": "main", "role": "admin"}' \ | ||
default_ttl="1h" \ | ||
max_ttl="24h" | ||
``` | ||
|
||
### Configure Role | ||
|
||
Roles are have a configurable 'branch' and 'role' that you can specifying using the `creation_statements` parameter | ||
|
||
```bash | ||
vault write database/roles/admin \ | ||
db_name=$MNT_PATH \ | ||
creation_statements='{"branch": "main", "role": "admin"}' \ | ||
default_ttl="1h" \ | ||
max_ttl="24h" | ||
``` | ||
|
||
### Rotating the Root Token | ||
|
||
The is not currently implemented, but will be added in the future. | ||
|
||
### Generate a new Token | ||
|
||
To generate a new token: | ||
|
||
[Configure a Role](#configure-role) and perform a 'read' operation on the `creds/<role-name>` endpoint. | ||
|
||
```bash | ||
# To read data using the api | ||
$ vault read database/creds/admin | ||
Key Value | ||
--- ----- | ||
lease_id database/creds/admin/p2rG2nCorEVTUTVpXnb0NHsh | ||
lease_duration 1h | ||
lease_renewable true | ||
password <password> | ||
username v-token-admin-qrez41hrdjt3n1zviwaz-1657678284 | ||
``` | ||
|
||
## Development | ||
|
||
The provided [Earthfile] ([think makefile, but using | ||
docker](https://earthly.dev)) is used to build, test, and publish the plugin. | ||
See the build targets for more information. Common targets include | ||
|
||
```bash | ||
# build a local version of the plugin | ||
$ earthly +build | ||
|
||
# execute integration tests | ||
# | ||
# use https://developers.auth0.com/api/tokens/create to create a token | ||
# with 'User:API Tokens:Edit' permissions | ||
$ TEST_auth0_TOKEN=<YOUR_auth0_TOKEN> earthly --secret TEST_auth0_TOKEN +test | ||
|
||
# start vault and enable the plugin locally | ||
earthly +dev | ||
``` | ||
|
||
[vault]: https://www.vaultproject.io/ | ||
[auth0-management-api-tokens]: https://auth0.com/docs/security/tokens/access-tokens/management-api-access-tokens | ||
[earthfile]: ./Earthfile | ||
[secrets plugin]: https://www.vaultproject.io/docs/secrets | ||
[database plugin]: https://www.vaultproject.io/docs/secrets/databases |
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,117 @@ | ||
package planetscale | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"sync" | ||
|
||
"github.com/hashicorp/vault/sdk/database/helper/connutil" | ||
"github.com/mitchellh/mapstructure" | ||
"github.com/planetscale/planetscale-go/planetscale" | ||
) | ||
|
||
type ConnectionParameters struct { | ||
Organization string `json:"organization" structs:"organization" mapstructure:"organization"` | ||
Database string `json:"database" structs:"database" mapstructure:"database"` | ||
} | ||
|
||
// planetscaleConnectionProducer implements ConnectionProducer and provides an | ||
// interface for databases to make connections. | ||
type planetscaleConnectionProducer struct { | ||
Organization string `json:"organization" structs:"organization" mapstructure:"organization"` | ||
Database string `json:"database" structs:"database" mapstructure:"database"` | ||
ServiceToken string `json:"service_token" structs:"service_token" mapstructure:"service_token"` | ||
TokenName string `json:"token_name" structs:"token_name" mapstructure:"token_name"` | ||
|
||
Initialized bool | ||
RawConfig map[string]interface{} | ||
Type string | ||
client *planetscale.Client | ||
sync.Mutex | ||
} | ||
|
||
func (c *planetscaleConnectionProducer) Init(ctx context.Context, conf map[string]interface{}, verifyConnection bool) (map[string]interface{}, error) { | ||
c.Lock() | ||
defer c.Unlock() | ||
|
||
c.RawConfig = conf | ||
|
||
err := mapstructure.WeakDecode(conf, &c) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
if c.Organization == "" { | ||
return nil, fmt.Errorf("organization cannot be empty") | ||
} | ||
if c.Database == "" { | ||
return nil, fmt.Errorf("database cannot be empty") | ||
} | ||
if c.ServiceToken == "" { | ||
return nil, fmt.Errorf("service_token cannot be empty") | ||
} | ||
if c.TokenName == "" { | ||
return nil, fmt.Errorf("token_name cannot be empty") | ||
} | ||
|
||
client, err := c.createClient(ctx) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to create planetscale client: %w", err) | ||
} | ||
c.client = client | ||
|
||
// Set initialized to true at this point since all fields are set, | ||
// and the connection can be established at a later time. | ||
c.Initialized = true | ||
|
||
return c.RawConfig, nil | ||
} | ||
|
||
// Connection creates or returns an existing a database connection. If the session fails | ||
// on a ping check, the session will be closed and then re-created. | ||
// This method does locks the mutex on its own. | ||
func (c *planetscaleConnectionProducer) Connection(ctx context.Context) (*planetscale.Client, error) { | ||
if !c.Initialized { | ||
return nil, connutil.ErrNotInitialized | ||
} | ||
|
||
c.Mutex.Lock() | ||
defer c.Mutex.Unlock() | ||
|
||
if c.client != nil { | ||
return c.client, nil | ||
} | ||
|
||
client, err := c.createClient(ctx) | ||
if err != nil { | ||
return nil, err | ||
} | ||
c.client = client | ||
return c.client, nil | ||
} | ||
|
||
func (c *planetscaleConnectionProducer) createClient(ctx context.Context) (client *planetscale.Client, err error) { | ||
client, err = planetscale.NewClient( | ||
planetscale.WithServiceToken(c.TokenName, c.ServiceToken), | ||
) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return client, nil | ||
} | ||
|
||
// Close terminates the database connection. | ||
func (c *planetscaleConnectionProducer) Close() error { | ||
c.Lock() | ||
defer c.Unlock() | ||
|
||
c.client = nil | ||
|
||
return nil | ||
} | ||
|
||
func (c *planetscaleConnectionProducer) secretValues() map[string]string { | ||
return map[string]string{ | ||
c.ServiceToken: "[ServiceToken]", | ||
} | ||
} |
Oops, something went wrong.