|
9 | 9 | "github.com/crossplane/crossplane-runtime/pkg/errors"
|
10 | 10 | "github.com/crossplane/crossplane-runtime/pkg/resource"
|
11 | 11 |
|
| 12 | + "github.com/crossplane/function-sdk-go/resource/composed" |
| 13 | + "github.com/crossplane/function-sdk-go/resource/composite" |
| 14 | + |
12 | 15 | "github.com/crossplane-contrib/function-patch-and-transform/input/v1beta1"
|
13 | 16 | )
|
14 | 17 |
|
@@ -102,3 +105,71 @@ func RenderToEnvironmentPatches(env *unstructured.Unstructured, o runtime.Object
|
102 | 105 | }
|
103 | 106 | return nil
|
104 | 107 | }
|
| 108 | + |
| 109 | +// RenderComposedPatches renders the supplied composed resource by applying all |
| 110 | +// patches that are to or from the supplied composite resource and environment |
| 111 | +// in the order they were defined. Properly selecting the right source or |
| 112 | +// destination between observed and desired resources. |
| 113 | +func RenderComposedPatches( //nolint:gocyclo // just a switch |
| 114 | + ocd *composed.Unstructured, |
| 115 | + dcd *composed.Unstructured, |
| 116 | + oxr *composite.Unstructured, |
| 117 | + dxr *composite.Unstructured, |
| 118 | + env *unstructured.Unstructured, |
| 119 | + ps []v1beta1.Patch, |
| 120 | +) (errs []error, store bool) { |
| 121 | + for i, p := range ps { |
| 122 | + switch t := p.Type; t { |
| 123 | + case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: |
| 124 | + // TODO(negz): Should failures to patch the XR be terminal? It could |
| 125 | + // indicate a required patch failed. A required patch means roughly |
| 126 | + // "this patch has to succeed before you mutate the resource". This |
| 127 | + // is useful to make sure we never create a composed resource in the |
| 128 | + // wrong state. It's less clear how useful it is for the XR, given |
| 129 | + // we'll only ever be updating it, not creating it. |
| 130 | + |
| 131 | + // We want to patch the XR from observed composed resources, not |
| 132 | + // from desired state. This is because folks will typically be |
| 133 | + // patching from a field that is set once the observed resource is |
| 134 | + // applied such as its status. |
| 135 | + if ocd == nil { |
| 136 | + continue |
| 137 | + } |
| 138 | + if err := ApplyToObjects(p, dxr, ocd); err != nil { |
| 139 | + errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) |
| 140 | + } |
| 141 | + case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: |
| 142 | + // TODO(negz): Same as above, but for the Environment. What does it |
| 143 | + // mean for a required patch to the environment to fail? Should it |
| 144 | + // be terminal? |
| 145 | + |
| 146 | + // Run all patches that are from the (observed) composed resource to |
| 147 | + // the environment. |
| 148 | + if ocd == nil { |
| 149 | + continue |
| 150 | + } |
| 151 | + if err := ApplyToObjects(p, env, ocd); err != nil { |
| 152 | + errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) |
| 153 | + } |
| 154 | + // If either of the below renderings return an error, most likely a |
| 155 | + // required FromComposite or FromEnvironment patch failed. A required |
| 156 | + // patch means roughly "this patch has to succeed before you mutate the |
| 157 | + // resource." This is useful to make sure we never create a composed |
| 158 | + // resource in the wrong state. To that end, we don't want to add this |
| 159 | + // resource to our accumulated desired state. |
| 160 | + case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite: |
| 161 | + if err := ApplyToObjects(p, oxr, dcd); err != nil { |
| 162 | + errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) |
| 163 | + return errs, false |
| 164 | + } |
| 165 | + case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment: |
| 166 | + if err := ApplyToObjects(p, env, dcd); err != nil { |
| 167 | + errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) |
| 168 | + return errs, false |
| 169 | + } |
| 170 | + case v1beta1.PatchTypePatchSet: |
| 171 | + // Already resolved - nothing to do. |
| 172 | + } |
| 173 | + } |
| 174 | + return errs, true |
| 175 | +} |
0 commit comments