Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix edit set image to parse both tag and digest #5234

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions api/pkg/util/image.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package util

import (
"sigs.k8s.io/kustomize/api/internal/image"
)

// Splits image string name into name, tag and digest
func SplitImageName(imageName string) (name string, tag string, digest string) {
blackjid marked this conversation as resolved.
Show resolved Hide resolved
return image.Split(imageName)
}
79 changes: 38 additions & 41 deletions kustomize/commands/edit/set/setimage.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"sort"
"strings"

"sigs.k8s.io/kustomize/api/pkg/util"
"sigs.k8s.io/kustomize/api/types"

"github.com/spf13/cobra"
Expand All @@ -31,8 +32,10 @@ var (
errImageInvalidArgs = errors.New(`invalid format of image, use one of the following options:
- <image>=<newimage>:<newtag>
- <image>=<newimage>@<digest>
- <image>=<newimage>:<newtag>@<digest>
- <image>=<newimage>
- <image>:<newtag>
- <image>:<newtag>@<digest>
- <image>@<digest>`)
)

Expand Down Expand Up @@ -76,7 +79,7 @@ images:
to the kustomization file if it doesn't exist,
and overwrite the previous ones if the image name exists.

The image tag can only contain alphanumeric, '.', '_' and '-'. Passing * (asterisk) either as the new name,
The image tag can only contain alphanumeric, '.', '_' and '-'. Passing * (asterisk) either as the new name,
the new tag, or the digest will preserve the appropriate values from the kustomization file.
`,
RunE: func(cmd *cobra.Command, args []string) error {
Expand Down Expand Up @@ -204,52 +207,46 @@ func replaceDigest(image types.Image, digest string) types.Image {
}

func parse(arg string) (types.Image, error) {
// matches if there is an image name to overwrite
// <image>=<new-image><:|@><new-tag>
blackjid marked this conversation as resolved.
Show resolved Hide resolved
if s := strings.Split(arg, separator); len(s) == 2 {
p, err := parseOverwrite(s[1], true)
return types.Image{
Name: s[0],
NewName: p.name,
NewTag: p.tag,
Digest: p.digest,
}, err
// matches if there is an image name
// <image>=<new-image>:<new-tag>@<digest>
// supports digest and tag and override the image name
key, value, err := imageArgParse(arg)
if err != nil {
return types.Image{}, err
}

// matches only for <tag|digest> overwrites
// <image><:|@><new-tag>
p, err := parseOverwrite(arg, false)
return types.Image{
Name: p.name,
NewTag: p.tag,
Digest: p.digest,
}, err
}
name, tag, digest := util.SplitImageName(value)
if name == arg {
return types.Image{}, errImageInvalidArgs
}

// parseOverwrite parses the overwrite parameters
// from the given arg into a struct
func parseOverwrite(arg string, overwriteImage bool) (overwrite, error) {
// match <image>@<digest>
if d := strings.Split(arg, "@"); len(d) > 1 {
return overwrite{
name: d[0],
digest: d[1],
}, nil
newImage := types.Image{
NewTag: tag,
Digest: digest,
}

// match <image>:<tag>
if t := pattern.FindStringSubmatch(arg); len(t) == 3 {
return overwrite{
name: t[1],
tag: t[2],
}, nil
if key == "" {
newImage.Name = name
} else {
newImage.Name = key
newImage.NewName = name
}

// match <image>
if len(arg) > 0 && overwriteImage {
return overwrite{
name: arg,
}, nil
return newImage, nil
}

func imageArgParse(arg string) (key string, value string, err error) {
const maxArgsSeparatorCount = 2
const keyAndValueArgsCount = 2

s := strings.SplitN(arg, separator, maxArgsSeparatorCount)
if len(s) == keyAndValueArgsCount {
// If separator is found it returns the key and value
return s[0], s[1], nil
} else if len(s) == 1 {
blackjid marked this conversation as resolved.
Show resolved Hide resolved
// If no separator is found it returns the whole string as value
// and the key is empty
return "", s[0], nil
}
return overwrite{}, errImageInvalidArgs
return "", "", errImageInvalidArgs
}
25 changes: 25 additions & 0 deletions kustomize/commands/edit/set/setimage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,31 @@ func TestSetImage(t *testing.T) {
" name: image1",
}},
},
{
given: given{
args: []string{"my-image1:my-tag@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"},
},
expected: expected{
fileOutput: []string{
"images:",
"- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3",
" name: my-image1",
" newTag: my-tag",
}},
},
{
given: given{
args: []string{"image1=my-image1:my-tag@sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3"},
},
expected: expected{
fileOutput: []string{
"images:",
"- digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3",
" name: image1",
" newName: my-image1",
" newTag: my-tag",
}},
},
{
description: "<image>=<image>",
given: given{
Expand Down