github.com/crossplane/upjet@v1.3.0/pkg/controller/conversion/functions.go (about) 1 // SPDX-FileCopyrightText: 2023 The Crossplane Authors <https://crossplane.io> 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 5 package conversion 6 7 import ( 8 "github.com/crossplane/crossplane-runtime/pkg/fieldpath" 9 "github.com/pkg/errors" 10 "k8s.io/apimachinery/pkg/runtime" 11 12 "github.com/crossplane/upjet/pkg/config/conversion" 13 "github.com/crossplane/upjet/pkg/resource" 14 ) 15 16 // RoundTrip round-trips from `src` to `dst` via an unstructured map[string]any 17 // representation of the `src` object and applies the registered webhook 18 // conversion functions of this registry. 19 func (r *registry) RoundTrip(dst, src resource.Terraformed) error { //nolint:gocyclo // considered breaking this according to the converters and I did not like it 20 srcMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(src) 21 if err != nil { 22 return errors.Wrap(err, "cannot convert the conversion source object into the map[string]any representation") 23 } 24 gvk := dst.GetObjectKind().GroupVersionKind() 25 if err := runtime.DefaultUnstructuredConverter.FromUnstructured(srcMap, dst); err != nil { 26 return errors.Wrap(err, "cannot convert the map[string]any representation of the source object to the conversion target object") 27 } 28 // restore the original GVK for the conversion destination 29 dst.GetObjectKind().SetGroupVersionKind(gvk) 30 31 // now we will try to run the registered webhook conversions 32 dstMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(dst) 33 if err != nil { 34 return errors.Wrap(err, "cannot convert the conversion destination object into the map[string]any representation") 35 } 36 srcPaved := fieldpath.Pave(srcMap) 37 dstPaved := fieldpath.Pave(dstMap) 38 for _, c := range r.GetConversions(dst) { 39 if pc, ok := c.(conversion.PavedConversion); ok { 40 if _, err := pc.ConvertPaved(srcPaved, dstPaved); err != nil { 41 return errors.Wrapf(err, "cannot apply the PavedConversion for the %q object", dst.GetTerraformResourceType()) 42 } 43 } 44 } 45 // convert the map[string]any representation of the conversion target back to 46 // the original type. 47 if err := runtime.DefaultUnstructuredConverter.FromUnstructured(dstMap, dst); err != nil { 48 return errors.Wrap(err, "cannot convert the map[string]any representation of the conversion target object to the target object") 49 } 50 51 for _, c := range r.GetConversions(dst) { 52 if tc, ok := c.(conversion.ManagedConversion); ok { 53 if _, err := tc.ConvertManaged(src, dst); err != nil { 54 return errors.Wrapf(err, "cannot apply the TerraformedConversion for the %q object", dst.GetTerraformResourceType()) 55 } 56 } 57 } 58 59 return nil 60 } 61 62 // RoundTrip round-trips from `src` to `dst` via an unstructured map[string]any 63 // representation of the `src` object and applies the registered webhook 64 // conversion functions. 65 func RoundTrip(dst, src resource.Terraformed) error { 66 return instance.RoundTrip(dst, src) 67 }