From c3dbcfe7e9dcfb2825ed648a57c075dacb03beff Mon Sep 17 00:00:00 2001 From: Fabio Gollinucci Date: Sat, 6 Mar 2021 15:24:06 +0100 Subject: [PATCH] Add lifecycle configuration, improve confirmations --- README.md | 10 ++--- cmd/deploy/deploy.go | 48 +++++++++++---------- cmd/remove/remove.go | 91 ++++++++++++++++++++++++++------------- internal/bucket/bucket.go | 19 ++++++++ 4 files changed, 110 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 1894917..acd9941 100644 --- a/README.md +++ b/README.md @@ -401,9 +401,9 @@ using `--upload` flag the zip code will be uploaded to the source bucket instead aws-canary deploy --upload ``` -Source bucket name can be customized using `--source-bucket` parameter: +Source bucket name can be customized using `--sources-bucket` parameter: ```bash -aws-canary deploy --source-bucket my-source-bucket-name --upload +aws-canary deploy --sources-bucket my-sources-bucket-name --upload ``` ## Start canaries (manually execution) @@ -452,14 +452,14 @@ aws-canary remove ``` The related Lambda function and Layer Versions (with name that starts with "cwsyn-") are also cleaned -In order to also remove artifact and source bucket with canaries run the `remove` command with `--delete-artifact-bucket` or `--delete-source-bucket` flag: +In order to also remove artifact and source bucket with canaries run the `remove` command with `--delete-artifact-bucket` or `--delete-sources-bucket` flag: ```bash aws-canary remove --delete-artifact-bucket --artifact-bucket my-bucket-bucket-name # delete only artifact bucket -aws-canary remove --delete-source-bucket --source-bucket my-source-bucket-name +aws-canary remove --delete-sources-bucket --sources-bucket my-sources-bucket-name # delete only source bucket -aws-canary remove --delete-source-bucket --delete-artifact-bucket --source-bucket my-source-bucket-name --artifact-bucket my-bucket-bucket-name +aws-canary remove --delete-sources-bucket --delete-artifact-bucket --sources-bucket my-sources-bucket-name --artifact-bucket my-bucket-bucket-name # delete both ``` diff --git a/cmd/deploy/deploy.go b/cmd/deploy/deploy.go index 5583466..fa4d1dd 100644 --- a/cmd/deploy/deploy.go +++ b/cmd/deploy/deploy.go @@ -32,9 +32,9 @@ func NewCommand(globalFlags []cli.Flag) *cli.Command { EnvVars: []string{"CANARY_ARTIFACT_BUCKET", "CANARY_ARTIFACT_BUCKET_NAME"}, }, &cli.StringFlag{ - Name: "source-bucket", + Name: "sources-bucket", Usage: "Then source code bucket name", - EnvVars: []string{"CANARY_SOURCE_BUCKET", "CANARY_SOURCE_BUCKET_NAME"}, + EnvVars: []string{"CANARY_SOURCES_BUCKET", "CANARY_SOURCES_BUCKET_NAME"}, }, &cli.BoolFlag{ Name: "yes", @@ -72,18 +72,6 @@ func Action(c *cli.Context) error { // Create AWS session ses := aws.NewAwsSession(c) - // Get canaries - canaries, err := config.LoadCanaries(c, ses) - if err != nil { - return err - } - - // Ask canaries selection - canaries, err = config.AskMultipleCanariesSelection(c, *canaries) - if err != nil { - return err - } - // Get caller infos accountID := aws.GetCallerAccountID(ses) region := aws.GetCallerRegion(ses) @@ -100,11 +88,27 @@ func Action(c *cli.Context) error { if err != nil { return err } + err = artifactBucket.DeployLifecycleConfigurationExpires(90) + if err != nil { + return err + } + + // Get canaries + canaries, err := config.LoadCanaries(c, ses) + if err != nil { + return err + } + + // Ask canaries selection + canaries, err = config.AskMultipleCanariesSelection(c, *canaries) + if err != nil { + return err + } // Deploy source bucket var sourceBucket *bucket.Bucket if c.Bool("upload") { - sourceBucketName := c.String("source-bucket") + sourceBucketName := c.String("sources-bucket") if len(sourceBucketName) == 0 { sourceBucketName = fmt.Sprintf("cw-syn-sources-%s-%s", *accountID, *region) } @@ -170,7 +174,7 @@ func Action(c *cli.Context) error { func deployBucket(ses *session.Session, bucketName *string) (*bucket.Bucket, error) { fmt.Println(fmt.Sprintf("Checking bucket %s..", *bucketName)) - // Check artifact bucket + // Check bucket bucket := bucket.New(ses, bucketName) if bucket.IsDeployed() == false { // Ask for deploy @@ -184,13 +188,13 @@ func deployBucket(ses *session.Session, bucketName *string) (*bucket.Bucket, err if confirm == false { return nil, fmt.Errorf("Bucket %s not found", *bucketName) } + } - // Deploy artifact bucket - fmt.Println(fmt.Sprintf("Deploying bucket %s..", *bucketName)) - err := bucket.Deploy() - if err != nil { - return bucket, err - } + // Deploy bucket + fmt.Println(fmt.Sprintf("Deploying bucket %s..", *bucketName)) + err := bucket.Deploy() + if err != nil { + return bucket, err } return bucket, nil diff --git a/cmd/remove/remove.go b/cmd/remove/remove.go index e2a805c..4f7d8b3 100644 --- a/cmd/remove/remove.go +++ b/cmd/remove/remove.go @@ -33,12 +33,12 @@ func NewCommand(globalFlags []cli.Flag) *cli.Command { Usage: "Remove also artifact bucket", }, &cli.StringFlag{ - Name: "source-bucket", + Name: "sources-bucket", Usage: "Then source code bucket name", - EnvVars: []string{"CANARY_SOURCE_BUCKET", "CANARY_SOURCE_BUCKET_NAME"}, + EnvVars: []string{"CANARY_SOURCES_BUCKET", "CANARY_SOURCES_BUCKET_NAME"}, }, &cli.BoolFlag{ - Name: "delete-source-bucket", + Name: "delete-sources-bucket", Usage: "Remove also source bucket", }, &cli.BoolFlag{ @@ -54,35 +54,11 @@ func NewCommand(globalFlags []cli.Flag) *cli.Command { // Action contain the command flow func Action(c *cli.Context) error { + var err error + // Create AWS session ses := aws.NewAwsSession(c) - // Get canaries - canaries, err := config.LoadCanaries(c, ses) - if err != nil { - return err - } - - // Ask canaries selection - canaries, err = config.AskMultipleCanariesSelection(c, *canaries) - if err != nil { - return err - } - - // Ask confirmation - if c.Bool("yes") == false { - confirm := false - prompt := &survey.Confirm{ - Message: fmt.Sprintf("Are you sure you want to remove %d canaries?", len(*canaries)), - } - survey.AskOne(prompt, &confirm) - - // Check respose - if confirm == false { - return errors.New("Not confirmed canaries remove, skip operation") - } - } - // Get caller infos accountID := aws.GetCallerAccountID(ses) region := aws.GetCallerRegion(ses) @@ -96,6 +72,13 @@ func Action(c *cli.Context) error { if len(artifactBucketName) == 0 { artifactBucketName = fmt.Sprintf("canary-artifact-%s-%s", *accountID, *region) } + + // Ask confirmation + err = askConfirmation(c, fmt.Sprintf("Are you sure you want to remove artifact bucket %s?", artifactBucketName)) + if err != nil { + return err + } + err = removeBucket(ses, &artifactBucketName) if err != nil { return err @@ -103,17 +86,42 @@ func Action(c *cli.Context) error { } // Remove source bucket - if c.Bool("delete-source-bucket") { - sourceBucketName := c.String("source-bucket") + if c.Bool("delete-sources-bucket") { + sourceBucketName := c.String("sources-bucket") if len(sourceBucketName) == 0 { sourceBucketName = fmt.Sprintf("cw-syn-sources-%s-%s", *accountID, *region) } + + // Ask confirmation + err = askConfirmation(c, fmt.Sprintf("Are you sure you want to remove sources bucket %s?", sourceBucketName)) + if err != nil { + return err + } + err = removeBucket(ses, &sourceBucketName) if err != nil { return err } } + // Get canaries + canaries, err := config.LoadCanaries(c, ses) + if err != nil { + return err + } + + // Ask canaries selection + canaries, err = config.AskMultipleCanariesSelection(c, *canaries) + if err != nil { + return err + } + + // Ask confirmation + err = askConfirmation(c, fmt.Sprintf("Are you sure you want to remove %d canaries?", len(*canaries))) + if err != nil { + return err + } + // Setup wait group for async jobs var waitGroup sync.WaitGroup @@ -226,3 +234,24 @@ func removeSingleCanary(ses *session.Session, canary *canary.Canary, region *str fmt.Println(fmt.Sprintf("[%s] Remove completed!", canary.Name)) return nil } + +func askConfirmation(c *cli.Context, message string) error { + // Check yes flag + if c.Bool("yes") { + return nil + } + + // Ask confirmation + confirm := false + prompt := &survey.Confirm{ + Message: message, + } + survey.AskOne(prompt, &confirm) + + // Check respose + if confirm == false { + return errors.New("Not confirmed canaries remove, skip operation") + } + + return nil +} diff --git a/internal/bucket/bucket.go b/internal/bucket/bucket.go index 5a77d73..efdb294 100644 --- a/internal/bucket/bucket.go +++ b/internal/bucket/bucket.go @@ -69,6 +69,25 @@ func (b *Bucket) Deploy() error { return err } +// DeployLifecycleConfigurationExpires deploy lifecycle configuration for expiration +func (b *Bucket) DeployLifecycleConfigurationExpires(days int64) error { + _, err := b.clients.s3.PutBucketLifecycleConfiguration(&s3.PutBucketLifecycleConfigurationInput{ + Bucket: b.Name, + LifecycleConfiguration: &s3.BucketLifecycleConfiguration{ + Rules: []*s3.LifecycleRule{ + { + Prefix: aws.String(""), + Status: aws.String("Enabled"), + Expiration: &s3.LifecycleExpiration{ + Days: aws.Int64(days), + }, + }, + }, + }, + }) + return err +} + // Empty Bucket func (b *Bucket) Empty() error {