Skip to content

Commit

Permalink
add: implement creating s3 bucket process
Browse files Browse the repository at this point in the history
  • Loading branch information
nao1215 committed Dec 26, 2023
1 parent 2dd78c4 commit bd918f5
Show file tree
Hide file tree
Showing 13 changed files with 329 additions and 63 deletions.
4 changes: 2 additions & 2 deletions app/di/wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
// S3App is the application service for S3.
type S3App struct {
// S3BucketCreator is the usecase for creating a new S3 bucket.
s3bucketCreator usecase.S3BucketCreator
S3BucketCreator usecase.S3BucketCreator
}

// NewS3App creates a new S3App.
Expand All @@ -34,6 +34,6 @@ func NewS3App(ctx context.Context, profile model.AWSProfile, region model.Region

func newS3App(s3bucketCreator usecase.S3BucketCreator) *S3App {
return &S3App{
s3bucketCreator: s3bucketCreator,
S3BucketCreator: s3bucketCreator,
}
}
4 changes: 2 additions & 2 deletions app/di/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion app/domain/model/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func NewAWSConfig(ctx context.Context, profile AWSProfile, region Region) (*AWSC
opts = append(opts, config.WithSharedConfigProfile(profile.String()))
}
if region.String() != "" {
opts = append(opts, config.WithRegion(string(region)))
opts = append(opts, config.WithRegion(region.String()))
}

cfg, err := config.LoadDefaultConfig(ctx, opts...)
Expand Down
38 changes: 38 additions & 0 deletions app/domain/model/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ const (
RegionUSGovWest1 Region = "us-gov-west-1"
)

var regions = []Region{
RegionUSEast1, RegionUSEast2, RegionUSWest1, RegionUSWest2, RegionAFSouth1, RegionAPEast1,
RegionAPSouth1, RegionAPNortheast1, RegionAPNortheast2, RegionAPNortheast3, RegionAPSoutheast1,
RegionAPSoutheast2, RegionCACentral1, RegionCNNorth1, RegionCNNorthwest1, RegionEUCentral1,
RegionEUNorth1, RegionEUSouth1, RegionEUWest1, RegionEUWest2, RegionEUWest3, RegionMESouth1,
RegionSASouth1, RegionUSGovEast1, RegionUSGovWest1,
}

// Validate returns true if the Region exists.
func (r Region) Validate() error {
switch r {
Expand All @@ -88,6 +96,36 @@ func (r Region) String() string {
return string(r)
}

// Next returns the next region.
// If the region is the last one, it returns the first region.
// If the region is invalid, it returns "ap-northeast-1".
func (r Region) Next() Region {
for i, region := range regions {
if r == region {
if i == len(regions)-1 {
return regions[0]
}
return regions[i+1]
}
}
return RegionAPNortheast1
}

// Prev returns the previous region.
// If the region is the first one, it returns the last region.
// If the region is invalid, it returns "ap-northeast-1".
func (r Region) Prev() Region {
for i, region := range regions {
if r == region {
if i == 0 {
return regions[len(regions)-1]
}
return regions[i-1]
}
}
return RegionAPNortheast1
}

// Bucket is the name of the S3 bucket.
type Bucket string

Expand Down
68 changes: 68 additions & 0 deletions app/domain/model/s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,71 @@ func TestBucketDomain(t *testing.T) {
})
}
}

func TestRegion_Next(t *testing.T) {
t.Parallel()
tests := []struct {
name string
r Region
want Region
}{
{
name: "success",
r: RegionAPNortheast1,
want: RegionAPNortheast2,
},
{
name: "success. last region",
r: RegionUSGovWest1,
want: RegionUSEast1,
},
{
name: "failure. invalid region",
r: Region("invalid"),
want: RegionAPNortheast1,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := tt.r.Next(); got != tt.want {
t.Errorf("Region.Next() = %v, want %v", got, tt.want)
}
})
}
}

func TestRegion_Prev(t *testing.T) {
t.Parallel()
tests := []struct {
name string
r Region
want Region
}{
{
name: "success",
r: RegionAPNortheast2,
want: RegionAPNortheast1,
},
{
name: "success. first region",
r: RegionUSEast1,
want: RegionUSGovWest1,
},
{
name: "failure. invalid region",
r: Region("invalid"),
want: RegionAPNortheast1,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := tt.r.Prev(); got != tt.want {
t.Errorf("Region.Prev() = %v, want %v", got, tt.want)
}
})
}
}
2 changes: 1 addition & 1 deletion app/domain/service/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
type S3BucketCreatorInput struct {
// Bucket is the name of the bucket to create.
Bucket model.Bucket
// Region is the name of the AWS region.
// Region is the region of the bucket that you want to create.
Region model.Region
}

Expand Down
9 changes: 7 additions & 2 deletions app/external/s3.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// Packgae external provides external dependencies.
package external

import (
"context"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/google/wire"
"github.com/nao1215/rainbow/app/domain/model"
"github.com/nao1215/rainbow/app/domain/service"
"github.com/shogo82148/pointer"
)

// NewS3Client creates a new S3 service client.
Expand Down Expand Up @@ -39,7 +41,10 @@ func NewS3BucketCreator(client *s3.Client) *S3BucketCreator {
// CreateBucket creates a new S3 bucket.
func (c *S3BucketCreator) CreateBucket(ctx context.Context, input *service.S3BucketCreatorInput) (*service.S3BucketCreatorOutput, error) {
_, err := c.client.CreateBucket(ctx, &s3.CreateBucketInput{
Bucket: pointer.String(input.Bucket.String()),
Bucket: aws.String(input.Bucket.String()),
CreateBucketConfiguration: &types.CreateBucketConfiguration{
LocationConstraint: types.BucketLocationConstraint(input.Region.String()),
},
})
if err != nil {
return nil, err
Expand Down
12 changes: 12 additions & 0 deletions app/interactor/s3.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// Package interactor contains the implementations of usecases.
package interactor

import (
Expand Down Expand Up @@ -32,5 +33,16 @@ func NewS3BucketCreator(c service.S3BucketCreator) *S3BucketCreator {

// CreateBucket creates a new S3 bucket.
func (s *S3BucketCreator) CreateBucket(ctx context.Context, input *usecase.S3BucketCreatorInput) (*usecase.S3BucketCreatorOutput, error) {
if err := input.Bucket.Validate(); err != nil {
return nil, err
}

in := service.S3BucketCreatorInput{
Bucket: input.Bucket,
Region: input.Region,
}
if _, err := s.S3BucketCreator.CreateBucket(ctx, &in); err != nil {
return nil, err
}
return &usecase.S3BucketCreatorOutput{}, nil
}
13 changes: 10 additions & 3 deletions app/usecase/s3.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
// Package usecase has interfaces that wrap the basic business logic.
package usecase

import "context"
import (
"context"

"github.com/nao1215/rainbow/app/domain/model"
)

// S3BucketCreatorInput is the input of the CreateBucket method.
type S3BucketCreatorInput struct {
Bucket string
Region string
// Bucket is the name of the bucket that you want to create.
Bucket model.Bucket
// Region is the region of the bucket that you want to create.
Region model.Region
}

// S3BucketCreatorOutput is the output of the CreateBucket method.
Expand Down
9 changes: 4 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/nao1215/rainbow
go 1.19

require (
github.com/aws/aws-sdk-go-v2 v1.24.0
github.com/aws/aws-sdk-go-v2/config v1.26.2
github.com/aws/aws-sdk-go-v2/service/s3 v1.47.7
github.com/charmbracelet/bubbles v0.17.1
Expand All @@ -11,13 +12,11 @@ require (
github.com/google/wire v0.5.0
github.com/muesli/reflow v0.3.0
github.com/muesli/termenv v0.15.2
github.com/shogo82148/pointer v1.3.0
github.com/spf13/cobra v1.8.0
)

require (
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aws/aws-sdk-go-v2 v1.24.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect
Expand Down Expand Up @@ -47,10 +46,10 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.3.8 // indirect
golang.org/x/tools v0.1.12 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.6.0 // indirect
)
14 changes: 6 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,13 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shogo82148/pointer v1.3.0 h1:LW5V2jUAjFNjS8e7k/PgFoh3EavOSB/vvN85aGue5+I=
github.com/shogo82148/pointer v1.3.0/go.mod h1:agZ5JFpavFPXznbWonIvbG78NDfvDTFppe+7o53up5w=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand All @@ -99,10 +97,10 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
18 changes: 17 additions & 1 deletion ui/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (
var (
term = termenv.EnvColorProfile()
subtle = makeFgStyle("241")
dot = colorFg(" • ", "236")
red = makeFgStyle("196")
green = makeFgStyle("46")
yellow = makeFgStyle("226")
)

type (
Expand All @@ -34,3 +36,17 @@ func checkbox(label string, checked bool) string {
}
return fmt.Sprintf("[ ] %s", label)
}

// split splits a string into multiple lines.
// Each line has a maximum length of 80 characters.
func split(s string) []string {
var result []string
for i := 0; i < len(s); i += 80 {
end := i + 80
if end > len(s) {
end = len(s)
}
result = append(result, s[i:end])
}
return result
}
Loading

0 comments on commit bd918f5

Please sign in to comment.