Skip to content

Commit

Permalink
*: add "ecr-utils"
Browse files Browse the repository at this point in the history
Signed-off-by: Gyuho Lee <leegyuho@amazon.com>
  • Loading branch information
gyuho committed Jul 20, 2020
1 parent baa55fb commit 50aa049
Show file tree
Hide file tree
Showing 11 changed files with 518 additions and 13 deletions.
26 changes: 19 additions & 7 deletions CHANGELOG/CHANGELOG-1.4.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@

## [v1.4.8](https://github.com/aws/aws-k8s-tester/releases/tag/v1.4.8) (2020-07)

See [code changes](https://github.com/aws/aws-k8s-tester/compare/v1.4.7...v1.4.8).

### `cmd`

- Add [`cmd/ecr-utils`](https://github.com/aws/aws-k8s-tester/commit/).

### `pkg`

- Change [`pkg/aws/ecr.Check` to return `ok bool`](https://github.com/aws/aws-k8s-tester/commit/e85f7f353d8bccb0462144219679d0945b065d04).
- Set `true` if the repository exists.
- Add [`pkg/aws/ecr.Create`](https://github.com/aws/aws-k8s-tester/commit/e85f7f353d8bccb0462144219679d0945b065d04).
- Add [`pkg/aws/ecr.Delete`](https://github.com/aws/aws-k8s-tester/commit/e85f7f353d8bccb0462144219679d0945b065d04).

### Go

- Compile with [*Go 1.14.6*](https://golang.org/doc/devel/release.html#go1.14).



<hr>
Expand All @@ -14,13 +33,6 @@ See [code changes](https://github.com/aws/aws-k8s-tester/compare/v1.4.6...v1.4.7
- Valid [China region service principals in `eks/ng` and `eks/mng`](https://github.com/aws/aws-k8s-tester/pull/132).
- Fix [`eks/prometheus-grafana`](https://github.com/aws/aws-k8s-tester/issues/131).

### `pkg`

- Change [`pkg/aws/ecr.Check` to return `ok bool`](https://github.com/aws/aws-k8s-tester/commit/e85f7f353d8bccb0462144219679d0945b065d04).
- Set `true` if the repository exists.
- Add [`pkg/aws/ecr.Create`](https://github.com/aws/aws-k8s-tester/commit/e85f7f353d8bccb0462144219679d0945b065d04).
- Add [`pkg/aws/ecr.Delete`](https://github.com/aws/aws-k8s-tester/commit/e85f7f353d8bccb0462144219679d0945b065d04).

### Dependency

- Upgrade [`github.com/aws/aws-sdk-go`](https://github.com/aws/aws-sdk-go/releases) from [`v1.33.6`](https://github.com/aws/aws-sdk-go/releases/tag/v1.33.6) to [`v1.33.7`](https://github.com/aws/aws-sdk-go/releases/tag/v1.33.7).
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ RUN aws --version
ARG RELEASE_VERSION=latest
COPY --from=aws-k8s-tester-builder /go/src/github.com/aws/aws-k8s-tester/bin/aws-k8s-tester-${RELEASE_VERSION}-linux-amd64 /aws-k8s-tester
COPY --from=aws-k8s-tester-builder /go/src/github.com/aws/aws-k8s-tester/bin/ec2-utils-${RELEASE_VERSION}-linux-amd64 /ec2-utils
COPY --from=aws-k8s-tester-builder /go/src/github.com/aws/aws-k8s-tester/bin/ecr-utils-${RELEASE_VERSION}-linux-amd64 /ecr-utils
COPY --from=aws-k8s-tester-builder /go/src/github.com/aws/aws-k8s-tester/bin/eks-utils-${RELEASE_VERSION}-linux-amd64 /eks-utils
COPY --from=aws-k8s-tester-builder /go/src/github.com/aws/aws-k8s-tester/bin/etcd-utils-${RELEASE_VERSION}-linux-amd64 /etcd-utils
COPY --from=aws-k8s-tester-builder /go/src/github.com/aws/aws-k8s-tester/bin/cw-utils-${RELEASE_VERSION}-linux-amd64 /cw-utils
Expand All @@ -38,6 +39,7 @@ RUN aws --version
RUN /aws-k8s-tester version
RUN /cw-utils version
RUN /ec2-utils version
RUN /ecr-utils version
RUN /eks-utils version
RUN /etcd-utils version
RUN /s3-utils version
Expand Down
161 changes: 161 additions & 0 deletions cmd/ecr-utils/create-repo/command.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// Package createrepo implements "ecr-utils create-repo" commands.
package createrepo

import (
"fmt"
"io/ioutil"
"os"
"sort"

pkg_aws "github.com/aws/aws-k8s-tester/pkg/aws"
pkg_ecr "github.com/aws/aws-k8s-tester/pkg/aws/ecr"
"github.com/aws/aws-k8s-tester/pkg/fileutil"
"github.com/aws/aws-k8s-tester/pkg/logutil"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ecr"
"github.com/manifoldco/promptui"
"github.com/spf13/cobra"
"go.uber.org/zap"
)

var (
enablePrompt bool
logLevel string
partition string
repoAccountID string
repoName string
regions []string
imgScanOnPush bool
imgTagMutability string
policyFilePath string
setPolicyForce bool
)

func init() {
cobra.EnablePrefixMatching = true
}

// NewCommand implements "ecr-utils create-repo" command.
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "create-repo",
Short: "ecr-utils create-repo commands",

Run: createFunc,
}
cmd.PersistentFlags().BoolVarP(&enablePrompt, "enable-prompt", "e", true, "'true' to enable prompt mode")
cmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Log level (debug, info, warn, error, dpanic, panic, fatal)")
cmd.PersistentFlags().StringVar(&partition, "partition", "aws", "AWS partition")
cmd.PersistentFlags().StringVar(&repoAccountID, "repo-account-id", "", "AWS repository account ID")
cmd.PersistentFlags().StringVar(&repoName, "repo-name", "", "AWS ECR repository name")
cmd.PersistentFlags().StringSliceVar(&regions, "regions", nil, "AWS regions to create repository; if empty create for all available regions")
cmd.PersistentFlags().BoolVar(&imgScanOnPush, "image-scan-on-push", false, "true to scan images on push")
cmd.PersistentFlags().StringVar(&imgTagMutability, "image-tag-mutability", ecr.ImageTagMutabilityMutable, "MUTABLE to allow tag overwrites")
cmd.PersistentFlags().StringVar(&policyFilePath, "policy-file-path", "", "AWS ECR policy JSON file path")
cmd.PersistentFlags().BoolVar(&setPolicyForce, "set-policy-force", false, "true to force-write ECR repository policy")
return cmd
}

func createFunc(cmd *cobra.Command, args []string) {
defaultRegion := ""
if len(regions) == 0 {
rm, err := pkg_aws.Regions(partition)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to ger regions for partition %q (%v)\n", partition, err)
os.Exit(1)
}
for rv := range rm {
regions = append(regions, rv)
}
sort.Strings(regions)
if _, ok := rm["us-west-2"]; ok {
defaultRegion = "us-west-2"
}
}
if defaultRegion == "" {
defaultRegion = regions[0]
}

lcfg := logutil.GetDefaultZapLoggerConfig()
lcfg.Level = zap.NewAtomicLevelAt(logutil.ConvertToZapLevel(logLevel))
lg, err := lcfg.Build()
if err != nil {
panic(err)
}
ss, stsOutput, _, err := pkg_aws.New(&pkg_aws.Config{
Logger: lg,
DebugAPICalls: logLevel == "debug",
Partition: partition,
Region: defaultRegion,
})
if stsOutput == nil || err != nil {
lg.Fatal("failed to create AWS session and get sts caller identity", zap.Error(err))
}

roleARN := aws.StringValue(stsOutput.Arn)
fmt.Fprintf(os.Stderr, "\nAccount: %q\n", aws.StringValue(stsOutput.Account))
fmt.Fprintf(os.Stderr, "Role Arn: %q\n", roleARN)
fmt.Fprintf(os.Stderr, "UserId: %q\n", aws.StringValue(stsOutput.UserId))
fmt.Fprintf(os.Stderr, "\nRepository Name: %q\n", repoName)
fmt.Fprintf(os.Stderr, "Regions: %q\n\n", regions)

if repoAccountID == "" {
lg.Fatal("empty repo account ID")
}
if repoAccountID != aws.StringValue(stsOutput.Account) {
lg.Fatal("unexpected repo account ID", zap.String("expected", repoAccountID), zap.String("got", aws.StringValue(stsOutput.Account)))
}
if repoName == "" {
lg.Fatal("empty repo name")
}

if enablePrompt {
prompt := promptui.Select{
Label: "Ready to create ECR resources, should we continue?",
Items: []string{
"No, cancel it!",
"Yes, let's create!",
},
}
idx, answer, err := prompt.Run()
if err != nil {
panic(err)
}
if idx != 1 {
fmt.Printf("returning 'create-repo' [index %d, answer %q]\n", idx, answer)
return
}
}

for _, region := range regions {
fmt.Fprintf(os.Stderr, "\n\n********************\n")
ecrSvc := ecr.New(ss, aws.NewConfig().WithRegion(region))
if policyFilePath != "" && !fileutil.Exist(policyFilePath) {
lg.Fatal("ECR repository policy file not found", zap.String("policy-file-path", policyFilePath))
}
policyTxt := ""
if fileutil.Exist(policyFilePath) {
d, err := ioutil.ReadFile(policyFilePath)
if err != nil {
lg.Fatal("failed to read policy file", zap.Error(err))
}
policyTxt = string(d)
}
repoURI, err := pkg_ecr.Create(
lg,
ecrSvc,
repoAccountID,
region,
repoName,
imgScanOnPush,
imgTagMutability,
policyTxt,
setPolicyForce,
)
if err != nil {
lg.Warn("failed to create", zap.Error(err))
} else {
fmt.Fprintf(os.Stderr, "ECR created %q (%q)\n", repoURI, region)
}
}
}
38 changes: 38 additions & 0 deletions cmd/ecr-utils/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// ecr-utils is a set of AWS utilities commands.
package main

import (
"fmt"
"os"

ecr_create_repo "github.com/aws/aws-k8s-tester/cmd/ecr-utils/create-repo"
ecr_set_policy "github.com/aws/aws-k8s-tester/cmd/ecr-utils/set-policy"
"github.com/aws/aws-k8s-tester/cmd/ecr-utils/version"
"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
Use: "ecr-utils",
Short: "AWS utils CLI",
SuggestFor: []string{"ecrutils"},
}

func init() {
cobra.EnablePrefixMatching = true
}

func init() {
rootCmd.AddCommand(
ecr_create_repo.NewCommand(),
ecr_set_policy.NewCommand(),
version.NewCommand(),
)
}

func main() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "ecr-utils failed %v\n", err)
os.Exit(1)
}
os.Exit(0)
}
Loading

0 comments on commit 50aa049

Please sign in to comment.