pull/30968/merge
Dan Walters 3 months ago committed by GitHub
commit 7d9e5446ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -25,6 +25,7 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"strings"
"sync"
"text/template"
@ -91,6 +92,63 @@ type Configuration struct {
mutex sync.Mutex
}
var sep = regexp.MustCompile("(?:^|\\s*\n)---\\s*")
var sourceFilename = regexp.MustCompile("^# Source: (\\S+)\n")
// Runs the PostRenderer on the given files, returning an updated map when complete.
func runPostRenderer(pr postrender.PostRenderer, files map[string]string) (map[string]string, error) {
postRenderedFiles := make(map[string]string)
// Serialize to a giant buffer, with a comment to indicate the filename
b := bytes.NewBuffer(nil)
for filename, content := range files {
// Skip partials and empty manifests
// Note that in helm v3, hooks are not run through the post renderer by default.
if content == "" || strings.HasPrefix(path.Base(filename), "_") {
continue
}
// Buffer for the post renderer
_, err := fmt.Fprintf(b, "---\n# Source: %s\n%s", filename, content)
if err != nil {
return nil, err
}
}
// Run through the post renderer.
b, err := pr.Run(b)
if err != nil {
return nil, err
}
// Rebuild the files map from the post render output.
docs := sep.Split(b.String(), -1)
for i, d := range docs {
if d == "" {
continue
}
// If the "# Source: ..." comments were preserved, we will keep the same filename here.
var filename string
m := sourceFilename.FindStringSubmatch(d)
if m != nil {
filename = m[1]
d = d[len(m[0]):]
} else {
filename = fmt.Sprintf("manifest-%d", i)
}
// Append the doc to the named pseudo-file
if data, ok := postRenderedFiles[filename]; ok {
postRenderedFiles[filename] = data + "\n---\n" + d
} else {
postRenderedFiles[filename] = d
}
}
return postRenderedFiles, nil
}
// renderResources renders the templates in a chart
//
// TODO: This function is badly in need of a refactor.
@ -160,6 +218,14 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Valu
}
notes := notesBuffer.String()
// Invoke the post renderer, if using.
if pr != nil {
files, err = runPostRenderer(pr, files)
if err != nil {
return hs, b, "", fmt.Errorf("error running post renderer: %w", err)
}
}
// Sort hooks, manifests, and partials. Only hooks and manifests are returned,
// as partials are not used after renderer.Render. Empty manifests are also
// removed here.
@ -208,8 +274,7 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Valu
if useReleaseName {
newDir = filepath.Join(outputDir, releaseName)
}
// NOTE: We do not have to worry about the post-renderer because
// output dir is only used by `helm template`. In the next major
// NOTE: Output dir is only used by `helm template`. In the next major
// release, we should move this logic to template only as it is not
// used by install or upgrade
err = writeToFile(newDir, m.Name, m.Content, fileWritten[m.Name])
@ -220,13 +285,6 @@ func (cfg *Configuration) renderResources(ch *chart.Chart, values chartutil.Valu
}
}
if pr != nil {
b, err = pr.Run(b)
if err != nil {
return hs, b, notes, fmt.Errorf("error while running post render on files: %w", err)
}
}
return hs, b, notes, nil
}

@ -16,10 +16,12 @@ limitations under the License.
package action
import (
"bytes"
"flag"
"fmt"
"io"
"log/slog"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@ -368,3 +370,28 @@ func TestGetVersionSet(t *testing.T) {
t.Error("Non-existent version is reported found.")
}
}
type mutatingPostRenderer struct {
Old, New []byte
}
func (pr *mutatingPostRenderer) Run(renderedManifests *bytes.Buffer) (*bytes.Buffer, error) {
modifiedManifests := bytes.ReplaceAll(renderedManifests.Bytes(), pr.Old, pr.New)
return bytes.NewBuffer(modifiedManifests), nil
}
func TestRunPostRenderer(t *testing.T) {
files := map[string]string{
"test-cm.yaml": manifestWithHook,
}
postRenderer := &mutatingPostRenderer{[]byte("name: value"), []byte("name: VALUE")}
postRenderedFiles, err := runPostRenderer(postRenderer, files)
if err != nil {
t.Fatal(err)
}
if postRenderedFiles["test-cm.yaml"] != strings.ReplaceAll(manifestWithHook, "name: value", "name: VALUE") {
t.Error("Expected test-cm to be present and mutated by the post processor")
}
}

Loading…
Cancel
Save