-
Notifications
You must be signed in to change notification settings - Fork 23
/
action.go
119 lines (101 loc) · 3.5 KB
/
action.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
// SPDX-FileCopyrightText: 2022 SAP SE or an SAP affiliate company and Open Component Model contributors.
//
// SPDX-License-Identifier: Apache-2.0
package actions
import (
"context"
"fmt"
"strings"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/ecr"
"github.com/aws/aws-sdk-go-v2/service/ecr/types"
ocmcreds "github.com/open-component-model/ocm/pkg/contexts/credentials"
"github.com/open-component-model/ocm/pkg/contexts/oci/actions/oci-repository-prepare"
"github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/s3/identity"
"github.com/open-component-model/ocm/pkg/contexts/ocm/plugin/ppi"
"github.com/open-component-model/ocm/pkg/errors"
)
type Action struct{}
var _ ppi.Action = (*Action)(nil)
func (a Action) Name() string {
return oci_repository_prepare.Type
}
func (a Action) Description() string {
return "Create ECR repository if it does not yet exist."
}
func (a Action) ConsumerType() string {
return "AWS"
}
func (a Action) Execute(p ppi.Plugin, spec ppi.ActionSpec, creds ocmcreds.DirectCredentials) (result ppi.ActionResult, err error) {
prepare, ok := spec.(*oci_repository_prepare.ActionSpec)
if !ok {
return nil, fmt.Errorf("invalid spec type %T", spec)
}
path := strings.Split(prepare.Hostname, ".")
if len(path) < 5 {
return nil, fmt.Errorf("unknown ecr host %q", prepare.Hostname)
}
if path[len(path)-4] != "ecr" {
return nil, fmt.Errorf("unknown ecr host %q", prepare.Hostname)
}
region := path[len(path)-3]
ctx := context.Background()
opts := []func(*config.LoadOptions) error{
config.WithRegion(region),
}
var awsCred aws.CredentialsProvider = aws.AnonymousCredentials{}
if creds != nil {
accessKeyID := creds.GetProperty(identity.ATTR_AWS_ACCESS_KEY_ID)
accessSecret := creds.GetProperty(identity.ATTR_AWS_SECRET_ACCESS_KEY)
accessToken := creds.GetProperty(identity.ATTR_TOKEN)
awsCred = credentials.NewStaticCredentialsProvider(accessKeyID, accessSecret, accessToken)
}
opts = append(opts, config.WithCredentialsProvider(awsCred))
cfg, err := config.LoadDefaultConfig(ctx, opts...)
if err != nil {
return nil, fmt.Errorf("failed to load configuration for AWS: %w", err)
}
client := ecr.NewFromConfig(cfg, func(o *ecr.Options) {
// Pass in creds because of https://github.com/aws/aws-sdk-go-v2/issues/1797
o.Credentials = awsCred
o.Region = region
})
msg := fmt.Sprintf("repository %q already exists in region %s", prepare.Repository, region)
in := &ecr.DescribeRepositoriesInput{
RepositoryNames: []string{prepare.Repository},
}
_, err = client.DescribeRepositories(ctx, in)
if err != nil {
var rnf *types.RepositoryNotFoundException
if errors.As(err, &rnf) {
in := &ecr.CreateRepositoryInput{
RepositoryName: aws.String(prepare.Repository),
Tags: []types.Tag{
{
Key: aws.String("ocm"),
Value: aws.String("ecrplugin"),
},
},
}
_, err := client.CreateRepository(ctx, in)
if err != nil {
var re *types.RepositoryAlreadyExistsException
if errors.As(err, &re) {
return oci_repository_prepare.Result(msg), nil
}
return nil, err
}
return oci_repository_prepare.Result(fmt.Sprintf("repository %q created in region %s", prepare.Repository, region)), nil
}
return nil, err
}
return oci_repository_prepare.Result(msg), nil
}
func (a *Action) DefaultSelectors() []string {
return []string{".*\\.dkr\\.ecr\\..*\\.amazonaws\\.com"}
}
func New() ppi.Action {
return &Action{}
}