Skip to content

Commit

Permalink
Fix: remove patch in apply to make it standalone action
Browse files Browse the repository at this point in the history
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
  • Loading branch information
FogDong committed Feb 15, 2023
1 parent 92d7b6a commit 73f3b67
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 52 deletions.
77 changes: 58 additions & 19 deletions pkg/providers/kube/handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ package kube
import (
"context"

"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
Expand All @@ -31,7 +33,7 @@ import (
"github.com/kubevela/pkg/util/k8s/patch"

wfContext "github.com/kubevela/workflow/pkg/context"
"github.com/kubevela/workflow/pkg/cue"
velacue "github.com/kubevela/workflow/pkg/cue"
"github.com/kubevela/workflow/pkg/cue/model"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/kubevela/workflow/pkg/types"
Expand Down Expand Up @@ -126,28 +128,64 @@ func (d *dispatcher) delete(ctx context.Context, cluster, owner string, manifest
return d.cli.Delete(ctx, manifest)
}

// Apply create or update CR in cluster.
func (h *provider) Apply(ctx monitorContext.Context, wfCtx wfContext.Context, v *value.Value, act types.Action) error {
// Patch patch CR in cluster.
func (h *provider) Patch(ctx monitorContext.Context, wfCtx wfContext.Context, v *value.Value, act types.Action) error {
val, err := v.LookupValue("value")
if err != nil {
return err
}
var workload = new(unstructured.Unstructured)
pv, err := v.Field("patch")
if pv.Exists() && err == nil {
base, err := model.NewBase(val.CueValue())
if err != nil {
return err
}
obj := new(unstructured.Unstructured)
if err := val.UnmarshalTo(obj); err != nil {
return err
}
key := client.ObjectKeyFromObject(obj)
if key.Namespace == "" {
key.Namespace = "default"
}
cluster, err := v.GetString("cluster")
if err != nil {
return err
}
multiCtx := handleContext(ctx, cluster)
if err := h.cli.Get(multiCtx, key, obj); err != nil {
return err
}
baseVal := cuecontext.New().CompileString("").FillPath(cue.ParsePath(""), obj)
patcher, err := v.LookupValue("patch")
if err != nil {
return err
}

if err := base.Unify(pv); err != nil {
return err
}
workload, err = base.Unstructured()
if err != nil {
base, err := model.NewBase(baseVal)
if err != nil {
return err
}
if err := base.Unify(patcher.CueValue()); err != nil {
return err
}
workload, err := base.Unstructured()
if err != nil {
return err
}
for k, v := range h.labels {
if err := k8s.AddLabel(workload, k, v); err != nil {
return err
}
} else if err := val.UnmarshalTo(workload); err != nil {
}
if err := h.handlers.Apply(multiCtx, cluster, WorkflowResourceCreator, workload); err != nil {
return err
}
return velacue.FillUnstructuredObject(v, workload, "result")
}

// Apply create or update CR in cluster.
func (h *provider) Apply(ctx monitorContext.Context, wfCtx wfContext.Context, v *value.Value, act types.Action) error {
val, err := v.LookupValue("value")
if err != nil {
return err
}
var workload = new(unstructured.Unstructured)
if err := val.UnmarshalTo(workload); err != nil {
return err
}
if workload.GetNamespace() == "" {
Expand All @@ -166,7 +204,7 @@ func (h *provider) Apply(ctx monitorContext.Context, wfCtx wfContext.Context, v
if err := h.handlers.Apply(deployCtx, cluster, WorkflowResourceCreator, workload); err != nil {
return err
}
return cue.SetUnstructuredObject(v, workload, "value")
return velacue.FillUnstructuredObject(v, workload, "value")
}

// ApplyInParallel create or update CRs in parallel.
Expand Down Expand Up @@ -225,7 +263,7 @@ func (h *provider) Read(ctx monitorContext.Context, wfCtx wfContext.Context, v *
if err := h.cli.Get(readCtx, key, obj); err != nil {
return v.FillObject(err.Error(), "err")
}
return cue.FillUnstructuredObject(v, obj, "value")
return velacue.FillUnstructuredObject(v, obj, "value")
}

// List lists CRs from cluster.
Expand Down Expand Up @@ -263,7 +301,7 @@ func (h *provider) List(ctx monitorContext.Context, wfCtx wfContext.Context, v *
if err := h.cli.List(readCtx, list, listOpts...); err != nil {
return v.FillObject(err.Error(), "err")
}
return cue.FillUnstructuredObject(v, list, "list")
return velacue.FillUnstructuredObject(v, list, "list")
}

// Delete deletes CR from cluster.
Expand Down Expand Up @@ -326,5 +364,6 @@ func Install(p types.Providers, cli client.Client, labels map[string]string, han
"read": prd.Read,
"list": prd.List,
"delete": prd.Delete,
"patch": prd.Patch,
})
}
61 changes: 28 additions & 33 deletions pkg/providers/kube/handle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,44 +173,39 @@ cluster: ""
Expect(err).ToNot(HaveOccurred())

v, err := value.NewValue(fmt.Sprintf(`
value: {%s}
cluster: ""
patch: {
value:{
%s
metadata: name: "test-app-1"
spec: containers: [{
// +patchStrategy=replace
env: [{
name: "APP"
value: "nginx-new"
}]
}]
}`, componentStr), nil, "")
metadata: labels: {
"test": "test"
}
}
cluster: ""
`, componentStr), nil, "")
Expect(err).ToNot(HaveOccurred())
mCtx := monitorContext.NewTraceContext(context.Background(), "")
err = p.Apply(mCtx, ctx, v, nil)
Expect(err).ToNot(HaveOccurred())
sub, err := v.LookupValue("value")
Expect(err).ToNot(HaveOccurred())
Expect(sub.Error()).To(BeNil())
v, err = v.MakeValue(`
cluster: ""
patch: {
metadata: name: "test-app-1"
spec: {
containers: [{
// +patchStrategy=retainKeys
image: "nginx:latest"
}]
}
}`)
Expect(err).ToNot(HaveOccurred())
err = v.FillObject(sub, "value")
Expect(err).ToNot(HaveOccurred())
err = p.Apply(mCtx, ctx, v, nil)

v, err = value.NewValue(`
value: {
apiVersion: "v1"
kind: "Pod"
metadata: name: "test-app-1"
}
cluster: ""
patch: {
metadata: name: "test-app-1"
spec: {
containers: [{
// +patchStrategy=retainKeys
image: "nginx:notfound"
}]
}
}`, nil, "")
Expect(err).ToNot(HaveOccurred())
sub2, err := v.LookupValue("value")
err = p.Patch(mCtx, ctx, v, nil)
Expect(err).ToNot(HaveOccurred())
Expect(sub2.Error()).To(BeNil())

pod := &corev1.Pod{}
Expect(err).ToNot(HaveOccurred())
Expand All @@ -221,7 +216,7 @@ patch: {
}, pod)
}, time.Second*2, time.Millisecond*300).Should(BeNil())
Expect(pod.Name).To(Equal("test-app-1"))
Expect(pod.Spec.Containers[0].Env[0].Value).To(Equal("nginx-new"))
Expect(pod.Spec.Containers[0].Image).To(Equal("nginx:notfound"))
})

It("list", func() {
Expand Down Expand Up @@ -273,7 +268,7 @@ cluster: ""
expected := &metav1.PartialObjectMetadataList{}
err = result.UnmarshalTo(expected)
Expect(err).ToNot(HaveOccurred())
Expect(len(expected.Items)).Should(Equal(3))
Expect(len(expected.Items)).Should(Equal(4))

By("List pods with labels index=test-1")
v, err = value.NewValue(`
Expand Down
2 changes: 2 additions & 0 deletions pkg/stdlib/actions/v1/op.cue
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ import (

#Apply: kube.#Apply

#Patch: kube.#Patch

#ApplyInParallel: kube.#ApplyInParallel

#Read: kube.#Read
Expand Down
15 changes: 15 additions & 0 deletions pkg/stdlib/actions/v1/pkgs/kube.cue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
...
}

#Patch: {
#do: "patch"
#provider: "kube"

// +usage=The cluster to use
cluster: *"" | string
// +usage=The resource to patch, we'll first get the resource from the cluster, then apply the patcher to it
value: {...}
// +usage=The patcher that will be applied to the resource, you can define the strategy of list merge through comments. Reference doc here: https://kubevela.io/docs/platform-engineers/traits/patch-trait#patch-in-workflow-step
patch: {...}
// +usage=The resource after applied will be filled in this field after the action is executed
result?: {...}
...
}

#ApplyInParallel: {
#do: "apply-in-parallel"
#provider: "kube"
Expand Down

0 comments on commit 73f3b67

Please sign in to comment.