Пример #1
0
//NewEcsImageCreator creates an instance of the EcsImageCreator from the docker environment variables, and returns the instance
func NewEcsImageCreator(repo string, region string) (ImageCreator, error) {
	//
	awsClient := ecr.New(session.New(), &aws.Config{Region: aws.String(region)})

	//only try to pull a single repository as a test
	describeRequest := &ecr.DescribeRepositoriesInput{
		MaxResults: aws.Int64(1),
	}

	_, err := awsClient.DescribeRepositories(describeRequest)

	if err != nil {
		return nil, err
	}

	localDocker, err := NewLocalImageCreator(repo)

	if err != nil {
		return nil, err
	}

	return &EcsImageCreator{
		awsClient:     awsClient,
		dockerCreator: localDocker,
	}, nil
}
Пример #2
0
func ExampleECR_BatchGetImage() {
	sess, err := session.NewSession()
	if err != nil {
		fmt.Println("failed to create session,", err)
		return
	}

	svc := ecr.New(sess)

	params := &ecr.BatchGetImageInput{
		ImageIds: []*ecr.ImageIdentifier{ // Required
			{ // Required
				ImageDigest: aws.String("ImageDigest"),
				ImageTag:    aws.String("ImageTag"),
			},
			// More values...
		},
		RepositoryName: aws.String("RepositoryName"), // Required
		RegistryId:     aws.String("RegistryId"),
	}
	resp, err := svc.BatchGetImage(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #3
0
func ExampleECR_PutImage() {
	sess, err := session.NewSession()
	if err != nil {
		fmt.Println("failed to create session,", err)
		return
	}

	svc := ecr.New(sess)

	params := &ecr.PutImageInput{
		ImageManifest:  aws.String("ImageManifest"),  // Required
		RepositoryName: aws.String("RepositoryName"), // Required
		RegistryId:     aws.String("RegistryId"),
	}
	resp, err := svc.PutImage(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #4
0
func ExampleECR_BatchCheckLayerAvailability() {
	sess, err := session.NewSession()
	if err != nil {
		fmt.Println("failed to create session,", err)
		return
	}

	svc := ecr.New(sess)

	params := &ecr.BatchCheckLayerAvailabilityInput{
		LayerDigests: []*string{ // Required
			aws.String("BatchedOperationLayerDigest"), // Required
			// More values...
		},
		RepositoryName: aws.String("RepositoryName"), // Required
		RegistryId:     aws.String("RegistryId"),
	}
	resp, err := svc.BatchCheckLayerAvailability(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #5
0
func ExampleECR_DescribeRepositories() {
	sess, err := session.NewSession()
	if err != nil {
		fmt.Println("failed to create session,", err)
		return
	}

	svc := ecr.New(sess)

	params := &ecr.DescribeRepositoriesInput{
		MaxResults: aws.Int64(1),
		NextToken:  aws.String("NextToken"),
		RegistryId: aws.String("RegistryId"),
		RepositoryNames: []*string{
			aws.String("RepositoryName"), // Required
			// More values...
		},
	}
	resp, err := svc.DescribeRepositories(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #6
0
func ExampleECR_SetRepositoryPolicy() {
	sess, err := session.NewSession()
	if err != nil {
		fmt.Println("failed to create session,", err)
		return
	}

	svc := ecr.New(sess)

	params := &ecr.SetRepositoryPolicyInput{
		PolicyText:     aws.String("RepositoryPolicyText"), // Required
		RepositoryName: aws.String("RepositoryName"),       // Required
		Force:          aws.Bool(true),
		RegistryId:     aws.String("RegistryId"),
	}
	resp, err := svc.SetRepositoryPolicy(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #7
0
func ExampleECR_GetAuthorizationToken() {
	sess, err := session.NewSession()
	if err != nil {
		fmt.Println("failed to create session,", err)
		return
	}

	svc := ecr.New(sess)

	params := &ecr.GetAuthorizationTokenInput{
		RegistryIds: []*string{
			aws.String("RegistryId"), // Required
			// More values...
		},
	}
	resp, err := svc.GetAuthorizationToken(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #8
0
func ExampleECR_ListImages() {
	sess, err := session.NewSession()
	if err != nil {
		fmt.Println("failed to create session,", err)
		return
	}

	svc := ecr.New(sess)

	params := &ecr.ListImagesInput{
		RepositoryName: aws.String("RepositoryName"), // Required
		Filter: &ecr.ListImagesFilter{
			TagStatus: aws.String("TagStatus"),
		},
		MaxResults: aws.Int64(1),
		NextToken:  aws.String("NextToken"),
		RegistryId: aws.String("RegistryId"),
	}
	resp, err := svc.ListImages(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #9
0
func ExampleECR_UploadLayerPart() {
	sess, err := session.NewSession()
	if err != nil {
		fmt.Println("failed to create session,", err)
		return
	}

	svc := ecr.New(sess)

	params := &ecr.UploadLayerPartInput{
		LayerPartBlob:  []byte("PAYLOAD"),            // Required
		PartFirstByte:  aws.Int64(1),                 // Required
		PartLastByte:   aws.Int64(1),                 // Required
		RepositoryName: aws.String("RepositoryName"), // Required
		UploadId:       aws.String("UploadId"),       // Required
		RegistryId:     aws.String("RegistryId"),
	}
	resp, err := svc.UploadLayerPart(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #10
0
func newAuthProvider(c *cli.Context) (dockerauth.AuthProvider, error) {
	awsSession := newConfigProvider(c)
	provider := dockerauth.NewMultiAuthProvider()
	provider.AddProvider(dockerauth.NewECRAuthProvider(func(region string) dockerauth.ECR {
		return ecr.New(awsSession, &aws.Config{Region: aws.String(region)})
	}))

	if dockerConfigPath := c.String(FlagDockerAuth); dockerConfigPath != "" {
		dockerConfigFile, err := os.Open(dockerConfigPath)
		if err != nil {
			return nil, err
		}

		defer dockerConfigFile.Close()

		dockerConfigProvider, err := dockerauth.NewDockerConfigAuthProvider(dockerConfigFile)
		if err != nil {
			return nil, err
		}

		provider.AddProvider(dockerConfigProvider)
	}

	return provider, nil
}
Пример #11
0
func (defaultClientFactory DefaultClientFactory) NewClient(region string) Client {
	awsSession := session.New()

	return &defaultClient{
		ecrClient:       ecr.New(awsSession, &aws.Config{Region: aws.String(region)}),
		credentialCache: defaultClientFactory.buildCredentialsCache(awsSession, region),
	}
}
Пример #12
0
func DockerLogin(ac docker.AuthConfiguration) (string, error) {
	if ac.Email == "" {
		ac.Email = "*****@*****.**"
	}

	// if ECR URL, try Username and Password as IAM keys to get auth token
	if match := regexpECR.FindStringSubmatch(ac.ServerAddress); len(match) > 1 {
		ECR := ecr.New(session.New(), &aws.Config{
			Credentials: credentials.NewStaticCredentials(ac.Username, ac.Password, ""),
			Region:      aws.String(match[2]),
		})

		res, err := ECR.GetAuthorizationToken(&ecr.GetAuthorizationTokenInput{
			RegistryIds: []*string{aws.String(match[1])},
		})

		if err != nil {
			return "", err
		}

		if len(res.AuthorizationData) < 1 {
			return "", fmt.Errorf("no authorization data")
		}

		endpoint := *res.AuthorizationData[0].ProxyEndpoint

		data, err := base64.StdEncoding.DecodeString(*res.AuthorizationData[0].AuthorizationToken)

		if err != nil {
			return "", err
		}

		parts := strings.SplitN(string(data), ":", 2)

		ac.Password = parts[1]
		ac.ServerAddress = endpoint[8:]
		ac.Username = parts[0]
	}

	args := []string{"login", "-e", ac.Email, "-u", ac.Username, "-p", ac.Password, ac.ServerAddress}

	out, err := exec.Command("docker", args...).CombinedOutput()

	// log args with password masked
	args[6] = "*****"
	cmd := fmt.Sprintf("docker %s", strings.Trim(fmt.Sprint(args), "[]"))

	if err != nil {
		fmt.Printf("ns=kernel cn=docker at=DockerLogin state=error step=exec.Command cmd=%q out=%q err=%q\n", cmd, out, err)
	} else {
		fmt.Printf("ns=kernel cn=docker at=DockerLogin state=success step=exec.Command cmd=%q\n", cmd)
	}

	return ac.ServerAddress, err
}
Пример #13
0
// GetECRAuth requests AWS ECR API to get docker.AuthConfiguration token
func GetECRAuth(registry, region string) (result docker.AuthConfiguration, err error) {
	_ecrAuthCache.mu.Lock()
	defer _ecrAuthCache.mu.Unlock()

	if token, ok := _ecrAuthCache.tokens[registry]; ok {
		return token, nil
	}

	defer func() {
		_ecrAuthCache.tokens[registry] = result
	}()

	cfg := &aws.Config{
		Region: aws.String(region),
	}

	if log.StandardLogger().Level >= log.DebugLevel {
		cfg.LogLevel = aws.LogLevel(aws.LogDebugWithRequestErrors)
	}

	split := strings.Split(registry, ".")

	svc := ecr.New(session.New(), cfg)
	params := &ecr.GetAuthorizationTokenInput{
		RegistryIds: []*string{aws.String(split[0])},
	}

	res, err := svc.GetAuthorizationToken(params)
	if err != nil {
		return result, err
	}

	if len(res.AuthorizationData) == 0 {
		return result, nil
	}

	data, err := base64.StdEncoding.DecodeString(*res.AuthorizationData[0].AuthorizationToken)
	if err != nil {
		return result, err
	}

	userpass := strings.Split(string(data), ":")
	if len(userpass) != 2 {
		return result, fmt.Errorf("Cannot parse token got from ECR: %s", string(data))
	}

	result = docker.AuthConfiguration{
		Username:      userpass[0],
		Password:      userpass[1],
		ServerAddress: *res.AuthorizationData[0].ProxyEndpoint,
	}

	return
}
Пример #14
0
// CreateImageRepo create a repository for the image on amazon's ECR(EC2 Container Repository)
// if it doesn't exist as repository needs to be present before pushing and image into it.
func CreateImageRepo(reponame string, params map[string]string) error {
	var (
		accessKey  string
		secretKey  string
		regionName string
		ok         bool
	)

	accessKey, ok = params["accesskey"]
	if !ok {
		accessKey = ""
	}
	secretKey, ok = params["secretkey"]
	if !ok {
		secretKey = ""
	}
	regionName, ok = params["region"]
	if !ok || fmt.Sprint(regionName) == "" {
		return fmt.Errorf("No region parameter provided")
	}
	region := fmt.Sprint(regionName)
	creds := credentials.NewChainCredentials([]credentials.Provider{
		&credentials.StaticProvider{
			Value: credentials.Value{
				AccessKeyID:     accessKey,
				SecretAccessKey: secretKey,
			},
		},
		&credentials.EnvProvider{},
		&credentials.SharedCredentialsProvider{},
		&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(session.New())},
	})
	awsConfig := aws.NewConfig()
	awsConfig.WithCredentials(creds)
	awsConfig.WithRegion(region)
	svc := ecr.New(session.New(awsConfig))

	repoInput := &ecr.CreateRepositoryInput{
		RepositoryName: aws.String(reponame),
	}

	_, err := svc.CreateRepository(repoInput)
	if err != nil {
		if s3Err, ok := err.(awserr.Error); ok && s3Err.Code() == "RepositoryAlreadyExistsException" {
			return nil
		}
		return err
	}
	return nil
}
func ExampleECR_CreateRepository() {
	svc := ecr.New(session.New())

	params := &ecr.CreateRepositoryInput{
		RepositoryName: aws.String("RepositoryName"), // Required
	}
	resp, err := svc.CreateRepository(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
// Enabled implements DockerConfigProvider.Enabled for the AWS token-based implementation.
// For now, it gets activated only if AWS was chosen as the cloud provider.
// TODO: figure how to enable it manually for deployments that are not on AWS but still
// use ECR somehow?
func (p *ecrProvider) Enabled() bool {
	if p.region == "" {
		glog.Errorf("Called ecrProvider.Enabled() with no region set")
		return false
	}

	getter := &ecrTokenGetter{svc: ecr.New(session.New(&aws.Config{
		Credentials: nil,
		Region:      &p.region,
	}))}
	getter.svc.Handlers.Sign.PushFrontNamed(request.NamedHandler{
		Name: "k8s/logger",
		Fn:   awsHandlerLogger,
	})
	p.getter = getter

	return true
}
func ExampleECR_InitiateLayerUpload() {
	svc := ecr.New(session.New())

	params := &ecr.InitiateLayerUploadInput{
		RepositoryName: aws.String("RepositoryName"), // Required
		RegistryId:     aws.String("RegistryId"),
	}
	resp, err := svc.InitiateLayerUpload(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
func ExampleECR_GetDownloadUrlForLayer() {
	svc := ecr.New(session.New())

	params := &ecr.GetDownloadUrlForLayerInput{
		LayerDigest:    aws.String("LayerDigest"),    // Required
		RepositoryName: aws.String("RepositoryName"), // Required
		RegistryId:     aws.String("RegistryId"),
	}
	resp, err := svc.GetDownloadUrlForLayer(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #19
0
// Get a login token for Amazon AWS ECR. Returns username and password
// or an error.
func (c *AwsAccessConfig) EcrGetLogin(ecrUrl string) (string, string, error) {

	exp := regexp.MustCompile("(?:http://|https://|)([0-9]*)\\.dkr\\.ecr\\.(.*)\\.amazonaws\\.com.*")
	splitUrl := exp.FindStringSubmatch(ecrUrl)
	accountId := splitUrl[1]
	region := splitUrl[2]

	log.Println(fmt.Sprintf("Getting ECR token for account: %s in %s..", accountId, region))

	awsConfig, err := c.config(region)
	if err != nil {
		return "", "", err
	}

	session, err := session.NewSession(awsConfig)
	if err != nil {
		return "", "", fmt.Errorf("failed to create session: %s", err)
	}

	service := ecr.New(session)

	params := &ecr.GetAuthorizationTokenInput{
		RegistryIds: []*string{
			aws.String(accountId),
		},
	}
	resp, err := service.GetAuthorizationToken(params)
	if err != nil {
		return "", "", fmt.Errorf(err.Error())
	}

	auth, err := base64.StdEncoding.DecodeString(*resp.AuthorizationData[0].AuthorizationToken)
	if err != nil {
		return "", "", fmt.Errorf("Error decoding ECR AuthorizationToken: %s", err)
	}

	authParts := strings.SplitN(string(auth), ":", 2)
	log.Printf("Successfully got login for ECR: %s", ecrUrl)

	return authParts[0], authParts[1], nil
}
func ExampleECR_ListImages() {
	svc := ecr.New(session.New())

	params := &ecr.ListImagesInput{
		RepositoryName: aws.String("RepositoryName"), // Required
		MaxResults:     aws.Int64(1),
		NextToken:      aws.String("NextToken"),
		RegistryId:     aws.String("RegistryId"),
	}
	resp, err := svc.ListImages(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #21
0
func newAuthProvider(c *cli.Context) (dockerauth.AuthProvider, error) {
	provider := dockerauth.NewMultiAuthProvider()
	provider.AddProvider(dockerauth.NewECRAuthProvider(ecr.New(newConfigProvider(c))))

	if dockerConfigPath := c.String(FlagDockerAuth); dockerConfigPath != "" {
		dockerConfigFile, err := os.Open(dockerConfigPath)
		if err != nil {
			return nil, err
		}

		defer dockerConfigFile.Close()

		dockerConfigProvider, err := dockerauth.NewDockerConfigAuthProvider(dockerConfigFile)
		if err != nil {
			return nil, err
		}

		provider.AddProvider(dockerConfigProvider)
	}

	return provider, nil
}
Пример #22
0
func (p *AWSProvider) authECR(host, access, secret string) (string, string, error) {
	config := p.config()

	if access != "" {
		config.Credentials = credentials.NewStaticCredentials(access, secret, "")
	}

	e := ecr.New(session.New(), config)

	if !regexpECRHost.MatchString(host) {
		return "", "", fmt.Errorf("invalid ECR hostname")
	}

	registry := regexpECRHost.FindStringSubmatch(host)

	res, err := e.GetAuthorizationToken(&ecr.GetAuthorizationTokenInput{
		RegistryIds: []*string{aws.String(registry[1])},
	})

	if err != nil {
		return "", "", err
	}
	if len(res.AuthorizationData) != 1 {
		return "", "", fmt.Errorf("no authorization data")
	}

	token, err := base64.StdEncoding.DecodeString(*res.AuthorizationData[0].AuthorizationToken)
	if err != nil {
		return "", "", err
	}

	parts := strings.SplitN(string(token), ":", 2)
	if len(parts) != 2 {
		return "", "", fmt.Errorf("invalid auth data")
	}

	return parts[0], parts[1], nil
}
Пример #23
0
func imageTagExists(repositoryName, tag, awsRegion, awsRegistryID string) (bool, error) {
	// Default to only look for tagged images
	awsTagStatus := "TAGGED"

	sess, err := session.NewSession()
	if err != nil {
		fmt.Println("failed to create session,", err)
		return false, err
	}

	svc := ecr.New(sess, &aws.Config{Region: aws.String(awsRegion)})

	// Get images
	params := &ecr.ListImagesInput{
		RepositoryName: aws.String(repositoryName), // Required
		Filter: &ecr.ListImagesFilter{
			TagStatus: aws.String(awsTagStatus),
		},
		RegistryId: aws.String(awsRegistryID),
	}

	resp, err := svc.ListImages(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return false, err
	}

	for _, image := range resp.ImageIds {
		if image.ImageTag != nil && *image.ImageTag == tag {
			return true, nil
		}
	}

	return false, nil
}
Пример #24
0
// Enabled implements DockerConfigProvider.Enabled for the AWS token-based implementation.
// For now, it gets activated only if AWS was chosen as the cloud provider.
// TODO: figure how to enable it manually for deployments that are not on AWS but still
// use ECR somehow?
func (p *ecrProvider) Enabled() bool {
	provider, err := cloudprovider.GetCloudProvider(aws_cloud.ProviderName, nil)
	if err != nil {
		glog.Errorf("while initializing AWS cloud provider %v", err)
		return false
	}
	if provider == nil {
		return false
	}

	zones, ok := provider.Zones()
	if !ok {
		glog.Errorf("couldn't get Zones() interface")
		return false
	}
	zone, err := zones.GetZone()
	if err != nil {
		glog.Errorf("while getting zone %v", err)
		return false
	}
	if zone.Region == "" {
		glog.Errorf("Region information is empty")
		return false
	}

	getter := &ecrTokenGetter{svc: ecr.New(session.New(&aws.Config{
		Credentials: nil,
		Region:      &zone.Region,
	}))}
	getter.svc.Handlers.Sign.PushFrontNamed(request.NamedHandler{
		Name: "k8s/logger",
		Fn:   awsHandlerLogger,
	})
	p.getter = getter

	return true
}
func ExampleECR_CompleteLayerUpload() {
	svc := ecr.New(session.New())

	params := &ecr.CompleteLayerUploadInput{
		LayerDigests: []*string{ // Required
			aws.String("LayerDigest"), // Required
			// More values...
		},
		RepositoryName: aws.String("RepositoryName"), // Required
		UploadId:       aws.String("UploadId"),       // Required
		RegistryId:     aws.String("RegistryId"),
	}
	resp, err := svc.CompleteLayerUpload(params)

	if err != nil {
		// Print the error, cast err to awserr.Error to get the Code and
		// Message from an error.
		fmt.Println(err.Error())
		return
	}

	// Pretty-print the response data.
	fmt.Println(resp)
}
Пример #26
0
// Client configures and returns a fully initialized AWSClient
func (c *Config) Client() (interface{}, error) {
	// Get the auth and region. This can fail if keys/regions were not
	// specified and we're attempting to use the environment.
	var errs []error

	log.Println("[INFO] Building AWS region structure")
	err := c.ValidateRegion()
	if err != nil {
		errs = append(errs, err)
	}

	var client AWSClient
	if len(errs) == 0 {
		// store AWS region in client struct, for region specific operations such as
		// bucket storage in S3
		client.region = c.Region

		log.Println("[INFO] Building AWS auth structure")
		creds := GetCredentials(c.AccessKey, c.SecretKey, c.Token, c.Profile, c.CredsFilename)
		// Call Get to check for credential provider. If nothing found, we'll get an
		// error, and we can present it nicely to the user
		cp, err := creds.Get()
		if err != nil {
			if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoCredentialProviders" {
				errs = append(errs, fmt.Errorf(`No valid credential sources found for AWS Provider.
  Please see https://terraform.io/docs/providers/aws/index.html for more information on
  providing credentials for the AWS Provider`))
			} else {
				errs = append(errs, fmt.Errorf("Error loading credentials for AWS Provider: %s", err))
			}
			return nil, &multierror.Error{Errors: errs}
		}

		log.Printf("[INFO] AWS Auth provider used: %q", cp.ProviderName)

		awsConfig := &aws.Config{
			Credentials: creds,
			Region:      aws.String(c.Region),
			MaxRetries:  aws.Int(c.MaxRetries),
			HTTPClient:  cleanhttp.DefaultClient(),
		}

		if logging.IsDebugOrHigher() {
			awsConfig.LogLevel = aws.LogLevel(aws.LogDebugWithHTTPBody)
			awsConfig.Logger = awsLogger{}
		}

		if c.Insecure {
			transport := awsConfig.HTTPClient.Transport.(*http.Transport)
			transport.TLSClientConfig = &tls.Config{
				InsecureSkipVerify: true,
			}
		}

		// Set up base session
		sess := session.New(awsConfig)
		sess.Handlers.Build.PushFrontNamed(addTerraformVersionToUserAgent)

		// Some services exist only in us-east-1, e.g. because they manage
		// resources that can span across multiple regions, or because
		// signature format v4 requires region to be us-east-1 for global
		// endpoints:
		// http://docs.aws.amazon.com/general/latest/gr/sigv4_changes.html
		usEast1Sess := sess.Copy(&aws.Config{Region: aws.String("us-east-1")})

		// Some services have user-configurable endpoints
		awsEc2Sess := sess.Copy(&aws.Config{Endpoint: aws.String(c.Ec2Endpoint)})
		awsElbSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.ElbEndpoint)})
		awsIamSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.IamEndpoint)})
		dynamoSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.DynamoDBEndpoint)})
		kinesisSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.KinesisEndpoint)})

		// These two services need to be set up early so we can check on AccountID
		client.iamconn = iam.New(awsIamSess)
		client.stsconn = sts.New(sess)

		err = c.ValidateCredentials(client.stsconn)
		if err != nil {
			errs = append(errs, err)
			return nil, &multierror.Error{Errors: errs}
		}
		accountId, err := GetAccountId(client.iamconn, client.stsconn, cp.ProviderName)
		if err == nil {
			client.accountid = accountId
		}

		authErr := c.ValidateAccountId(client.accountid)
		if authErr != nil {
			errs = append(errs, authErr)
		}

		client.apigateway = apigateway.New(sess)
		client.autoscalingconn = autoscaling.New(sess)
		client.cfconn = cloudformation.New(sess)
		client.cloudfrontconn = cloudfront.New(sess)
		client.cloudtrailconn = cloudtrail.New(sess)
		client.cloudwatchconn = cloudwatch.New(sess)
		client.cloudwatcheventsconn = cloudwatchevents.New(sess)
		client.cloudwatchlogsconn = cloudwatchlogs.New(sess)
		client.codecommitconn = codecommit.New(usEast1Sess)
		client.codedeployconn = codedeploy.New(sess)
		client.dsconn = directoryservice.New(sess)
		client.dynamodbconn = dynamodb.New(dynamoSess)
		client.ec2conn = ec2.New(awsEc2Sess)
		client.ecrconn = ecr.New(sess)
		client.ecsconn = ecs.New(sess)
		client.efsconn = efs.New(sess)
		client.elasticacheconn = elasticache.New(sess)
		client.elasticbeanstalkconn = elasticbeanstalk.New(sess)
		client.elastictranscoderconn = elastictranscoder.New(sess)
		client.elbconn = elb.New(awsElbSess)
		client.emrconn = emr.New(sess)
		client.esconn = elasticsearch.New(sess)
		client.firehoseconn = firehose.New(sess)
		client.glacierconn = glacier.New(sess)
		client.kinesisconn = kinesis.New(kinesisSess)
		client.kmsconn = kms.New(sess)
		client.lambdaconn = lambda.New(sess)
		client.opsworksconn = opsworks.New(usEast1Sess)
		client.r53conn = route53.New(usEast1Sess)
		client.rdsconn = rds.New(sess)
		client.redshiftconn = redshift.New(sess)
		client.simpledbconn = simpledb.New(sess)
		client.s3conn = s3.New(sess)
		client.sesConn = ses.New(sess)
		client.snsconn = sns.New(sess)
		client.sqsconn = sqs.New(sess)
	}

	if len(errs) > 0 {
		return nil, &multierror.Error{Errors: errs}
	}

	return &client, nil
}
Пример #27
0
// Client configures and returns a fully initialized AWSClient
func (c *Config) Client() (interface{}, error) {
	var client AWSClient

	// Get the auth and region. This can fail if keys/regions were not
	// specified and we're attempting to use the environment.
	var errs []error

	log.Println("[INFO] Building AWS region structure")
	err := c.ValidateRegion()
	if err != nil {
		errs = append(errs, err)
	}

	if len(errs) == 0 {
		// store AWS region in client struct, for region specific operations such as
		// bucket storage in S3
		client.region = c.Region

		log.Println("[INFO] Building AWS auth structure")
		creds := getCreds(c.AccessKey, c.SecretKey, c.Token)
		// Call Get to check for credential provider. If nothing found, we'll get an
		// error, and we can present it nicely to the user
		_, err = creds.Get()
		if err != nil {
			errs = append(errs, fmt.Errorf("Error loading credentials for AWS Provider: %s", err))
			return nil, &multierror.Error{Errors: errs}
		}
		awsConfig := &aws.Config{
			Credentials: creds,
			Region:      aws.String(c.Region),
			MaxRetries:  aws.Int(c.MaxRetries),
			HTTPClient:  cleanhttp.DefaultClient(),
		}

		log.Println("[INFO] Initializing IAM Connection")
		sess := session.New(awsConfig)
		client.iamconn = iam.New(sess)

		err = c.ValidateCredentials(client.iamconn)
		if err != nil {
			errs = append(errs, err)
		}

		// Some services exist only in us-east-1, e.g. because they manage
		// resources that can span across multiple regions, or because
		// signature format v4 requires region to be us-east-1 for global
		// endpoints:
		// http://docs.aws.amazon.com/general/latest/gr/sigv4_changes.html
		usEast1AwsConfig := &aws.Config{
			Credentials: creds,
			Region:      aws.String("us-east-1"),
			MaxRetries:  aws.Int(c.MaxRetries),
			HTTPClient:  cleanhttp.DefaultClient(),
		}
		usEast1Sess := session.New(usEast1AwsConfig)

		awsDynamoDBConfig := *awsConfig
		awsDynamoDBConfig.Endpoint = aws.String(c.DynamoDBEndpoint)

		log.Println("[INFO] Initializing DynamoDB connection")
		dynamoSess := session.New(&awsDynamoDBConfig)
		client.dynamodbconn = dynamodb.New(dynamoSess)

		log.Println("[INFO] Initializing ELB connection")
		client.elbconn = elb.New(sess)

		log.Println("[INFO] Initializing S3 connection")
		client.s3conn = s3.New(sess)

		log.Println("[INFO] Initializing SQS connection")
		client.sqsconn = sqs.New(sess)

		log.Println("[INFO] Initializing SNS connection")
		client.snsconn = sns.New(sess)

		log.Println("[INFO] Initializing RDS Connection")
		client.rdsconn = rds.New(sess)

		awsKinesisConfig := *awsConfig
		awsKinesisConfig.Endpoint = aws.String(c.KinesisEndpoint)

		log.Println("[INFO] Initializing Kinesis Connection")
		kinesisSess := session.New(&awsKinesisConfig)
		client.kinesisconn = kinesis.New(kinesisSess)

		authErr := c.ValidateAccountId(client.iamconn)
		if authErr != nil {
			errs = append(errs, authErr)
		}

		log.Println("[INFO] Initializing Kinesis Firehose Connection")
		client.firehoseconn = firehose.New(sess)

		log.Println("[INFO] Initializing AutoScaling connection")
		client.autoscalingconn = autoscaling.New(sess)

		log.Println("[INFO] Initializing EC2 Connection")
		client.ec2conn = ec2.New(sess)

		log.Println("[INFO] Initializing ECR Connection")
		client.ecrconn = ecr.New(sess)

		log.Println("[INFO] Initializing ECS Connection")
		client.ecsconn = ecs.New(sess)

		log.Println("[INFO] Initializing EFS Connection")
		client.efsconn = efs.New(sess)

		log.Println("[INFO] Initializing ElasticSearch Connection")
		client.esconn = elasticsearch.New(sess)

		log.Println("[INFO] Initializing Route 53 connection")
		client.r53conn = route53.New(usEast1Sess)

		log.Println("[INFO] Initializing Elasticache Connection")
		client.elasticacheconn = elasticache.New(sess)

		log.Println("[INFO] Initializing Lambda Connection")
		client.lambdaconn = lambda.New(sess)

		log.Println("[INFO] Initializing Cloudformation Connection")
		client.cfconn = cloudformation.New(sess)

		log.Println("[INFO] Initializing CloudWatch SDK connection")
		client.cloudwatchconn = cloudwatch.New(sess)

		log.Println("[INFO] Initializing CloudTrail connection")
		client.cloudtrailconn = cloudtrail.New(sess)

		log.Println("[INFO] Initializing CloudWatch Logs connection")
		client.cloudwatchlogsconn = cloudwatchlogs.New(sess)

		log.Println("[INFO] Initializing OpsWorks Connection")
		client.opsworksconn = opsworks.New(usEast1Sess)

		log.Println("[INFO] Initializing Directory Service connection")
		client.dsconn = directoryservice.New(sess)

		log.Println("[INFO] Initializing Glacier connection")
		client.glacierconn = glacier.New(sess)

		log.Println("[INFO] Initializing CodeDeploy Connection")
		client.codedeployconn = codedeploy.New(sess)

		log.Println("[INFO] Initializing CodeCommit SDK connection")
		client.codecommitconn = codecommit.New(usEast1Sess)

		log.Println("[INFO] Initializing Redshift SDK connection")
		client.redshiftconn = redshift.New(sess)

	}

	if len(errs) > 0 {
		return nil, &multierror.Error{Errors: errs}
	}

	return &client, nil
}
Пример #28
0
// Client configures and returns a fully initialized AWSClient
func (c *Config) Client() (interface{}, error) {
	// Get the auth and region. This can fail if keys/regions were not
	// specified and we're attempting to use the environment.
	log.Println("[INFO] Building AWS region structure")
	err := c.ValidateRegion()
	if err != nil {
		return nil, err
	}

	var client AWSClient
	// store AWS region in client struct, for region specific operations such as
	// bucket storage in S3
	client.region = c.Region

	log.Println("[INFO] Building AWS auth structure")
	creds, err := GetCredentials(c)
	if err != nil {
		return nil, err
	}
	// Call Get to check for credential provider. If nothing found, we'll get an
	// error, and we can present it nicely to the user
	cp, err := creds.Get()
	if err != nil {
		if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "NoCredentialProviders" {
			return nil, errors.New(`No valid credential sources found for AWS Provider.
  Please see https://terraform.io/docs/providers/aws/index.html for more information on
  providing credentials for the AWS Provider`)
		}

		return nil, fmt.Errorf("Error loading credentials for AWS Provider: %s", err)
	}

	log.Printf("[INFO] AWS Auth provider used: %q", cp.ProviderName)

	awsConfig := &aws.Config{
		Credentials:      creds,
		Region:           aws.String(c.Region),
		MaxRetries:       aws.Int(c.MaxRetries),
		HTTPClient:       cleanhttp.DefaultClient(),
		S3ForcePathStyle: aws.Bool(c.S3ForcePathStyle),
	}

	if logging.IsDebugOrHigher() {
		awsConfig.LogLevel = aws.LogLevel(aws.LogDebugWithHTTPBody)
		awsConfig.Logger = awsLogger{}
	}

	if c.Insecure {
		transport := awsConfig.HTTPClient.Transport.(*http.Transport)
		transport.TLSClientConfig = &tls.Config{
			InsecureSkipVerify: true,
		}
	}

	// Set up base session
	sess, err := session.NewSession(awsConfig)
	if err != nil {
		return nil, errwrap.Wrapf("Error creating AWS session: {{err}}", err)
	}

	// Removes the SDK Version handler, so we only have the provider User-Agent
	// Ex: "User-Agent: APN/1.0 HashiCorp/1.0 Terraform/0.7.9-dev"
	sess.Handlers.Build.Remove(request.NamedHandler{Name: "core.SDKVersionUserAgentHandler"})
	sess.Handlers.Build.PushFrontNamed(addTerraformVersionToUserAgent)

	if extraDebug := os.Getenv("TERRAFORM_AWS_AUTHFAILURE_DEBUG"); extraDebug != "" {
		sess.Handlers.UnmarshalError.PushFrontNamed(debugAuthFailure)
	}

	// Some services exist only in us-east-1, e.g. because they manage
	// resources that can span across multiple regions, or because
	// signature format v4 requires region to be us-east-1 for global
	// endpoints:
	// http://docs.aws.amazon.com/general/latest/gr/sigv4_changes.html
	usEast1Sess := sess.Copy(&aws.Config{Region: aws.String("us-east-1")})

	// Some services have user-configurable endpoints
	awsEc2Sess := sess.Copy(&aws.Config{Endpoint: aws.String(c.Ec2Endpoint)})
	awsElbSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.ElbEndpoint)})
	awsIamSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.IamEndpoint)})
	awsS3Sess := sess.Copy(&aws.Config{Endpoint: aws.String(c.S3Endpoint)})
	dynamoSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.DynamoDBEndpoint)})
	kinesisSess := sess.Copy(&aws.Config{Endpoint: aws.String(c.KinesisEndpoint)})

	// These two services need to be set up early so we can check on AccountID
	client.iamconn = iam.New(awsIamSess)
	client.stsconn = sts.New(sess)

	if !c.SkipCredsValidation {
		err = c.ValidateCredentials(client.stsconn)
		if err != nil {
			return nil, err
		}
	}

	if !c.SkipRequestingAccountId {
		partition, accountId, err := GetAccountInfo(client.iamconn, client.stsconn, cp.ProviderName)
		if err == nil {
			client.partition = partition
			client.accountid = accountId
		}
	}

	authErr := c.ValidateAccountId(client.accountid)
	if authErr != nil {
		return nil, authErr
	}

	client.acmconn = acm.New(sess)
	client.apigateway = apigateway.New(sess)
	client.appautoscalingconn = applicationautoscaling.New(sess)
	client.autoscalingconn = autoscaling.New(sess)
	client.cfconn = cloudformation.New(sess)
	client.cloudfrontconn = cloudfront.New(sess)
	client.cloudtrailconn = cloudtrail.New(sess)
	client.cloudwatchconn = cloudwatch.New(sess)
	client.cloudwatcheventsconn = cloudwatchevents.New(sess)
	client.cloudwatchlogsconn = cloudwatchlogs.New(sess)
	client.codecommitconn = codecommit.New(usEast1Sess)
	client.codedeployconn = codedeploy.New(sess)
	client.dsconn = directoryservice.New(sess)
	client.dynamodbconn = dynamodb.New(dynamoSess)
	client.ec2conn = ec2.New(awsEc2Sess)
	client.ecrconn = ecr.New(sess)
	client.ecsconn = ecs.New(sess)
	client.efsconn = efs.New(sess)
	client.elasticacheconn = elasticache.New(sess)
	client.elasticbeanstalkconn = elasticbeanstalk.New(sess)
	client.elastictranscoderconn = elastictranscoder.New(sess)
	client.elbconn = elb.New(awsElbSess)
	client.elbv2conn = elbv2.New(awsElbSess)
	client.emrconn = emr.New(sess)
	client.esconn = elasticsearch.New(sess)
	client.firehoseconn = firehose.New(sess)
	client.glacierconn = glacier.New(sess)
	client.kinesisconn = kinesis.New(kinesisSess)
	client.kmsconn = kms.New(sess)
	client.lambdaconn = lambda.New(sess)
	client.lightsailconn = lightsail.New(usEast1Sess)
	client.opsworksconn = opsworks.New(usEast1Sess)
	client.r53conn = route53.New(usEast1Sess)
	client.rdsconn = rds.New(sess)
	client.redshiftconn = redshift.New(sess)
	client.simpledbconn = simpledb.New(sess)
	client.s3conn = s3.New(awsS3Sess)
	client.sesConn = ses.New(sess)
	client.snsconn = sns.New(sess)
	client.sqsconn = sqs.New(sess)
	client.ssmconn = ssm.New(sess)
	client.wafconn = waf.New(sess)

	return &client, nil
}
Пример #29
0
// PushDockerImageToECR pushes a local Docker image to an ECR repository
func PushDockerImageToECR(localImageTag string,
	ecrRepoName string,
	awsSession *session.Session,
	logger *logrus.Logger) (string, error) {

	stsSvc := sts.New(awsSession)
	ecrSvc := ecr.New(awsSession)

	// 1. Get the caller identity s.t. we can get the ECR URL which includes the
	// account name
	stsIdentityOutput, stsIdentityErr := stsSvc.GetCallerIdentity(&sts.GetCallerIdentityInput{})
	if nil != stsIdentityErr {
		return "", stsIdentityErr
	}

	// 2. Create the URL to which we're going to do the push
	localImageTagParts := strings.Split(localImageTag, ":")
	ecrTagValue := fmt.Sprintf("%s.dkr.ecr.%s.amazonaws.com/%s:%s",
		*stsIdentityOutput.Account,
		*awsSession.Config.Region,
		ecrRepoName,
		localImageTagParts[len(localImageTagParts)-1])

	// 3. Tag the local image with the ECR tag
	dockerTagCmd := exec.Command("docker", "tag", localImageTag, ecrTagValue)
	dockerTagCmdErr := runOSCommand(dockerTagCmd, logger)
	if nil != dockerTagCmdErr {
		return "", dockerTagCmdErr
	}

	// 4. Push the image - if that fails attempt to reauthorize with the docker
	// client and try again
	var pushError error
	dockerPushCmd := exec.Command("docker", "push", ecrTagValue)
	pushError = runOSCommand(dockerPushCmd, logger)
	if nil != pushError {
		logger.WithFields(logrus.Fields{
			"Error": pushError,
		}).Info("ECR push failed - reauthorizing")
		ecrAuthTokenResult, ecrAuthTokenResultErr := ecrSvc.GetAuthorizationToken(&ecr.GetAuthorizationTokenInput{})
		if nil != ecrAuthTokenResultErr {
			pushError = ecrAuthTokenResultErr
		} else {
			authData := ecrAuthTokenResult.AuthorizationData[0]
			authToken, authTokenErr := base64.StdEncoding.DecodeString(*authData.AuthorizationToken)
			if nil != authTokenErr {
				pushError = authTokenErr
			} else {
				authTokenString := string(authToken)
				authTokenParts := strings.Split(authTokenString, ":")
				dockerURL := fmt.Sprintf("https://%s.dkr.ecr.%s.amazonaws.com",
					*stsIdentityOutput.Account,
					*awsSession.Config.Region)
				dockerLoginCmd := exec.Command("docker",
					"login",
					"-u",
					authTokenParts[0],
					"-p",
					authTokenParts[1],
					"-e",
					"none",
					dockerURL)
				dockerLoginCmdErr := runOSCommand(dockerLoginCmd, logger)
				if nil != dockerLoginCmdErr {
					pushError = dockerLoginCmdErr
				} else {
					// Try it again...
					dockerRetryPushCmd := exec.Command("docker", "push", ecrTagValue)
					dockerRetryPushCmdErr := runOSCommand(dockerRetryPushCmd, logger)
					pushError = dockerRetryPushCmdErr
				}
			}
		}
	}
	return ecrTagValue, pushError
}
Пример #30
-6
func DockerLogin(ac docker.AuthConfiguration) (string, error) {
	log := Logger.At("DockerLogin").Start()

	if ac.Email == "" {
		ac.Email = "*****@*****.**"
	}

	// if ECR URL, try Username and Password as IAM keys to get auth token
	if match := regexpECR.FindStringSubmatch(ac.ServerAddress); len(match) > 1 {
		ECR := ecr.New(session.New(), &aws.Config{
			Credentials: credentials.NewStaticCredentials(ac.Username, ac.Password, ""),
			Region:      aws.String(match[2]),
		})

		res, err := ECR.GetAuthorizationToken(&ecr.GetAuthorizationTokenInput{
			RegistryIds: []*string{aws.String(match[1])},
		})

		if err != nil {
			return "", err
		}

		if len(res.AuthorizationData) < 1 {
			return "", fmt.Errorf("no authorization data")
		}

		endpoint := *res.AuthorizationData[0].ProxyEndpoint

		data, err := base64.StdEncoding.DecodeString(*res.AuthorizationData[0].AuthorizationToken)

		if err != nil {
			return "", err
		}

		parts := strings.SplitN(string(data), ":", 2)

		ac.Password = parts[1]
		ac.ServerAddress = endpoint[8:]
		ac.Username = parts[0]
	}

	log = log.Namespace("host=%q user=%q", ac.ServerAddress, ac.Username)

	args := []string{"login", "-e", ac.Email, "-u", ac.Username, "-p", ac.Password, ac.ServerAddress}

	if _, err := exec.Command("docker", args...).CombinedOutput(); err != nil {
		log.Error(err)
		return "", err
	}

	log.Success()
	return ac.ServerAddress, nil
}