Skip to content
This repository was archived by the owner on Nov 1, 2022. It is now read-only.

Parse image refs in HelmReleases with >2 elements #2620

Merged
merged 1 commit into from
Nov 19, 2019
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
160 changes: 86 additions & 74 deletions pkg/cluster/kubernetes/resource/helmrelease.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,46 +240,52 @@ func interpretAsContainer(m mapper) (image.Ref, ImageSetter, bool) {
case string:
// container:
// image: 'repo/image:tag'
imageRef, err := image.ParseRef(img)
if err == nil {
var reggy bool
if registry, ok := m.get("registry"); ok {
// container:
// registry: registry.com
// image: repo/foo
if registryStr, ok := registry.(string); ok {
reggy = true
imageRef.Domain = registryStr
}
fullImgStr := img

var reggy bool
// container:
// registry: registry.com
// image: repo/foo
if registry, ok := m.get("registry"); ok {
if registryStr, ok := registry.(string); ok {
reggy = true
fullImgStr = registryStr + "/" + fullImgStr
}
var taggy bool
if tag, ok := m.get("tag"); ok {
// container:
// image: repo/foo
// tag: v1
if tagStr, ok := tag.(string); ok {
taggy = true
imageRef.Tag = tagStr
}
}

var taggy bool
// container:
// image: repo/foo
// tag: v1
if tag, ok := m.get("tag"); ok {
if tagStr, ok := tag.(string); ok {
taggy = true
fullImgStr = fullImgStr + ":" + tagStr
}
return imageRef, func(ref image.Ref) {
switch {
case (reggy && taggy):
m.set("registry", ref.Domain)
m.set("image", ref.Image)
m.set("tag", ref.Tag)
return
case reggy:
m.set("registry", ref.Domain)
m.set("image", ref.Name.Image+":"+ref.Tag)
case taggy:
m.set("image", ref.Name.String())
m.set("tag", ref.Tag)
default:
m.set("image", ref.String())
}
}, true
}

imageRef, err := image.ParseRef(fullImgStr)
if err != nil {
return image.Ref{}, nil, false
}

return imageRef, func(ref image.Ref) {
switch {
case reggy && taggy:
m.set("registry", ref.Domain)
m.set("image", ref.Image)
m.set("tag", ref.Tag)
return
case reggy:
m.set("registry", ref.Domain)
m.set("image", ref.Name.Image+":"+ref.Tag)
case taggy:
m.set("image", ref.Name.String())
m.set("tag", ref.Tag)
default:
m.set("image", ref.String())
}
}, true
case map[string]interface{}:
return interpretAsImage(stringMap(img))
case map[interface{}]interface{}:
Expand All @@ -300,46 +306,52 @@ func interpretAsImage(m mapper) (image.Ref, ImageSetter, bool) {
// image:
// repository: repo/foo
if imgStr, ok := imgRepo.(string); ok {
imageRef, err := image.ParseRef(imgStr)
if err == nil {
var reggy bool
// image:
// registry: registry.com
// repository: repo/foo
if registry, ok := m.get("registry"); ok {
if registryStr, ok := registry.(string); ok {
reggy = true
imageRef.Domain = registryStr
}
fullImgStr := imgStr

var reggy bool
// image:
// registry: registry.com
// repository: repo/foo
if registry, ok := m.get("registry"); ok {
if registryStr, ok := registry.(string); ok {
reggy = ok
fullImgStr = registryStr + "/" + fullImgStr
}
var taggy bool
// image:
// repository: repo/foo
// tag: v1
if tag, ok := m.get("tag"); ok {
if tagStr, ok := tag.(string); ok {
taggy = true
imageRef.Tag = tagStr
}
}

var taggy bool
// image:
// repository: repo/foo
// tag: v1
if tag, ok := m.get("tag"); ok {
if tagStr, ok := tag.(string); ok {
taggy = ok
fullImgStr = fullImgStr + ":" + tagStr
}
return imageRef, func(ref image.Ref) {
switch {
case (reggy && taggy):
m.set("registry", ref.Domain)
m.set("repository", ref.Image)
m.set("tag", ref.Tag)
return
case reggy:
m.set("registry", ref.Domain)
m.set("repository", ref.Name.Image+":"+ref.Tag)
case taggy:
m.set("repository", ref.Name.String())
m.set("tag", ref.Tag)
default:
m.set("repository", ref.String())
}
}, true
}

imageRef, err := image.ParseRef(fullImgStr)
if err != nil {
return image.Ref{}, nil, false
}

return imageRef, func(ref image.Ref) {
switch {
case reggy && taggy:
m.set("registry", ref.Domain)
m.set("repository", ref.Image)
m.set("tag", ref.Tag)
return
case reggy:
m.set("registry", ref.Domain)
m.set("repository", ref.Name.Image+":"+ref.Tag)
case taggy:
m.set("repository", ref.Name.String())
m.set("tag", ref.Tag)
default:
m.set("repository", ref.String())
}
}, true
}

return image.Ref{}, nil, false
Expand Down
77 changes: 77 additions & 0 deletions pkg/cluster/kubernetes/resource/helmrelease_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -716,6 +716,83 @@ spec:
}
}

func TestParseNamedImageObjectFormatWithRegistryAndMultiElementImage(t *testing.T) {
expectedContainer := "db"
expectedRegistry := "registry.com"
expectedImageName := "public/bitnami/ghost"
expectedImageTag := "1.21.5-r0"
expectedImage := expectedRegistry + "/" + expectedImageName + ":" + expectedImageTag

doc := `---
apiVersion: helm.fluxcd.io/v1
kind: HelmRelease
metadata:
name: ghost
namespace: ghost
labels:
chart: ghost
spec:
chart:
git: git@github.com:fluxcd/flux-get-started
ref: master
path: charts/ghost
values:
other:
not: "containing image"
` + expectedContainer + `:
first: post
image:
registry: ` + expectedRegistry + `
repository: ` + expectedImageName + `
tag: ` + expectedImageTag + `
persistence:
enabled: false
`

resources, err := ParseMultidoc([]byte(doc), "test")
if err != nil {
t.Fatal(err)
}
res, ok := resources["ghost:helmrelease/ghost"]
if !ok {
t.Fatalf("expected resource not found; instead got %#v", resources)
}
hr, ok := res.(resource.Workload)
if !ok {
t.Fatalf("expected resource to be a Workload, instead got %#v", res)
}

containers := hr.Containers()
if len(containers) != 1 {
t.Fatalf("expected 1 container; got %#v", containers)
}
image := containers[0].Image.String()
if image != expectedImage {
t.Errorf("expected container image %q, got %q", expectedImage, image)
}
if containers[0].Name != expectedContainer {
t.Errorf("expected container name %q, got %q", expectedContainer, containers[0].Name)
}

newImage := containers[0].Image.WithNewTag("some-other-tag")
newImage.Domain = "someotherregistry.com"
if err := hr.SetContainerImage(expectedContainer, newImage); err != nil {
t.Error(err)
}

containers = hr.Containers()
if len(containers) != 1 {
t.Fatalf("expected 1 container; got %#v", containers)
}
image = containers[0].Image.String()
if image != newImage.String() {
t.Errorf("expected container image %q, got %q", newImage.String(), image)
}
if containers[0].Name != expectedContainer {
t.Errorf("expected container name %q, got %q", expectedContainer, containers[0].Name)
}
}

func TestParseNamedImageObjectFormatWithRegistryWitoutTag(t *testing.T) {
expectedContainer := "db"
expectedRegistry := "registry.com"
Expand Down