Skip to content

Commit

Permalink
Move post renderers into separate package
Browse files Browse the repository at this point in the history
Plus change the tests a tiny bit to work with Gomega, and break the
further API free from direct attachment to our Helm API objects.

Signed-off-by: Hidde Beydals <[email protected]>
  • Loading branch information
hiddeco committed May 6, 2022
1 parent d487b2c commit ca71ba0
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,32 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package runner
package postrender

import (
"bytes"

"helm.sh/helm/v3/pkg/postrender"
)

// combinedPostRenderer, a collection of Helm PostRenders which are
// Combined is a collection of Helm PostRenders which are
// invoked in the order of insertion.
type combinedPostRenderer struct {
type Combined struct {
renderers []postrender.PostRenderer
}

func newCombinedPostRenderer() combinedPostRenderer {
return combinedPostRenderer{
renderers: make([]postrender.PostRenderer, 0),
func NewCombined(renderer ...postrender.PostRenderer) *Combined {
pr := make([]postrender.PostRenderer, 0)
for _, r := range renderer {
pr = append(pr, r)
}
return &Combined{
renderers: pr,
}
}

func (c *combinedPostRenderer) addRenderer(renderer postrender.PostRenderer) {
c.renderers = append(c.renderers, renderer)
}

func (c *combinedPostRenderer) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) {
var result *bytes.Buffer = renderedManifests
func (c *Combined) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) {
var result = renderedManifests
for _, renderer := range c.renderers {
result, err = renderer.Run(result)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package runner
package postrender

import (
"bytes"
Expand All @@ -31,67 +31,17 @@ import (
v2 "github.com/fluxcd/helm-controller/api/v2beta1"
)

type postRendererKustomize struct {
type Kustomize struct {
spec *v2.Kustomize
}

func newPostRendererKustomize(spec *v2.Kustomize) *postRendererKustomize {
return &postRendererKustomize{
func NewKustomize(spec *v2.Kustomize) *Kustomize {
return &Kustomize{
spec: spec,
}
}

func writeToFile(fs filesys.FileSystem, path string, content []byte) error {
helmOutput, err := fs.Create(path)
if err != nil {
return err
}
helmOutput.Write(content)
if err := helmOutput.Close(); err != nil {
return err
}
return nil
}

func writeFile(fs filesys.FileSystem, path string, content *bytes.Buffer) error {
helmOutput, err := fs.Create(path)
if err != nil {
return err
}
content.WriteTo(helmOutput)
if err := helmOutput.Close(); err != nil {
return err
}
return nil
}

func adaptImages(images []kustomize.Image) (output []kustypes.Image) {
for _, image := range images {
output = append(output, kustypes.Image{
Name: image.Name,
NewName: image.NewName,
NewTag: image.NewTag,
Digest: image.Digest,
})
}
return
}

func adaptSelector(selector *kustomize.Selector) (output *kustypes.Selector) {
if selector != nil {
output = &kustypes.Selector{}
output.Gvk.Group = selector.Group
output.Gvk.Kind = selector.Kind
output.Gvk.Version = selector.Version
output.Name = selector.Name
output.Namespace = selector.Namespace
output.LabelSelector = selector.LabelSelector
output.AnnotationSelector = selector.AnnotationSelector
}
return
}

func (k *postRendererKustomize) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) {
func (k *Kustomize) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) {
fs := filesys.MakeFsInMemory()
cfg := kustypes.Kustomization{}
cfg.APIVersion = kustypes.KustomizationVersion
Expand Down Expand Up @@ -149,6 +99,56 @@ func (k *postRendererKustomize) Run(renderedManifests *bytes.Buffer) (modifiedMa
return bytes.NewBuffer(yaml), nil
}

func writeToFile(fs filesys.FileSystem, path string, content []byte) error {
helmOutput, err := fs.Create(path)
if err != nil {
return err
}
helmOutput.Write(content)
if err := helmOutput.Close(); err != nil {
return err
}
return nil
}

func writeFile(fs filesys.FileSystem, path string, content *bytes.Buffer) error {
helmOutput, err := fs.Create(path)
if err != nil {
return err
}
content.WriteTo(helmOutput)
if err := helmOutput.Close(); err != nil {
return err
}
return nil
}

func adaptImages(images []kustomize.Image) (output []kustypes.Image) {
for _, image := range images {
output = append(output, kustypes.Image{
Name: image.Name,
NewName: image.NewName,
NewTag: image.NewTag,
Digest: image.Digest,
})
}
return
}

func adaptSelector(selector *kustomize.Selector) (output *kustypes.Selector) {
if selector != nil {
output = &kustypes.Selector{}
output.Gvk.Group = selector.Group
output.Gvk.Kind = selector.Kind
output.Gvk.Version = selector.Version
output.Name = selector.Name
output.Namespace = selector.Namespace
output.LabelSelector = selector.LabelSelector
output.AnnotationSelector = selector.AnnotationSelector
}
return
}

// TODO: remove mutex when kustomize fixes the concurrent map read/write panic
var kustomizeRenderMutex sync.Mutex

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package runner
package postrender

import (
"bytes"
"encoding/json"
"reflect"
"testing"

. "github.com/onsi/gomega"
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"sigs.k8s.io/yaml"

Expand Down Expand Up @@ -253,22 +253,23 @@ spec:
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

spec, err := mockKustomize(tt.patches, tt.patchesStrategicMerge, tt.patchesJson6902, tt.images)
if err != nil {
t.Errorf("Run() mockKustomize returned %v", err)
return
}
k := &postRendererKustomize{
g.Expect(err).ToNot(HaveOccurred())

k := &Kustomize{
spec: spec,
}
gotModifiedManifests, err := k.Run(bytes.NewBufferString(tt.renderedManifests))
if (err != nil) != tt.expectErr {
t.Errorf("Run() error = %v, expectErr %v", err, tt.expectErr)
if tt.expectErr {
g.Expect(err).ToNot(HaveOccurred())
g.Expect(gotModifiedManifests.String()).To(BeEmpty())
return
}
if !reflect.DeepEqual(gotModifiedManifests, bytes.NewBufferString(tt.expectManifests)) {
t.Errorf("Run() gotModifiedManifests = %v, want %v", gotModifiedManifests, tt.expectManifests)
}

g.Expect(err).ToNot(HaveOccurred())
g.Expect(gotModifiedManifests).To(Equal(bytes.NewBufferString(tt.expectManifests)))
})
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package runner
package postrender

import (
"bytes"
Expand All @@ -24,23 +24,23 @@ import (
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
kustypes "sigs.k8s.io/kustomize/api/types"

v2 "github.com/fluxcd/helm-controller/api/v2beta1"
)

func newPostRendererOriginLabels(release *v2.HelmRelease) *postRendererOriginLabels {
return &postRendererOriginLabels{
name: release.ObjectMeta.Name,
namespace: release.ObjectMeta.Namespace,
func NewOriginLabels(group, namespace, name string) *OriginLabels {
return &OriginLabels{
group: group,
name: name,
namespace: namespace,
}
}

type postRendererOriginLabels struct {
type OriginLabels struct {
group string
name string
namespace string
}

func (k *postRendererOriginLabels) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) {
func (k *OriginLabels) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) {
resFactory := provider.NewDefaultDepProvider().GetResourceFactory()
resMapFactory := resmap.NewFactory(resFactory)

Expand All @@ -50,7 +50,7 @@ func (k *postRendererOriginLabels) Run(renderedManifests *bytes.Buffer) (modifie
}

labelTransformer := builtins.LabelTransformerPlugin{
Labels: originLabels(k.name, k.namespace),
Labels: originLabels(k.group, k.namespace, k.name),
FieldSpecs: []kustypes.FieldSpec{
{Path: "metadata/labels", CreateIfNotPresent: true},
},
Expand All @@ -67,9 +67,9 @@ func (k *postRendererOriginLabels) Run(renderedManifests *bytes.Buffer) (modifie
return bytes.NewBuffer(yaml), nil
}

func originLabels(name, namespace string) map[string]string {
func originLabels(group, namespace, name string) map[string]string {
return map[string]string{
fmt.Sprintf("%s/name", v2.GroupVersion.Group): name,
fmt.Sprintf("%s/namespace", v2.GroupVersion.Group): namespace,
fmt.Sprintf("%s/name", group): name,
fmt.Sprintf("%s/namespace", group): namespace,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package runner
package postrender

import (
"bytes"
"reflect"
"testing"

. "github.com/onsi/gomega"
)

const mixedResourceMock = `apiVersion: v1
Expand All @@ -35,7 +36,7 @@ metadata:
existing: label
`

func Test_postRendererOriginLabels_Run(t *testing.T) {
func Test_OriginLabels_Run(t *testing.T) {
tests := []struct {
name string
renderedManifests string
Expand Down Expand Up @@ -66,18 +67,17 @@ metadata:
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
k := &postRendererOriginLabels{
name: "name",
namespace: "namespace",
}
g := NewWithT(t)

k := NewOriginLabels("helm.toolkit.fluxcd.io", "namespace", "name")
gotModifiedManifests, err := k.Run(bytes.NewBufferString(tt.renderedManifests))
if (err != nil) != tt.expectErr {
t.Errorf("Run() error = %v, expectErr %v", err, tt.expectErr)
if tt.expectErr {
g.Expect(err).To(HaveOccurred())
g.Expect(gotModifiedManifests.String()).To(BeEmpty())
return
}
if !reflect.DeepEqual(gotModifiedManifests, bytes.NewBufferString(tt.expectManifests)) {
t.Errorf("Run() gotModifiedManifests = %v, want %v", gotModifiedManifests, tt.expectManifests)
}
g.Expect(err).ToNot(HaveOccurred())
g.Expect(gotModifiedManifests).To(Equal(bytes.NewBufferString(tt.expectManifests)))
})
}
}
12 changes: 7 additions & 5 deletions internal/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"helm.sh/helm/v3/pkg/postrender"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/storage/driver"
"k8s.io/api/autoscaling/v2beta1"
apiextension "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
"k8s.io/cli-runtime/pkg/genericclioptions"
"k8s.io/cli-runtime/pkg/resource"
Expand All @@ -42,6 +43,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"

v2 "github.com/fluxcd/helm-controller/api/v2beta1"
intpostrender "github.com/fluxcd/helm-controller/internal/postrender"
)

type ActionError struct {
Expand Down Expand Up @@ -82,17 +84,17 @@ func NewRunner(getter genericclioptions.RESTClientGetter, storageNamespace strin
// Create post renderer instances from HelmRelease and combine them into
// a single combined post renderer.
func postRenderers(hr v2.HelmRelease) (postrender.PostRenderer, error) {
var combinedRenderer = newCombinedPostRenderer()
renderers := make([]postrender.PostRenderer, 0)
for _, r := range hr.Spec.PostRenderers {
if r.Kustomize != nil {
combinedRenderer.addRenderer(newPostRendererKustomize(r.Kustomize))
renderers = append(renderers, intpostrender.NewKustomize(r.Kustomize))
}
}
combinedRenderer.addRenderer(newPostRendererOriginLabels(&hr))
if len(combinedRenderer.renderers) == 0 {
renderers = append(renderers, intpostrender.NewOriginLabels(v2beta1.SchemeGroupVersion.Group, hr.Namespace, hr.Name))
if len(renderers) == 0 {
return nil, nil
}
return &combinedRenderer, nil
return intpostrender.NewCombined(renderers...), nil
}

// Install runs an Helm install action for the given v2beta1.HelmRelease.
Expand Down

0 comments on commit ca71ba0

Please sign in to comment.