Skip to content

Commit

Permalink
PR Comments
Browse files Browse the repository at this point in the history
  • Loading branch information
ludydoo committed Jul 28, 2023
1 parent 2a0b495 commit 8ac34c0
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 11 deletions.
16 changes: 5 additions & 11 deletions pkg/client/actionclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,12 @@ import (
"gomodules.xyz/jsonpatch/v2"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/kube"
helmkube "helm.sh/helm/v3/pkg/kube"
"helm.sh/helm/v3/pkg/postrender"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/storage/driver"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
apitypes "k8s.io/apimachinery/pkg/types"
Expand Down Expand Up @@ -110,8 +107,6 @@ func AppendUpgradeFailureRollbackOptions(opts ...RollbackOption) ActionClientGet
}
}

type PostRendererProvider func(rm meta.RESTMapper, kubeClient kube.Interface, obj client.Object) postrender.PostRenderer

func AppendPostRenderers(postRendererFns ...PostRendererProvider) ActionClientGetterOption {
return func(getter *actionClientGetter) error {
getter.postRendererProviders = append(getter.postRendererProviders, postRendererFns...)
Expand Down Expand Up @@ -154,12 +149,11 @@ func (hcg *actionClientGetter) ActionClientFor(obj client.Object) (ActionInterfa
if err != nil {
return nil, err
}
var chainedPostRenderer = chainedPostRenderer{
DefaultPostRendererFunc(rm, actionConfig.KubeClient, obj),
}
var cpr = chainedPostRenderer{}
for _, provider := range hcg.postRendererProviders {
chainedPostRenderer = append(chainedPostRenderer, provider(rm, actionConfig.KubeClient, obj))
cpr = append(cpr, provider(rm, actionConfig.KubeClient, obj))
}
cpr = append(cpr, DefaultPostRendererFunc(rm, actionConfig.KubeClient, obj))

return &actionClient{
conf: actionConfig,
Expand All @@ -168,8 +162,8 @@ func (hcg *actionClientGetter) ActionClientFor(obj client.Object) (ActionInterfa
// on purpose because we want user-provided defaults to be able to override the
// post-renderer that we automatically configure for the client.
defaultGetOpts: hcg.defaultGetOpts,
defaultInstallOpts: append([]InstallOption{WithInstallPostRenderer(chainedPostRenderer)}, hcg.defaultInstallOpts...),
defaultUpgradeOpts: append([]UpgradeOption{WithUpgradePostRenderer(chainedPostRenderer)}, hcg.defaultUpgradeOpts...),
defaultInstallOpts: append([]InstallOption{WithInstallPostRenderer(cpr)}, hcg.defaultInstallOpts...),
defaultUpgradeOpts: append([]UpgradeOption{WithUpgradePostRenderer(cpr)}, hcg.defaultUpgradeOpts...),
defaultUninstallOpts: hcg.defaultUninstallOpts,

installFailureUninstallOpts: hcg.installFailureUninstallOpts,
Expand Down
102 changes: 102 additions & 0 deletions pkg/client/actionclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ limitations under the License.
package client

import (
"bytes"
"context"
"errors"
"fmt"
"io"
"strconv"
"time"

Expand All @@ -27,6 +30,8 @@ import (
. "github.com/onsi/gomega"
"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/kube"
"helm.sh/helm/v3/pkg/postrender"
"helm.sh/helm/v3/pkg/release"
"helm.sh/helm/v3/pkg/releaseutil"
"helm.sh/helm/v3/pkg/storage/driver"
Expand All @@ -36,6 +41,7 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
apitypes "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/rand"
Expand Down Expand Up @@ -78,12 +84,15 @@ var _ = Describe("ActionClient", func() {

var (
actionConfigGetter ActionConfigGetter
cli kube.Interface
obj client.Object
)
BeforeEach(func() {
var err error
actionConfigGetter, err = NewActionConfigGetter(cfg, rm, logr.Discard())
Expect(err).ShouldNot(HaveOccurred())
cli = kube.New(newRESTClientGetter(cfg, rm, ""))
Expect(err).ShouldNot(HaveOccurred())
obj = testutil.BuildTestCR(gvk)
})

Expand Down Expand Up @@ -236,6 +245,42 @@ var _ = Describe("ActionClient", func() {
})
Expect(err).To(MatchError(ContainSubstring(expectErr.Error())))

// Uninstall the chart to cleanup for other tests.
_, err = ac.Uninstall(obj.GetName())
Expect(err).To(BeNil())
})
It("should get clients with postrenderers", func() {

acg, err := NewActionClientGetter(actionConfigGetter, AppendPostRenderers(newMockPostRenderer("foo", "bar")))
Expect(err).To(BeNil())
Expect(acg).NotTo(BeNil())

ac, err := acg.ActionClientFor(obj)
Expect(err).To(BeNil())

_, err = ac.Install(obj.GetName(), obj.GetNamespace(), &chrt, chartutil.Values{})
Expect(err).To(BeNil())

rel, err := ac.Get(obj.GetName())
Expect(err).To(BeNil())

rl, err := cli.Build(bytes.NewBufferString(rel.Manifest), false)
Expect(err).To(BeNil())

Expect(rl).NotTo(BeEmpty())
err = rl.Visit(func(info *resource.Info, err error) error {
Expect(err).To(BeNil())
Expect(info.Object).NotTo(BeNil())
objMeta, err := meta.Accessor(info.Object)
Expect(err).To(BeNil())
Expect(objMeta.GetAnnotations()).To(HaveKey("foo"))
Expect(objMeta.GetAnnotations()["foo"]).To(Equal("bar"))
return nil
})
Expect(err).To(BeNil())

fmt.Println(rel.Manifest)

// Uninstall the chart to cleanup for other tests.
_, err = ac.Uninstall(obj.GetName())
Expect(err).To(BeNil())
Expand Down Expand Up @@ -807,3 +852,60 @@ func newTestDeployment(containers []v1.Container) *appsv1.Deployment {
},
}
}

type mockPostRenderer struct {
k8sCli kube.Interface
key string
value string
}

var _ postrender.PostRenderer = &mockPostRenderer{}

func newMockPostRenderer(key, value string) PostRendererProvider {
return func(rm meta.RESTMapper, kubeClient kube.Interface, obj client.Object) postrender.PostRenderer {
return &mockPostRenderer{
k8sCli: kubeClient,
key: key,
value: value,
}
}
}

func (m *mockPostRenderer) Run(renderedManifests *bytes.Buffer) (modifiedManifests *bytes.Buffer, err error) {
b, err := io.ReadAll(renderedManifests)
if err != nil {
return nil, err
}
rl, err := m.k8sCli.Build(bytes.NewBuffer(b), false)
if err != nil {
return nil, err
}
out := bytes.Buffer{}
err = rl.Visit(func(r *resource.Info, err error) error {

Check failure on line 884 in pkg/client/actionclient_test.go

View workflow job for this annotation

GitHub Actions / Test

SA4009: argument err is overwritten before first use (staticcheck)

Check failure on line 884 in pkg/client/actionclient_test.go

View workflow job for this annotation

GitHub Actions / Lint

SA4009: argument err is overwritten before first use (staticcheck)

Check failure on line 884 in pkg/client/actionclient_test.go

View workflow job for this annotation

GitHub Actions / Lint

SA4009: argument err is overwritten before first use (staticcheck)

Check failure on line 884 in pkg/client/actionclient_test.go

View workflow job for this annotation

GitHub Actions / Test

SA4009: argument err is overwritten before first use (staticcheck)
objMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(r.Object)

Check failure on line 885 in pkg/client/actionclient_test.go

View workflow job for this annotation

GitHub Actions / Test

SA4009(related information): assignment to err (staticcheck)

Check failure on line 885 in pkg/client/actionclient_test.go

View workflow job for this annotation

GitHub Actions / Lint

SA4009(related information): assignment to err (staticcheck)

Check failure on line 885 in pkg/client/actionclient_test.go

View workflow job for this annotation

GitHub Actions / Lint

SA4009(related information): assignment to err (staticcheck)

Check failure on line 885 in pkg/client/actionclient_test.go

View workflow job for this annotation

GitHub Actions / Test

SA4009(related information): assignment to err (staticcheck)
if err != nil {
return err
}
u := &unstructured.Unstructured{Object: objMap}

annotations := u.GetAnnotations()
if annotations == nil {
annotations = map[string]string{}
}
annotations[m.key] = m.value
u.SetAnnotations(annotations)

outData, err := yaml.Marshal(u.Object)
if err != nil {
return err
}
if _, err := out.WriteString("---\n" + string(outData)); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return &out, nil
}
4 changes: 4 additions & 0 deletions pkg/client/postrenderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import (
"github.com/operator-framework/helm-operator-plugins/pkg/manifestutil"
)

// PostRendererProvider is a function that returns a post-renderer for a given object.
// obj represents the custom resource that is being reconciled.
type PostRendererProvider func(rm meta.RESTMapper, kubeClient kube.Interface, obj client.Object) postrender.PostRenderer

// WithInstallPostRenderer sets the post-renderer to use for the install.
// It overrides any post-renderer that may already be configured or set
// as a default.
Expand Down

0 comments on commit 8ac34c0

Please sign in to comment.