upjet icon indicating copy to clipboard operation
upjet copied to clipboard

Add a new late-init configuration to skip already filled field in spec.initProvider

Open sergenyalcin opened this issue 1 year ago • 0 comments

Description of your changes

This PR adds a new late-init API to skip already filled field in spec.initProvider.

Even though a field is specified in initProvider, it is late-init for forProvider. This can cause problems in some cases because forProvider is more powerful. With this new configuration API, the late-init operation of the field in forProvider can be skipped for fields set in initProvider.

I have:

  • [x] Read and followed Upjet's contribution process.
  • [x] Run make reviewable to ensure this PR is ready for review.
  • [ ] Added backport release-x.y labels to auto-backport this PR if necessary.

How has this code been tested

Tested in provider-aws by using this configuration. The example configuration for aws ec2.Subnet resource:

	p.AddResourceConfigurator("aws_subnet", func(r *config.Resource) {
		r.LateInitializer = config.LateInitializer{
			ConditionalIgnoredFields: []string{
				"cidr_block",
			},
		}
	})

Generated LateInitialize function:

func (tr *Subnet) LateInitialize(attrs []byte) (bool, error) {
	params := &SubnetParameters_2{}
	if err := json.TFParser.Unmarshal(attrs, params); err != nil {
		return false, errors.Wrap(err, "failed to unmarshal Terraform state parameters for late-initialization")
	}
	opts := []resource.GenericLateInitializerOption{resource.WithZeroValueJSONOmitEmptyFilter(resource.CNameWildcard)}
	initParams, err := tr.GetInitParameters()
	if err != nil {
		return false, errors.Wrapf(err, "cannot get init parameters for resource '%q'", tr.GetName())
	}
	opts = append(opts, resource.WithConditionalFilter("CidrBlock", initParams))

	li := resource.NewGenericLateInitializer(opts...)
	return li.LateInitialize(&tr.Spec.ForProvider, params)
}

sergenyalcin avatar May 22 '24 13:05 sergenyalcin