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

Added AWS cloud functionaly #11

Merged
merged 4 commits into from
Nov 20, 2023
Merged
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
30 changes: 28 additions & 2 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"github.com/scalescape/dolores/config"
"github.com/scalescape/dolores/store/aws"
"github.com/scalescape/dolores/store/google"
)

Expand Down Expand Up @@ -106,12 +107,37 @@
return objs, nil
}

func getStore(ctx context.Context, cfg config.Client) (clouldStore, error) {

Check failure on line 110 in client/client.go

View workflow job for this annotation

GitHub Actions / golangci-lint

getStore returns interface (github.com/scalescape/dolores/client.clouldStore) (ireturn)

Check failure on line 110 in client/client.go

View workflow job for this annotation

GitHub Actions / golangci-lint

getStore returns interface (github.com/scalescape/dolores/client.clouldStore) (ireturn)
var store clouldStore
var err error
switch cfg.Provider {
case config.AWS:
{
store, err = aws.NewStore(ctx)
if err != nil {
return nil, err
}
}
case config.GCS:
{
gcfg := google.Config{ServiceAccountFile: cfg.Cloud.ApplicationCredentials}
store, err = google.NewStore(ctx, gcfg)
if err != nil {
return nil, err
}
}
default:
err = fmt.Errorf("failed to get store: %w", config.ErrCloudProviderNotFound)
}

return store, err
}

func New(ctx context.Context, cfg config.Client) (*Client, error) {
if err := cfg.Valid(); err != nil {
return nil, err
}
gcfg := google.Config{ServiceAccountFile: cfg.Google.ApplicationCredentials}
st, err := google.NewStore(ctx, gcfg)
st, err := getStore(ctx, cfg)
if err != nil {
return nil, err
}
Expand Down
12 changes: 6 additions & 6 deletions client/gcs_service.go → client/cloud_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@

"github.com/rs/zerolog/log"
"github.com/scalescape/dolores/config"
"github.com/scalescape/dolores/store/google"
"github.com/scalescape/dolores/store/cloud"
)

var ErrInvalidPublicKeys = errors.New("invalid public keys")

const metadataFile = "dolores.md"

type Service struct {
store gcsStore
store clouldStore
}

type gcsStore interface {
type clouldStore interface {
WriteToObject(ctx context.Context, bucketName, fileName string, data []byte) error
ReadObject(ctx context.Context, bucketName, fileName string) ([]byte, error)
ListObject(ctx context.Context, bucketName, path string) ([]google.Object, error)
ListObject(ctx context.Context, bucketName, path string) ([]cloud.Object, error)
ExistsObject(ctx context.Context, bucketName, fileName string) (bool, error)
}

Expand Down Expand Up @@ -73,7 +73,7 @@
return s.store.WriteToObject(ctx, bucket, fileName, data)
}

func (s Service) GetOrgPublicKeys(ctx context.Context, env, bucketName, path string) ([]string, error) {

Check warning on line 76 in client/cloud_service.go

View workflow job for this annotation

GitHub Actions / golangci-lint

unused-parameter: parameter 'env' seems to be unused, consider removing or renaming it as _ (revive)

Check warning on line 76 in client/cloud_service.go

View workflow job for this annotation

GitHub Actions / golangci-lint

unused-parameter: parameter 'env' seems to be unused, consider removing or renaming it as _ (revive)
pubKey := os.Getenv("DOLORES_PUBLIC_KEY")
if pubKey != "" {
return []string{pubKey}, nil
Expand Down Expand Up @@ -109,7 +109,7 @@
return data, nil
}

func (s Service) getObjectPrefix(ctx context.Context, env, bucket string) (string, error) {

Check warning on line 112 in client/cloud_service.go

View workflow job for this annotation

GitHub Actions / golangci-lint

unused-parameter: parameter 'env' seems to be unused, consider removing or renaming it as _ (revive)

Check warning on line 112 in client/cloud_service.go

View workflow job for this annotation

GitHub Actions / golangci-lint

unused-parameter: parameter 'env' seems to be unused, consider removing or renaming it as _ (revive)
md, err := s.readMetadata(ctx, bucket, metadataFile)
if err != nil {
return "", fmt.Errorf("failed to read metadata: %w", err)
Expand Down Expand Up @@ -138,14 +138,14 @@
return s.store.WriteToObject(ctx, bucket, fname, data)
}

func (s Service) ListObject(ctx context.Context, bucket, path string) ([]google.Object, error) {
func (s Service) ListObject(ctx context.Context, bucket, path string) ([]cloud.Object, error) {
resp, err := s.store.ListObject(ctx, bucket, path)
if err != nil {
return nil, err
}
return resp, nil
}

func NewService(st gcsStore) Service {
func NewService(st clouldStore) Service {
return Service{store: st}
}
9 changes: 5 additions & 4 deletions client/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/scalescape/dolores/client"
"github.com/scalescape/dolores/config"
"github.com/scalescape/dolores/store/google"
"github.com/scalescape/dolores/store/cloud"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -39,9 +39,9 @@ func (m *mockGCS) ReadObject(ctx context.Context, bucketName, fileName string) (
return args.Get(0).([]byte), args.Error(1)
}

func (m *mockGCS) ListObject(ctx context.Context, bucketName, path string) ([]google.Object, error) {
func (m *mockGCS) ListObject(ctx context.Context, bucketName, path string) ([]cloud.Object, error) {
args := m.Called(ctx, bucketName, path)
return args.Get(0).([]google.Object), args.Error(1)
return args.Get(0).([]cloud.Object), args.Error(1)
}

func (m *mockGCS) ExistsObject(ctx context.Context, bucketName, fileName string) (bool, error) {
Expand Down Expand Up @@ -69,7 +69,8 @@ func (s *serviceSuite) TestShouldNotOverwriteMetadata() {
cfg := client.Configuration{
PublicKey: "public_key",
Metadata: config.Metadata{Location: "secrets"},
UserID: "test_user"}
UserID: "test_user",
}
s.gcs.On("ExistsObject", mock.AnythingOfType("context.backgroundCtx"), s.bucket, name).Return(true, nil).Once()
s.gcs.On("WriteToObject", mock.AnythingOfType("context.backgroundCtx"), s.bucket, "secrets/keys/test_user.key", []byte(cfg.PublicKey)).Return(nil).Once()

Expand Down
77 changes: 56 additions & 21 deletions cmd/dolores/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,16 @@ func NewInitCommand(newCli GetClient) *cli.Command {
}

type Input struct {
CloudProvider string `survey:"cloud_provider"`
UserID string `survey:"user_id"`
Bucket string
Location string
ApplicationCredentials string `survey:"google_creds"`
ApplicationCredentials string `survey:"creds"`
}

func (inp Input) ToMetadata(env string) config.Metadata {
return config.Metadata{
CloudProvider: inp.CloudProvider,
Bucket: inp.Bucket,
Location: inp.Location,
CreatedAt: time.Now(),
Expand All @@ -57,13 +59,61 @@ func (inp Input) ToMetadata(env string) config.Metadata {
}
}

func (c *InitCommand) getCred(res *Input) error {
qs := []*survey.Question{}

switch res.CloudProvider {
case config.GCS:
{
credFile := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")
if credFile != "" {
qs = append(qs, &survey.Question{
Name: "creds",
Validate: survey.Required,
Prompt: &survey.Select{
Message: "Use GOOGLE_APPLICATION_CREDENTIALS env as credentials file",
Options: []string{credFile},
},
})
} else {
qs = append(qs, &survey.Question{
Name: "creds",
Prompt: &survey.Input{
Message: "Enter google service account file path",
},
Validate: survey.Required,
})
}
}
case config.AWS:
{
res.ApplicationCredentials = "aws_default"
return nil
}
}

credRes := new(Input)
if err := survey.Ask(qs, credRes); err != nil {
return fmt.Errorf("failed to get appropriate input: %w", err)
}
res.ApplicationCredentials = credRes.ApplicationCredentials
return nil
}

func (c *InitCommand) getData(env string) (*Input, error) {
credFile := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")
qs := []*survey.Question{
{
Name: "cloud_provider",
Validate: survey.Required,
Prompt: &survey.Select{
Message: "Select Cloud provider",
Options: []string{config.AWS, config.GCS},
},
},
{
Name: "bucket",
Prompt: &survey.Input{
Message: "Enter the GCS bucket name:",
Message: "Enter the bucket name:",
},
Validate: survey.Required,
},
Expand All @@ -84,28 +134,13 @@ func (c *InitCommand) getData(env string) (*Input, error) {
},
},
}
if credFile != "" {
qs = append(qs, &survey.Question{
Name: "google_creds",
Validate: survey.Required,
Prompt: &survey.Select{
Message: "Use GOOGLE_APPLICATION_CREDENTIALS env as credentials file",
Options: []string{credFile},
},
})
} else {
qs = append(qs, &survey.Question{
Name: "google_creds",
Prompt: &survey.Input{
Message: "Enter google service account file path",
},
Validate: survey.Required,
})
}
res := new(Input)
if err := survey.Ask(qs, res); err != nil {
return nil, fmt.Errorf("failed to get appropriate input: %w", err)
}
if err := c.getCred(res); err != nil {
return nil, fmt.Errorf("failed to get appropriate input: %w", err)
}
return res, nil
}

Expand Down
41 changes: 28 additions & 13 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@
)

var (
ErrInvalidGoogleCreds = errors.New("invalid google application credentials")
ErrInvalidStorageBucket = errors.New("invalid storage bucket")
ErrInvalidKeyFile = errors.New("invalid key file")
ErrInvalidGoogleCreds = errors.New("invalid google application credentials")
ErrInvalidStorageBucket = errors.New("invalid storage bucket")
ErrInvalidKeyFile = errors.New("invalid key file")
ErrCloudProviderNotFound = errors.New("cloud provider not found")
)

var (
AWS = "AWS"
GCS = "GCS"
)

type CtxKey string
Expand All @@ -27,13 +33,14 @@
File = filepath.Join(Dir, "dolores.json")
)

type Google struct {
type Cloud struct {
ApplicationCredentials string `split_words:"true"`
StorageBucket string `split_words:"true"`
StoragePrefix string
}

type Metadata struct {
CloudProvider string `json:"cloud_provider"`
Bucket string `json:"bucket"`
Location string `json:"location"`
Environment string `json:"environment"`
Expand All @@ -42,46 +49,54 @@
}

type Client struct {
Google
Cloud
Provider string
}

func (c Client) BucketName() string {
return c.Google.StorageBucket
return c.Cloud.StorageBucket
}

func (c Client) Valid() error {
if c.Google.ApplicationCredentials == "" {
if c.Provider == "" {
return ErrCloudProviderNotFound
}
if c.Cloud.ApplicationCredentials == "" {
return ErrInvalidGoogleCreds
}
if c.Google.StorageBucket == "" {
if c.Cloud.StorageBucket == "" {
return ErrInvalidStorageBucket
}
return nil
}

func LoadClient(ctx context.Context, env string) (Client, error) {

Check warning on line 73 in config/config.go

View workflow job for this annotation

GitHub Actions / golangci-lint

unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)

Check warning on line 73 in config/config.go

View workflow job for this annotation

GitHub Actions / golangci-lint

unused-parameter: parameter 'ctx' seems to be unused, consider removing or renaming it as _ (revive)
var cfg Client
d, err := LoadFromDisk()
if err != nil {
return Client{}, fmt.Errorf("dolores not initialized yet: %w", err)
}
if err := envconfig.Process("GOOGLE", &cfg.Google); err != nil {
if err := envconfig.Process("GOOGLE", &cfg.Cloud); err != nil {
return Client{}, fmt.Errorf("processing config: %w", err)
}

md := d.Environments[env].Metadata
if cfg.Google.ApplicationCredentials == "" {
if cloudProvider := md.CloudProvider; cloudProvider != "" {
cfg.Provider = cloudProvider
}

if cfg.Cloud.ApplicationCredentials == "" {
if creds := md.ApplicationCredentials; creds != "" {
cfg.Google.ApplicationCredentials = creds
cfg.Cloud.ApplicationCredentials = creds
}
}

if bucket := md.Bucket; bucket != "" {
cfg.Google.StorageBucket = bucket
cfg.Cloud.StorageBucket = bucket
}

if location := md.Location; location != "" {
cfg.Google.StoragePrefix = location
cfg.Cloud.StoragePrefix = location
}

if err := cfg.Valid(); err != nil {
Expand Down
29 changes: 24 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ require (
cloud.google.com/go/storage v1.30.1
filippo.io/age v1.1.1
github.com/AlecAivazis/survey/v2 v2.3.7
github.com/aws/aws-sdk-go-v2/config v1.23.0
github.com/aws/aws-sdk-go-v2/service/s3 v1.42.1
github.com/kelseyhightower/envconfig v1.4.0
github.com/rs/zerolog v1.29.1
github.com/scalescape/go-metrics v0.0.0-20230825040750-1888415fe69a
Expand All @@ -14,11 +16,28 @@ require (
google.golang.org/api v0.129.0
)

require github.com/aws/aws-sdk-go-v2/credentials v1.15.2 // indirect

require (
cloud.google.com/go v0.110.0 // indirect
cloud.google.com/go/compute v1.19.3 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
cloud.google.com/go/iam v0.13.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.22.2
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.0 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.3 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.2 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.6.0 // indirect
github.com/aws/aws-sdk-go-v2/internal/v4a v1.2.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.0 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.2.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.16.2 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.17.1 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.19.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.25.1 // indirect
github.com/aws/smithy-go v1.16.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cactus/go-statsd-client/v5 v5.0.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
Expand All @@ -45,12 +64,12 @@ require (
github.com/stretchr/objx v0.5.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/net v0.11.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.9.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/term v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc // indirect
Expand Down
Loading
Loading