Base migration framework by ulucinar · Pull Request #119 · crossplane/upjet (original) (raw)

Description of your changes

Fixes https://github.com/upbound/team-extensions/issues/29

This PR introduces the base framework for migrating from community providers to official providers.

I have:

How has this code been tested

Manually tested using the implemented sample converter and the following manifests:

apiVersion: apiextensions.crossplane.io/v1 kind: CompositeResourceDefinition metadata: name: xmyresources.test.com spec: claimNames: kind: MyResource plural: myresources group: test.com names: kind: XMyResource plural: xmyresources versions:


apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: labels: purpose: example name: example spec: compositeTypeRef: apiVersion: test.com/v1alpha1 kind: XMyResource resources: - base: apiVersion: ec2.aws.crossplane.io/v1beta1 kind: VPC spec: forProvider: cidrBlock: "192.168.0.0/16" ipv6Pool: pool1 region: "West Europe" tags: - key: key1 value: val1 - key: key2 value: val2 - key: key3 value: val3 name: vpc patches: - fromFieldPath: "spec.parameters.tagValue" toFieldPath: spec.forProvider.tags[0].value - fromFieldPath: "spec.parameters.tagValue" toFieldPath: spec.forProvider.tags[1].value - fromFieldPath: "spec.parameters.tagValue" toFieldPath: spec.forProvider.tags[2].value


apiVersion: test.com/v1alpha1 kind: MyResource metadata: name: my-resource namespace: upbound-system spec: compositionRef: name: example parameters: tagValue: demo-test


apiVersion: ec2.aws.crossplane.io/v1beta1 kind: VPC metadata: name: test-vpc spec: forProvider: cidrBlock: 192.168.0.0/16 ipv6Pool: pool1 region: West Europe tags: - key: key1 value: val1 - key: key2 value: val2 - key: key3 value: val3 status: atProvider: vpcId: vpc-0391605a3bf7977dd

And the following sample converter for community provider VPC resources (under pkg/migration/converters/vpc_converter.go):

func resources(mg resource.Managed) ([]resource.Managed, error) { source := mg.(*srcv1beta1.VPC) target := &targetv1beta1.VPC{} if _, err := migration.CopyInto(source, target, targetv1beta1.VPC_GroupVersionKind, "spec.forProvider.tags"); err != nil { return nil, errors.Wrap(err, "failed to copy source into target") } target.Spec.ForProvider.Tags = make(map[string]*string, len(source.Spec.ForProvider.Tags)) for _, t := range source.Spec.ForProvider.Tags { v := t.Value target.Spec.ForProvider.Tags[t.Key] = &v } return []resource.Managed{ target, }, nil }

func composedTemplates(cmp v1.ComposedTemplate, convertedBase ...*v1.ComposedTemplate) error { for i, cb := range convertedBase { for j, p := range cb.Patches { if p.ToFieldPath == nil || !strings.HasPrefix(*p.ToFieldPath, "spec.forProvider.tags") { continue } u, err := migration.FromRawExtension(cmp.Base) if err != nil { return errors.Wrap(err, "failed to convert ComposedTemplate with VPC base") } paved := fieldpath.Pave(u.Object) key, err := paved.GetString(strings.ReplaceAll(*p.ToFieldPath, ".value", ".key")) if err != nil { return errors.Wrap(err, "failed to get value from paved") } s := fmt.Sprintf(spec.forProvider.tags["%s"], key) convertedBase[i].Patches[j].ToFieldPath = &s } } return nil }

The converted resources are as follows:

apiVersion: apiextensions.crossplane.io/v1 kind: Composition metadata: labels: purpose: example name: example spec: compositeTypeRef: apiVersion: test.com/v1alpha1 kind: XMyResource resources:


apiVersion: ec2.aws.upbound.io/v1beta1 kind: VPC metadata: name: test-vpc spec: forProvider: cidrBlock: 192.168.0.0/16 region: West Europe tags: key1: val1 key2: val2 key3: val3