diff --git a/app/di/wire.go b/app/di/wire.go index b18e095..f360b23 100644 --- a/app/di/wire.go +++ b/app/di/wire.go @@ -17,9 +17,15 @@ import ( // S3App is the application service for S3. type S3App struct { // S3BucketCreator is the usecase for creating a new S3 bucket. - S3BucketCreator usecase.S3BucketCreator + usecase.S3BucketCreator // S3BucketLister is the usecase for listing S3 buckets. - S3BucketLister usecase.S3BucketLister + usecase.S3BucketLister + // S3BucketDeleter is the usecase for deleting a S3 bucket. + usecase.S3BucketDeleter + // S3BucketObjectsLister is the usecase for listing S3 bucket objects. + usecase.S3BucketObjectsLister + // S3BucketObjectsDeleter is the usecase for deleting S3 bucket objects. + usecase.S3BucketObjectsDeleter } // NewS3App creates a new S3App. @@ -30,16 +36,31 @@ func NewS3App(ctx context.Context, profile model.AWSProfile, region model.Region external.S3BucketCreatorSet, external.S3BucketListerSet, external.S3BucketLocationGetterSet, - interactor.S3bucketCreatorSet, - interactor.S3bucketListerSet, + external.S3BucketDeleterSet, + external.S3BucketObjectsListerSet, + external.S3BucketObjectsDeleterSet, + interactor.S3BucketCreatorSet, + interactor.S3BucketListerSet, + interactor.S3BucketDeleterSet, + interactor.S3BucketObjectsListerSet, + interactor.S3BucketObjectsDeleterSet, newS3App, ) return nil, nil } -func newS3App(s3bucketCreator usecase.S3BucketCreator, s3bucketLister usecase.S3BucketLister) *S3App { +func newS3App( + s3BucketCreator usecase.S3BucketCreator, + s3BucketLister usecase.S3BucketLister, + s3BucketDeleter usecase.S3BucketDeleter, + s3BucketObjectsLister usecase.S3BucketObjectsLister, + s3BucketObjectsDeleter usecase.S3BucketObjectsDeleter, +) *S3App { return &S3App{ - S3BucketCreator: s3bucketCreator, - S3BucketLister: s3bucketLister, + S3BucketCreator: s3BucketCreator, + S3BucketLister: s3BucketLister, + S3BucketDeleter: s3BucketDeleter, + S3BucketObjectsLister: s3BucketObjectsLister, + S3BucketObjectsDeleter: s3BucketObjectsDeleter, } } diff --git a/app/di/wire_gen.go b/app/di/wire_gen.go index 587a98f..2646552 100644 --- a/app/di/wire_gen.go +++ b/app/di/wire_gen.go @@ -31,7 +31,13 @@ func NewS3App(ctx context.Context, profile model.AWSProfile, region model.Region s3BucketLister := external.NewS3BucketLister(client) s3BucketLocationGetter := external.NewS3BucketLocationGetter(client) interactorS3BucketLister := interactor.NewS3BucketLister(s3BucketLister, s3BucketLocationGetter) - s3App := newS3App(interactorS3BucketCreator, interactorS3BucketLister) + s3BucketDeleter := external.NewS3BucketDeleter(client) + interactorS3BucketDeleter := interactor.NewS3BucketDeleter(s3BucketDeleter, s3BucketLocationGetter) + s3BucketObjectsLister := external.NewS3BucketObjectsLister(client) + interactorS3BucketObjectsLister := interactor.NewS3BucketObjectsLister(s3BucketObjectsLister) + s3BucketObjectsDeleter := external.NewS3BucketObjectsDeleter(client) + interactorS3BucketObjectsDeleter := interactor.NewS3BucketObjectsDeleter(s3BucketObjectsDeleter) + s3App := newS3App(interactorS3BucketCreator, interactorS3BucketLister, interactorS3BucketDeleter, interactorS3BucketObjectsLister, interactorS3BucketObjectsDeleter) return s3App, nil } @@ -39,15 +45,35 @@ func NewS3App(ctx context.Context, profile model.AWSProfile, region model.Region // S3App is the application service for S3. type S3App struct { - // S3BucketCreator is the usecase for creating a new S3 bucket. - S3BucketCreator usecase.S3BucketCreator + usecase. + // S3BucketCreator is the usecase for creating a new S3 bucket. + S3BucketCreator + usecase.S3BucketLister + usecase.S3BucketDeleter + // S3BucketLister is the usecase for listing S3 buckets. - S3BucketLister usecase.S3BucketLister + + // S3BucketDeleter is the usecase for deleting a S3 bucket. + usecase.S3BucketObjectsLister + // S3BucketObjectsLister is the usecase for listing S3 bucket objects. + usecase.S3BucketObjectsDeleter + + // S3BucketObjectsDeleter is the usecase for deleting S3 bucket objects. + } -func newS3App(s3bucketCreator usecase.S3BucketCreator, s3bucketLister usecase.S3BucketLister) *S3App { +func newS3App( + s3BucketCreator usecase.S3BucketCreator, + s3BucketLister usecase.S3BucketLister, + s3BucketDeleter usecase.S3BucketDeleter, + s3BucketObjectsLister usecase.S3BucketObjectsLister, + s3BucketObjectsDeleter usecase.S3BucketObjectsDeleter, +) *S3App { return &S3App{ - S3BucketCreator: s3bucketCreator, - S3BucketLister: s3bucketLister, + S3BucketCreator: s3BucketCreator, + S3BucketLister: s3BucketLister, + S3BucketDeleter: s3BucketDeleter, + S3BucketObjectsLister: s3BucketObjectsLister, + S3BucketObjectsDeleter: s3BucketObjectsDeleter, } } diff --git a/app/domain/model/s3.go b/app/domain/model/s3.go index fd1bc27..c06c3ee 100644 --- a/app/domain/model/s3.go +++ b/app/domain/model/s3.go @@ -6,6 +6,8 @@ import ( "strings" "time" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/s3/types" "github.com/nao1215/rainbow/utils/errfmt" "github.com/nao1215/rainbow/utils/xregex" ) @@ -244,3 +246,55 @@ func (b BucketSets) Len() int { func (b BucketSets) Empty() bool { return b.Len() == 0 } + +// S3ObjectSets is the set of the S3ObjectSet. +type S3ObjectSets []S3Object + +// Len returns the length of the S3ObjectSets. +func (s S3ObjectSets) Len() int { + return len(s) +} + +// ToS3ObjectIdentifiers converts the S3ObjectSets to the ObjectIdentifiers. +func (s S3ObjectSets) ToS3ObjectIdentifiers() []types.ObjectIdentifier { + var ids []types.ObjectIdentifier + for _, o := range s { + ids = append(ids, *o.ToS3ObjectIdentifier()) + } + return ids +} + +// S3Object is the object in the S3 bucket. +type S3Object struct { + // S3Key is the name of the object. + S3Key S3Key + // VersionID is the version ID for the specific version of the object to delete. + VersionID VersionID +} + +// ToS3ObjectIdentifier converts the S3Object to the ObjectIdentifier. +func (o S3Object) ToS3ObjectIdentifier() *types.ObjectIdentifier { + return &types.ObjectIdentifier{ + Key: aws.String(o.S3Key.String()), + VersionId: aws.String(o.VersionID.String()), + } +} + +// S3Key is the name of the object. +// Replacement must be made for object keys containing special characters (such as carriage returns) when using XML requests. +// For more information, see XML related object key constraints (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html#object-key-xml-related-constraints). +type S3Key string + +// String returns the string representation of the S3Key. +func (k S3Key) String() string { + return string(k) +} + +// VersionID is the version ID for the specific version of the object to delete. +// This functionality is not supported for directory buckets. +type VersionID string + +// String returns the string representation of the VersionID. +func (v VersionID) String() string { + return string(v) +} diff --git a/app/domain/service/s3.go b/app/domain/service/s3.go index 0f3b341..1a4470a 100644 --- a/app/domain/service/s3.go +++ b/app/domain/service/s3.go @@ -20,7 +20,7 @@ type S3BucketCreatorOutput struct{} // S3BucketCreator is the interface that wraps the basic CreateBucket method. type S3BucketCreator interface { - CreateBucket(ctx context.Context, input *S3BucketCreatorInput) (*S3BucketCreatorOutput, error) + CreateS3Bucket(ctx context.Context, input *S3BucketCreatorInput) (*S3BucketCreatorOutput, error) } // S3BucketListerInput is the input of the ListBuckets method. @@ -34,7 +34,7 @@ type S3BucketListerOutput struct { // S3BucketLister is the interface that wraps the basic ListBuckets method. type S3BucketLister interface { - ListBuckets(ctx context.Context, input *S3BucketListerInput) (*S3BucketListerOutput, error) + ListS3Buckets(ctx context.Context, input *S3BucketListerInput) (*S3BucketListerOutput, error) } // S3BucketLocationGetterInput is the input of the GetBucketLocation method. @@ -50,5 +50,54 @@ type S3BucketLocationGetterOutput struct { // S3BucketLocationGetter is the interface that wraps the basic GetBucketLocation method. type S3BucketLocationGetter interface { - GetBucketLocation(ctx context.Context, input *S3BucketLocationGetterInput) (*S3BucketLocationGetterOutput, error) + GetS3BucketLocation(ctx context.Context, input *S3BucketLocationGetterInput) (*S3BucketLocationGetterOutput, error) +} + +// S3BucketDeleterInput is the input of the DeleteBucket method. +type S3BucketDeleterInput struct { + // Bucket is the name of the bucket to delete. + Bucket model.Bucket + // Region is the region of the bucket that you want to delete. + Region model.Region +} + +// S3BucketDeleterOutput is the output of the DeleteBucket method. +type S3BucketDeleterOutput struct{} + +// S3BucketDeleter is the interface that wraps the basic DeleteBucket method. +type S3BucketDeleter interface { + DeleteS3Bucket(ctx context.Context, input *S3BucketDeleterInput) (*S3BucketDeleterOutput, error) +} + +// S3BucketObjectsDeleterInput is the input of the DeleteBucketObjects method. +type S3BucketObjectsDeleterInput struct { + // Bucket is the name of the bucket to delete. + Bucket model.Bucket + // S3ObjectSets is the list of the objects to delete. + S3ObjectSets model.S3ObjectSets +} + +// S3BucketObjectsDeleterOutput is the output of the DeleteBucketObjects method. +type S3BucketObjectsDeleterOutput struct{} + +// S3BucketObjectsDeleter is the interface that wraps the basic DeleteBucketObjects method. +type S3BucketObjectsDeleter interface { + DeleteS3BucketObjects(ctx context.Context, input *S3BucketObjectsDeleterInput) (*S3BucketObjectsDeleterOutput, error) +} + +// S3BucketObjectsListerInput is the input of the ListBucketObjects method. +type S3BucketObjectsListerInput struct { + // Bucket is the name of the bucket to list. + Bucket model.Bucket +} + +// S3BucketObjectsListerOutput is the output of the ListBucketObjects method. +type S3BucketObjectsListerOutput struct { + // Objects is the list of the objects. + Objects model.S3ObjectSets +} + +// S3BucketObjectsLister is the interface that wraps the basic ListBucketObjects method. +type S3BucketObjectsLister interface { + ListS3BucketObjects(ctx context.Context, input *S3BucketObjectsListerInput) (*S3BucketObjectsListerOutput, error) } diff --git a/app/external/s3.go b/app/external/s3.go index c4f3347..d9b0ef8 100644 --- a/app/external/s3.go +++ b/app/external/s3.go @@ -39,8 +39,8 @@ func NewS3BucketCreator(client *s3.Client) *S3BucketCreator { return &S3BucketCreator{client: client} } -// CreateBucket creates a new S3 bucket. -func (c *S3BucketCreator) CreateBucket(ctx context.Context, input *service.S3BucketCreatorInput) (*service.S3BucketCreatorOutput, error) { +// CreateS3Bucket creates a new S3 bucket. +func (c *S3BucketCreator) CreateS3Bucket(ctx context.Context, input *service.S3BucketCreatorInput) (*service.S3BucketCreatorOutput, error) { // If region is us-east-1, you must not specify the location constraint. // If you specify the location constraint in this case, the following error will occur. // [api error InvalidLocationConstraint: The specified location-constraint is not valid] @@ -81,8 +81,8 @@ func NewS3BucketLister(client *s3.Client) *S3BucketLister { return &S3BucketLister{client: client} } -// ListBuckets lists the buckets. -func (c *S3BucketLister) ListBuckets(ctx context.Context, _ *service.S3BucketListerInput) (*service.S3BucketListerOutput, error) { +// ListS3Buckets lists the buckets. +func (c *S3BucketLister) ListS3Buckets(ctx context.Context, _ *service.S3BucketListerInput) (*service.S3BucketListerOutput, error) { out, err := c.client.ListBuckets(ctx, &s3.ListBucketsInput{}) if err != nil { return nil, err @@ -118,8 +118,8 @@ func NewS3BucketLocationGetter(client *s3.Client) *S3BucketLocationGetter { return &S3BucketLocationGetter{client: client} } -// GetBucketLocation gets the location of the bucket. -func (c *S3BucketLocationGetter) GetBucketLocation(ctx context.Context, input *service.S3BucketLocationGetterInput) (*service.S3BucketLocationGetterOutput, error) { +// GetS3BucketLocation gets the location of the bucket. +func (c *S3BucketLocationGetter) GetS3BucketLocation(ctx context.Context, input *service.S3BucketLocationGetterInput) (*service.S3BucketLocationGetterOutput, error) { out, err := c.client.GetBucketLocation(ctx, &s3.GetBucketLocationInput{ Bucket: aws.String(input.Bucket.String()), }) @@ -136,3 +136,110 @@ func (c *S3BucketLocationGetter) GetBucketLocation(ctx context.Context, input *s Region: region, }, nil } + +// S3BucketDeleter implements the S3BucketDeleter interface. +type S3BucketDeleter struct { + client *s3.Client +} + +// S3BucketDeleterSet is a provider set for S3BucketDeleter. +// +//nolint:gochecknoglobals +var S3BucketDeleterSet = wire.NewSet( + NewS3BucketDeleter, + wire.Bind(new(service.S3BucketDeleter), new(*S3BucketDeleter)), +) + +var _ service.S3BucketDeleter = (*S3BucketDeleter)(nil) + +// NewS3BucketDeleter creates a new S3BucketDeleter. +func NewS3BucketDeleter(client *s3.Client) *S3BucketDeleter { + return &S3BucketDeleter{client: client} +} + +// DeleteS3Bucket deletes the bucket. +func (c *S3BucketDeleter) DeleteS3Bucket(ctx context.Context, input *service.S3BucketDeleterInput) (*service.S3BucketDeleterOutput, error) { + _, err := c.client.DeleteBucket(ctx, + &s3.DeleteBucketInput{ + Bucket: aws.String(input.Bucket.String()), + }, + func(o *s3.Options) { + o.Region = input.Region.String() + }) + if err != nil { + return nil, err + } + return &service.S3BucketDeleterOutput{}, nil +} + +// S3BucketObjectsDeleter implements the S3BucketObjectsDeleter interface. +type S3BucketObjectsDeleter struct { + client *s3.Client +} + +// S3BucketObjectsDeleterSet is a provider set for S3BucketObjectsDeleter. +// +//nolint:gochecknoglobals +var S3BucketObjectsDeleterSet = wire.NewSet( + NewS3BucketObjectsDeleter, + wire.Bind(new(service.S3BucketObjectsDeleter), new(*S3BucketObjectsDeleter)), +) + +var _ service.S3BucketObjectsDeleter = (*S3BucketObjectsDeleter)(nil) + +// NewS3BucketObjectsDeleter creates a new S3BucketObjectsDeleter. +func NewS3BucketObjectsDeleter(client *s3.Client) *S3BucketObjectsDeleter { + return &S3BucketObjectsDeleter{client: client} +} + +// DeleteS3BucketObjects deletes the objects in the bucket. +func (c *S3BucketObjectsDeleter) DeleteS3BucketObjects(ctx context.Context, input *service.S3BucketObjectsDeleterInput) (*service.S3BucketObjectsDeleterOutput, error) { + _, err := c.client.DeleteObjects(ctx, &s3.DeleteObjectsInput{ + Bucket: aws.String(input.Bucket.String()), + Delete: &types.Delete{ + Objects: input.S3ObjectSets.ToS3ObjectIdentifiers(), + }, + }) + if err != nil { + return nil, err + } + return &service.S3BucketObjectsDeleterOutput{}, nil +} + +// S3BucketObjectsLister implements the S3BucketObjectsLister interface. +type S3BucketObjectsLister struct { + client *s3.Client +} + +// S3BucketObjectsListerSet is a provider set for S3BucketObjectsLister. +// +//nolint:gochecknoglobals +var S3BucketObjectsListerSet = wire.NewSet( + NewS3BucketObjectsLister, + wire.Bind(new(service.S3BucketObjectsLister), new(*S3BucketObjectsLister)), +) + +var _ service.S3BucketObjectsLister = (*S3BucketObjectsLister)(nil) + +// NewS3BucketObjectsLister creates a new S3BucketObjectsLister. +func NewS3BucketObjectsLister(client *s3.Client) *S3BucketObjectsLister { + return &S3BucketObjectsLister{client: client} +} + +// ListS3BucketObjects lists the objects in the bucket. +func (c *S3BucketObjectsLister) ListS3BucketObjects(ctx context.Context, input *service.S3BucketObjectsListerInput) (*service.S3BucketObjectsListerOutput, error) { + out, err := c.client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{ + Bucket: aws.String(input.Bucket.String()), + }) + if err != nil { + return nil, err + } + + var objects model.S3ObjectSets + for _, o := range out.Contents { + objects = append(objects, model.S3Object{ + S3Key: model.S3Key(*o.Key), + }) + } + return &service.S3BucketObjectsListerOutput{Objects: objects}, nil +} diff --git a/app/interactor/s3.go b/app/interactor/s3.go index d573f46..c032fdc 100644 --- a/app/interactor/s3.go +++ b/app/interactor/s3.go @@ -9,10 +9,10 @@ import ( "github.com/nao1215/rainbow/app/usecase" ) -// S3bucketCreatorSet is a provider set for S3BucketCreator. +// S3BucketCreatorSet is a provider set for S3BucketCreator. // //nolint:gochecknoglobals -var S3bucketCreatorSet = wire.NewSet( +var S3BucketCreatorSet = wire.NewSet( NewS3BucketCreator, wire.Bind(new(usecase.S3BucketCreator), new(*S3BucketCreator)), ) @@ -31,8 +31,8 @@ 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) { +// CreateS3Bucket creates a new S3 bucket. +func (s *S3BucketCreator) CreateS3Bucket(ctx context.Context, input *usecase.S3BucketCreatorInput) (*usecase.S3BucketCreatorOutput, error) { if err := input.Bucket.Validate(); err != nil { return nil, err } @@ -44,16 +44,16 @@ func (s *S3BucketCreator) CreateBucket(ctx context.Context, input *usecase.S3Buc Bucket: input.Bucket, Region: input.Region, } - if _, err := s.S3BucketCreator.CreateBucket(ctx, &in); err != nil { + if _, err := s.S3BucketCreator.CreateS3Bucket(ctx, &in); err != nil { return nil, err } return &usecase.S3BucketCreatorOutput{}, nil } -// S3bucketListerSet is a provider set for S3BucketLister. +// S3BucketListerSet is a provider set for S3BucketLister. // //nolint:gochecknoglobals -var S3bucketListerSet = wire.NewSet( +var S3BucketListerSet = wire.NewSet( NewS3BucketLister, wire.Bind(new(usecase.S3BucketLister), new(*S3BucketLister)), ) @@ -74,9 +74,9 @@ func NewS3BucketLister(l service.S3BucketLister, g service.S3BucketLocationGette } } -// ListBuckets lists the buckets. -func (s *S3BucketLister) ListBuckets(ctx context.Context, _ *usecase.S3BucketListerInput) (*usecase.S3BucketListerOutput, error) { - out, err := s.S3BucketLister.ListBuckets(ctx, &service.S3BucketListerInput{}) +// ListS3Buckets lists the buckets. +func (s *S3BucketLister) ListS3Buckets(ctx context.Context, _ *usecase.S3BucketListerInput) (*usecase.S3BucketListerOutput, error) { + out, err := s.S3BucketLister.ListS3Buckets(ctx, &service.S3BucketListerInput{}) if err != nil { return nil, err } @@ -85,7 +85,7 @@ func (s *S3BucketLister) ListBuckets(ctx context.Context, _ *usecase.S3BucketLis in := service.S3BucketLocationGetterInput{ Bucket: b.Bucket, } - o, err := s.S3BucketLocationGetter.GetBucketLocation(ctx, &in) + o, err := s.S3BucketLocationGetter.GetS3BucketLocation(ctx, &in) if err != nil { return nil, err } @@ -96,3 +96,128 @@ func (s *S3BucketLister) ListBuckets(ctx context.Context, _ *usecase.S3BucketLis Buckets: out.Buckets, }, nil } + +// S3BucketObjectsLister implements the S3BucketObjectsLister interface. +type S3BucketObjectsLister struct { + service.S3BucketObjectsLister +} + +// S3BucketObjectsListerSet is a provider set for S3BucketObjectsLister. +// +//nolint:gochecknoglobals +var S3BucketObjectsListerSet = wire.NewSet( + NewS3BucketObjectsLister, + wire.Bind(new(usecase.S3BucketObjectsLister), new(*S3BucketObjectsLister)), +) + +var _ usecase.S3BucketObjectsLister = (*S3BucketObjectsLister)(nil) + +// NewS3BucketObjectsLister creates a new S3BucketObjectsLister. +func NewS3BucketObjectsLister(l service.S3BucketObjectsLister) *S3BucketObjectsLister { + return &S3BucketObjectsLister{ + S3BucketObjectsLister: l, + } +} + +// ListS3BucketObjects lists the objects in the S3 bucket. +func (s *S3BucketObjectsLister) ListS3BucketObjects(ctx context.Context, input *usecase.S3BucketObjectsListerInput) (*usecase.S3BucketObjectsListerOutput, error) { + if err := input.Bucket.Validate(); err != nil { + return nil, err + } + + out, err := s.S3BucketObjectsLister.ListS3BucketObjects(ctx, &service.S3BucketObjectsListerInput{ + Bucket: input.Bucket, + }) + if err != nil { + return nil, err + } + return &usecase.S3BucketObjectsListerOutput{ + Objects: out.Objects, + }, nil +} + +// S3BucketObjectsDeleter implements the S3BucketObjectsDeleter interface. +type S3BucketObjectsDeleter struct { + service.S3BucketObjectsDeleter +} + +// S3BucketObjectsDeleterSet is a provider set for S3BucketObjectsDeleter. +// +//nolint:gochecknoglobals +var S3BucketObjectsDeleterSet = wire.NewSet( + NewS3BucketObjectsDeleter, + wire.Bind(new(usecase.S3BucketObjectsDeleter), new(*S3BucketObjectsDeleter)), +) + +var _ usecase.S3BucketObjectsDeleter = (*S3BucketObjectsDeleter)(nil) + +// NewS3BucketObjectsDeleter creates a new S3BucketObjectsDeleter. +func NewS3BucketObjectsDeleter(d service.S3BucketObjectsDeleter) *S3BucketObjectsDeleter { + return &S3BucketObjectsDeleter{ + S3BucketObjectsDeleter: d, + } +} + +// DeleteS3BucketObjects deletes the objects in the bucket. +func (s *S3BucketObjectsDeleter) DeleteS3BucketObjects(ctx context.Context, input *usecase.S3BucketObjectsDeleterInput) (*usecase.S3BucketObjectsDeleterOutput, error) { + if err := input.Bucket.Validate(); err != nil { + return nil, err + } + _, err := s.S3BucketObjectsDeleter.DeleteS3BucketObjects(ctx, &service.S3BucketObjectsDeleterInput{ + Bucket: input.Bucket, + S3ObjectSets: input.S3ObjectSets, + }) + if err != nil { + return nil, err + } + return &usecase.S3BucketObjectsDeleterOutput{}, nil +} + +// S3BucketDeleterSet is a provider set for S3BucketDeleter. +// +//nolint:gochecknoglobals +var S3BucketDeleterSet = wire.NewSet( + NewS3BucketDeleter, + wire.Bind(new(usecase.S3BucketDeleter), new(*S3BucketDeleter)), +) + +var _ usecase.S3BucketDeleter = (*S3BucketDeleter)(nil) + +// S3BucketDeleter implements the S3BucketDeleter interface. +type S3BucketDeleter struct { + service.S3BucketLocationGetter + service.S3BucketDeleter +} + +// NewS3BucketDeleter creates a new S3BucketDeleter. +func NewS3BucketDeleter( + s3BucketDeleter service.S3BucketDeleter, + s3BucketLocationGetter service.S3BucketLocationGetter, +) *S3BucketDeleter { + return &S3BucketDeleter{ + S3BucketDeleter: s3BucketDeleter, + S3BucketLocationGetter: s3BucketLocationGetter, + } +} + +// DeleteS3Bucket deletes the bucket. +func (s *S3BucketDeleter) DeleteS3Bucket(ctx context.Context, input *usecase.S3BucketDeleterInput) (*usecase.S3BucketDeleterOutput, error) { + if err := input.Bucket.Validate(); err != nil { + return nil, err + } + + location, err := s.S3BucketLocationGetter.GetS3BucketLocation(ctx, &service.S3BucketLocationGetterInput{ + Bucket: input.Bucket, + }) + if err != nil { + return nil, err + } + + if _, err := s.S3BucketDeleter.DeleteS3Bucket(ctx, &service.S3BucketDeleterInput{ + Bucket: input.Bucket, + Region: location.Region, + }); err != nil { + return nil, err + } + return &usecase.S3BucketDeleterOutput{}, nil +} diff --git a/app/usecase/s3.go b/app/usecase/s3.go index e565bd3..beff4ff 100644 --- a/app/usecase/s3.go +++ b/app/usecase/s3.go @@ -20,7 +20,7 @@ type S3BucketCreatorOutput struct{} // S3BucketCreator is the interface that wraps the basic CreateBucket method. type S3BucketCreator interface { - CreateBucket(ctx context.Context, input *S3BucketCreatorInput) (*S3BucketCreatorOutput, error) + CreateS3Bucket(ctx context.Context, input *S3BucketCreatorInput) (*S3BucketCreatorOutput, error) } // S3BucketListerInput is the input of the ListBuckets method. @@ -34,5 +34,52 @@ type S3BucketListerOutput struct { // S3BucketLister is the interface that wraps the basic ListBuckets method. type S3BucketLister interface { - ListBuckets(ctx context.Context, input *S3BucketListerInput) (*S3BucketListerOutput, error) + ListS3Buckets(ctx context.Context, input *S3BucketListerInput) (*S3BucketListerOutput, error) +} + +// S3BucketObjectsListerInput is the input of the ListObjects method. +type S3BucketObjectsListerInput struct { + // Bucket is the name of the bucket that you want to list objects. + Bucket model.Bucket +} + +// S3BucketObjectsListerOutput is the output of the ListObjects method. +type S3BucketObjectsListerOutput struct { + // Objects is the list of the objects. + Objects model.S3ObjectSets +} + +// S3BucketObjectsLister is the interface that wraps the basic ListObjects method. +type S3BucketObjectsLister interface { + ListS3BucketObjects(ctx context.Context, input *S3BucketObjectsListerInput) (*S3BucketObjectsListerOutput, error) +} + +// S3BucketDeleterInput is the input of the DeleteBucket method. +type S3BucketDeleterInput struct { + // Bucket is the name of the bucket that you want to delete. + Bucket model.Bucket +} + +// S3BucketDeleterOutput is the output of the DeleteBucket method. +type S3BucketDeleterOutput struct{} + +// S3BucketDeleter is the interface that wraps the basic DeleteBucket method. +type S3BucketDeleter interface { + DeleteS3Bucket(ctx context.Context, input *S3BucketDeleterInput) (*S3BucketDeleterOutput, error) +} + +// S3BucketObjectsDeleterInput is the input of the DeleteObjects method. +type S3BucketObjectsDeleterInput struct { + // Bucket is the name of the bucket that you want to delete. + Bucket model.Bucket + // S3ObjectSets is the list of the objects to delete. + S3ObjectSets model.S3ObjectSets +} + +// S3BucketObjectsDeleterOutput is the output of the DeleteObjects method. +type S3BucketObjectsDeleterOutput struct{} + +// S3BucketObjectsDeleter is the interface that wraps the basic DeleteObjects method. +type S3BucketObjectsDeleter interface { + DeleteS3BucketObjects(ctx context.Context, input *S3BucketObjectsDeleterInput) (*S3BucketObjectsDeleterOutput, error) } diff --git a/cmd/subcmd/s3hub/ls.go b/cmd/subcmd/s3hub/ls.go index ac2f9fd..47897bf 100644 --- a/cmd/subcmd/s3hub/ls.go +++ b/cmd/subcmd/s3hub/ls.go @@ -43,7 +43,7 @@ func (l *lsCmd) Parse(cmd *cobra.Command, args []string) error { } func (l *lsCmd) Do() error { - out, err := l.s3hub.S3BucketLister.ListBuckets(l.ctx, &usecase.S3BucketListerInput{}) + out, err := l.s3hub.S3BucketLister.ListS3Buckets(l.ctx, &usecase.S3BucketListerInput{}) if err != nil { return err } diff --git a/cmd/subcmd/s3hub/mb.go b/cmd/subcmd/s3hub/mb.go index b0a53d2..26693a6 100644 --- a/cmd/subcmd/s3hub/mb.go +++ b/cmd/subcmd/s3hub/mb.go @@ -47,7 +47,7 @@ func (m *mbCmd) Parse(cmd *cobra.Command, args []string) error { // Do executes mb command. func (m *mbCmd) Do() error { - _, err := m.S3BucketCreator.CreateBucket(m.ctx, &usecase.S3BucketCreatorInput{ + _, err := m.S3BucketCreator.CreateS3Bucket(m.ctx, &usecase.S3BucketCreatorInput{ Bucket: m.bucket, Region: m.region, }) diff --git a/ui/s3hub.go b/ui/s3hub.go index 918dfb3..49ef74f 100644 --- a/ui/s3hub.go +++ b/ui/s3hub.go @@ -368,7 +368,7 @@ func (m *s3hubCreateBucketModel) createS3BucketCmd() tea.Cmd { } m.state = s3hubCreateBucketStateCreating - if _, err := m.app.S3BucketCreator.CreateBucket(m.ctx, input); err != nil { + if _, err := m.app.S3BucketCreator.CreateS3Bucket(m.ctx, input); err != nil { return errMsg(err) } return createMsg{}