diff --git a/app/cmd/docker.go b/app/cmd/docker.go index 1810498..6ed9520 100644 --- a/app/cmd/docker.go +++ b/app/cmd/docker.go @@ -28,6 +28,7 @@ var CmdDocker = cli.Command{ &docker.CmdComposeUpOnce, &docker.CmdComposePull, &docker.CmdComposeStop, + &docker.CmdDockerLogin, }, } diff --git a/app/cmd/docker/login.go b/app/cmd/docker/login.go new file mode 100644 index 0000000..44656bc --- /dev/null +++ b/app/cmd/docker/login.go @@ -0,0 +1,32 @@ +package docker + +import ( + "github.com/urfave/cli/v2" + "ledo/app/modules/context" + "ledo/app/modules/docker" +) + +var CmdDockerLogin = cli.Command{ + Name: "login", + Aliases: []string{"l"}, + Usage: "Docker Registry login", + Description: `Login to docker registry`, + Subcommands: []*cli.Command{ + &CmdDockerEcrLogin, + }, +} + +var CmdDockerEcrLogin = cli.Command{ + Name: "ecr", + Aliases: []string{"e"}, + Usage: "AWS Elastic Docker Registry", + Description: `Login to docker registry`, + Action: RunDockerEcrLogin, +} + +func RunDockerEcrLogin(cmd *cli.Context) error { + ctx := context.InitCommand(cmd) + docker.DockerEcrLogin(ctx) + return nil +} + diff --git a/app/modules/aws_ledo/ecr_login.go b/app/modules/aws_ledo/ecr_login.go new file mode 100644 index 0000000..944ace4 --- /dev/null +++ b/app/modules/aws_ledo/ecr_login.go @@ -0,0 +1,36 @@ +package aws_ledo + +import ( + "fmt" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/ecr" + "os" +) + +func getRegion() string { + region, exists := os.LookupEnv("AWS_REGION") + if !exists { + fmt.Printf("AWS_REGION not set and unable to fetch region") + os.Exit(1) + } + return region +} + +func EcrLogin() (*ecr.GetAuthorizationTokenOutput, error) { + var input *ecr.GetAuthorizationTokenInput + var token *ecr.GetAuthorizationTokenOutput + + config := &aws.Config{ + Region: aws.String(getRegion()), + } + sess, _ := session.NewSession(config) + _, err := sess.Config.Credentials.Get() + if err != nil { + return token, err + } + + ecrCtx := ecr.New(sess) + token, err = ecrCtx.GetAuthorizationToken(input) + return token, nil +} diff --git a/app/modules/context/context.go b/app/modules/context/context.go index a2dd426..cf40714 100644 --- a/app/modules/context/context.go +++ b/app/modules/context/context.go @@ -81,3 +81,11 @@ func (lx *LedoContext) ExecCmd(cmd string, cmdArgs []string) error { command.Stderr = os.Stderr return command.Run() } + +func (lx *LedoContext) ExecCmdSilent(cmd string, cmdArgs []string) error { + command := exec.Command(cmd, cmdArgs...) + command.Stdin = os.Stdin + command.Stdout = os.Stdout + command.Stderr = os.Stderr + return command.Run() +} diff --git a/app/modules/docker/login.go b/app/modules/docker/login.go new file mode 100644 index 0000000..b200eaf --- /dev/null +++ b/app/modules/docker/login.go @@ -0,0 +1,40 @@ +package docker + +import ( + b64 "encoding/base64" + "fmt" + "ledo/app/modules/aws_ledo" + "ledo/app/modules/context" + "net/url" + "os" +) + +func trimLeftChars(s string, n int) string { + m := 0 + for i := range s { + if m >= n { + return s[i:] + } + m++ + } + return s[:0] +} + +func DockerEcrLogin(ctx *context.LedoContext) error { + ecr, err := aws_ledo.EcrLogin() + if err != nil { + fmt.Println("Ecr login error: %s", err) + os.Exit(1) + } + password := *ecr.AuthorizationData[0].AuthorizationToken + ecrUrl := *ecr.AuthorizationData[0].ProxyEndpoint + sDec, _ := b64.StdEncoding.DecodeString(password) + registryAddr, err := url.Parse(ecrUrl) + if err != nil { + fmt.Printf("Ecr endpoint addr parse error: %s", err) + os.Exit(1) + } + ctx.ExecCmdSilent("docker", []string{"login", "-u", "AWS", "-p", string(trimLeftChars(string(sDec), 4)), registryAddr.Host}) + + return nil +} diff --git a/go.mod b/go.mod index 3a6182c..63a84bb 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/AlecAivazis/survey/v2 v2.3.2 github.com/Masterminds/semver v1.5.0 github.com/adrg/xdg v0.3.4 + github.com/aws/aws-sdk-go v1.42.15 github.com/sanbornm/go-selfupdate v0.0.0-20210106163404-c9b625feac49 github.com/spf13/viper v1.8.1 github.com/thoas/go-funk v0.9.1 @@ -17,6 +18,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kr/binarydist v0.1.0 // indirect @@ -37,7 +39,7 @@ require ( github.com/subosito/gotenv v1.2.0 // indirect golang.org/x/sys v0.0.0-20210902050250-f475640dd07b // indirect golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect - golang.org/x/text v0.3.5 // indirect + golang.org/x/text v0.3.6 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/inconshreveable/go-update.v0 v0.0.0-20150814200126-d8b0b1d421aa // indirect gopkg.in/ini.v1 v1.62.0 // indirect diff --git a/go.sum b/go.sum index 7371919..3633bc6 100644 --- a/go.sum +++ b/go.sum @@ -51,6 +51,8 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aws/aws-sdk-go v1.42.15 h1:RcUChuF7KzrrTqx9LAzJbLBX00LkUY7cH9T1VdxNdqk= +github.com/aws/aws-sdk-go v1.42.15/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -174,6 +176,10 @@ github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDG github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -224,6 +230,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -365,6 +372,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -429,6 +437,7 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210902050250-f475640dd07b h1:S7hKs0Flbq0bbc9xgYt4stIEG1zNDFqyrPwAX2Wj/sE= golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -441,8 +450,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=