Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First stab at attr.TypeWithModifyPlan. #162

Closed
wants to merge 8 commits into from

Conversation

paddycarver
Copy link
Contributor

Addresses #161.

@paddycarver paddycarver added the types Issues and pull requests about our types abstraction and implementations. label Sep 21, 2021
@paddycarver paddycarver force-pushed the paddy_attr_type_modifyplan branch from 466b911 to 0d33ed0 Compare November 3, 2021 17:54
@paddycarver paddycarver force-pushed the paddy_attr_type_modifyplan branch 2 times, most recently from 765b493 to 5fdd181 Compare December 3, 2021 14:27
@paddycarver
Copy link
Contributor Author

I think this is ready for review, but is rebased on top of #231 and so depends on that being reviewed/merged first.

@paddycarver paddycarver marked this pull request as ready for review December 3, 2021 14:55
@paddycarver paddycarver requested a review from a team December 3, 2021 14:55
@paddycarver paddycarver added the enhancement New feature or request label Dec 3, 2021
@paddycarver paddycarver force-pushed the paddy_attr_type_modifyplan branch from 7dc5310 to 9ff49d4 Compare December 7, 2021 20:24
@bflad bflad self-assigned this Dec 13, 2021
@bflad
Copy link
Contributor

bflad commented Dec 13, 2021

I'll review once #231 is sorted and this change set is clearer. 👍

@paddycarver paddycarver force-pushed the paddy_attr_type_modifyplan branch from 9ff49d4 to 69053e4 Compare December 20, 2021 07:50
@paddycarver
Copy link
Contributor Author

Rebased after merging #231.

Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial thoughts/considerations -- I apologize I'm out of time today, but can look again tomorrow. This also certainly feels like it'd be much easier if everything was already refactored for attr.Value throughout.

"github.com/hashicorp/terraform-plugin-go/tftypes"
)

func runTypePlanModifiers(ctx context.Context, state, plan tftypes.Value, schema Schema, resp *planResourceChangeResponse) (tftypes.Value, bool) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the bool return value could be dropped here (or return its own diag.Diagnostics) in preference of the caller checking resp.Diagnostics.HasError() similar to other existing logic.

Comment on lines +42 to +45
// TODO: this isn't ideal
// but should it be a pathed diagnostic?
// Terraform is horribly broken at this point
// there may be nothing in the config to point to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree on the sentiment, but I still feel like we should set the expected attribute path and let Terraform CLI handle the UI details.

return plan, false
}
}
for attrName, a := range schema.Attributes {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to walking schema.Attributes, schema.Blocks should also be walked for their nested Blocks and Attributes to ensure those type plan modifiers are executed.

Comment on lines +336 to +350
// modifying the plan for each element in a set isn't
// supported at the moment, because there's no way to
// correlate the new value in the plan with the old
// value in the state; sets can only be reliably
// compared by the identity of the elements, and the
// identity of the element changed.
//
// as such, sets must have plan modification applied at
// the set level, because anything else doesn't really
// make much sense.
//
// providers unhappy with this can always implement the
// logic to call each element's ModifyPlan inside their
// set type's ModifyPlan, but I can't see a way to do
// it that's not rife with weird behaviors.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried that there are no Go documentation, diagnostics, logging, etc. breadcrumbs around this explicit omission in handling. Here's some potential ideas (not necessarily mutually exclusive):

  • Add Go documentation to attr.TypeWithPlanModification
  • Add a line item/comment to Consider InternalValidate equivalent #113
  • Deeply continuing to traverse the set to find any potential attr.TypeWithPlanModification, skip plan modification and output a warning log (I'm guessing preferable over warning diagnostics since it could be very noisy)
  • Save the current plan value for each element, perform the traversal with plan modifications, compare the two values and remove the current (now old) value if modified

func attributeTypeModifyPlan(ctx context.Context, typ attr.Type, state, plan tftypes.Value, path *tftypes.AttributePath) (attr.Value, diag.Diagnostics) {
var diags diag.Diagnostics
if plan.IsKnown() && !plan.IsNull() {
if typ.TerraformType(ctx).Is(tftypes.Object{}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Seems this logic could be simplified via:

tfType := typ.TerraformType(ctx)
switch {
case tfType.Is(tftypes.Object{}):
  plan, diags = attributeTypeModifyPlanObject(ctx, typ, state, plan, path)
case tfType.Is(tftypes.Map{}):
  plan, diags = attributeTypeModifyPlanMap(ctx, typ, state, plan, path)
// ...
}
if diags.HasError() {
  return plan, diags
}

Unless there's some explicit reason to return a nil value instead of the prior plan value during errors.

// ModifyPlan returns the Value that should be used in the plan. It is
// generally used to suppress diffs that do not correspond to semantic
// differences. In these cases, the `state` Value should be returned.
ModifyPlan(ctx context.Context, state, plan Value, path *tftypes.AttributePath) (Value, diag.Diagnostics)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open question: Should these also have access to the configuration value?

@hashicorp-cla
Copy link

hashicorp-cla commented Mar 12, 2022

CLA assistant check
All committers have signed the CLA.

@bflad
Copy link
Contributor

bflad commented Jun 22, 2022

@paddycarver I think we're finally at a place where we can work on this after a lot of refactoring. Do you have interest in the implementation still?

@bflad bflad added waiting-response Issues or pull requests waiting for an external response labels Jun 22, 2022
@bflad
Copy link
Contributor

bflad commented Nov 30, 2022

There have been a lot of changes to the framework affecting this particular code, so I'm going to close this.

@bflad bflad closed this Nov 30, 2022
@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 31, 2022
@bflad bflad deleted the paddy_attr_type_modifyplan branch January 11, 2023 17:33
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request types Issues and pull requests about our types abstraction and implementations. waiting-response Issues or pull requests waiting for an external response
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants