Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use aws secret manager #128

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion cmd/scratchdata/scratchdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func setupLogs(logConfig config.Logging) {
}
}

func GetStorageServices(c config.ScratchDataConfig) (*models.StorageServices, error) {
func GetStorageServices(c config.ScratchDataConfig, vault vault.Vault) (*models.StorageServices, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not change the signature of this function. Instead, add a new Vault member to the models.StorageServices struct. You can follow the same pattern we use for the blobstore and queue in this function.

rc := &models.StorageServices{}

blobStore, err := blobstore.NewBlobStore(c.BlobStore)
Expand All @@ -90,6 +90,11 @@ func GetStorageServices(c config.ScratchDataConfig) (*models.StorageServices, er
db := database.NewDatabaseConnection(c.Database, c.Destinations, c.APIKeys)
rc.Database = db

vault, err := vault.NewVault(c.Vault, c.Destinations, c.APIKeys)
if err != nil {
return nil, err
}

return rc, nil
}

Expand Down
3 changes: 3 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ cache:
database:
type: memory

vault:
type: memory

destinations:
- type: duckdb
name: Local DuckDB file
Expand Down
5 changes: 5 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ type Database struct {
Settings map[string]any `yaml:"settings"`
}

type Vault struct {
Type string `yaml:"type"`
Settings map[string]any `yaml:"settings"`
}

type BlobStore struct {
Type string `yaml:"type"`
Settings map[string]any `yaml:"settings"`
Expand Down
7 changes: 4 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.22.1
require (
github.com/ClickHouse/clickhouse-go/v2 v2.20.0
github.com/EagleChen/mapmutex v0.0.0-20200716162114-c133e97096b7
github.com/aws/aws-sdk-go-v2 v1.25.3
github.com/aws/aws-sdk-go-v2 v1.26.0
github.com/aws/aws-sdk-go-v2/config v1.27.7
github.com/aws/aws-sdk-go-v2/credentials v1.17.7
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.9
Expand Down Expand Up @@ -42,14 +42,15 @@ require (
github.com/andybalholm/brotli v1.1.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.3 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.5 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.3 // indirect
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.20.2 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.28.4 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
github.com/aws/aws-sdk-go-v2 v1.25.3 h1:xYiLpZTQs1mzvz5PaI6uR0Wh57ippuEthxS4iK5v0n0=
github.com/aws/aws-sdk-go-v2 v1.25.3/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I=
github.com/aws/aws-sdk-go-v2 v1.26.0 h1:/Ce4OCiM3EkpW7Y+xUnfAFpchU78K7/Ug01sZni9PgA=
github.com/aws/aws-sdk-go-v2 v1.26.0/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 h1:gTK2uhtAPtFcdRRJilZPx8uJLL2J85xK11nKtWL0wfU=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1/go.mod h1:sxpLb+nZk7tIfCWChfd+h4QwHNUR57d8hA1cleTkjJo=
github.com/aws/aws-sdk-go-v2/config v1.27.7 h1:JSfb5nOQF01iOgxFI5OIKWwDiEXWTyTgg1Mm1mHi0A4=
Expand All @@ -33,8 +35,12 @@ github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.9 h1:vXY/Hq1XdxHBIYgBUmug/
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.9/go.mod h1:GyJJTZoHVuENM4TeJEl5Ffs4W9m19u+4wKJcDi/GZ4A=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.3 h1:ifbIbHZyGl1alsAhPIYsHOg5MuApgqOvVeI8wIugXfs=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.3/go.mod h1:oQZXg3c6SNeY6OZrDY+xHcF4VGIEoNotX2B4PrDeoJI=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4 h1:0ScVK/4qZ8CIW0k8jOeFVsyS/sAiXpYxRBLolMkuLQM=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.4/go.mod h1:84KyjNZdHC6QZW08nfHI6yZgPd+qRgaWcYsyLUo3QY8=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.3 h1:Qvodo9gHG9F3E8SfYOspPeBt0bjSbsevK8WhRAUHcoY=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.3/go.mod h1:vCKrdLXtybdf/uQd/YfVR2r5pcbNuEYKzMQpcxmeSJw=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4 h1:sHmMWWX5E7guWEFQ9SVo6A3S4xpPrWnd77a6y4WM6PU=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4/go.mod h1:WjpDrhWisWOIoS9n3nk67A3Ll1vfULJ9Kq6h29HTD48=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU=
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.3 h1:mDnFOE2sVkyphMWtTH+stv0eW3k0OTx94K63xpxHty4=
Expand All @@ -49,6 +55,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.3 h1:4t+QEX7BsXz98W
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.3/go.mod h1:oFcjjUq5Hm09N9rpxTdeMeLeQcxS7mIkBkL8qUKng+A=
github.com/aws/aws-sdk-go-v2/service/s3 v1.51.4 h1:lW5xUzOPGAMY7HPuNF4FdyBwRc3UJ/e8KsapbesVeNU=
github.com/aws/aws-sdk-go-v2/service/s3 v1.51.4/go.mod h1:MGTaf3x/+z7ZGugCGvepnx2DS6+caCYYqKhzVoLNYPk=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.4 h1:5GYToReUFSGP6/zqvG3fv8qNqeetyfsSiPHduHShjAc=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.28.4/go.mod h1:slgOMs1CQu8UVgwoFqEvCi71L4HVoZgM0r8MtcNP6Mc=
github.com/aws/aws-sdk-go-v2/service/sqs v1.31.2 h1:A9ihuyTKpS8Z1ou/D4ETfOEFMyokA6JjRsgXWTiHvCk=
github.com/aws/aws-sdk-go-v2/service/sqs v1.31.2/go.mod h1:J3XhTE+VsY1jDsdDY+ACFAppZj/gpvygzC5JE0bTLbQ=
github.com/aws/aws-sdk-go-v2/service/sso v1.20.2 h1:XOPfar83RIRPEzfihnp+U6udOveKZJvPQ76SKWrLRHc=
Expand Down
3 changes: 2 additions & 1 deletion pkg/storage/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import (
"github.com/scratchdata/scratchdata/config"
"github.com/scratchdata/scratchdata/pkg/storage/database/memory"
"github.com/scratchdata/scratchdata/pkg/storage/database/models"
"github.com/scratchdata/scratchdata/pkg/storage/vault"
)

type Database interface {
VerifyAdminAPIKey(hashedAPIKey string) bool

GetDestinations() []config.Destination
CreateDestination(destType string, settings map[string]any) (config.Destination, error)
GetDestinationCredentials(dbID int64) (config.Destination, error)
GetStorageServices() []config.StorageService
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed. When creating a database, we already pass the StorageServices struct into the New... function.


AddAPIKey(destId int64, hashedAPIKey string) error
GetAPIKeyDetails(hashedAPIKey string) (models.APIKey, error)
Expand Down
129 changes: 129 additions & 0 deletions pkg/storage/vault/aws/aws.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package aws

import (
"context"
"fmt"
"github.com/scratchdata/scratchdata/config"
"github.com/scratchdata/scratchdata/pkg/storage/vault"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
"github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
)

type AWSVault struct {
AccessKeyId string `mapstructure:"access_key_id"`
SecretAccessKey string `mapstructure
Prefix string `mapstructure:"prefix"`
}

func NewAWSVault(conf config.Vault) *AWSVault {
return &AWSVault{
AccessKeyId: conf.AccessKeyId,
SecretAccessKey: conf.SecretAccessKey,
Prefix: conf.Prefix,
}
}

func (vault *AWSVault) GetSecret(ctx context.Context, key string) (string, error) {
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
return "", err
}

client := secretsmanager.NewFromConfig(cfg)

input := &secretsmanager.GetSecretValueInput{
SecretId: aws.String(vault.Prefix + key),
}

result, err := client.GetSecretValue(ctx, input)
if err != nil {
return "", err
}

return *result.SecretString, nil
}

func (vault *AWSVault) SetSecret(ctx context.Context, key string, value string) error {
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
return err
}

client := secretsmanager.NewFromConfig(cfg)

input := &secretsmanager.CreateSecretInput{
Name: aws.String(vault.Prefix + key),
SecretString: aws.String(value),
}

_, err = client.CreateSecret(ctx, input)
if err != nil {
return err
}

return nil
}

func (vault *AWSVault) DeleteSecret(ctx context.Context, key string) error {
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
return err
}

client := secretsmanager.NewFromConfig(cfg)

input := &secretsmanager.DeleteSecretInput{
SecretId: aws.String(vault.Prefix + key),
}

_, err = client.DeleteSecret(ctx, input)
if err != nil {
return err
}

return nil
}

func (vault *AWSVault) ListSecrets(ctx context.Context) ([]string, error) {
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
return nil, err
}

client := secretsmanager.NewFromConfig(cfg)

input := &secretsmanager.ListSecretsInput{}

result, err := client.ListSecrets(ctx, input)
if err != nil {
return nil, err
}

var secrets []string
for _, secret := range result.SecretList {
secrets = append(secrets, *secret.Name)
}

return secrets, nil
}

func (vault *AWSVault) GetSecrets(ctx context.Context) (map[string]string, error) {

secrets, err := vault.ListSecrets(ctx)
if err != nil {
return nil, err
}

secretMap := map[string]string{}
for _, secret := range secrets {
value, err := vault.GetSecret(ctx, secret)
if err != nil {
return nil, err
}
secretMap[secret] = value
}

return secretMap, nil
}
26 changes: 26 additions & 0 deletions pkg/storage/vault/memory/memory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package memory

import (
"github.com/scratchdata/scratchdata/config"
)

func NewMemoryVault(conf config.vault destination []config.Destination, apiKeys []config.APIKey) *MemoryVault {
rc := MemoryVault{
conf: conf,
destinations: destination,
apiKeyToDestination: map[string]int64{},
adminAPIKeys: apiKeys
}

for i, destination := range destinations {
for _, apiKey := range destination.APIKeys {
rc.apiKeyToDestination[apiKey] = int64(i)
}
}

return &rc
}

func (vault *MemoryVault) GetDestinationCredentials(vaultID int64) (config.Destination, error) {
return vault.destinations[vaultID], nil
}
23 changes: 23 additions & 0 deletions pkg/storage/vault/vault.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package vault

import (
"github.com/scratchdata/scratchdata/config"
"github.com/scratchdata/scratchdata/pkg/storage/vault/vault"
"io"
)

type Vault interface {
GetCredentails(name string) string
SetCredentials(name, value string)
}

func NewVault(conf config.Vault, destinations []config.Destination, adminKeys []config.APIKey) Vault {
switch conf.Type {
case "memory":
return memory.NewMemoryVault(conf, destinations, adminKeys)
case "aws":
return aws.NewAWSVault(conf)
}

return nil
}