Skip to content

Commit

Permalink
Add code for aws client
Browse files Browse the repository at this point in the history
  • Loading branch information
nabbar committed Aug 26, 2020
1 parent 39ba6c8 commit 6d6dd88
Show file tree
Hide file tree
Showing 39 changed files with 2,247 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# Test binary, built with `go test -c`
*.test
*.cover*

# Output of the go coverage tool, specifically when used with LiteIDE
*.out
Expand All @@ -22,3 +23,4 @@ go.sum
.idea/*
.idea/**/*


184 changes: 184 additions & 0 deletions aws/aws_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package aws_test

import (
"context"
"io/ioutil"
"net"
"net/url"
"os"
"strconv"
"testing"

"github.com/nabbar/golib/password"

"github.com/go-playground/validator/v10"
minio "github.com/minio/minio/cmd"
"github.com/nabbar/golib/aws"
"github.com/nabbar/golib/aws/configCustom"
"github.com/nabbar/golib/logger"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var (
cli aws.AWS
cfg aws.Config
ctx context.Context
filename = "./config.json"
)

/*
Using https://onsi.github.io/ginkgo/
Running with $> ginkgo -cover .
*/

func TestGolibAwsHelper(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Aws Helper Suite")
}

var _ = BeforeSuite(func() {
var (
err error
cnl context.CancelFunc
)

ctx, cnl = context.WithCancel(context.Background())
defer cnl()

if err = loadConfig(); err != nil {
var (
uri = &url.URL{
Scheme: "http",
Host: "localhost:" + strconv.Itoa(GetFreePort()),
}

accessKey = password.Generate(20)
secretKey = password.Generate(64)
)

cfg = configCustom.NewConfig("", accessKey, secretKey, uri)

cfg.SetRegion("us-east-1")
err = cfg.RegisterRegionAws(nil)
Expect(err).NotTo(HaveOccurred())

go LaunchMinio(uri.Host, accessKey, secretKey)
}

cli, err = aws.New(ctx, cfg, nil)
Expect(err).NotTo(HaveOccurred())
Expect(cli).NotTo(BeNil())
})

func loadConfig() error {
var (
cnfByt []byte
err error
)

validate := validator.New()

if _, err = os.Stat(filename); err != nil {
// if err = writeConfig(filename); err != nil {
return err
// }
}

if cnfByt, err = ioutil.ReadFile(filename); err != nil {
return err
}

if cfg, err = configCustom.NewConfigJsonUnmashal(cnfByt); err != nil {
return err
}

if err := validate.Struct(cfg); err != nil {
for _, err := range err.(validator.ValidationErrors) {
logger.WarnLevel.Logf("Missing field: %s", err.Namespace())
}

return err
}

return nil
}

func writeConfig(filename string) error {
var (
cnfByt []byte
err error
)

if cnfByt, err = cfg.JSON(); err != nil {
return err
}
if err = ioutil.WriteFile(filename, cnfByt, 0644); err != nil {
return err
}
logger.DebugLevel.Logf("%s created", filename)

return nil
}

func BuildPolicy() string {
return `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:Get*"],"Resource":["arn:aws:s3:::*/*"]}]}`
}

func BuildRole() string {
return `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"sts:AssumeRole","Principal":{"Service":"replication"}}]}`
}

func GetFreePort() int {
var (
addr *net.TCPAddr
lstn *net.TCPListener
err error
)

if addr, err = net.ResolveTCPAddr("tcp", "localhost:0"); err != nil {
panic(err)
}

if lstn, err = net.ListenTCP("tcp", addr); err != nil {
panic(err)
}

defer func() {
_ = lstn.Close()
}()

return lstn.Addr().(*net.TCPAddr).Port
}

func GetTempFolder() string {
if tmp, err := ioutil.TempDir("", "minio-data-*"); err != nil {
panic(err)
} else {
if _, err = os.Stat(tmp); err == os.ErrNotExist {
if err = os.Mkdir(tmp, 0700); err != nil {
panic(err)
}
} else if err != nil {
panic(err)
}

return tmp
}
}

func DelTempFolder(folder string) {
if err := os.RemoveAll(folder); err != nil {
panic(err)
}
}

func LaunchMinio(host, accessKey, secretKey string) {
os.Setenv("MINIO_ACCESS_KEY", accessKey)
os.Setenv("MINIO_SECRET_KEY", secretKey)

tmp := GetTempFolder()
defer DelTempFolder(tmp)

minio.Main([]string{"minio", "server", "--address", host, tmp})
}
148 changes: 148 additions & 0 deletions aws/bucket/bucket.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package bucket

import (
"fmt"

"github.com/nabbar/golib/aws/helper"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/nabbar/golib/errors"
)

func (cli *client) Check() errors.Error {
req := cli.s3.HeadBucketRequest(&s3.HeadBucketInput{
Bucket: cli.GetBucketAws(),
})

out, err := req.Send(cli.GetContext())
defer cli.Close(req.HTTPRequest, req.HTTPResponse)

if err != nil {
return cli.GetError(err)
}

if out == nil || out.HeadBucketOutput == nil {
return helper.ErrorBucketNotFound.ErrorParent(fmt.Errorf("bucket: %s", cli.GetBucketName()))
}

return nil
}

func (cli *client) Create() errors.Error {
req := cli.s3.CreateBucketRequest(&s3.CreateBucketInput{
Bucket: cli.GetBucketAws(),
})

_, err := req.Send(cli.GetContext())
defer cli.Close(req.HTTPRequest, req.HTTPResponse)

return cli.GetError(err)
}

func (cli *client) Delete() errors.Error {
req := cli.s3.DeleteBucketRequest(&s3.DeleteBucketInput{
Bucket: cli.GetBucketAws(),
})

_, err := req.Send(cli.GetContext())
defer cli.Close(req.HTTPRequest, req.HTTPResponse)

return cli.GetError(err)
}

func (cli *client) List() ([]s3.Bucket, errors.Error) {
req := cli.s3.ListBucketsRequest(nil)

out, err := req.Send(cli.GetContext())
defer cli.Close(req.HTTPRequest, req.HTTPResponse)

if err != nil {
return make([]s3.Bucket, 0), cli.GetError(err)
}

if out == nil || out.Buckets == nil {
return make([]s3.Bucket, 0), helper.ErrorAwsEmpty.Error(nil)
}

return out.Buckets, nil
}

func (cli *client) SetVersioning(state bool) errors.Error {
var status s3.BucketVersioningStatus = helper.STATE_ENABLED
if !state {
status = helper.STATE_SUSPENDED
}

vConf := s3.VersioningConfiguration{
Status: status,
}
input := s3.PutBucketVersioningInput{
Bucket: cli.GetBucketAws(),
VersioningConfiguration: &vConf,
}

req := cli.s3.PutBucketVersioningRequest(&input)
_, err := req.Send(cli.GetContext())
defer cli.Close(req.HTTPRequest, req.HTTPResponse)

return cli.GetError(err)
}

func (cli *client) GetVersioning() (string, errors.Error) {
input := s3.GetBucketVersioningInput{
Bucket: cli.GetBucketAws(),
}

req := cli.s3.GetBucketVersioningRequest(&input)
defer cli.Close(req.HTTPRequest, req.HTTPResponse)

out, err := req.Send(cli.GetContext())

if err != nil {
return "", cli.GetError(err)
}

// MarshalValue always return error as nil
v, _ := out.Status.MarshalValue()

return v, nil
}

func (cli *client) EnableReplication(srcRoleARN, dstRoleARN, dstBucketName string) errors.Error {
var status s3.ReplicationRuleStatus = helper.STATE_ENABLED

replicationConf := s3.ReplicationConfiguration{
Role: aws.String(srcRoleARN + "," + dstRoleARN),
Rules: []s3.ReplicationRule{
s3.ReplicationRule{
Destination: &s3.Destination{
Bucket: aws.String("arn:aws:s3:::" + dstBucketName),
},
Status: status,
Prefix: aws.String(""),
},
},
}

req := cli.s3.PutBucketReplicationRequest(&s3.PutBucketReplicationInput{
Bucket: cli.GetBucketAws(),
ReplicationConfiguration: &replicationConf,
})
defer cli.Close(req.HTTPRequest, req.HTTPResponse)

_, err := req.Send(cli.GetContext())

return cli.GetError(err)
}

func (cli *client) DeleteReplication() errors.Error {
req := cli.s3.DeleteBucketReplicationRequest(&s3.DeleteBucketReplicationInput{
Bucket: cli.GetBucketAws(),
})
defer cli.Close(req.HTTPRequest, req.HTTPResponse)

_, err := req.Send(cli.GetContext())

return cli.GetError(err)
}
40 changes: 40 additions & 0 deletions aws/bucket/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package bucket

import (
"context"

"github.com/aws/aws-sdk-go-v2/service/iam"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/nabbar/golib/aws/helper"
"github.com/nabbar/golib/errors"
)

type client struct {
helper.Helper
iam *iam.Client
s3 *s3.Client
}

type Bucket interface {
Check() errors.Error

List() ([]s3.Bucket, errors.Error)
Create() errors.Error
Delete() errors.Error

//FindObject(pattern string) ([]string, errors.Error)

SetVersioning(state bool) errors.Error
GetVersioning() (string, errors.Error)

EnableReplication(srcRoleARN, dstRoleARN, dstBucketName string) errors.Error
DeleteReplication() errors.Error
}

func New(ctx context.Context, bucket string, iam *iam.Client, s3 *s3.Client) Bucket {
return &client{
Helper: helper.New(ctx, bucket),
iam: iam,
s3: s3,
}
}
Loading

0 comments on commit 6d6dd88

Please sign in to comment.