Skip to content
Permalink
Browse files

chart: split multiple objects inside the same yaml file

An user reported to us that Shipper is not rendering multiple objects
inside the same yaml file (as in, multiple segments separated by a
`---`) in a chart. For instance, the following YAML excerpt will only
result in the first object being rendered, while the second one is
completely ignored:

```
apiVersion: v1
kind: Service
---
apiVersion: v1
kind: Pod
```

This patch is pretty much lifted from Helm itself:
https://github.com/helm/helm/blob/2d77db1/pkg/releaseutil/manifest.go#L37-L59
  • Loading branch information...
juliogreff authored and parhamdoustdar committed Oct 4, 2019
1 parent ec4c7f8 commit 64649145d4e69077c4319b24b3e6262d1f8d690d
Showing with 44 additions and 52 deletions.
  1. +27 −9 pkg/chart/chart.go
  2. +17 −43 pkg/chart/chart_test.go
@@ -2,6 +2,7 @@ package chart

import (
"fmt"
"regexp"
"sort"
"strings"

@@ -53,15 +54,7 @@ func Render(chart *helmchart.Chart, name, ns string, shipperValues *shipper.Char
return nil, fmt.Errorf("could not render the chart: %s", err)
}

objects := make([]string, 0, len(rendered))
for n, o := range rendered {
// It's annoying to ensure that your template doesn't render spurious
// newlines.
o = strings.TrimSpace(o)
if len(o) > 0 && (strings.HasSuffix(n, ".yaml") || strings.HasSuffix(n, ".yml")) {
objects = append(objects, o)
}
}
objects := CollectObjects(rendered)

ks, err := newKindSorter(objects, InstallOrder)
if err != nil {
@@ -71,3 +64,28 @@ func Render(chart *helmchart.Chart, name, ns string, shipperValues *shipper.Char

return ks.Manifests(), nil
}

var sep = regexp.MustCompile("(?:^|\\s*\n)---\\s*")

func CollectObjects(rendered map[string]string) []string {
objects := make([]string, 0, len(rendered))

for n, o := range rendered {
if !strings.HasSuffix(n, ".yaml") && !strings.HasSuffix(n, ".yml") {
continue
}

// Making sure that any extra whitespace in YAML stream doesn't
// interfere in splitting documents correctly.
objs := sep.Split(strings.TrimSpace(o), -1)

for _, o := range objs {
o = strings.TrimSpace(o)
if len(o) > 0 {
objects = append(objects, o)
}
}
}

return objects
}
@@ -3,6 +3,7 @@ package chart
import (
"os"
"path/filepath"
"reflect"
"testing"

"k8s.io/helm/pkg/chartutil"
@@ -43,54 +44,27 @@ func TestRender(t *testing.T) {
}
}

func TestRenderZeroByteTemplates(t *testing.T) {
cwd, _ := filepath.Abs(".")
chartFile, err := os.Open(filepath.Join(cwd, "testdata", "my-complex-app-0.2.0.tgz"))
if err != nil {
t.Fatal(err)
}

testCases := []string{
"",
"\n",
" \n \n\t",
"apiVersion: v1\nkind: Service",
func TestCollectObjects(t *testing.T) {
testCases := []map[string]string{
map[string]string{"foo.yaml": ""},
map[string]string{"foo.yaml": "\n"},
map[string]string{"foo.yaml": " \n \n\t"},
map[string]string{"foo.yaml": "apiVersion: v1\nkind: Service"},
map[string]string{"foo.yaml": "apiVersion: v1\nkind: Service\n---\napiVersion: v1\nkind: Pod"},
}

expected := []string{
"",
"",
"",
"apiVersion: v1\nkind: Service",
expected := [][]string{
[]string{},
[]string{},
[]string{},
[]string{"apiVersion: v1\nkind: Service"},
[]string{"apiVersion: v1\nkind: Service", "apiVersion: v1\nkind: Pod"},
}

for i, testCase := range testCases {
// need to reset the file position to 0 to reload
chartFile.Seek(0, 0)
chart, err := chartutil.LoadArchive(chartFile)
if err != nil {
t.Fatal(err)
}

for _, template := range chart.Templates {
if template.Name == "templates/service.yaml" {
template.Data = []byte(testCase)
}
}

rendered, err := Render(chart, "my-complex-app", "my-complex-app", &shipper.ChartValues{})
if err != nil {
t.Fatalf("failed to render test case %q: %s", testCase, err)
}

if expected[i] == "" {
if len(rendered) != 1 {
t.Fatalf("expected chart.Render to strip out an object with contents %q, but it did not. rendered stuff: %v", testCase, rendered)
}
} else {
if len(rendered) == 1 {
t.Fatalf("chart.Render stripped out an object it should not have: contents %q", testCase)
}
got := CollectObjects(testCase)
if !reflect.DeepEqual(expected[i], got) {
t.Fatalf("expected %q to produce %q, but got %q", testCase, expected[i], got)
}
}
}

0 comments on commit 6464914

Please sign in to comment.
You can’t perform that action at this time.