Skip to content
This repository was archived by the owner on Jan 8, 2024. It is now read-only.

Commit 3073a71

Browse files
plugin/ecr-pull: update ecr-pull to support doing entrypoint injection
go-fmt + hcl gen
1 parent 16bf13f commit 3073a71

File tree

23 files changed

+223
-10
lines changed

23 files changed

+223
-10
lines changed

builtin/aws/alb/plugin.pb.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builtin/aws/ami/plugin.pb.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builtin/aws/ec2/plugin.pb.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builtin/aws/ecr/mapper.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,15 @@ func ECRImageMapper(src *Image) *docker.Image {
1212
return &docker.Image{
1313
Image: src.Image,
1414
Tag: src.Tag,
15-
1615
Location: &docker.Image_Registry{
1716
Registry: &docker.Image_RegistryLocation{},
1817
},
1918
}
2019
}
20+
21+
func DockerToEcrImageMapper(src *docker.Image) *Image {
22+
return &Image{
23+
Image: src.Image,
24+
Tag: src.Tag,
25+
}
26+
}

builtin/aws/ecr/plugin.pb.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builtin/aws/ecr/pull/builder.go

Lines changed: 150 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,18 @@ import (
1717
"github.com/aws/aws-sdk-go/aws"
1818
awsecr "github.com/aws/aws-sdk-go/service/ecr"
1919
"github.com/aws/aws-sdk-go/service/lambda"
20+
"github.com/hashicorp/waypoint-plugin-sdk/component"
2021
"github.com/hashicorp/waypoint-plugin-sdk/docs"
2122
"github.com/hashicorp/waypoint-plugin-sdk/terminal"
2223
"github.com/hashicorp/waypoint/builtin/aws/ecr"
2324
"github.com/hashicorp/waypoint/builtin/aws/utils"
2425

26+
"encoding/base64"
27+
"encoding/json"
28+
29+
wpdocker "github.com/hashicorp/waypoint/builtin/docker"
30+
wpdockerpull "github.com/hashicorp/waypoint/builtin/docker/pull"
31+
2532
validation "github.com/go-ozzo/ozzo-validation/v4"
2633
)
2734

@@ -35,12 +42,22 @@ func (b *Builder) BuildFunc() interface{} {
3542
return b.Build
3643
}
3744

45+
// BuildFunc implements component.BuilderODR
46+
func (b *Builder) BuildODRFunc() interface{} {
47+
return b.BuildODR
48+
}
49+
3850
// Config is the configuration structure for the registry.
3951
type Config struct {
4052
Region string `hcl:"region,optional"`
4153
Repository string `hcl:"repository,attr"`
4254
Tag string `hcl:"tag,attr"`
4355
ForceArchitecture string `hcl:"force_architecture,optional"`
56+
DisableCEB bool `hcl:"disable_entrypoint,optional"`
57+
}
58+
59+
type authInfo struct {
60+
Base64Token *string
4461
}
4562

4663
func (b *Builder) Documentation() (*docs.Documentation, error) {
@@ -150,7 +167,125 @@ func (b *Builder) Config() (interface{}, error) {
150167

151168
// Build
152169
func (b *Builder) Build(ctx context.Context, ui terminal.UI, log hclog.Logger) (*ecr.Image, error) {
170+
sg := ui.StepGroup()
171+
ecrImage, buildAuthInfo, err := b.getErcImage(ctx, ui, log, sg)
172+
if err != nil {
173+
return nil, err
174+
}
175+
176+
if b.config.DisableCEB {
177+
return ecrImage, nil
178+
}
179+
180+
repoUser, repoPass, err := credentialsFromEcr(*buildAuthInfo.Base64Token)
181+
if err != nil {
182+
return nil, err
183+
}
184+
185+
// Use the authorization token to create the base64 package that
186+
// Docker requires to perform authentication.
187+
authInfo := map[string]string{
188+
"username": repoUser,
189+
"password": repoPass,
190+
}
191+
192+
authData, err := json.Marshal(authInfo)
193+
if err != nil {
194+
return nil, err
195+
}
196+
encodedAuth := base64.StdEncoding.EncodeToString(authData)
197+
198+
pullBuilder := &wpdockerpull.Builder{}
199+
raw, err := pullBuilder.Config()
200+
if err != nil {
201+
return nil, err
202+
}
203+
pullConfig := raw.(*wpdockerpull.BuilderConfig)
204+
pullConfig.EncodedAuth = encodedAuth
205+
pullConfig.Image = ecrImage.Image
206+
pullConfig.Tag = ecrImage.Tag
207+
pullConfig.DisableCEB = b.config.DisableCEB
208+
209+
img, err := pullBuilder.Build(wpdockerpull.BuildArgs{
210+
Ctx: ctx,
211+
UI: ui,
212+
Log: log,
213+
HasRegistry: true,
214+
})
215+
216+
if err != nil {
217+
return nil, err
218+
}
219+
return ecr.DockerToEcrImageMapper(img), nil
220+
}
221+
222+
// Build
223+
func (b *Builder) BuildODR(ctx context.Context, ui terminal.UI, log hclog.Logger, src *component.Source, ai *wpdocker.AccessInfo) (*ecr.Image, error) {
224+
sg := ui.StepGroup()
225+
ecrImage, buildAuthInfo, err := b.getErcImage(ctx, ui, log, sg)
226+
if err != nil {
227+
return nil, err
228+
}
229+
230+
if b.config.DisableCEB {
231+
return ecrImage, nil
232+
}
233+
234+
repoUser, repoPass, err := credentialsFromEcr(*buildAuthInfo.Base64Token)
235+
if err != nil {
236+
return nil, err
237+
}
238+
239+
// Use the authorization token to create the base64 package that
240+
// Docker requires to perform authentication.
241+
authInfo := map[string]string{
242+
"username": repoUser,
243+
"password": repoPass,
244+
}
245+
246+
authData, err := json.Marshal(authInfo)
247+
if err != nil {
248+
return nil, err
249+
}
250+
encodedAuth := base64.StdEncoding.EncodeToString(authData)
251+
252+
pullBuilder := &wpdockerpull.Builder{}
253+
raw, err := pullBuilder.Config()
254+
if err != nil {
255+
return nil, err
256+
}
257+
pullConfig := raw.(*wpdockerpull.BuilderConfig)
258+
pullConfig.EncodedAuth = encodedAuth
259+
pullConfig.Image = ecrImage.Image
260+
pullConfig.Tag = ecrImage.Tag
261+
pullConfig.DisableCEB = b.config.DisableCEB
153262

263+
img, err := pullBuilder.BuildODR(ctx, ui, src, log, ai)
264+
if err != nil {
265+
return nil, err
266+
}
267+
return ecr.DockerToEcrImageMapper(img), nil
268+
}
269+
270+
// CredentialsFromEcr returns the username and password present in the encoded
271+
// auth string. This encoded auth string is one that users can pass as authentication
272+
// information to registry.
273+
func credentialsFromEcr(encodedAuth string) (string, string, error) {
274+
// Create a reader that base64 decodes our encoded auth and then splits off USER:PASS
275+
dec, err := base64.StdEncoding.DecodeString(encodedAuth)
276+
if err != nil {
277+
return "", "", fmt.Errorf("invalid encoded auth string: %s", encodedAuth[:5])
278+
}
279+
280+
userPassSplit := strings.SplitN(string(dec), ":", 2)
281+
if len(userPassSplit) != 2 {
282+
return "", "", fmt.Errorf("ecr credentials were invalid or did not container user:password. Number of elements in split: %d", len(userPassSplit))
283+
}
284+
285+
return userPassSplit[0], userPassSplit[1], nil
286+
}
287+
288+
func (b *Builder) getErcImage(ctx context.Context, ui terminal.UI, log hclog.Logger, sg terminal.StepGroup) (*ecr.Image, *authInfo, error) {
154289
// If there is no region setup. Try and load it from environment variables.
155290
if b.config.Region == "" {
156291
b.config.Region = os.Getenv("AWS_REGION")
@@ -161,12 +296,11 @@ func (b *Builder) Build(ctx context.Context, ui terminal.UI, log hclog.Logger) (
161296
}
162297

163298
if b.config.Region == "" {
164-
return nil, status.Error(
299+
return nil, nil, status.Error(
165300
codes.FailedPrecondition,
166301
"Please set your aws region in the deployment config, or set the environment variable 'AWS_REGION' or 'AWS_DEFAULT_REGION'")
167302
}
168303

169-
sg := ui.StepGroup()
170304
step := sg.Add("")
171305
defer func() {
172306
if step != nil {
@@ -183,7 +317,7 @@ func (b *Builder) Build(ctx context.Context, ui terminal.UI, log hclog.Logger) (
183317

184318
if err != nil {
185319
log.Error("error connecting to AWS", "error", err)
186-
return nil, err
320+
return nil, nil, err
187321
}
188322

189323
step.Done()
@@ -195,6 +329,15 @@ func (b *Builder) Build(ctx context.Context, ui terminal.UI, log hclog.Logger) (
195329
cfgTag := b.config.Tag
196330
cfgRepository := b.config.Repository
197331

332+
tokenResp, err := ecrsvc.GetAuthorizationToken(&awsecr.GetAuthorizationTokenInput{})
333+
if err != nil {
334+
log.Error("error getting authorization token", "error", err)
335+
return nil, nil, err
336+
}
337+
// docs say the token is good for all registries the user has access to. so just grab the first token
338+
token := tokenResp.AuthorizationData[0].AuthorizationToken
339+
log.Debug("successfully retrieved authorization token")
340+
198341
// should be acceptable to filter images by TAGGED status
199342
imgs, err := ecrsvc.DescribeImages(&awsecr.DescribeImagesInput{
200343
RepositoryName: aws.String(cfgRepository),
@@ -204,12 +347,12 @@ func (b *Builder) Build(ctx context.Context, ui terminal.UI, log hclog.Logger) (
204347
})
205348
if err != nil {
206349
log.Error("error describing images", "error", err, "repository", cfgRepository)
207-
return nil, err
350+
return nil, nil, err
208351
}
209352

210353
if len(imgs.ImageDetails) == 0 {
211354
log.Error("no tagged images found", "repository", cfgRepository)
212-
return nil, status.Error(codes.FailedPrecondition, "No images found")
355+
return nil, nil, status.Error(codes.FailedPrecondition, "No images found")
213356
}
214357
log.Debug("found images", "image count", len(imgs.ImageDetails))
215358

@@ -248,11 +391,11 @@ func (b *Builder) Build(ctx context.Context, ui terminal.UI, log hclog.Logger) (
248391
// if no image was found, return an error
249392
if output.Image == "" {
250393
log.Error("no matching image was found", "tag", cfgTag, "repository", cfgRepository)
251-
return nil, status.Error(codes.FailedPrecondition, "No matching tags found")
394+
return nil, nil, status.Error(codes.FailedPrecondition, "No matching tags found")
252395
}
253396

254397
step.Update("Using image: " + output.Image + ":" + output.Tag)
255398
step.Done()
256399

257-
return &output, nil
400+
return &output, &authInfo{Base64Token: token}, nil
258401
}

builtin/aws/ecr/pull/components/builder/aws-ecr-pull-builder/parameters.hcl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
# This file was generated via `make gen/integrations-hcl`
2+
parameter {
3+
key = "disable_entrypoint"
4+
description = ""
5+
type = "bool"
6+
required = false
7+
}
8+
29
parameter {
310
key = "force_architecture"
411
description = "**Note**: This is a temporary field that enables overriding the `architecture` output attribute. Valid values are: `\"x86_64\"`, `\"arm64\"`"

builtin/aws/ecs/plugin.pb.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builtin/aws/lambda/function_url/plugin.pb.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

builtin/aws/lambda/plugin.pb.go

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)