-
Notifications
You must be signed in to change notification settings - Fork 79
/
command.go
153 lines (141 loc) · 4.53 KB
/
command.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Package setpolicy implements "ecr-utils set-policy" commands.
package setpolicy
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
policyFilePath string
setPolicyForce bool
)
func init() {
cobra.EnablePrefixMatching = true
}
// NewCommand implements "ecr-utils set-policy" command.
func NewCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "set-policy",
Short: "ecr-utils set-policy 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(®ions, "regions", nil, "AWS regions to create repository; if empty create for all available regions")
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")
}
d, err := ioutil.ReadFile(policyFilePath)
if err != nil {
lg.Fatal("failed to read policy file", zap.Error(err))
}
policyTxt := string(d)
fmt.Fprintf(os.Stderr, "Policy:\n%s\n\n", policyTxt)
if enablePrompt {
prompt := promptui.Select{
Label: "Ready to set ECR repository policy, 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 'set-policy' [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))
}
repoURI, err := pkg_ecr.SetPolicy(
lg,
ecrSvc,
repoAccountID,
region,
repoName,
policyTxt,
setPolicyForce,
)
if err != nil {
lg.Warn("failed to create", zap.Error(err))
} else {
fmt.Fprintf(os.Stderr, "ECR policy updated %q (%q)\n", repoURI, region)
}
}
}