2017-08-27 19:27:28 +00:00
|
|
|
package main
|
|
|
|
|
2017-10-31 06:05:06 +00:00
|
|
|
import (
|
|
|
|
"encoding/base64"
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
|
|
|
"github.com/aws/aws-sdk-go/service/ecr"
|
|
|
|
)
|
|
|
|
|
|
|
|
const defaultRegion = "us-east-1"
|
|
|
|
|
2017-08-27 19:27:28 +00:00
|
|
|
func main() {
|
2017-10-31 06:05:06 +00:00
|
|
|
var (
|
2018-10-26 14:24:12 +00:00
|
|
|
repo = getenv("PLUGIN_REPO")
|
|
|
|
registry = getenv("PLUGIN_REGISTRY")
|
|
|
|
region = getenv("PLUGIN_REGION", "ECR_REGION", "AWS_REGION")
|
|
|
|
key = getenv("PLUGIN_ACCESS_KEY", "ECR_ACCESS_KEY", "AWS_ACCESS_KEY_ID")
|
|
|
|
secret = getenv("PLUGIN_SECRET_KEY", "ECR_SECRET_KEY", "AWS_SECRET_ACCESS_KEY")
|
|
|
|
create = parseBoolOrDefault(false, getenv("PLUGIN_CREATE_REPOSITORY", "ECR_CREATE_REPOSITORY"))
|
2017-10-31 06:05:06 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// set the region
|
|
|
|
if region == "" {
|
|
|
|
region = defaultRegion
|
|
|
|
}
|
|
|
|
|
|
|
|
os.Setenv("AWS_REGION", region)
|
|
|
|
|
2017-11-01 15:09:11 +00:00
|
|
|
if key != "" && secret != "" {
|
|
|
|
os.Setenv("AWS_ACCESS_KEY_ID", key)
|
|
|
|
os.Setenv("AWS_SECRET_ACCESS_KEY", secret)
|
|
|
|
}
|
|
|
|
|
|
|
|
sess, err := session.NewSession(&aws.Config{Region: ®ion})
|
2017-10-31 06:05:06 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(fmt.Sprintf("error creating aws session: %v", err))
|
|
|
|
}
|
|
|
|
|
|
|
|
svc := ecr.New(sess)
|
2018-10-26 14:24:12 +00:00
|
|
|
username, password, defaultRegistry, err := getAuthInfo(svc)
|
|
|
|
|
|
|
|
if registry == "" {
|
|
|
|
registry = defaultRegistry
|
|
|
|
}
|
|
|
|
|
2017-10-31 06:05:06 +00:00
|
|
|
if err != nil {
|
2017-11-01 15:09:11 +00:00
|
|
|
log.Fatal(fmt.Sprintf("error getting ECR auth: %v", err))
|
2017-10-31 06:05:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if !strings.HasPrefix(repo, registry) {
|
|
|
|
repo = fmt.Sprintf("%s/%s", registry, repo)
|
|
|
|
}
|
|
|
|
|
|
|
|
if create {
|
2018-02-10 22:41:49 +00:00
|
|
|
err = ensureRepoExists(svc, trimHostname(repo, registry))
|
2017-10-31 06:05:06 +00:00
|
|
|
if err != nil {
|
2018-02-10 05:58:41 +00:00
|
|
|
log.Fatal(fmt.Sprintf("error creating ECR repo: %v", err))
|
2017-10-31 06:05:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
os.Setenv("PLUGIN_REPO", repo)
|
|
|
|
os.Setenv("PLUGIN_REGISTRY", registry)
|
|
|
|
os.Setenv("DOCKER_USERNAME", username)
|
|
|
|
os.Setenv("DOCKER_PASSWORD", password)
|
|
|
|
|
|
|
|
// invoke the base docker plugin binary
|
|
|
|
cmd := exec.Command("drone-docker")
|
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
if err = cmd.Run(); err != nil {
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-10 22:41:49 +00:00
|
|
|
func trimHostname(repo, registry string) string {
|
|
|
|
repo = strings.TrimPrefix(repo, registry)
|
|
|
|
repo = strings.TrimLeft(repo, "/")
|
|
|
|
return repo
|
2018-02-10 16:41:07 +00:00
|
|
|
}
|
|
|
|
|
2017-10-31 06:05:06 +00:00
|
|
|
func ensureRepoExists(svc *ecr.ECR, name string) (err error) {
|
|
|
|
input := &ecr.CreateRepositoryInput{}
|
|
|
|
input.SetRepositoryName(name)
|
|
|
|
_, err = svc.CreateRepository(input)
|
|
|
|
if err != nil {
|
|
|
|
if aerr, ok := err.(awserr.Error); ok && aerr.Code() == ecr.ErrCodeRepositoryAlreadyExistsException {
|
|
|
|
// eat it, we skip checking for existing to save two requests
|
|
|
|
err = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func getAuthInfo(svc *ecr.ECR) (username, password, registry string, err error) {
|
|
|
|
var result *ecr.GetAuthorizationTokenOutput
|
|
|
|
var decoded []byte
|
|
|
|
|
|
|
|
result, err = svc.GetAuthorizationToken(&ecr.GetAuthorizationTokenInput{})
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
auth := result.AuthorizationData[0]
|
|
|
|
token := *auth.AuthorizationToken
|
|
|
|
decoded, err = base64.StdEncoding.DecodeString(token)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
registry = strings.TrimPrefix(*auth.ProxyEndpoint, "https://")
|
|
|
|
creds := strings.Split(string(decoded), ":")
|
|
|
|
username = creds[0]
|
|
|
|
password = creds[1]
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseBoolOrDefault(defaultValue bool, s string) (result bool) {
|
|
|
|
var err error
|
|
|
|
result, err = strconv.ParseBool(s)
|
|
|
|
if err != nil {
|
|
|
|
result = false
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
2017-08-27 19:27:28 +00:00
|
|
|
|
2017-10-31 06:05:06 +00:00
|
|
|
func getenv(key ...string) (s string) {
|
|
|
|
for _, k := range key {
|
|
|
|
s = os.Getenv(k)
|
|
|
|
if s != "" {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
2017-08-27 19:27:28 +00:00
|
|
|
}
|