Skip to content

Commit

Permalink
Merge pull request #13 from nao1215/feat/spare-command
Browse files Browse the repository at this point in the history
introduce spare command
  • Loading branch information
nao1215 authored Dec 31, 2023
2 parents 227e923 + 48bf68a commit 34262af
Show file tree
Hide file tree
Showing 46 changed files with 2,653 additions and 46 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ cover.*
data
localstack
/s3hub
/spare
3 changes: 2 additions & 1 deletion .gitleaksignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
389697647cbf4df63a2d2949f648216025355763:localstack/cache/server.test.pem.key:private-key:1
389697647cbf4df63a2d2949f648216025355763:localstack/cache/server.test.pem:private-key:1
389697647cbf4df63a2d2949f648216025355763:localstack/cache/server.test.pem:private-key:1
21b942e8aebe04827785fe961d4c97fb8323f7ba:doc/spare/README.md:generic-api-key:68
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.PHONY: build test clean changelog tools help docker generate gif

S3HUB = s3hub
SPARE = spare
VERSION = $(shell git describe --tags --abbrev=0)
GO = go
GO_BUILD = $(GO) build
Expand All @@ -16,9 +17,11 @@ GO_LDFLAGS = -ldflags '-X github.com/nao1215/rainbow/version.Version=${VERSION}

build: ## Build binary
env GO111MODULE=on GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO_BUILD) $(GO_LDFLAGS) -o $(S3HUB) cmd/s3hub/main.go
env GO111MODULE=on GOOS=$(GOOS) GOARCH=$(GOARCH) $(GO_BUILD) $(GO_LDFLAGS) -o $(SPARE) cmd/spare/main.go


clean: ## Clean project
-rm -rf $(S3HUB) cover.out cover.html
-rm -rf $(S3HUB) $(SPARE) cover.out cover.html

test: ## Start unit test
env GOOS=$(GOOS) $(GO_TEST) -cover $(GO_PKGROOT) -coverprofile=cover.out
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ The rainbow project is a toolset for managing AWS resources. This project consis
[WIP]
|Name|README|implementation|Description|
|:--|:--|:--|:--|
|[s3hub](./doc/s3hub/README.md)|||user-friendly s3 management tool|
|[s3hub](./doc/s3hub/README.md)|||User-friendly s3 management tool|
|[spare](./doc/spare/README.md)|||Single Page Application Release Easily|

### s3hub example
#### Create a bucket(s)
Expand Down
53 changes: 53 additions & 0 deletions app/di/wire.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,56 @@ func newS3App(
S3BucketObjectsDeleter: s3BucketObjectsDeleter,
}
}

// SpareApp is the application service for spare command.
type SpareApp struct {
// CloudFrontCreator is the usecase for creating CloudFront.
usecase.CloudFrontCreator
// FileUploader is the usecase for uploading a file.
usecase.FileUploader
// S3BucketCreator is the usecase for creating a new S3 bucket.
usecase.S3BucketCreator
// S3BucketPublicAccessBlocker is the usecase for blocking public access to a S3 bucket.
usecase.S3BucketPublicAccessBlocker
// BucketPolicySetter is the usecase for setting a bucket policy.
usecase.S3BucketPolicySetter
}

// NewSpareApp creates a new SpareApp.
func NewSpareApp(ctx context.Context, profile model.AWSProfile, region model.Region) (*SpareApp, error) {
wire.Build(
model.NewAWSConfig,
external.NewCloudFrontClient,
external.CloudFrontCreatorSet,
external.OAICreatorSet,
external.NewS3Client,
external.S3BucketCreatorSet,
external.S3BucketObjectUploaderSet,
external.S3BucketPublicAccessBlockerSet,
external.S3BucketPolicySetterSet,
interactor.CloudFrontCreatorSet,
interactor.FileUploaderSet,
interactor.S3BucketCreatorSet,
interactor.S3BucketPublicAccessBlockerSet,
interactor.S3BucketPolicySetterSet,
newSpareApp,
)
return nil, nil
}

// newSpareApp creates a new SpareApp.
func newSpareApp(
cloudFrontCreator usecase.CloudFrontCreator,
fileUploader usecase.FileUploader,
s3BucketCreator usecase.S3BucketCreator,
s3BucketPublicAccessBlocker usecase.S3BucketPublicAccessBlocker,
s3BucketPolicySetter usecase.S3BucketPolicySetter,
) *SpareApp {
return &SpareApp{
CloudFrontCreator: cloudFrontCreator,
FileUploader: fileUploader,
S3BucketCreator: s3BucketCreator,
S3BucketPublicAccessBlocker: s3BucketPublicAccessBlocker,
S3BucketPolicySetter: s3BucketPolicySetter,
}
}
72 changes: 72 additions & 0 deletions app/di/wire_gen.go

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

98 changes: 98 additions & 0 deletions app/domain/model/domain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package model

import (
"errors"
"fmt"
"net/url"
"strings"

"github.com/nao1215/rainbow/utils/errfmt"
)

// Domain is a type that represents a domain name.
type Domain string

// String returns the string representation of Domain.
func (d Domain) String() string {
return string(d)
}

// Validate validates Domain. If Domain is invalid, it returns an error.
// If domain is empty, it returns nil and the default CloudFront domain will be used.
func (d Domain) Validate() error {
for _, part := range strings.Split(d.String(), ".") {
if !isAlphaNumeric(part) {
return errfmt.Wrap(ErrInvalidDomain, fmt.Sprintf("domain %s is invalid", d))
}
}
return nil
}

// isAlphaNumeric returns true if s is alphanumeric.
func isAlphaNumeric(s string) bool {
for _, r := range s {
if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') && (r < '0' || r > '9') {
return false
}
}
return true
}

// Empty is whether domain is empty
func (d Domain) Empty() bool {
return d == ""
}

// AllowOrigins is list of origins (domain names) that CloudFront can use as
// the value for the Access-Control-Allow-Origin HTTP response header.
type AllowOrigins []Domain

// Validate validates AllowOrigins. If AllowOrigins is invalid, it returns an error.
func (a AllowOrigins) Validate() (err error) {
for _, origin := range a {
if e := origin.Validate(); e != nil {
err = errors.Join(err, e)
}
}
return err
}

// String returns the string representation of AllowOrigins.
func (a AllowOrigins) String() string {
origins := make([]string, 0, len(a))
for _, origin := range a {
if origin.Empty() {
continue
}
origins = append(origins, origin.String())
}
return strings.Join(origins, ",")
}

// Endpoint is a type that represents an endpoint.
type Endpoint string

// String returns the string representation of Endpoint.
func (e Endpoint) String() string {
return string(e)
}

// Validate validates Endpoint. If Endpoint is invalid, it returns an error.
func (e Endpoint) Validate() error {
if e == "" {
return errfmt.Wrap(ErrInvalidEndpoint, "endpoint is empty")
}

parsedURL, err := url.Parse(e.String())
if err != nil {
return errfmt.Wrap(ErrInvalidDomain, err.Error())
}
host := parsedURL.Host
if host == "" || parsedURL.Scheme == "" {
return errfmt.Wrap(ErrInvalidDomain, host)
}
return nil
}

// DebugLocalstackEndpoint is the endpoint for localstack. It's used for testing.
const DebugLocalstackEndpoint = "http://localhost:4566"
Loading

0 comments on commit 34262af

Please sign in to comment.