diff --git a/pkg/migration/converter.go b/pkg/migration/converter.go index 6019060a..c8f86bbd 100644 --- a/pkg/migration/converter.go +++ b/pkg/migration/converter.go @@ -259,3 +259,45 @@ func toPackageLock(u unstructured.Unstructured) (*xppkgv1beta1.Lock, error) { } return lock, nil } + +// ConvertComposedTemplatePatchesMap converts the composed templates with given conversionMap +// Key of the conversionMap points to the source field +// Value of the conversionMap points to the target field +func ConvertComposedTemplatePatchesMap(sourceTemplate xpv1.ComposedTemplate, conversionMap map[string]string) []xpv1.Patch { + var patchesToAdd []xpv1.Patch + for _, p := range sourceTemplate.Patches { + switch p.Type { // nolint:exhaustive + case xpv1.PatchTypeFromCompositeFieldPath, xpv1.PatchTypeCombineFromComposite, "": + { + if p.ToFieldPath != nil { + if to, ok := conversionMap[*p.ToFieldPath]; ok { + patchesToAdd = append(patchesToAdd, xpv1.Patch{ + Type: p.Type, + FromFieldPath: p.FromFieldPath, + ToFieldPath: &to, + Transforms: p.Transforms, + Policy: p.Policy, + Combine: p.Combine, + }) + } + } + } + case xpv1.PatchTypeToCompositeFieldPath, xpv1.PatchTypeCombineToComposite: + { + if p.FromFieldPath != nil { + if to, ok := conversionMap[*p.FromFieldPath]; ok { + patchesToAdd = append(patchesToAdd, xpv1.Patch{ + Type: p.Type, + FromFieldPath: &to, + ToFieldPath: p.ToFieldPath, + Transforms: p.Transforms, + Policy: p.Policy, + Combine: p.Combine, + }) + } + } + } + } + } + return patchesToAdd +} diff --git a/pkg/migration/registry.go b/pkg/migration/registry.go index 12a06d23..b88a7b27 100644 --- a/pkg/migration/registry.go +++ b/pkg/migration/registry.go @@ -471,6 +471,30 @@ func (d *delegatingConverter) ComposedTemplate(sourceTemplate xpv1.ComposedTempl return d.cmpFn(sourceTemplate, convertedTemplates...) } +// DefaultCompositionConverter is a generic composition converter +// conversionMap: is fieldpath map for conversion +// Key of the conversionMap points to the source field +// Value of the conversionMap points to the target field +// Example: "spec.forProvider.assumeRolePolicyDocument": "spec.forProvider.assumeRolePolicy", +// fns are functions that manipulate the patchsets +func DefaultCompositionConverter(conversionMap map[string]string, fns ...func(sourceTemplate xpv1.ComposedTemplate) ([]xpv1.Patch, error)) ComposedTemplateConversionFn { + return func(sourceTemplate xpv1.ComposedTemplate, convertedTemplates ...*xpv1.ComposedTemplate) error { + var patchesToAdd []xpv1.Patch + for _, fn := range fns { + patches, err := fn(sourceTemplate) + if err != nil { + return errors.Wrap(err, "cannot run the patch sets converter function") + } + patchesToAdd = append(patchesToAdd, patches...) + } + patchesToAdd = append(patchesToAdd, ConvertComposedTemplatePatchesMap(sourceTemplate, conversionMap)...) + for i := range convertedTemplates { + convertedTemplates[i].Patches = append(convertedTemplates[i].Patches, patchesToAdd...) + } + return nil + } +} + // RegisterAPIConversionFunctions registers the supplied ResourceConversionFn and // ComposedTemplateConversionFn for the specified GVK, and the supplied // PatchSetsConversionFn for all the discovered Compositions.