From 987e96f2bc2c00b193b3ea5794d94fffa17bae54 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 14 Nov 2023 05:11:30 +0000
Subject: [PATCH 1/9] Update module github.com/crossplane/crossplane-runtime to
v1.14.2
---
go.mod | 2 +-
go.sum | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/go.mod b/go.mod
index 4b2ffac..b198a8f 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ toolchain go1.21.3
require (
github.com/alecthomas/kong v0.8.1
- github.com/crossplane/crossplane-runtime v1.14.1
+ github.com/crossplane/crossplane-runtime v1.14.2
github.com/crossplane/function-sdk-go v0.1.0
github.com/google/go-cmp v0.6.0
github.com/pkg/errors v0.9.1
diff --git a/go.sum b/go.sum
index 154f53e..8495ff8 100644
--- a/go.sum
+++ b/go.sum
@@ -65,6 +65,8 @@ github.com/crossplane/crossplane-runtime v1.14.0 h1:MFo93iOJLvYaMCaCoyH2vFWsHebd
github.com/crossplane/crossplane-runtime v1.14.0/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
github.com/crossplane/crossplane-runtime v1.14.1 h1:TCa7R1N4bDGHjsLhiRxR/mUhwmistlMACHm0kiiYKck=
github.com/crossplane/crossplane-runtime v1.14.1/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
+github.com/crossplane/crossplane-runtime v1.14.2 h1:pV5JMzyzi/kcbeVBVPCat5MHH8zS94MBUapAyGx/Ry0=
+github.com/crossplane/crossplane-runtime v1.14.2/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
github.com/crossplane/function-sdk-go v0.0.0-20231016233407-0a4b30c5dacc h1:hhupaJGj8I4LXhWr9lCm5MZLeeTAiuFF+/mesGi1y/8=
github.com/crossplane/function-sdk-go v0.0.0-20231016233407-0a4b30c5dacc/go.mod h1:U3UsQAVOCrsUUQAYAyF25PlbSFR2WaLl89dLq58/b2s=
github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8=
From 2431b1148eab750bd45bfc52980e8fc334590cf7 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 21 Nov 2023 17:23:20 +0000
Subject: [PATCH 2/9] Update k8s.io/utils digest to cf03d44
---
go.mod | 2 +-
go.sum | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/go.mod b/go.mod
index 4b2ffac..07be828 100644
--- a/go.mod
+++ b/go.mod
@@ -14,7 +14,7 @@ require (
k8s.io/api v0.28.3
k8s.io/apiextensions-apiserver v0.28.3
k8s.io/apimachinery v0.28.3
- k8s.io/utils v0.0.0-20230726121419-3b25d923346b
+ k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf
sigs.k8s.io/controller-tools v0.13.0
)
diff --git a/go.sum b/go.sum
index 154f53e..3df4870 100644
--- a/go.sum
+++ b/go.sum
@@ -653,6 +653,8 @@ k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5Ohx
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf h1:iTzha1p7Fi83476ypNSz8nV9iR9932jIIs26F7gNLsU=
+k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
From adb7dabbc429b23a0357987246357df42d114b1d Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Wed, 22 Nov 2023 03:08:28 +0000
Subject: [PATCH 3/9] Update kubernetes packages to v0.28.4
---
go.mod | 10 +++++-----
go.sum | 10 ++++++++++
2 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/go.mod b/go.mod
index 07be828..7149f8b 100644
--- a/go.mod
+++ b/go.mod
@@ -11,9 +11,9 @@ require (
github.com/google/go-cmp v0.6.0
github.com/pkg/errors v0.9.1
google.golang.org/protobuf v1.31.0
- k8s.io/api v0.28.3
- k8s.io/apiextensions-apiserver v0.28.3
- k8s.io/apimachinery v0.28.3
+ k8s.io/api v0.28.4
+ k8s.io/apiextensions-apiserver v0.28.4
+ k8s.io/apimachinery v0.28.4
k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf
sigs.k8s.io/controller-tools v0.13.0
)
@@ -76,8 +76,8 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- k8s.io/client-go v0.28.3 // indirect
- k8s.io/component-base v0.28.3 // indirect
+ k8s.io/client-go v0.28.4 // indirect
+ k8s.io/component-base v0.28.4 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
sigs.k8s.io/controller-runtime v0.16.3 // indirect
diff --git a/go.sum b/go.sum
index 3df4870..a4bf477 100644
--- a/go.sum
+++ b/go.sum
@@ -639,14 +639,24 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM=
k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc=
+k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
+k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08=
k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc=
+k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU=
+k8s.io/apiextensions-apiserver v0.28.4/go.mod h1:pgQIZ1U8eJSMQcENew/0ShUTlePcSGFq6dxSxf2mwPM=
k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A=
k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8=
+k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
+k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4=
k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo=
+k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY=
+k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4=
k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI=
k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8=
+k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo=
+k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
From 873f26b034a9934de34cb6674e4a44bf0ac6442b Mon Sep 17 00:00:00 2001
From: Philippe Scorsolini
Date: Thu, 23 Nov 2023 10:28:04 +0100
Subject: [PATCH 4/9] fix: run patches in order for composed resources
Signed-off-by: Philippe Scorsolini
---
fn.go | 55 ++++++------------------------------------
fn_test.go | 2 +-
render.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+), 48 deletions(-)
diff --git a/fn.go b/fn.go
index 7161787..0bc758f 100644
--- a/fn.go
+++ b/fn.go
@@ -196,58 +196,19 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe
log.Debug("Found corresponding observed resource",
"ready", ready,
"name", ocd.Resource.GetName())
-
- // TODO(negz): Should failures to patch the XR be terminal? It could
- // indicate a required patch failed. A required patch means roughly
- // "this patch has to succeed before you mutate the resource". This
- // is useful to make sure we never create a composed resource in the
- // wrong state. It's less clear how useful it is for the XR, given
- // we'll only ever be updating it, not creating it.
-
- // We want to patch the XR from observed composed resources, not
- // from desired state. This is because folks will typically be
- // patching from a field that is set once the observed resource is
- // applied such as its status.
- if err := RenderToCompositePatches(dxr.Resource, ocd.Resource, t.Patches); err != nil {
- response.Warning(rsp, errors.Wrapf(err, "cannot render ToComposite patches for composed resource %q", t.Name))
- log.Info("Cannot render ToComposite patches for composed resource", "warning", err)
- warnings++
- }
-
- // TODO(negz): Same as above, but for the Environment. What does it
- // mean for a required patch to the environment to fail? Should it
- // be terminal?
-
- // Run all patches that are from the (observed) composed resource to
- // the environment.
- if err := RenderToEnvironmentPatches(env, ocd.Resource, t.Patches); err != nil {
- response.Warning(rsp, errors.Wrapf(err, "cannot render ToEnvironment patches for composed resource %q", t.Name))
- log.Info("Cannot render ToEnvironment patches for composed resource", "warning", err)
- warnings++
- }
}
- // If either of the below renderings return an error, most likely a
- // required FromComposite or FromEnvironment patch failed. A required
- // patch means roughly "this patch has to succeed before you mutate the
- // resource." This is useful to make sure we never create a composed
- // resource in the wrong state. To that end, we don't want to add this
- // resource to our accumulated desired state.
- if err := RenderFromCompositePatches(dcd.Resource, oxr.Resource, t.Patches); err != nil {
- response.Warning(rsp, errors.Wrapf(err, "cannot render FromComposite patches for composed resource %q", t.Name))
- log.Info("Cannot render FromComposite patches for composed resource", "warning", err)
+ errs, store := RenderComposedPatches(ocd.Resource, dcd.Resource, oxr.Resource, dxr.Resource, env, t.Patches)
+ for _, err := range errs {
+ response.Warning(rsp, errors.Wrapf(err, "cannot render patches for composed resource %q", t.Name))
+ log.Info("Cannot render patches for composed resource", "warning", err)
warnings++
- continue
- }
- if err := RenderFromEnvironmentPatches(dcd.Resource, env, t.Patches); err != nil {
- response.Warning(rsp, errors.Wrapf(err, "cannot render FromEnvironment patches for composed resource %q", t.Name))
- log.Info("Cannot render FromEnvironment patches for composed resource", "warning", err)
- warnings++
- continue
}
- // Add or replace our desired resource.
- desired[resource.Name(t.Name)] = dcd
+ if store {
+ // Add or replace our desired resource.
+ desired[resource.Name(t.Name)] = dcd
+ }
}
if err := response.SetDesiredCompositeResource(rsp, dxr); err != nil {
diff --git a/fn_test.go b/fn_test.go
index ea1fa3e..78a25d1 100644
--- a/fn_test.go
+++ b/fn_test.go
@@ -447,7 +447,7 @@ func TestRunFunction(t *testing.T) {
Results: []*fnv1beta1.Result{
{
Severity: fnv1beta1.Severity_SEVERITY_WARNING,
- Message: fmt.Sprintf("cannot render FromComposite patches for composed resource %q: cannot apply the %q patch at index 1: spec.doesNotExist: no such field", "cool-resource", "FromCompositeFieldPath"),
+ Message: fmt.Sprintf("cannot render patches for composed resource %q: cannot apply the %q patch at index 1: spec.doesNotExist: no such field", "cool-resource", "FromCompositeFieldPath"),
},
},
Context: &structpb.Struct{Fields: map[string]*structpb.Value{fncontext.KeyEnvironment: structpb.NewStructValue(nil)}},
diff --git a/render.go b/render.go
index e1669b2..56a5c74 100644
--- a/render.go
+++ b/render.go
@@ -9,6 +9,9 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/errors"
"github.com/crossplane/crossplane-runtime/pkg/resource"
+ "github.com/crossplane/function-sdk-go/resource/composed"
+ "github.com/crossplane/function-sdk-go/resource/composite"
+
"github.com/crossplane-contrib/function-patch-and-transform/input/v1beta1"
)
@@ -102,3 +105,71 @@ func RenderToEnvironmentPatches(env *unstructured.Unstructured, o runtime.Object
}
return nil
}
+
+// RenderComposedPatches renders the supplied composed resource by applying all
+// patches that are to or from the supplied composite resource and environment
+// in the order they were defined. Properly selecting the right source or
+// destination between observed and desired resources.
+func RenderComposedPatches( //nolint:gocyclo // just a switch
+ ocd *composed.Unstructured,
+ dcd *composed.Unstructured,
+ oxr *composite.Unstructured,
+ dxr *composite.Unstructured,
+ env *unstructured.Unstructured,
+ ps []v1beta1.Patch,
+) (errs []error, store bool) {
+ for i, p := range ps {
+ switch t := p.Type; t {
+ case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite:
+ // TODO(negz): Should failures to patch the XR be terminal? It could
+ // indicate a required patch failed. A required patch means roughly
+ // "this patch has to succeed before you mutate the resource". This
+ // is useful to make sure we never create a composed resource in the
+ // wrong state. It's less clear how useful it is for the XR, given
+ // we'll only ever be updating it, not creating it.
+
+ // We want to patch the XR from observed composed resources, not
+ // from desired state. This is because folks will typically be
+ // patching from a field that is set once the observed resource is
+ // applied such as its status.
+ if ocd == nil {
+ continue
+ }
+ if err := ApplyToObjects(p, dxr, ocd); err != nil {
+ errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i))
+ }
+ case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment:
+ // TODO(negz): Same as above, but for the Environment. What does it
+ // mean for a required patch to the environment to fail? Should it
+ // be terminal?
+
+ // Run all patches that are from the (observed) composed resource to
+ // the environment.
+ if ocd == nil {
+ continue
+ }
+ if err := ApplyToObjects(p, env, ocd); err != nil {
+ errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i))
+ }
+ // If either of the below renderings return an error, most likely a
+ // required FromComposite or FromEnvironment patch failed. A required
+ // patch means roughly "this patch has to succeed before you mutate the
+ // resource." This is useful to make sure we never create a composed
+ // resource in the wrong state. To that end, we don't want to add this
+ // resource to our accumulated desired state.
+ case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite:
+ if err := ApplyToObjects(p, oxr, dcd); err != nil {
+ errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i))
+ return errs, false
+ }
+ case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment:
+ if err := ApplyToObjects(p, env, dcd); err != nil {
+ errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i))
+ return errs, false
+ }
+ case v1beta1.PatchTypePatchSet:
+ // Already resolved - nothing to do.
+ }
+ }
+ return errs, true
+}
From 7fb1c722974c1ac8e7f1077a119f8c2a2f6069f9 Mon Sep 17 00:00:00 2001
From: Philippe Scorsolini
Date: Thu, 23 Nov 2023 16:54:46 +0100
Subject: [PATCH 5/9] refactor: run environment patches in order
Signed-off-by: Philippe Scorsolini
---
fn.go | 10 +----
go.sum | 129 +++++++++++++++++++++++++++++++++++-------------------
render.go | 57 +++++++-----------------
3 files changed, 101 insertions(+), 95 deletions(-)
diff --git a/fn.go b/fn.go
index 0bc758f..81727e2 100644
--- a/fn.go
+++ b/fn.go
@@ -114,17 +114,11 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe
}
if input.Environment != nil {
- // Run all patches that are from the (observed) XR to the environment.
- if err := RenderToEnvironmentPatches(env, oxr.Resource, input.Environment.Patches); err != nil {
+ // Run all patches that are from the (observed) XR to the environment or from the environment to the (desired) XR.
+ if err := RenderEnvironmentPatches(env, oxr.Resource, dxr.Resource, input.Environment.Patches); err != nil {
response.Fatal(rsp, errors.Wrapf(err, "cannot render ToEnvironment patches from the composite resource"))
return rsp, nil
}
-
- // Run all patches that are from the environment to the (desired) XR.
- if err := RenderFromEnvironmentPatches(dxr.Resource, env, input.Environment.Patches); err != nil {
- response.Fatal(rsp, errors.Wrapf(err, "cannot render FromEnvironment patches to the composite resource"))
- return rsp, nil
- }
}
// Increment this if you emit a warning result.
diff --git a/go.sum b/go.sum
index 6c5ccd7..5c8071d 100644
--- a/go.sum
+++ b/go.sum
@@ -40,10 +40,20 @@ dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
+github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0=
+github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA=
github.com/alecthomas/kong v0.8.1 h1:acZdn3m4lLRobeh3Zi2S2EpnXTd1mOL6U7xVml+vfkY=
github.com/alecthomas/kong v0.8.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
+github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
+github.com/antchfx/htmlquery v1.2.4 h1:qLteofCMe/KGovBI6SQgmou2QNyedFUW+pE+BpeZ494=
+github.com/antchfx/htmlquery v1.2.4/go.mod h1:2xO6iu3EVWs7R2JYqBbp8YzG50gj/ofqs5/0VZoDZLc=
+github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8=
+github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
+github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
+github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
@@ -59,23 +69,15 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/crossplane/crossplane-runtime v1.13.0 h1:EumInUbS8mXV7otwoI3xa0rPczexJOky4XLVlHxxjO0=
-github.com/crossplane/crossplane-runtime v1.13.0/go.mod h1:FuKIC8Mg8hE2gIAMyf2wCPkxkFPz+VnMQiYWBq1/p5A=
-github.com/crossplane/crossplane-runtime v1.14.0 h1:MFo93iOJLvYaMCaCoyH2vFWsHebdA1kv3QdOm7hcm5k=
-github.com/crossplane/crossplane-runtime v1.14.0/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
-github.com/crossplane/crossplane-runtime v1.14.1 h1:TCa7R1N4bDGHjsLhiRxR/mUhwmistlMACHm0kiiYKck=
-github.com/crossplane/crossplane-runtime v1.14.1/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
github.com/crossplane/crossplane-runtime v1.14.2 h1:pV5JMzyzi/kcbeVBVPCat5MHH8zS94MBUapAyGx/Ry0=
github.com/crossplane/crossplane-runtime v1.14.2/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
-github.com/crossplane/function-sdk-go v0.0.0-20231016233407-0a4b30c5dacc h1:hhupaJGj8I4LXhWr9lCm5MZLeeTAiuFF+/mesGi1y/8=
-github.com/crossplane/function-sdk-go v0.0.0-20231016233407-0a4b30c5dacc/go.mod h1:U3UsQAVOCrsUUQAYAyF25PlbSFR2WaLl89dLq58/b2s=
github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8=
github.com/crossplane/function-sdk-go v0.1.0/go.mod h1:oRqHZ6RufpfZJ1N8aT4EfkP+5KpkhOKpWz7SeUDwwcw=
+github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505 h1:eCmYgfRopVn6r8RM1Ra4XQAPwVsjTGfktBj2Dk7yy+Y=
+github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505/go.mod h1:Ov+eoYS2n0Zge/E50zm65meOTYbAHnU6jPt27fQrpbc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE=
-github.com/emicklei/go-restful/v3 v3.10.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -84,9 +86,12 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
+github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
+github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
+github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
+github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
@@ -97,7 +102,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2
github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d h1:zqfo2jECgX5eYQseB/X+uV4Y5ocGOG/vG/LTztUCyPA=
github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d/go.mod h1:6daplAwHHGbUGib4990V3Il26O0OC4aRyvewaaAihaA=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
@@ -110,6 +114,7 @@ github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA=
github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -178,21 +183,48 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ=
+github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
+github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
+github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
+github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
+github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw=
+github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
+github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
+github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
+github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
+github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/hcl/v2 v2.14.1 h1:x0BpjfZ+CYdbiz+8yZTQ+gdLO7IXvOut7Da+XJayx34=
+github.com/hashicorp/hcl/v2 v2.14.1/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0=
+github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s=
+github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM=
+github.com/hashicorp/terraform-plugin-go v0.14.0 h1:ttnSlS8bz3ZPYbMb84DpcPhY4F5DsQtcAS7cHo8uvP4=
+github.com/hashicorp/terraform-plugin-go v0.14.0/go.mod h1:2nNCBeRLaenyQEi78xrGrs9hMbulveqG/zDMQSvVJTE=
+github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs=
+github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4=
+github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.0 h1:FtCLTiTcykdsURXPt/ku7fYXm3y19nbzbZcUxHx9RbI=
+github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.0/go.mod h1:80wf5oad1tW+oLnbXS4UTYmDCrl7BuN1Q+IA91X1a4Y=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
+github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
+github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
+github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
+github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@@ -208,6 +240,7 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -221,6 +254,16 @@ github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPn
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
+github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
+github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU=
+github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8=
+github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
+github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
+github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
+github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
+github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -229,9 +272,13 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
+github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
-github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
+github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
+github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
+github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
+github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -249,9 +296,8 @@ github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+Pymzi
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
+github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
-github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
@@ -270,11 +316,25 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/tmccombs/hcl2json v0.3.3 h1:+DLNYqpWE0CsOQiEZu+OZm5ZBImake3wtITYxQ8uLFQ=
+github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w=
+github.com/upbound/provider-aws v0.43.0 h1:ycb6ybc1Dauy0DKiuXShbcjuh7GmPJRBjNngd5dluz8=
+github.com/upbound/provider-aws v0.43.0/go.mod h1:m7hoCp3D469sk1vaRh8u4hC8SmpPBJO70JrZS9p2H/U=
+github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
+github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
+github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
+github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
+github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
+github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/zclconf/go-cty v1.11.0 h1:726SxLdi2SDnjY+BStqB9J1hNp4+2WlzyXLuimibIe0=
+github.com/zclconf/go-cty v1.11.0/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
@@ -284,6 +344,7 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
+go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
@@ -333,8 +394,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
-golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -380,8 +440,6 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
-golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU=
golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -395,7 +453,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
+golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
+golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -505,15 +564,12 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
-golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc=
-gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
@@ -579,8 +635,6 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -599,8 +653,6 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
-google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -625,6 +677,7 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
@@ -639,39 +692,25 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM=
-k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc=
k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY=
k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0=
-k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08=
-k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc=
k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU=
k8s.io/apiextensions-apiserver v0.28.4/go.mod h1:pgQIZ1U8eJSMQcENew/0ShUTlePcSGFq6dxSxf2mwPM=
-k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A=
-k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8=
k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8=
k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg=
-k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4=
-k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo=
k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY=
k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4=
-k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI=
-k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8=
k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo=
k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU=
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
-k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
-k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf h1:iTzha1p7Fi83476ypNSz8nV9iR9932jIIs26F7gNLsU=
k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/controller-runtime v0.15.0 h1:ML+5Adt3qZnMSYxZ7gAverBLNPSMQEibtzAgp0UPojU=
-sigs.k8s.io/controller-runtime v0.15.0/go.mod h1:7ngYvp1MLT+9GeZ+6lH3LOlcHkp/+tzA/fmHa4iq9kk=
sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4=
sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0=
sigs.k8s.io/controller-tools v0.13.0 h1:NfrvuZ4bxyolhDBt/rCZhDnx3M2hzlhgo5n3Iv2RykI=
@@ -680,7 +719,5 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMm
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
-sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
-sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
diff --git a/render.go b/render.go
index 56a5c74..44da046 100644
--- a/render.go
+++ b/render.go
@@ -2,7 +2,6 @@ package main
import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
- "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/json"
@@ -61,46 +60,22 @@ func RenderFromJSON(o resource.Object, data []byte) error {
return nil
}
-// RenderFromCompositePatches renders the supplied composed resource by applying
-// all patches that are _from_ the supplied composite resource.
-func RenderFromCompositePatches(cd resource.Composed, xr resource.Composite, p []v1beta1.Patch) error {
- for i := range p {
- if err := Apply(p[i], xr, cd, v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite); err != nil {
- return errors.Wrapf(err, errFmtPatch, p[i].GetType(), i)
- }
- }
- return nil
-}
-
-// RenderToCompositePatches renders the supplied composite resource by applying
-// all patches that are _from_ the supplied composed resource.
-func RenderToCompositePatches(xr resource.Composite, cd resource.Composed, p []v1beta1.Patch) error {
- for i := range p {
- if err := Apply(p[i], xr, cd, v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite); err != nil {
- return errors.Wrapf(err, errFmtPatch, p[i].GetType(), i)
- }
- }
- return nil
-}
-
-// RenderFromEnvironmentPatches renders the supplied object (an XR or composed
-// resource) by applying all patches that are from the supplied environment.
-func RenderFromEnvironmentPatches(o runtime.Object, env *unstructured.Unstructured, p []v1beta1.Patch) error {
- for i := range p {
- if err := ApplyToObjects(p[i], env, o, v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment); err != nil {
- return errors.Wrapf(err, errFmtPatch, p[i].Type, i)
- }
- }
- return nil
-}
-
-// RenderToEnvironmentPatches renders the supplied environment by applying all
-// patches that are to the environment, from the supplied object (an XR or
-// composed resource).
-func RenderToEnvironmentPatches(env *unstructured.Unstructured, o runtime.Object, p []v1beta1.Patch) error {
- for i := range p {
- if err := ApplyToObjects(p[i], env, o, v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment); err != nil {
- return errors.Wrapf(err, errFmtPatch, p[i].Type, i)
+// RenderEnvironmentPatches renders the supplied environment by applying all
+// patches that are to the environment, from the supplied XR.
+func RenderEnvironmentPatches(env *unstructured.Unstructured, oxr, dxr *composite.Unstructured, ps []v1beta1.Patch) error {
+ for i, p := range ps {
+ p := p
+ switch p.Type {
+ case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment:
+ if err := ApplyToObjects(p, env, oxr); err != nil {
+ return errors.Wrapf(err, errFmtPatch, p.Type, i)
+ }
+ case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment:
+ if err := ApplyToObjects(p, env, dxr); err != nil {
+ return errors.Wrapf(err, errFmtPatch, p.Type, i)
+ }
+ case v1beta1.PatchTypePatchSet, v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite, v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite:
+ // nothing to do
}
}
return nil
From 74aefe60226e630e8d71d5f034a215e008b58abb Mon Sep 17 00:00:00 2001
From: Philippe Scorsolini
Date: Thu, 23 Nov 2023 17:04:17 +0100
Subject: [PATCH 6/9] fix: correct patches in input CRD
Signed-off-by: Philippe Scorsolini
---
fn_test.go | 134 ++++---
input/v1beta1/resources_common.go | 16 +-
input/v1beta1/resources_patches.go | 110 +++++-
input/v1beta1/zz_generated.deepcopy.go | 64 ++-
.../input/pt.fn.crossplane.io_resources.yaml | 48 ++-
patches.go | 82 ++--
patches_test.go | 365 +++++++++++-------
render.go | 17 +-
validate.go | 37 +-
validate_test.go | 62 +--
10 files changed, 586 insertions(+), 349 deletions(-)
diff --git a/fn_test.go b/fn_test.go
index 78a25d1..806038e 100644
--- a/fn_test.go
+++ b/fn_test.go
@@ -156,23 +156,25 @@ func TestRunFunction(t *testing.T) {
{
Name: "cool-resource",
Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)},
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.widgets"),
- ToFieldPath: ptr.To[string]("spec.watchers"),
- Transforms: []v1beta1.Transform{
- {
- Type: v1beta1.TransformTypeConvert,
- Convert: &v1beta1.ConvertTransform{
- ToType: v1beta1.TransformIOTypeInt64,
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.widgets"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ Transforms: []v1beta1.Transform{
+ {
+ Type: v1beta1.TransformTypeConvert,
+ Convert: &v1beta1.ConvertTransform{
+ ToType: v1beta1.TransformIOTypeInt64,
+ },
},
- },
- {
- Type: v1beta1.TransformTypeMath,
- Math: &v1beta1.MathTransform{
- Type: v1beta1.MathTransformTypeMultiply,
- Multiply: ptr.To[int64](3),
+ {
+ Type: v1beta1.TransformTypeMath,
+ Math: &v1beta1.MathTransform{
+ Type: v1beta1.MathTransformTypeMultiply,
+ Multiply: ptr.To[int64](3),
+ },
},
},
},
@@ -221,23 +223,25 @@ func TestRunFunction(t *testing.T) {
// patch the resource named "cool-resource" in
// the desired resources array.
Name: "cool-resource",
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.widgets"),
- ToFieldPath: ptr.To[string]("spec.watchers"),
- Transforms: []v1beta1.Transform{
- {
- Type: v1beta1.TransformTypeConvert,
- Convert: &v1beta1.ConvertTransform{
- ToType: v1beta1.TransformIOTypeInt64,
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.widgets"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ Transforms: []v1beta1.Transform{
+ {
+ Type: v1beta1.TransformTypeConvert,
+ Convert: &v1beta1.ConvertTransform{
+ ToType: v1beta1.TransformIOTypeInt64,
+ },
},
- },
- {
- Type: v1beta1.TransformTypeMath,
- Math: &v1beta1.MathTransform{
- Type: v1beta1.MathTransformTypeMultiply,
- Multiply: ptr.To[int64](3),
+ {
+ Type: v1beta1.TransformTypeMath,
+ Math: &v1beta1.MathTransform{
+ Type: v1beta1.MathTransformTypeMultiply,
+ Multiply: ptr.To[int64](3),
+ },
},
},
},
@@ -291,11 +295,13 @@ func TestRunFunction(t *testing.T) {
// patch the resource named "cool-resource" in
// the desired resources array.
Name: "cool-resource",
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.widgets"),
- ToFieldPath: ptr.To[string]("spec.watchers"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.widgets"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ },
},
},
},
@@ -387,25 +393,29 @@ func TestRunFunction(t *testing.T) {
// patch the resource named "cool-resource" in
// the desired resources array.
Name: "cool-resource",
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
// This patch should work.
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.widgets"),
- ToFieldPath: ptr.To[string]("spec.watchers"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.widgets"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ },
},
{
// This patch should return an error,
// because the required path does not
// exist.
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.doesNotExist"),
- ToFieldPath: ptr.To[string]("spec.explode"),
- Policy: &v1beta1.PatchPolicy{
- FromFieldPath: func() *v1beta1.FromFieldPathPolicy {
- r := v1beta1.FromFieldPathPolicyRequired
- return &r
- }(),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.doesNotExist"),
+ ToFieldPath: ptr.To[string]("spec.explode"),
+ Policy: &v1beta1.PatchPolicy{
+ FromFieldPath: func() *v1beta1.FromFieldPathPolicy {
+ r := v1beta1.FromFieldPathPolicyRequired
+ return &r
+ }(),
+ },
},
},
},
@@ -572,23 +582,25 @@ func TestRunFunction(t *testing.T) {
{
Name: "cool-resource",
Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)},
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
- Type: v1beta1.PatchTypeToCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.widgets"),
- ToFieldPath: ptr.To[string]("spec.watchers"),
- Transforms: []v1beta1.Transform{
- {
- Type: v1beta1.TransformTypeConvert,
- Convert: &v1beta1.ConvertTransform{
- ToType: v1beta1.TransformIOTypeInt64,
+ Type: v1beta1.PatchTypeToCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.widgets"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ Transforms: []v1beta1.Transform{
+ {
+ Type: v1beta1.TransformTypeConvert,
+ Convert: &v1beta1.ConvertTransform{
+ ToType: v1beta1.TransformIOTypeInt64,
+ },
},
- },
- {
- Type: v1beta1.TransformTypeMath,
- Math: &v1beta1.MathTransform{
- Type: v1beta1.MathTransformTypeMultiply,
- Multiply: ptr.To[int64](3),
+ {
+ Type: v1beta1.TransformTypeMath,
+ Math: &v1beta1.MathTransform{
+ Type: v1beta1.MathTransformTypeMultiply,
+ Multiply: ptr.To[int64](3),
+ },
},
},
},
diff --git a/input/v1beta1/resources_common.go b/input/v1beta1/resources_common.go
index abed367..c1d750b 100644
--- a/input/v1beta1/resources_common.go
+++ b/input/v1beta1/resources_common.go
@@ -28,7 +28,19 @@ type PatchSet struct {
Name string `json:"name"`
// Patches will be applied as an overlay to the base resource.
- Patches []Patch `json:"patches"`
+ Patches []PatchSetPatch `json:"patches"`
+}
+
+// GetComposedPatches returns the composed patches from the patch set.
+func (ps *PatchSet) GetComposedPatches() []ComposedPatch {
+ out := make([]ComposedPatch, len(ps.Patches))
+ for i, p := range ps.Patches {
+ out[i] = ComposedPatch{
+ Type: p.GetType(),
+ Patch: p.Patch,
+ }
+ }
+ return out
}
// ComposedTemplate is used to provide information about how the composed
@@ -49,7 +61,7 @@ type ComposedTemplate struct {
// Patches to and from the composed resource.
// +optional
- Patches []Patch `json:"patches,omitempty"`
+ Patches []ComposedPatch `json:"patches,omitempty"`
// ConnectionDetails lists the propagation secret keys from this composed
// resource to the composition instance connection secret.
diff --git a/input/v1beta1/resources_patches.go b/input/v1beta1/resources_patches.go
index 8924362..9478a79 100644
--- a/input/v1beta1/resources_patches.go
+++ b/input/v1beta1/resources_patches.go
@@ -57,21 +57,91 @@ type Environment struct {
// composition's resources are composed. These patches are between the XR
// and the Environment. Either from the Environment to the XR, or vice
// versa.
- Patches []Patch `json:"patches,omitempty"`
+ Patches []EnvironmentPatch `json:"patches,omitempty"`
}
-// Patch objects are applied between composite and composed resources. Their
-// behaviour depends on the Type selected. The default Type,
-// FromCompositeFieldPath, copies a value from the composite resource to
-// the composed resource, applying any defined transformers.
-type Patch struct {
+// EnvironmentPatch objects are applied between the composite resource and
+// the environment. Their behaviour depends on the Type selected. The default
+// Type, FromCompositeFieldPath, copies a value from the composite resource
+// to the environment, applying any defined transformers.
+type EnvironmentPatch struct {
// Type sets the patching behaviour to be used. Each patch type may require
// its own fields to be set on the Patch object.
// +optional
- // +kubebuilder:validation:Enum=FromCompositeFieldPath;PatchSet;ToCompositeFieldPath;CombineFromComposite;CombineToComposite
+ // +kubebuilder:validation:Enum=FromCompositeFieldPath;ToCompositeFieldPath;CombineFromComposite;CombineToComposite
// +kubebuilder:default=FromCompositeFieldPath
Type PatchType `json:"type,omitempty"`
+ Patch `json:",inline"`
+}
+
+// GetType returns the patch type. If the type is not set, it returns the default type.
+func (ep *EnvironmentPatch) GetType() PatchType {
+ if ep.Type == "" {
+ return PatchTypeFromCompositeFieldPath
+ }
+ return ep.Type
+}
+
+// ComposedPatch objects are applied between composite and composed resources.
+// Their behaviour depends on the Type selected. The default Type,
+// FromCompositeFieldPath, copies a value from the composite resource to the
+// composed resource, applying any defined transformers.
+type ComposedPatch struct {
+ // Type sets the patching behaviour to be used. Each patch type may require
+ // its own fields to be set on the ComposedPatch object.
+ // +optional
+ // +kubebuilder:validation:Enum=FromCompositeFieldPath;PatchSet;ToCompositeFieldPath;CombineFromComposite;CombineToComposite;FromEnvironmentFieldPath;ToEnvironmentFieldPath;CombineFromEnvironment;CombineToEnvironment
+ // +kubebuilder:default=FromCompositeFieldPath
+ Type PatchType `json:"type,omitempty"`
+
+ // PatchSetName to include patches from. Required when type is PatchSet.
+ // +optional
+ PatchSetName *string `json:"patchSetName,omitempty"`
+
+ Patch `json:",inline"`
+}
+
+// GetType returns the patch type. If the type is not set, it returns the default type.
+func (p *ComposedPatch) GetType() PatchType {
+ if p.Type == "" {
+ return PatchTypeFromCompositeFieldPath
+ }
+ return p.Type
+}
+
+// GetPatchSetName returns the PatchSetName for this ComposedPatch, or an empty
+// string if it is nil.
+func (p *ComposedPatch) GetPatchSetName() string {
+ if p.PatchSetName == nil {
+ return ""
+ }
+ return *p.PatchSetName
+}
+
+// PatchSetPatch defines a set of Patches that can be referenced by name by
+// other patches of type PatchSet.
+type PatchSetPatch struct {
+ // Type sets the patching behaviour to be used. Each patch type may require
+ // its own fields to be set on the ComposedPatch object.
+ // +optional
+ // +kubebuilder:validation:Enum=FromCompositeFieldPath;ToCompositeFieldPath;CombineFromComposite;CombineToComposite;FromEnvironmentFieldPath;ToEnvironmentFieldPath;CombineFromEnvironment;CombineToEnvironment
+ // +kubebuilder:default=FromCompositeFieldPath
+ Type PatchType `json:"type,omitempty"`
+
+ Patch `json:",inline"`
+}
+
+// GetType returns the patch type. If the type is not set, it returns the default type.
+func (psp *PatchSetPatch) GetType() PatchType {
+ if psp.Type == "" {
+ return PatchTypeFromCompositeFieldPath
+ }
+ return psp.Type
+}
+
+// Patch defines a patch between a source and destination.
+type Patch struct {
// FromFieldPath is the path of the field on the resource whose value is
// to be used as input. Required when type is FromCompositeFieldPath or
// ToCompositeFieldPath.
@@ -89,10 +159,6 @@ type Patch struct {
// +optional
ToFieldPath *string `json:"toFieldPath,omitempty"`
- // PatchSetName to include patches from. Required when type is PatchSet.
- // +optional
- PatchSetName *string `json:"patchSetName,omitempty"`
-
// Transforms are the list of functions that are used as a FIFO pipe for the
// input to be transformed.
// +optional
@@ -114,17 +180,25 @@ func (p *Patch) GetFromFieldPath() string {
// GetToFieldPath returns the ToFieldPath for this Patch, or an empty string if it is nil.
func (p *Patch) GetToFieldPath() string {
if p.ToFieldPath == nil {
- return ""
+ // Default to patching the same field on the composed resource.
+ return p.GetFromFieldPath()
}
return *p.ToFieldPath
}
-// GetType returns the patch type. If the type is not set, it returns the default type.
-func (p *Patch) GetType() PatchType {
- if p.Type == "" {
- return PatchTypeFromCompositeFieldPath
- }
- return p.Type
+// GetCombine returns the Combine for this ComposedPatch, or nil if it is nil.
+func (p *Patch) GetCombine() *Combine {
+ return p.Combine
+}
+
+// GetTransforms returns the Transforms for this ComposedPatch, or nil if it is nil.
+func (p *Patch) GetTransforms() []Transform {
+ return p.Transforms
+}
+
+// GetPolicy returns the PatchPolicy for this ComposedPatch, or nil if it is nil.
+func (p *Patch) GetPolicy() *PatchPolicy {
+ return p.Policy
}
// A CombineVariable defines the source of a value that is combined with
diff --git a/input/v1beta1/zz_generated.deepcopy.go b/input/v1beta1/zz_generated.deepcopy.go
index fa224c5..5787099 100644
--- a/input/v1beta1/zz_generated.deepcopy.go
+++ b/input/v1beta1/zz_generated.deepcopy.go
@@ -49,6 +49,27 @@ func (in *CombineVariable) DeepCopy() *CombineVariable {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ComposedPatch) DeepCopyInto(out *ComposedPatch) {
+ *out = *in
+ if in.PatchSetName != nil {
+ in, out := &in.PatchSetName, &out.PatchSetName
+ *out = new(string)
+ **out = **in
+ }
+ in.Patch.DeepCopyInto(&out.Patch)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComposedPatch.
+func (in *ComposedPatch) DeepCopy() *ComposedPatch {
+ if in == nil {
+ return nil
+ }
+ out := new(ComposedPatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComposedTemplate) DeepCopyInto(out *ComposedTemplate) {
*out = *in
@@ -59,7 +80,7 @@ func (in *ComposedTemplate) DeepCopyInto(out *ComposedTemplate) {
}
if in.Patches != nil {
in, out := &in.Patches, &out.Patches
- *out = make([]Patch, len(*in))
+ *out = make([]ComposedPatch, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -145,7 +166,7 @@ func (in *Environment) DeepCopyInto(out *Environment) {
*out = *in
if in.Patches != nil {
in, out := &in.Patches, &out.Patches
- *out = make([]Patch, len(*in))
+ *out = make([]EnvironmentPatch, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -162,6 +183,22 @@ func (in *Environment) DeepCopy() *Environment {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *EnvironmentPatch) DeepCopyInto(out *EnvironmentPatch) {
+ *out = *in
+ in.Patch.DeepCopyInto(&out.Patch)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvironmentPatch.
+func (in *EnvironmentPatch) DeepCopy() *EnvironmentPatch {
+ if in == nil {
+ return nil
+ }
+ out := new(EnvironmentPatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MapTransform) DeepCopyInto(out *MapTransform) {
*out = *in
@@ -296,11 +333,6 @@ func (in *Patch) DeepCopyInto(out *Patch) {
*out = new(string)
**out = **in
}
- if in.PatchSetName != nil {
- in, out := &in.PatchSetName, &out.PatchSetName
- *out = new(string)
- **out = **in
- }
if in.Transforms != nil {
in, out := &in.Transforms, &out.Transforms
*out = make([]Transform, len(*in))
@@ -350,7 +382,7 @@ func (in *PatchSet) DeepCopyInto(out *PatchSet) {
*out = *in
if in.Patches != nil {
in, out := &in.Patches, &out.Patches
- *out = make([]Patch, len(*in))
+ *out = make([]PatchSetPatch, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
@@ -367,6 +399,22 @@ func (in *PatchSet) DeepCopy() *PatchSet {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PatchSetPatch) DeepCopyInto(out *PatchSetPatch) {
+ *out = *in
+ in.Patch.DeepCopyInto(&out.Patch)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PatchSetPatch.
+func (in *PatchSetPatch) DeepCopy() *PatchSetPatch {
+ if in == nil {
+ return nil
+ }
+ out := new(PatchSetPatch)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ReadinessCheck) DeepCopyInto(out *ReadinessCheck) {
*out = *in
diff --git a/package/input/pt.fn.crossplane.io_resources.yaml b/package/input/pt.fn.crossplane.io_resources.yaml
index 9751e43..1b68e97 100644
--- a/package/input/pt.fn.crossplane.io_resources.yaml
+++ b/package/input/pt.fn.crossplane.io_resources.yaml
@@ -37,10 +37,11 @@ spec:
between the XR and the Environment. Either from the Environment
to the XR, or vice versa.
items:
- description: Patch objects are applied between composite and composed
- resources. Their behaviour depends on the Type selected. The default
- Type, FromCompositeFieldPath, copies a value from the composite
- resource to the composed resource, applying any defined transformers.
+ description: EnvironmentPatch objects are applied between the composite
+ resource and the environment. Their behaviour depends on the Type
+ selected. The default Type, FromCompositeFieldPath, copies a value
+ from the composite resource to the environment, applying any defined
+ transformers.
properties:
combine:
description: Combine is the patch configuration for a CombineFromComposite,
@@ -91,10 +92,6 @@ spec:
whose value is to be used as input. Required when type is
FromCompositeFieldPath or ToCompositeFieldPath.
type: string
- patchSetName:
- description: PatchSetName to include patches from. Required
- when type is PatchSet.
- type: string
policy:
description: Policy configures the specifics of patching behaviour.
properties:
@@ -322,7 +319,6 @@ spec:
object.
enum:
- FromCompositeFieldPath
- - PatchSet
- ToCompositeFieldPath
- CombineFromComposite
- CombineToComposite
@@ -350,11 +346,8 @@ spec:
patches:
description: Patches will be applied as an overlay to the base resource.
items:
- description: Patch objects are applied between composite and composed
- resources. Their behaviour depends on the Type selected. The
- default Type, FromCompositeFieldPath, copies a value from the
- composite resource to the composed resource, applying any defined
- transformers.
+ description: PatchSetPatch defines a set of Patches that can be
+ referenced by name by other patches of type PatchSet.
properties:
combine:
description: Combine is the patch configuration for a CombineFromComposite,
@@ -406,10 +399,6 @@ spec:
resource whose value is to be used as input. Required when
type is FromCompositeFieldPath or ToCompositeFieldPath.
type: string
- patchSetName:
- description: PatchSetName to include patches from. Required
- when type is PatchSet.
- type: string
policy:
description: Policy configures the specifics of patching behaviour.
properties:
@@ -638,13 +627,16 @@ spec:
default: FromCompositeFieldPath
description: Type sets the patching behaviour to be used.
Each patch type may require its own fields to be set on
- the Patch object.
+ the ComposedPatch object.
enum:
- FromCompositeFieldPath
- - PatchSet
- ToCompositeFieldPath
- CombineFromComposite
- CombineToComposite
+ - FromEnvironmentFieldPath
+ - ToEnvironmentFieldPath
+ - CombineFromEnvironment
+ - CombineToEnvironment
type: string
type: object
type: array
@@ -720,11 +712,11 @@ spec:
patches:
description: Patches to and from the composed resource.
items:
- description: Patch objects are applied between composite and composed
- resources. Their behaviour depends on the Type selected. The
- default Type, FromCompositeFieldPath, copies a value from the
- composite resource to the composed resource, applying any defined
- transformers.
+ description: ComposedPatch objects are applied between composite
+ and composed resources. Their behaviour depends on the Type
+ selected. The default Type, FromCompositeFieldPath, copies a
+ value from the composite resource to the composed resource,
+ applying any defined transformers.
properties:
combine:
description: Combine is the patch configuration for a CombineFromComposite,
@@ -1008,13 +1000,17 @@ spec:
default: FromCompositeFieldPath
description: Type sets the patching behaviour to be used.
Each patch type may require its own fields to be set on
- the Patch object.
+ the ComposedPatch object.
enum:
- FromCompositeFieldPath
- PatchSet
- ToCompositeFieldPath
- CombineFromComposite
- CombineToComposite
+ - FromEnvironmentFieldPath
+ - ToEnvironmentFieldPath
+ - CombineFromEnvironment
+ - CombineToEnvironment
type: string
type: object
type: array
diff --git a/patches.go b/patches.go
index 3ac372f..efe1056 100644
--- a/patches.go
+++ b/patches.go
@@ -25,16 +25,32 @@ const (
errFmtExpandingArrayFieldPaths = "cannot expand ToFieldPath %s"
)
+// A PatchInterface is a patch that can be applied between resources.
+type PatchInterface interface {
+ GetType() v1beta1.PatchType
+ GetFromFieldPath() string
+ GetToFieldPath() string
+ GetCombine() *v1beta1.Combine
+ GetTransforms() []v1beta1.Transform
+ GetPolicy() *v1beta1.PatchPolicy
+}
+
+// PatchWithPatchSetName is a PatchInterface that has a PatchSetName field.
+type PatchWithPatchSetName interface {
+ PatchInterface
+ GetPatchSetName() string
+}
+
// Apply executes a patching operation between the from and to resources.
// Applies all patch types unless an 'only' filter is supplied.
-func Apply(p v1beta1.Patch, xr resource.Composite, cd resource.Composed, only ...v1beta1.PatchType) error {
+func Apply(p PatchInterface, xr resource.Composite, cd resource.Composed, only ...v1beta1.PatchType) error {
return ApplyToObjects(p, xr, cd, only...)
}
// ApplyToObjects works like Apply but accepts any kind of runtime.Object. It
// might be vulnerable to conversion panics (see
// https://github.com/crossplane/crossplane/pull/3394 for details).
-func ApplyToObjects(p v1beta1.Patch, a, b runtime.Object, only ...v1beta1.PatchType) error {
+func ApplyToObjects(p PatchInterface, a, b runtime.Object, only ...v1beta1.PatchType) error {
if filterPatch(p, only...) {
return nil
}
@@ -51,11 +67,11 @@ func ApplyToObjects(p v1beta1.Patch, a, b runtime.Object, only ...v1beta1.PatchT
case v1beta1.PatchTypePatchSet:
// Already resolved - nothing to do.
}
- return errors.Errorf(errFmtInvalidPatchType, p.Type)
+ return errors.Errorf(errFmtInvalidPatchType, p.GetType())
}
// filterPatch returns true if patch should be filtered (not applied)
-func filterPatch(p v1beta1.Patch, only ...v1beta1.PatchType) bool {
+func filterPatch(p PatchInterface, only ...v1beta1.PatchType) bool {
// filter does not apply if not set
if len(only) == 0 {
return false
@@ -70,9 +86,9 @@ func filterPatch(p v1beta1.Patch, only ...v1beta1.PatchType) bool {
}
// ResolveTransforms applies a list of transforms to a patch value.
-func ResolveTransforms(c v1beta1.Patch, input any) (any, error) {
+func ResolveTransforms(ts []v1beta1.Transform, input any) (any, error) {
var err error
- for i, t := range c.Transforms {
+ for i, t := range ts {
if input, err = Resolve(t, input); err != nil {
// TODO(negz): Including the type might help find the offending transform faster.
return nil, errors.Wrapf(err, errFmtTransformAtIndex, i)
@@ -84,14 +100,9 @@ func ResolveTransforms(c v1beta1.Patch, input any) (any, error) {
// ApplyFromFieldPathPatch patches the "to" resource, using a source field
// on the "from" resource. Values may be transformed if any are defined on
// the patch.
-func ApplyFromFieldPathPatch(p v1beta1.Patch, from, to runtime.Object) error {
- if p.FromFieldPath == nil {
- return errors.Errorf(errFmtRequiredField, "FromFieldPath", p.Type)
- }
-
- // Default to patching the same field on the composed resource.
- if p.ToFieldPath == nil {
- p.ToFieldPath = p.FromFieldPath
+func ApplyFromFieldPathPatch(p PatchInterface, from, to runtime.Object) error {
+ if p.GetFromFieldPath() == "" {
+ return errors.Errorf(errFmtRequiredField, "FromFieldPath", p.GetType())
}
fromMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(from)
@@ -99,8 +110,8 @@ func ApplyFromFieldPathPatch(p v1beta1.Patch, from, to runtime.Object) error {
return err
}
- in, err := fieldpath.Pave(fromMap).GetValue(*p.FromFieldPath)
- if IsOptionalFieldPathNotFound(err, p.Policy) {
+ in, err := fieldpath.Pave(fromMap).GetValue(p.GetFromFieldPath())
+ if IsOptionalFieldPathNotFound(err, p.GetPolicy()) {
return nil
}
if err != nil {
@@ -108,35 +119,36 @@ func ApplyFromFieldPathPatch(p v1beta1.Patch, from, to runtime.Object) error {
}
// Apply transform pipeline
- out, err := ResolveTransforms(p, in)
+ out, err := ResolveTransforms(p.GetTransforms(), in)
if err != nil {
return err
}
- // Patch all expanded fields if the ToFieldPath contains wildcards
- if strings.Contains(*p.ToFieldPath, "[*]") {
- return patchFieldValueToMultiple(*p.ToFieldPath, out, to)
+ // ComposedPatch all expanded fields if the ToFieldPath contains wildcards
+ if strings.Contains(p.GetToFieldPath(), "[*]") {
+ return patchFieldValueToMultiple(p.GetToFieldPath(), out, to)
}
- return errors.Wrap(patchFieldValueToObject(*p.ToFieldPath, out, to), "cannot patch to object")
+ return errors.Wrap(patchFieldValueToObject(p.GetToFieldPath(), out, to), "cannot patch to object")
}
// ApplyCombineFromVariablesPatch patches the "to" resource, taking a list of
// input variables and combining them into a single output value.
// The single output value may then be further transformed if they are defined
// on the patch.
-func ApplyCombineFromVariablesPatch(p v1beta1.Patch, from, to runtime.Object) error {
+func ApplyCombineFromVariablesPatch(p PatchInterface, from, to runtime.Object) error {
// Combine patch requires configuration
- if p.Combine == nil {
- return errors.Errorf(errFmtRequiredField, "Combine", p.Type)
+ if p.GetCombine() == nil {
+ return errors.Errorf(errFmtRequiredField, "Combine", p.GetType())
}
// Destination field path is required since we can't default to multiple
// fields.
- if p.ToFieldPath == nil {
- return errors.Errorf(errFmtRequiredField, "ToFieldPath", p.Type)
+ if p.GetToFieldPath() == "" {
+ return errors.Errorf(errFmtRequiredField, "ToFieldPath", p.GetType())
}
- vl := len(p.Combine.Variables)
+ combine := p.GetCombine()
+ vl := len(combine.Variables)
if vl < 1 {
return errors.New(errCombineRequiresVariables)
@@ -153,7 +165,7 @@ func ApplyCombineFromVariablesPatch(p v1beta1.Patch, from, to runtime.Object) er
// NOTE: This currently assumes all variables define a 'fromFieldPath'
// value. If we add new variable types, this may not be the case and
// this code may be better served split out into a dedicated function.
- for i, sp := range p.Combine.Variables {
+ for i, sp := range combine.Variables {
iv, err := fieldpath.Pave(fromMap).GetValue(sp.FromFieldPath)
// If any source field is not found, we will not
@@ -162,7 +174,7 @@ func ApplyCombineFromVariablesPatch(p v1beta1.Patch, from, to runtime.Object) er
// number of inputs (e.g. a string format
// expecting 3 fields '%s-%s-%s' but only
// receiving 2 values).
- if IsOptionalFieldPathNotFound(err, p.Policy) {
+ if IsOptionalFieldPathNotFound(err, p.GetPolicy()) {
return nil
}
if err != nil {
@@ -172,18 +184,18 @@ func ApplyCombineFromVariablesPatch(p v1beta1.Patch, from, to runtime.Object) er
}
// Combine input values
- cb, err := Combine(*p.Combine, in)
+ cb, err := Combine(*p.GetCombine(), in)
if err != nil {
return err
}
// Apply transform pipeline
- out, err := ResolveTransforms(p, cb)
+ out, err := ResolveTransforms(p.GetTransforms(), cb)
if err != nil {
return err
}
- return errors.Wrap(patchFieldValueToObject(*p.ToFieldPath, out, to), "cannot patch to object")
+ return errors.Wrap(patchFieldValueToObject(p.GetToFieldPath(), out, to), "cannot patch to object")
}
// IsOptionalFieldPathNotFound returns true if the supplied error indicates a
@@ -231,19 +243,19 @@ func CombineString(format string, vars []any) string {
// ComposedTemplates returns the supplied composed resource templates with any
// supplied patchsets dereferenced.
func ComposedTemplates(pss []v1beta1.PatchSet, cts []v1beta1.ComposedTemplate) ([]v1beta1.ComposedTemplate, error) {
- pn := make(map[string][]v1beta1.Patch)
+ pn := make(map[string][]v1beta1.ComposedPatch)
for _, s := range pss {
for _, p := range s.Patches {
if p.Type == v1beta1.PatchTypePatchSet {
return nil, errors.New(errPatchSetType)
}
}
- pn[s.Name] = s.Patches
+ pn[s.Name] = s.GetComposedPatches()
}
ct := make([]v1beta1.ComposedTemplate, len(cts))
for i, r := range cts {
- var po []v1beta1.Patch
+ var po []v1beta1.ComposedPatch
for _, p := range r.Patches {
if p.Type != v1beta1.PatchTypePatchSet {
po = append(po, p)
diff --git a/patches_test.go b/patches_test.go
index b6f6986..a98f158 100644
--- a/patches_test.go
+++ b/patches_test.go
@@ -28,7 +28,7 @@ func TestPatchApply(t *testing.T) {
}
type args struct {
- patch v1beta1.Patch
+ patch v1beta1.ComposedPatch
xr *composite.Unstructured
cd *composed.Unstructured
only []v1beta1.PatchType
@@ -47,7 +47,7 @@ func TestPatchApply(t *testing.T) {
"InvalidCompositeFieldPathPatch": {
reason: "Should return error when required fields not passed to applyFromFieldPathPatch",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: v1beta1.PatchTypeFromCompositeFieldPath,
// This is missing fields.
},
@@ -61,7 +61,7 @@ func TestPatchApply(t *testing.T) {
"Invalidv1.PatchType": {
reason: "Should return an error if an invalid patch type is specified",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: "invalid-patchtype",
},
xr: &composite.Unstructured{},
@@ -74,10 +74,12 @@ func TestPatchApply(t *testing.T) {
"ValidCompositeFieldPathPatch": {
reason: "Should correctly apply a CompositeFieldPathPatch with valid settings",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.labels"),
- ToFieldPath: ptr.To[string]("metadata.labels"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.labels"),
+ ToFieldPath: ptr.To[string]("metadata.labels"),
+ },
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -119,10 +121,12 @@ func TestPatchApply(t *testing.T) {
"ValidCompositeFieldPathPatchWithWildcards": {
reason: "When passed a wildcarded path, adds a field to each element of an array",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.name"),
- ToFieldPath: ptr.To[string]("metadata.ownerReferences[*].name"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.name"),
+ ToFieldPath: ptr.To[string]("metadata.ownerReferences[*].name"),
+ },
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -172,10 +176,12 @@ func TestPatchApply(t *testing.T) {
"InvalidCompositeFieldPathPatchWithWildcards": {
reason: "When passed a wildcarded path, throws an error if ToFieldPath cannot be expanded",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.name"),
- ToFieldPath: ptr.To[string]("metadata.ownerReferences[*].badField"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.name"),
+ ToFieldPath: ptr.To[string]("metadata.ownerReferences[*].badField"),
+ },
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -210,10 +216,12 @@ func TestPatchApply(t *testing.T) {
"MissingOptionalFieldPath": {
reason: "A FromFieldPath patch should be a no-op when an optional fromFieldPath doesn't exist",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.labels"),
- ToFieldPath: ptr.To[string]("metadata.labels"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.labels"),
+ ToFieldPath: ptr.To[string]("metadata.labels"),
+ },
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -250,16 +258,18 @@ func TestPatchApply(t *testing.T) {
"MissingRequiredFieldPath": {
reason: "A FromFieldPath patch should return an error when a required fromFieldPath doesn't exist",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("wat"),
- Policy: &v1beta1.PatchPolicy{
- FromFieldPath: func() *v1beta1.FromFieldPathPolicy {
- s := v1beta1.FromFieldPathPolicyRequired
- return &s
- }(),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("wat"),
+ Policy: &v1beta1.PatchPolicy{
+ FromFieldPath: func() *v1beta1.FromFieldPathPolicy {
+ s := v1beta1.FromFieldPathPolicyRequired
+ return &s
+ }(),
+ },
+ ToFieldPath: ptr.To[string]("wat"),
},
- ToFieldPath: ptr.To[string]("wat"),
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -296,10 +306,12 @@ func TestPatchApply(t *testing.T) {
"FilterExcludeCompositeFieldPathPatch": {
reason: "Should not apply the patch as the v1.PatchType is not present in filter.",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.labels"),
- ToFieldPath: ptr.To[string]("metadata.labels"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.labels"),
+ ToFieldPath: ptr.To[string]("metadata.labels"),
+ },
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -323,10 +335,12 @@ func TestPatchApply(t *testing.T) {
"FilterIncludeCompositeFieldPathPatch": {
reason: "Should apply the patch as the v1.PatchType is present in filter.",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.labels"),
- ToFieldPath: ptr.To[string]("metadata.labels"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.labels"),
+ ToFieldPath: ptr.To[string]("metadata.labels"),
+ },
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -365,9 +379,11 @@ func TestPatchApply(t *testing.T) {
"DefaultToFieldCompositeFieldPathPatch": {
reason: "Should correctly default the ToFieldPath value if not specified.",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.labels"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.labels"),
+ },
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -405,10 +421,12 @@ func TestPatchApply(t *testing.T) {
"ValidToCompositeFieldPathPatch": {
reason: "Should correctly apply a ToCompositeFieldPath patch with valid settings",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeToCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.labels"),
- ToFieldPath: ptr.To[string]("metadata.labels"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeToCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.labels"),
+ ToFieldPath: ptr.To[string]("metadata.labels"),
+ },
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -446,10 +464,12 @@ func TestPatchApply(t *testing.T) {
"ValidToCompositeFieldPathPatchWithWildcards": {
reason: "When passed a wildcarded path, adds a field to each element of an array",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeToCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.name"),
- ToFieldPath: ptr.To[string]("metadata.ownerReferences[*].name"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeToCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.name"),
+ ToFieldPath: ptr.To[string]("metadata.ownerReferences[*].name"),
+ },
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -499,10 +519,13 @@ func TestPatchApply(t *testing.T) {
"MissingCombineFromCompositeConfig": {
reason: "Should return an error if Combine config is not passed",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeCombineFromComposite,
- ToFieldPath: ptr.To[string]("metadata.labels.destination"),
- // Missing a Combine field
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeCombineFromComposite,
+ Patch: v1beta1.Patch{
+ ToFieldPath: ptr.To[string]("metadata.labels.destination"),
+ // Missing a Combine field
+ Combine: nil,
+ },
},
xr: &composite.Unstructured{},
cd: &composed.Unstructured{},
@@ -516,17 +539,19 @@ func TestPatchApply(t *testing.T) {
"MissingCombineStrategyFromCompositeConfig": {
reason: "Should return an error if Combine strategy config is not passed",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: v1beta1.PatchTypeCombineFromComposite,
- Combine: &v1beta1.Combine{
- Variables: []v1beta1.CombineVariable{
- {FromFieldPath: "metadata.labels.source1"},
- {FromFieldPath: "metadata.labels.source2"},
+ Patch: v1beta1.Patch{
+ Combine: &v1beta1.Combine{
+ Variables: []v1beta1.CombineVariable{
+ {FromFieldPath: "metadata.labels.source1"},
+ {FromFieldPath: "metadata.labels.source2"},
+ },
+ Strategy: v1beta1.CombineStrategyString,
+ // Missing a String combine config.
},
- Strategy: v1beta1.CombineStrategyString,
- // Missing a String combine config.
+ ToFieldPath: ptr.To[string]("metadata.labels.destination"),
},
- ToFieldPath: ptr.To[string]("metadata.labels.destination"),
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -548,15 +573,17 @@ func TestPatchApply(t *testing.T) {
"MissingCombineVariablesFromCompositeConfig": {
reason: "Should return an error if no variables have been passed",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: v1beta1.PatchTypeCombineFromComposite,
- Combine: &v1beta1.Combine{
- // This is empty.
- Variables: []v1beta1.CombineVariable{},
- Strategy: v1beta1.CombineStrategyString,
- String: &v1beta1.StringCombine{Format: "%s-%s"},
+ Patch: v1beta1.Patch{
+ Combine: &v1beta1.Combine{
+ // This is empty.
+ Variables: []v1beta1.CombineVariable{},
+ Strategy: v1beta1.CombineStrategyString,
+ String: &v1beta1.StringCombine{Format: "%s-%s"},
+ },
+ ToFieldPath: ptr.To[string]("objectMeta.labels.destination"),
},
- ToFieldPath: ptr.To[string]("objectMeta.labels.destination"),
},
},
want: want{
@@ -569,18 +596,20 @@ func TestPatchApply(t *testing.T) {
// not available.
reason: "Should return no error and not apply patch if an optional variable is missing",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: v1beta1.PatchTypeCombineFromComposite,
- Combine: &v1beta1.Combine{
- Variables: []v1beta1.CombineVariable{
- {FromFieldPath: "metadata.labels.source1"},
- {FromFieldPath: "metadata.labels.source2"},
- {FromFieldPath: "metadata.labels.source3"},
+ Patch: v1beta1.Patch{
+ Combine: &v1beta1.Combine{
+ Variables: []v1beta1.CombineVariable{
+ {FromFieldPath: "metadata.labels.source1"},
+ {FromFieldPath: "metadata.labels.source2"},
+ {FromFieldPath: "metadata.labels.source3"},
+ },
+ Strategy: v1beta1.CombineStrategyString,
+ String: &v1beta1.StringCombine{Format: "%s-%s"},
},
- Strategy: v1beta1.CombineStrategyString,
- String: &v1beta1.StringCombine{Format: "%s-%s"},
+ ToFieldPath: ptr.To[string]("metadata.labels.destination"),
},
- ToFieldPath: ptr.To[string]("metadata.labels.destination"),
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -602,17 +631,19 @@ func TestPatchApply(t *testing.T) {
"ValidCombineFromComposite": {
reason: "Should correctly apply a CombineFromComposite patch with valid settings",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: v1beta1.PatchTypeCombineFromComposite,
- Combine: &v1beta1.Combine{
- Variables: []v1beta1.CombineVariable{
- {FromFieldPath: "metadata.labels.source1"},
- {FromFieldPath: "metadata.labels.source2"},
+ Patch: v1beta1.Patch{
+ Combine: &v1beta1.Combine{
+ Variables: []v1beta1.CombineVariable{
+ {FromFieldPath: "metadata.labels.source1"},
+ {FromFieldPath: "metadata.labels.source2"},
+ },
+ Strategy: v1beta1.CombineStrategyString,
+ String: &v1beta1.StringCombine{Format: "%s-%s"},
},
- Strategy: v1beta1.CombineStrategyString,
- String: &v1beta1.StringCombine{Format: "%s-%s"},
+ ToFieldPath: ptr.To[string]("metadata.labels.destination"),
},
- ToFieldPath: ptr.To[string]("metadata.labels.destination"),
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -657,17 +688,19 @@ func TestPatchApply(t *testing.T) {
"ValidCombineToComposite": {
reason: "Should correctly apply a CombineToComposite patch with valid settings",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: v1beta1.PatchTypeCombineToComposite,
- Combine: &v1beta1.Combine{
- Variables: []v1beta1.CombineVariable{
- {FromFieldPath: "metadata.labels.source1"},
- {FromFieldPath: "metadata.labels.source2"},
+ Patch: v1beta1.Patch{
+ Combine: &v1beta1.Combine{
+ Variables: []v1beta1.CombineVariable{
+ {FromFieldPath: "metadata.labels.source1"},
+ {FromFieldPath: "metadata.labels.source2"},
+ },
+ Strategy: v1beta1.CombineStrategyString,
+ String: &v1beta1.StringCombine{Format: "%s-%s"},
},
- Strategy: v1beta1.CombineStrategyString,
- String: &v1beta1.StringCombine{Format: "%s-%s"},
+ ToFieldPath: ptr.To[string]("metadata.labels.destination"),
},
- ToFieldPath: ptr.To[string]("metadata.labels.destination"),
},
xr: &composite.Unstructured{
Unstructured: unstructured.Unstructured{Object: MustObject(`{
@@ -713,7 +746,7 @@ func TestPatchApply(t *testing.T) {
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
ncp := tc.args.xr.DeepCopyObject().(resource.Composite)
- err := Apply(tc.args.patch, ncp, tc.args.cd, tc.args.only...)
+ err := Apply(&tc.args.patch, ncp, tc.args.cd, tc.args.only...)
if tc.want.xr != nil {
if diff := cmp.Diff(tc.want.xr, ncp); diff != "" {
@@ -851,14 +884,18 @@ func TestComposedTemplates(t *testing.T) {
args: args{
cts: []v1beta1.ComposedTemplate{
{
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.name"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.name"),
+ },
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.namespace"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.namespace"),
+ },
},
},
},
@@ -867,14 +904,18 @@ func TestComposedTemplates(t *testing.T) {
want: want{
ct: []v1beta1.ComposedTemplate{
{
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.name"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.name"),
+ },
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.namespace"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.namespace"),
+ },
},
},
},
@@ -885,7 +926,7 @@ func TestComposedTemplates(t *testing.T) {
reason: "Should return error and not modify the patches field when referring to an undefined PatchSet",
args: args{
cts: []v1beta1.ComposedTemplate{{
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
Type: v1beta1.PatchTypePatchSet,
PatchSetName: ptr.To[string]("patch-set-1"),
@@ -905,50 +946,60 @@ func TestComposedTemplates(t *testing.T) {
pss: []v1beta1.PatchSet{
{
Name: "patch-set-1",
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.PatchSetPatch{
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.namespace"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.namespace"),
+ },
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.parameters.test"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.parameters.test"),
+ },
},
},
},
{
Name: "patch-set-2",
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.PatchSetPatch{
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.annotations.patch-test-1"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.annotations.patch-test-1"),
+ },
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.annotations.patch-test-2"),
- Transforms: []v1beta1.Transform{{
- Type: v1beta1.TransformTypeMap,
- Map: &v1beta1.MapTransform{
- Pairs: map[string]extv1.JSON{
- "k-1": asJSON("v-1"),
- "k-2": asJSON("v-2"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.annotations.patch-test-2"),
+ Transforms: []v1beta1.Transform{{
+ Type: v1beta1.TransformTypeMap,
+ Map: &v1beta1.MapTransform{
+ Pairs: map[string]extv1.JSON{
+ "k-1": asJSON("v-1"),
+ "k-2": asJSON("v-2"),
+ },
},
- },
- }},
+ }},
+ },
},
},
},
},
cts: []v1beta1.ComposedTemplate{
{
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
Type: v1beta1.PatchTypePatchSet,
PatchSetName: ptr.To[string]("patch-set-2"),
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.name"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.name"),
+ },
},
{
Type: v1beta1.PatchTypePatchSet,
@@ -957,7 +1008,7 @@ func TestComposedTemplates(t *testing.T) {
},
},
{
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
Type: v1beta1.PatchTypePatchSet,
PatchSetName: ptr.To[string]("patch-set-1"),
@@ -970,47 +1021,61 @@ func TestComposedTemplates(t *testing.T) {
err: nil,
ct: []v1beta1.ComposedTemplate{
{
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.annotations.patch-test-1"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.annotations.patch-test-1"),
+ },
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.annotations.patch-test-2"),
- Transforms: []v1beta1.Transform{{
- Type: v1beta1.TransformTypeMap,
- Map: &v1beta1.MapTransform{
- Pairs: map[string]extv1.JSON{
- "k-1": asJSON("v-1"),
- "k-2": asJSON("v-2"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.annotations.patch-test-2"),
+ Transforms: []v1beta1.Transform{{
+ Type: v1beta1.TransformTypeMap,
+ Map: &v1beta1.MapTransform{
+ Pairs: map[string]extv1.JSON{
+ "k-1": asJSON("v-1"),
+ "k-2": asJSON("v-2"),
+ },
},
- },
- }},
+ }},
+ },
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.name"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.name"),
+ },
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.namespace"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.namespace"),
+ },
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.parameters.test"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.parameters.test"),
+ },
},
},
},
{
- Patches: []v1beta1.Patch{
+ Patches: []v1beta1.ComposedPatch{
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("metadata.namespace"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("metadata.namespace"),
+ },
},
{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.parameters.test"),
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.parameters.test"),
+ },
},
},
},
@@ -1114,7 +1179,7 @@ func TestResolveTransforms(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- got, err := ResolveTransforms(v1beta1.Patch{Transforms: tt.args.ts}, tt.args.input)
+ got, err := ResolveTransforms(tt.args.ts, tt.args.input)
if diff := cmp.Diff(tt.want.err, err, test.EquateErrors()); diff != "" {
t.Errorf("ResolveTransforms(...): -want error, +got error:\n%s", diff)
}
diff --git a/render.go b/render.go
index 44da046..f29cab8 100644
--- a/render.go
+++ b/render.go
@@ -62,16 +62,16 @@ func RenderFromJSON(o resource.Object, data []byte) error {
// RenderEnvironmentPatches renders the supplied environment by applying all
// patches that are to the environment, from the supplied XR.
-func RenderEnvironmentPatches(env *unstructured.Unstructured, oxr, dxr *composite.Unstructured, ps []v1beta1.Patch) error {
+func RenderEnvironmentPatches(env *unstructured.Unstructured, oxr, dxr *composite.Unstructured, ps []v1beta1.EnvironmentPatch) error {
for i, p := range ps {
p := p
switch p.Type {
case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment:
- if err := ApplyToObjects(p, env, oxr); err != nil {
+ if err := ApplyToObjects(&p, env, oxr); err != nil {
return errors.Wrapf(err, errFmtPatch, p.Type, i)
}
case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment:
- if err := ApplyToObjects(p, env, dxr); err != nil {
+ if err := ApplyToObjects(&p, env, dxr); err != nil {
return errors.Wrapf(err, errFmtPatch, p.Type, i)
}
case v1beta1.PatchTypePatchSet, v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite, v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite:
@@ -91,9 +91,10 @@ func RenderComposedPatches( //nolint:gocyclo // just a switch
oxr *composite.Unstructured,
dxr *composite.Unstructured,
env *unstructured.Unstructured,
- ps []v1beta1.Patch,
+ ps []v1beta1.ComposedPatch,
) (errs []error, store bool) {
for i, p := range ps {
+ p := p
switch t := p.Type; t {
case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite:
// TODO(negz): Should failures to patch the XR be terminal? It could
@@ -110,7 +111,7 @@ func RenderComposedPatches( //nolint:gocyclo // just a switch
if ocd == nil {
continue
}
- if err := ApplyToObjects(p, dxr, ocd); err != nil {
+ if err := ApplyToObjects(&p, dxr, ocd); err != nil {
errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i))
}
case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment:
@@ -123,7 +124,7 @@ func RenderComposedPatches( //nolint:gocyclo // just a switch
if ocd == nil {
continue
}
- if err := ApplyToObjects(p, env, ocd); err != nil {
+ if err := ApplyToObjects(&p, env, ocd); err != nil {
errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i))
}
// If either of the below renderings return an error, most likely a
@@ -133,12 +134,12 @@ func RenderComposedPatches( //nolint:gocyclo // just a switch
// resource in the wrong state. To that end, we don't want to add this
// resource to our accumulated desired state.
case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite:
- if err := ApplyToObjects(p, oxr, dcd); err != nil {
+ if err := ApplyToObjects(&p, oxr, dcd); err != nil {
errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i))
return errs, false
}
case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment:
- if err := ApplyToObjects(p, env, dcd); err != nil {
+ if err := ApplyToObjects(&p, env, dcd); err != nil {
errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i))
return errs, false
}
diff --git a/validate.go b/validate.go
index 417a326..ff006e9 100644
--- a/validate.go
+++ b/validate.go
@@ -59,7 +59,8 @@ func ValidateComposedTemplate(t v1beta1.ComposedTemplate) *field.Error {
return field.Required(field.NewPath("name"), "name is required")
}
for i, p := range t.Patches {
- if err := ValidatePatch(p); err != nil {
+ p := p
+ if err := ValidatePatch(&p); err != nil {
return WrapFieldError(err, field.NewPath("patches").Index(i))
}
}
@@ -82,7 +83,8 @@ func ValidatePatchSet(ps v1beta1.PatchSet) *field.Error {
return field.Required(field.NewPath("name"), "name is required")
}
for i, p := range ps.Patches {
- if err := ValidatePatch(p); err != nil {
+ p := p
+ if err := ValidatePatch(&p); err != nil {
return WrapFieldError(err, field.NewPath("patches").Index(i))
}
}
@@ -95,6 +97,7 @@ func ValidateEnvironment(e *v1beta1.Environment) *field.Error {
return nil
}
for i, p := range e.Patches {
+ p := p
switch p.GetType() { //nolint:exhaustive // Intentionally targeting only environment patches.
case v1beta1.PatchTypeCombineToEnvironment,
v1beta1.PatchTypeCombineFromEnvironment,
@@ -104,7 +107,7 @@ func ValidateEnvironment(e *v1beta1.Environment) *field.Error {
return field.Invalid(field.NewPath("patches").Index(i).Key("type"), p.Type, "invalid environment patch type")
}
- if err := ValidatePatch(p); err != nil {
+ if err := ValidatePatch(&p); err != nil {
return WrapFieldError(err, field.NewPath("patches").Index(i))
}
}
@@ -157,35 +160,39 @@ func ValidateMatchConditionReadinessCheck(m *v1beta1.MatchConditionReadinessChec
return nil
}
-// ValidatePatch validates a Patch.
-func ValidatePatch(p v1beta1.Patch) *field.Error {
+// ValidatePatch validates a ComposedPatch.
+func ValidatePatch(p PatchInterface) *field.Error { //nolint: gocyclo // This is a long but simple/same-y switch.
switch p.GetType() {
case v1beta1.PatchTypeFromCompositeFieldPath,
v1beta1.PatchTypeToCompositeFieldPath,
v1beta1.PatchTypeFromEnvironmentFieldPath,
v1beta1.PatchTypeToEnvironmentFieldPath:
- if p.FromFieldPath == nil {
- return field.Required(field.NewPath("fromFieldPath"), fmt.Sprintf("fromFieldPath must be set for patch type %s", p.Type))
+ if p.GetFromFieldPath() == "" {
+ return field.Required(field.NewPath("fromFieldPath"), fmt.Sprintf("fromFieldPath must be set for patch type %s", p.GetType()))
}
case v1beta1.PatchTypePatchSet:
- if p.PatchSetName == nil {
- return field.Required(field.NewPath("patchSetName"), fmt.Sprintf("patchSetName must be set for patch type %s", p.Type))
+ ps, ok := p.(PatchWithPatchSetName)
+ if !ok {
+ return field.Invalid(field.NewPath("type"), p.GetType(), fmt.Sprintf("patch type %T does not support patch of type %s", p, p.GetType()))
+ }
+ if ps.GetPatchSetName() == "" {
+ return field.Required(field.NewPath("patchSetName"), fmt.Sprintf("patchSetName must be set for patch type %s", p.GetType()))
}
case v1beta1.PatchTypeCombineFromComposite,
v1beta1.PatchTypeCombineToComposite,
v1beta1.PatchTypeCombineFromEnvironment,
v1beta1.PatchTypeCombineToEnvironment:
- if p.Combine == nil {
- return field.Required(field.NewPath("combine"), fmt.Sprintf("combine must be set for patch type %s", p.Type))
+ if p.GetCombine() == nil {
+ return field.Required(field.NewPath("combine"), fmt.Sprintf("combine must be set for patch type %s", p.GetType()))
}
- if p.ToFieldPath == nil {
- return field.Required(field.NewPath("toFieldPath"), fmt.Sprintf("toFieldPath must be set for patch type %s", p.Type))
+ if p.GetToFieldPath() == "" {
+ return field.Required(field.NewPath("toFieldPath"), fmt.Sprintf("toFieldPath must be set for patch type %s", p.GetType()))
}
default:
// Should never happen
- return field.Invalid(field.NewPath("type"), p.Type, "unknown patch type")
+ return field.Invalid(field.NewPath("type"), p.GetType(), "unknown patch type")
}
- for i, t := range p.Transforms {
+ for i, t := range p.GetTransforms() {
if err := ValidateTransform(t); err != nil {
return WrapFieldError(err, field.NewPath("transforms").Index(i))
}
diff --git a/validate_test.go b/validate_test.go
index 69e7c52..dde1333 100644
--- a/validate_test.go
+++ b/validate_test.go
@@ -237,7 +237,7 @@ func TestValidateConnectionDetail(t *testing.T) {
func TestValidatePatch(t *testing.T) {
type args struct {
- patch v1beta1.Patch
+ patch v1beta1.ComposedPatch
}
type want struct {
@@ -252,22 +252,26 @@ func TestValidatePatch(t *testing.T) {
"ValidFromCompositeFieldPath": {
reason: "FromCompositeFieldPath patch with FromFieldPath set should be valid",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.forProvider.foo"),
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.forProvider.foo"),
+ },
},
},
},
"FromCompositeFieldPathWithInvalidTransforms": {
reason: "FromCompositeFieldPath with invalid transforms should return error",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: ptr.To[string]("spec.forProvider.foo"),
- Transforms: []v1beta1.Transform{
- {
- Type: v1beta1.TransformTypeMath,
- Math: nil,
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.forProvider.foo"),
+ Transforms: []v1beta1.Transform{
+ {
+ Type: v1beta1.TransformTypeMath,
+ Math: nil,
+ },
},
},
},
@@ -282,9 +286,11 @@ func TestValidatePatch(t *testing.T) {
"InvalidFromCompositeFieldPathMissingFromFieldPath": {
reason: "Invalid FromCompositeFieldPath missing FromFieldPath should return error",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeFromCompositeFieldPath,
- FromFieldPath: nil,
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: nil,
+ },
},
},
want: want{
@@ -297,9 +303,11 @@ func TestValidatePatch(t *testing.T) {
"InvalidFromCompositeFieldPathMissingToFieldPath": {
reason: "Invalid ToCompositeFieldPath missing ToFieldPath should return error",
args: args{
- patch: v1beta1.Patch{
- Type: v1beta1.PatchTypeToCompositeFieldPath,
- ToFieldPath: nil,
+ patch: v1beta1.ComposedPatch{
+ Type: v1beta1.PatchTypeToCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ ToFieldPath: nil,
+ },
},
},
want: want{
@@ -312,7 +320,7 @@ func TestValidatePatch(t *testing.T) {
"Invalidv1beta1.PatchSetMissingv1beta1.PatchSetName": {
reason: "Invalid v1beta1.PatchSet missing v1beta1.PatchSetName should return error",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: v1beta1.PatchTypePatchSet,
},
},
@@ -326,7 +334,7 @@ func TestValidatePatch(t *testing.T) {
"InvalidCombineMissingCombine": {
reason: "Invalid Combine missing Combine should return error",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: v1beta1.PatchTypeCombineToComposite,
},
},
@@ -340,16 +348,18 @@ func TestValidatePatch(t *testing.T) {
"InvalidCombineMissingToFieldPath": {
reason: "Invalid Combine missing ToFieldPath should return error",
args: args{
- patch: v1beta1.Patch{
+ patch: v1beta1.ComposedPatch{
Type: v1beta1.PatchTypeCombineToComposite,
- Combine: &v1beta1.Combine{
- Variables: []v1beta1.CombineVariable{
- {
- FromFieldPath: "spec.forProvider.foo",
+ Patch: v1beta1.Patch{
+ Combine: &v1beta1.Combine{
+ Variables: []v1beta1.CombineVariable{
+ {
+ FromFieldPath: "spec.forProvider.foo",
+ },
},
},
+ ToFieldPath: nil,
},
- ToFieldPath: nil,
},
},
want: want{
@@ -362,7 +372,7 @@ func TestValidatePatch(t *testing.T) {
}
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
- err := ValidatePatch(tc.args.patch)
+ err := ValidatePatch(&tc.args.patch)
if diff := cmp.Diff(tc.want.err, err, cmpopts.IgnoreFields(field.Error{}, "Detail", "BadValue")); diff != "" {
t.Errorf("%s\nValidatePatch(...): -want, +got:\n%s", tc.reason, diff)
}
From 11603643e3255812850f5ed6ba8a3ec52dbbdbec Mon Sep 17 00:00:00 2001
From: Philippe Scorsolini
Date: Thu, 23 Nov 2023 22:13:24 +0100
Subject: [PATCH 7/9] tests: render with environment
Signed-off-by: Philippe Scorsolini
---
fn_test.go | 296 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 296 insertions(+)
diff --git a/fn_test.go b/fn_test.go
index 806038e..7462518 100644
--- a/fn_test.go
+++ b/fn_test.go
@@ -10,7 +10,9 @@ import (
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/structpb"
+ "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/utils/ptr"
"github.com/crossplane/crossplane-runtime/pkg/logging"
@@ -643,6 +645,279 @@ func TestRunFunction(t *testing.T) {
},
},
},
+ "PatchToCompositeWithEnvironmentPatches": {
+ reason: "A basic ToCompositeFieldPath patch should work with environment.patches.",
+ args: args{
+ req: &fnv1beta1.RunFunctionRequest{
+ Input: resource.MustStructObject(&v1beta1.Resources{
+ Resources: []v1beta1.ComposedTemplate{
+ {
+ Name: "cool-resource",
+ Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)},
+ }},
+ Environment: &v1beta1.Environment{
+ Patches: []v1beta1.EnvironmentPatch{
+ {
+ Type: v1beta1.PatchTypeFromEnvironmentFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("data.widgets"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ Transforms: []v1beta1.Transform{
+ {
+ Type: v1beta1.TransformTypeConvert,
+ Convert: &v1beta1.ConvertTransform{
+ ToType: v1beta1.TransformIOTypeInt64,
+ },
+ },
+ {
+ Type: v1beta1.TransformTypeMath,
+ Math: &v1beta1.MathTransform{
+ Type: v1beta1.MathTransformTypeMultiply,
+ Multiply: ptr.To[int64](3),
+ }}}}}}}}),
+ Observed: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{}}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{},
+ },
+ Context: contextWithEnvironment(map[string]interface{}{
+ "widgets": "10",
+ })},
+ },
+ want: want{
+ rsp: &fnv1beta1.RunFunctionResponse{
+ Meta: &fnv1beta1.ResponseMeta{Ttl: durationpb.New(response.DefaultTTL)},
+ Desired: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ // spec.watchers = 10 * 3 = 30
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":30}}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{
+ "cool-resource": {
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD"}`),
+ }}},
+ Context: contextWithEnvironment(map[string]interface{}{
+ "widgets": "10",
+ })}}},
+ "EnvironmentPatchToEnvironment": {
+ reason: "A basic ToEnvironment patch should work with environment.patches.",
+ args: args{
+ req: &fnv1beta1.RunFunctionRequest{
+ Input: resource.MustStructObject(&v1beta1.Resources{
+ Resources: []v1beta1.ComposedTemplate{
+ {
+ Name: "cool-resource",
+ Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)},
+ }},
+ Environment: &v1beta1.Environment{
+ Patches: []v1beta1.EnvironmentPatch{
+ {
+ Type: v1beta1.PatchTypeToEnvironmentFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.watchers"),
+ ToFieldPath: ptr.To[string]("data.widgets"),
+ Transforms: []v1beta1.Transform{
+ {
+ Type: v1beta1.TransformTypeMath,
+ Math: &v1beta1.MathTransform{
+ Type: v1beta1.MathTransformTypeMultiply,
+ Multiply: ptr.To[int64](3),
+ },
+ },
+ {
+ Type: v1beta1.TransformTypeConvert,
+ Convert: &v1beta1.ConvertTransform{
+ ToType: v1beta1.TransformIOTypeString,
+ },
+ }}}}}}}),
+ Observed: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":10}}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{},
+ },
+ Context: contextWithEnvironment(nil)},
+ },
+ want: want{
+ rsp: &fnv1beta1.RunFunctionResponse{
+ Meta: &fnv1beta1.ResponseMeta{Ttl: durationpb.New(response.DefaultTTL)},
+ Desired: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD"}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{
+ "cool-resource": {
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD"}`),
+ }}},
+ Context: contextWithEnvironment(map[string]interface{}{
+ "widgets": "30",
+ })}}},
+ "PatchComposedResourceFromEnvironment": {
+ reason: "A basic FromEnvironmentPatch should work if defined at spec.resources[*].patches.",
+ args: args{
+ req: &fnv1beta1.RunFunctionRequest{
+ Input: resource.MustStructObject(&v1beta1.Resources{
+ Resources: []v1beta1.ComposedTemplate{{
+ Name: "cool-resource",
+ Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)},
+ Patches: []v1beta1.ComposedPatch{{
+ Type: v1beta1.PatchTypeFromEnvironmentFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("data.widgets"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ Transforms: []v1beta1.Transform{{
+ Type: v1beta1.TransformTypeConvert,
+ Convert: &v1beta1.ConvertTransform{
+ ToType: v1beta1.TransformIOTypeInt64,
+ },
+ }, {
+ Type: v1beta1.TransformTypeMath,
+ Math: &v1beta1.MathTransform{
+ Type: v1beta1.MathTransformTypeMultiply,
+ Multiply: ptr.To[int64](3),
+ },
+ }}}}},
+ }}}),
+ Observed: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{}}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{},
+ },
+ Context: contextWithEnvironment(map[string]interface{}{
+ "widgets": "10",
+ })},
+ },
+ want: want{
+ rsp: &fnv1beta1.RunFunctionResponse{
+ Meta: &fnv1beta1.ResponseMeta{Ttl: durationpb.New(response.DefaultTTL)},
+ Desired: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD"}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{
+ "cool-resource": {
+ // spec.watchers = 10 * 3 = 30
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":30}}`),
+ }}},
+ Context: contextWithEnvironment(map[string]interface{}{
+ "widgets": "10",
+ })}}},
+
+ "PatchComposedResourceFromEnvironmentShadowedNotSet": {
+ reason: "A basic FromEnvironmentPatch should work if defined at spec.resources[*].patches, even if a successive patch shadows it and its source is not set.",
+ args: args{
+ req: &fnv1beta1.RunFunctionRequest{
+ Input: resource.MustStructObject(&v1beta1.Resources{
+ Resources: []v1beta1.ComposedTemplate{{
+ Name: "cool-resource",
+ Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)},
+ Patches: []v1beta1.ComposedPatch{{
+ Type: v1beta1.PatchTypeFromEnvironmentFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("data.widgets"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ Transforms: []v1beta1.Transform{{
+ Type: v1beta1.TransformTypeConvert,
+ Convert: &v1beta1.ConvertTransform{
+ ToType: v1beta1.TransformIOTypeInt64,
+ },
+ }, {
+ Type: v1beta1.TransformTypeMath,
+ Math: &v1beta1.MathTransform{
+ Type: v1beta1.MathTransformTypeMultiply,
+ Multiply: ptr.To[int64](3),
+ },
+ }}}},
+ {
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.watchers"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ }}}}}}),
+ Observed: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{}}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{},
+ },
+ Context: contextWithEnvironment(map[string]interface{}{
+ "widgets": "10",
+ })},
+ },
+ want: want{
+ rsp: &fnv1beta1.RunFunctionResponse{
+ Meta: &fnv1beta1.ResponseMeta{Ttl: durationpb.New(response.DefaultTTL)},
+ Desired: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD"}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{
+ "cool-resource": {
+ // spec.watchers = 10 * 3 = 30
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":30}}`),
+ }}},
+ Context: contextWithEnvironment(map[string]interface{}{
+ "widgets": "10",
+ })}}},
+ "PatchComposedResourceFromEnvironmentShadowedSet": {
+ reason: "A basic FromEnvironmentPatch should work if defined at spec.resources[*].patches, even if a successive patch shadows it and its source is set.",
+ args: args{
+ req: &fnv1beta1.RunFunctionRequest{
+ Input: resource.MustStructObject(&v1beta1.Resources{
+ Resources: []v1beta1.ComposedTemplate{{
+ Name: "cool-resource",
+ Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)},
+ Patches: []v1beta1.ComposedPatch{{
+ Type: v1beta1.PatchTypeFromEnvironmentFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("data.widgets"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ Transforms: []v1beta1.Transform{{
+ Type: v1beta1.TransformTypeConvert,
+ Convert: &v1beta1.ConvertTransform{
+ ToType: v1beta1.TransformIOTypeInt64,
+ },
+ }, {
+ Type: v1beta1.TransformTypeMath,
+ Math: &v1beta1.MathTransform{
+ Type: v1beta1.MathTransformTypeMultiply,
+ Multiply: ptr.To[int64](3),
+ },
+ }}}},
+ {
+ Type: v1beta1.PatchTypeFromCompositeFieldPath,
+ Patch: v1beta1.Patch{
+ FromFieldPath: ptr.To[string]("spec.watchers"),
+ ToFieldPath: ptr.To[string]("spec.watchers"),
+ }}}}}}),
+ Observed: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ // I want this in the environment, 42
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":42}}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{},
+ },
+ Context: contextWithEnvironment(map[string]interface{}{
+ "widgets": "10",
+ })},
+ },
+ want: want{
+ rsp: &fnv1beta1.RunFunctionResponse{
+ Meta: &fnv1beta1.ResponseMeta{Ttl: durationpb.New(response.DefaultTTL)},
+ Desired: &fnv1beta1.State{
+ Composite: &fnv1beta1.Resource{
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD"}`),
+ },
+ Resources: map[string]*fnv1beta1.Resource{
+ "cool-resource": {
+ // spec.watchers comes from the composite resource, 42
+ Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":42}}`),
+ }}},
+ Context: contextWithEnvironment(map[string]interface{}{
+ "widgets": "10",
+ })}}},
}
for name, tc := range cases {
@@ -660,3 +935,24 @@ func TestRunFunction(t *testing.T) {
})
}
}
+
+// Crossplane sends as context a fake resource:
+// { "apiVersion": "internal.crossplane.io/v1alpha1", "kind": "Environment", "data": {... the actual environment content ...} }
+// See: https://github.com/crossplane/crossplane/blob/806f0d20d146f6f4f1735c5ec6a7dc78923814b3/internal/controller/apiextensions/composite/environment_fetcher.go#L85C1-L85C1
+// That's because the patching code expects a resource to be able to use
+// runtime.DefaultUnstructuredConverter.FromUnstructured to convert it back to
+// an object. This is also why all patches need to specify the full path from data.
+func contextWithEnvironment(data map[string]interface{}) *structpb.Struct {
+ if data == nil {
+ data = map[string]interface{}{}
+ }
+ u := unstructured.Unstructured{Object: map[string]interface{}{
+ "data": data,
+ }}
+ u.SetGroupVersionKind(schema.GroupVersionKind{Group: "internal.crossplane.io", Version: "v1alpha1", Kind: "Environment"})
+ d, err := structpb.NewStruct(u.UnstructuredContent())
+ if err != nil {
+ panic(err)
+ }
+ return &structpb.Struct{Fields: map[string]*structpb.Value{fncontext.KeyEnvironment: structpb.NewStructValue(d)}}
+}
From 1074aa01904b815a272528d9efc96569c278163f Mon Sep 17 00:00:00 2001
From: Steven Borrelli
Date: Wed, 29 Nov 2023 20:00:25 -0600
Subject: [PATCH 8/9] update examples
Signed-off-by: Steven Borrelli
---
examples/conditional-resources/composition.yaml | 1 +
examples/conditional-resources/functions.yaml | 4 +++-
go.sum | 8 ++++----
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/examples/conditional-resources/composition.yaml b/examples/conditional-resources/composition.yaml
index 2d3b277..7fc75ee 100644
--- a/examples/conditional-resources/composition.yaml
+++ b/examples/conditional-resources/composition.yaml
@@ -15,6 +15,7 @@ spec:
input:
apiVersion: conditional-pt.fn.crossplane.io/v1beta1
kind: Resources
+ condition: observed.composite.resource.spec.render == true
resources:
- name: blue-resource
condition: observed.composite.resource.spec.deployment.blue == true
diff --git a/examples/conditional-resources/functions.yaml b/examples/conditional-resources/functions.yaml
index 20ff604..d41d492 100644
--- a/examples/conditional-resources/functions.yaml
+++ b/examples/conditional-resources/functions.yaml
@@ -2,6 +2,8 @@ apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-conditional-patch-and-transform
+ annotations:
+ render.crossplane.io/runtime: Development
spec:
- package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.3.0
+ package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.4.0
packagePullPolicy: Always
diff --git a/go.sum b/go.sum
index c7cad90..1217ae5 100644
--- a/go.sum
+++ b/go.sum
@@ -42,8 +42,6 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
-github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
-github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0=
github.com/alecthomas/kong v0.8.1 h1:acZdn3m4lLRobeh3Zi2S2EpnXTd1mOL6U7xVml+vfkY=
github.com/alecthomas/kong v0.8.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
@@ -72,10 +70,10 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/stevendborrelli/function-conditional-patch-and-transform v0.2.1 h1:8CNU6BGXWO+lqQw7t+calDuM9JEjQ61YYVA9fM9yv+8=
-github.com/stevendborrelli/function-conditional-patch-and-transform v0.2.1/go.mod h1:B9hSlytx1BSH/zezwsRkLhcnEG1NHDQJE7Q5P4zxJGI=
github.com/crossplane/crossplane-runtime v1.14.1 h1:TCa7R1N4bDGHjsLhiRxR/mUhwmistlMACHm0kiiYKck=
github.com/crossplane/crossplane-runtime v1.14.1/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
+github.com/crossplane/crossplane-runtime v1.14.2 h1:pV5JMzyzi/kcbeVBVPCat5MHH8zS94MBUapAyGx/Ry0=
+github.com/crossplane/crossplane-runtime v1.14.2/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o=
github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8=
github.com/crossplane/function-sdk-go v0.1.0/go.mod h1:oRqHZ6RufpfZJ1N8aT4EfkP+5KpkhOKpWz7SeUDwwcw=
github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505 h1:eCmYgfRopVn6r8RM1Ra4XQAPwVsjTGfktBj2Dk7yy+Y=
@@ -311,6 +309,8 @@ github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/stevendborrelli/function-conditional-patch-and-transform v0.2.1 h1:8CNU6BGXWO+lqQw7t+calDuM9JEjQ61YYVA9fM9yv+8=
+github.com/stevendborrelli/function-conditional-patch-and-transform v0.2.1/go.mod h1:B9hSlytx1BSH/zezwsRkLhcnEG1NHDQJE7Q5P4zxJGI=
github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
From 61e33723e2be1c213f149a75acdc58f1549a013f Mon Sep 17 00:00:00 2001
From: Steven Borrelli
Date: Wed, 29 Nov 2023 20:11:41 -0600
Subject: [PATCH 9/9] update version
Signed-off-by: Steven Borrelli
---
README.md | 2 +-
examples/conditional-rendering/functions.yaml | 2 +-
examples/conditional-resources/functions.yaml | 2 --
3 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 6c0a44d..775cc79 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ metadata:
annotations:
render.crossplane.io/runtime: Development
spec:
- package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.3.0
+ package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.4.0
```
## What this function does
diff --git a/examples/conditional-rendering/functions.yaml b/examples/conditional-rendering/functions.yaml
index 20ff604..b197224 100644
--- a/examples/conditional-rendering/functions.yaml
+++ b/examples/conditional-rendering/functions.yaml
@@ -3,5 +3,5 @@ kind: Function
metadata:
name: function-conditional-patch-and-transform
spec:
- package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.3.0
+ package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.4.0
packagePullPolicy: Always
diff --git a/examples/conditional-resources/functions.yaml b/examples/conditional-resources/functions.yaml
index d41d492..b197224 100644
--- a/examples/conditional-resources/functions.yaml
+++ b/examples/conditional-resources/functions.yaml
@@ -2,8 +2,6 @@ apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-conditional-patch-and-transform
- annotations:
- render.crossplane.io/runtime: Development
spec:
package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.4.0
packagePullPolicy: Always