From b15649bdb66996136245765c5ea6d9157a1c37e6 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Thu, 21 Dec 2023 23:11:17 +0300 Subject: [PATCH 1/3] Alias diag import Signed-off-by: Alper Rifat Ulucinar --- pkg/controller/external_nofork.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/controller/external_nofork.go b/pkg/controller/external_nofork.go index 52a9413a..36c76f4d 100644 --- a/pkg/controller/external_nofork.go +++ b/pkg/controller/external_nofork.go @@ -17,7 +17,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" xpresource "github.com/crossplane/crossplane-runtime/pkg/resource" "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + tfdiag "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" tf "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" "github.com/pkg/errors" @@ -104,8 +104,8 @@ func getJSONMap(mg xpresource.Managed) (map[string]any, error) { } type Resource interface { - Apply(ctx context.Context, s *tf.InstanceState, d *tf.InstanceDiff, meta interface{}) (*tf.InstanceState, diag.Diagnostics) - RefreshWithoutUpgrade(ctx context.Context, s *tf.InstanceState, meta interface{}) (*tf.InstanceState, diag.Diagnostics) + Apply(ctx context.Context, s *tf.InstanceState, d *tf.InstanceDiff, meta interface{}) (*tf.InstanceState, tfdiag.Diagnostics) + RefreshWithoutUpgrade(ctx context.Context, s *tf.InstanceState, meta interface{}) (*tf.InstanceState, tfdiag.Diagnostics) } type noForkExternal struct { From 74159f85d129838d6fa355fe5fa106de4e704f40 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Thu, 21 Dec 2023 23:13:06 +0300 Subject: [PATCH 2/3] Return the cty.Value of InstanceState from noForkExternal.fromInstanceStateToJSONMap Signed-off-by: Alper Rifat Ulucinar --- pkg/controller/external_nofork.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/controller/external_nofork.go b/pkg/controller/external_nofork.go index 36c76f4d..3b98cdee 100644 --- a/pkg/controller/external_nofork.go +++ b/pkg/controller/external_nofork.go @@ -496,7 +496,7 @@ func (n *noForkExternal) Observe(ctx context.Context, mg xpresource.Managed) (ma addTTR(mg) } mg.SetConditions(xpv1.Available()) - stateValueMap, err := n.fromInstanceStateToJSONMap(newState) + stateValueMap, _, err := n.fromInstanceStateToJSONMap(newState) if err != nil { return managed.ExternalObservation{}, errors.Wrap(err, "cannot convert instance state to JSON map") } @@ -601,12 +601,12 @@ func (n *noForkExternal) Create(ctx context.Context, mg xpresource.Managed) (man } n.opTracker.SetTfState(newState) - stateValueMap, err := n.fromInstanceStateToJSONMap(newState) + stateValueMap, _, err := n.fromInstanceStateToJSONMap(newState) if err != nil { return managed.ExternalCreation{}, errors.Wrap(err, "failed to convert instance state to map") } if _, err := n.setExternalName(mg, stateValueMap); err != nil { - return managed.ExternalCreation{}, errors.Wrapf(err, "failed to set the external-name of the managed resource during create") + return managed.ExternalCreation{}, errors.Wrap(err, "failed to set the external-name of the managed resource during create") } err = mg.(resource.Terraformed).SetObservation(stateValueMap) if err != nil { @@ -655,7 +655,7 @@ func (n *noForkExternal) Update(ctx context.Context, mg xpresource.Managed) (man } n.opTracker.SetTfState(newState) - stateValueMap, err := n.fromInstanceStateToJSONMap(newState) + stateValueMap, _, err := n.fromInstanceStateToJSONMap(newState) if err != nil { return managed.ExternalUpdate{}, err } @@ -686,15 +686,15 @@ func (n *noForkExternal) Delete(ctx context.Context, _ xpresource.Managed) error return nil } -func (n *noForkExternal) fromInstanceStateToJSONMap(newState *tf.InstanceState) (map[string]interface{}, error) { +func (n *noForkExternal) fromInstanceStateToJSONMap(newState *tf.InstanceState) (map[string]interface{}, cty.Value, error) { impliedType := n.config.TerraformResource.CoreConfigSchema().ImpliedType() attrsAsCtyValue, err := newState.AttrsAsObjectValue(impliedType) if err != nil { - return nil, errors.Wrap(err, "could not convert attrs to cty value") + return nil, cty.NilVal, errors.Wrap(err, "could not convert attrs to cty value") } stateValueMap, err := schema.StateValueToJSONMap(attrsAsCtyValue, impliedType) if err != nil { - return nil, errors.Wrap(err, "could not convert instance state value to JSON") + return nil, cty.NilVal, errors.Wrap(err, "could not convert instance state value to JSON") } - return stateValueMap, nil + return stateValueMap, attrsAsCtyValue, nil } From f0de67a3ce046a61a1fe0a030b5657bca9485cc5 Mon Sep 17 00:00:00 2001 From: Alper Rifat Ulucinar Date: Fri, 22 Dec 2023 10:49:59 +0300 Subject: [PATCH 3/3] Set the RawPlan for a new terraform.InstanceState returned from an observation Signed-off-by: Alper Rifat Ulucinar --- pkg/controller/external_nofork.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/pkg/controller/external_nofork.go b/pkg/controller/external_nofork.go index 3b98cdee..4bb73c60 100644 --- a/pkg/controller/external_nofork.go +++ b/pkg/controller/external_nofork.go @@ -474,10 +474,21 @@ func (n *noForkExternal) Observe(ctx context.Context, mg xpresource.Managed) (ma if diag != nil && diag.HasError() { return managed.ExternalObservation{}, errors.Errorf("failed to observe the resource: %v", diag) } + diffState := n.opTracker.GetTfState() n.opTracker.SetTfState(newState) // TODO: missing RawConfig & RawPlan here... - resourceExists := newState != nil && newState.ID != "" - instanceDiff, err := n.getResourceDataDiff(mg.(resource.Terraformed), ctx, newState, resourceExists) + + var stateValueMap map[string]any + if resourceExists { + jsonMap, stateValue, err := n.fromInstanceStateToJSONMap(newState) + if err != nil { + return managed.ExternalObservation{}, errors.Wrap(err, "cannot convert instance state to JSON map") + } + stateValueMap = jsonMap + newState.RawPlan = stateValue + diffState = newState + } + instanceDiff, err := n.getResourceDataDiff(mg.(resource.Terraformed), ctx, diffState, resourceExists) if err != nil { return managed.ExternalObservation{}, errors.Wrap(err, "cannot compute the instance diff") } @@ -496,10 +507,6 @@ func (n *noForkExternal) Observe(ctx context.Context, mg xpresource.Managed) (ma addTTR(mg) } mg.SetConditions(xpv1.Available()) - stateValueMap, _, err := n.fromInstanceStateToJSONMap(newState) - if err != nil { - return managed.ExternalObservation{}, errors.Wrap(err, "cannot convert instance state to JSON map") - } buff, err := json.TFParser.Marshal(stateValueMap) if err != nil {