mirror of https://github.com/helm/helm
Allow --post-renderer to be specified multiple times to chain post-renderers together. Each renderer's output is piped into the next in the order specified. The --post-renderer-args flag now applies to the most recently specified --post-renderer. Signed-off-by: David Otto <ottodavid@gmx.net>pull/32510/head
parent
ae877c8bfb
commit
df8fb0652d
@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
name: "postrenderer-v1-second"
|
||||||
|
version: "1.2.3"
|
||||||
|
type: postrenderer/v1
|
||||||
|
runtime: subprocess
|
||||||
|
runtimeConfig:
|
||||||
|
platformCommand:
|
||||||
|
- command: "${HELM_PLUGIN_DIR}/sed-test.sh"
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
sed s/BARTEST/BAZTEST/g <&0
|
||||||
|
else
|
||||||
|
sed s/BARTEST/"$*"/g <&0
|
||||||
|
fi
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
Copyright The Helm Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package postrenderer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Chain is a PostRenderer that runs a sequence of PostRenderers, feeding the
|
||||||
|
// output of each renderer as the input to the next. This allows multiple
|
||||||
|
// post-renderer plugins to be composed into a single pipeline.
|
||||||
|
type Chain struct {
|
||||||
|
renderers []PostRenderer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewChain creates a Chain that will run the given renderers in order. An
|
||||||
|
// empty chain is valid and behaves as a no-op renderer that returns its
|
||||||
|
// input unchanged.
|
||||||
|
func NewChain(renderers ...PostRenderer) *Chain {
|
||||||
|
return &Chain{renderers: renderers}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Chain) Run(renderedManifests *bytes.Buffer) (*bytes.Buffer, error) {
|
||||||
|
manifests := renderedManifests
|
||||||
|
for i, renderer := range c.renderers {
|
||||||
|
var err error
|
||||||
|
manifests, err = renderer.Run(manifests)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("post-renderer %d/%d failed: %w", i+1, len(c.renderers), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return manifests, nil
|
||||||
|
}
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
Copyright The Helm Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package postrenderer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
// fakeRenderer is a simple PostRenderer used for chain testing. It appends
|
||||||
|
// its suffix to the input, or returns an error if configured to fail.
|
||||||
|
type fakeRenderer struct {
|
||||||
|
suffix string
|
||||||
|
failErr error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fakeRenderer) Run(renderedManifests *bytes.Buffer) (*bytes.Buffer, error) {
|
||||||
|
if f.failErr != nil {
|
||||||
|
return nil, f.failErr
|
||||||
|
}
|
||||||
|
out := bytes.NewBufferString(renderedManifests.String() + f.suffix)
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChain_Empty(t *testing.T) {
|
||||||
|
c := NewChain()
|
||||||
|
out, err := c.Run(bytes.NewBufferString("hello"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "hello", out.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChain_Single(t *testing.T) {
|
||||||
|
c := NewChain(&fakeRenderer{suffix: "-a"})
|
||||||
|
out, err := c.Run(bytes.NewBufferString("hello"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "hello-a", out.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChain_Multiple_OrderPreserved(t *testing.T) {
|
||||||
|
c := NewChain(
|
||||||
|
&fakeRenderer{suffix: "-a"},
|
||||||
|
&fakeRenderer{suffix: "-b"},
|
||||||
|
&fakeRenderer{suffix: "-c"},
|
||||||
|
)
|
||||||
|
out, err := c.Run(bytes.NewBufferString("hello"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, "hello-a-b-c", out.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestChain_ErrorStopsPipeline(t *testing.T) {
|
||||||
|
boom := errors.New("boom")
|
||||||
|
c := NewChain(
|
||||||
|
&fakeRenderer{suffix: "-a"},
|
||||||
|
&fakeRenderer{failErr: boom},
|
||||||
|
&fakeRenderer{suffix: "-c"},
|
||||||
|
)
|
||||||
|
out, err := c.Run(bytes.NewBufferString("hello"))
|
||||||
|
require.Error(t, err)
|
||||||
|
assert.Nil(t, out)
|
||||||
|
assert.ErrorIs(t, err, boom)
|
||||||
|
}
|
||||||
Loading…
Reference in new issue