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

Implement DiffConfig #1683

Merged
merged 17 commits into from
Feb 21, 2024
Merged

Implement DiffConfig #1683

merged 17 commits into from
Feb 21, 2024

Conversation

t0yv0
Copy link
Member

@t0yv0 t0yv0 commented Feb 13, 2024

Fixes #244

Upon re-investigation DiffConfig appears to be a Pulumi-only feature as the notion of provider replacements, and especially cascading replacement plan from explicit provider to every resource managed by that provider, seems to be a Pulumi-only concept. The implementation is done accordingly at Pulumi-only level, not turning around through any TF internals. Path translation helpers are used to join in ForcesProviderReplace information from SchemaInfo overrides to changing property paths, and indicate replacement when a change is happening to such a property. Pulumi-level ignoreChanges is lifted from the Plugin Framework implementation and reused here.

Outside of the checked in tests, I have verified that the scenario outlined by @EvanBoyle in #244 (comment) is now made to work with AWS with this change. Getting there required taking some fixes to the muxer around DiffConfig muxing.

return plugin.DiffResult{}, fmt.Errorf("Error applying ignoreChanges: %v", err)
}

objDiff := oldInputs.DiffIncludeUnknowns(newInputsIC)
Copy link
Member Author

@t0yv0 t0yv0 Feb 13, 2024

Choose a reason for hiding this comment

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

Is this appropriate to use here? Does the comment at L624 make sense? It sounds like this function almost supported ignoreChanges but not quite.

Copy link
Member

Choose a reason for hiding this comment

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

It looks like a reasonable usage to me.

@@ -21,7 +21,7 @@ import (
"github.com/pulumi/pulumi/sdk/v3/go/common/resource"
)

func applyIgnoreChanges(old, new resource.PropertyMap, ignoreChanges []string) (resource.PropertyMap, error) {
func ApplyIgnoreChanges(old, new resource.PropertyMap, ignoreChanges []string) (resource.PropertyMap, error) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Moving this around, kind of wondering are we sure there's no primitives in pulumi/pulumi that compute this or something like this? I found resource.PropertyValue has Contains now which interpreters matching against a pattern.

Copy link
Contributor

@VenelinMartinov VenelinMartinov left a comment

Choose a reason for hiding this comment

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

LGTM

pkg/tfbridge/provider.go Show resolved Hide resolved
@t0yv0 t0yv0 changed the title Toward implementing DiffConfig Implement DiffConfig Feb 20, 2024
@t0yv0 t0yv0 marked this pull request as ready for review February 20, 2024 21:06
@t0yv0
Copy link
Member Author

t0yv0 commented Feb 20, 2024

@Frassle reusing some of the code from p/p does this look reasonable. Also are there reference implementations for DiffConfig, sounds like it's a Pulumi-specific feature and the only "bridge"-related thing here is the reinterpretation of TF ForceNew as something indicating a replace plan in DiffConfig. Thanks.

Copy link
Member

@iwahbe iwahbe left a comment

Choose a reason for hiding this comment

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

I want to make sure that we agree on the lifecycle of EnableDiffConfig before merging. Otherwise it looks good. I'm ok addressing the muxer issue.

// also the section on Explicit Provider Configuration in the docs:
//
// https://www.pulumi.com/docs/concepts/resources/providers/
EnableDiffConfig bool
Copy link
Member

Choose a reason for hiding this comment

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

I'm assuming that the arc of this variable will be:

  1. EnableDiffConfig defaults to false. We roll EnableDiffConfig out to a select set of our providers for live testing.
  2. EnableDiffConfig defaults to false, but we have rolled it out individually to all of our tier 1 providers.
  3. EnableDiffConfig defaults to true and is enabled on all of our providers. We leave the option to disable to avoid blocking 3rd party providers if their provider doesn't work with EnableDiffConfig: true. We ask 3rd party providers who set EnableDiffConfig: false to file a bug explaining what doesn't work.
  4. EnableDiffConfig is deprecated. The message says it will be removed in a future release.
  5. EnableDiffConfig is no longer an option. All bridged providers correctly implement DiffConfig.

To do that, we need to distinguish between true, false and unset:

Suggested change
EnableDiffConfig bool
EnableDiffConfig *bool

Comment on lines +219 to +221
if resp := dominatingDiffResponse(responses); resp != nil {
return resp, nil
}
Copy link
Member

Choose a reason for hiding this comment

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

The logic below to merge diff responses should handle a single response correctly (merge({diff}) = diff). If it doesn't, that indicates a bug in merge.

What happens when we remove dominatingDiffResponse?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this PR makes DiffConfig return ErrUnimplemented instead of the previous empty responses and it seems like these get returned from the muxer on line 282

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah at first I observed it was swallowing detailedDiff seemingly intentionally. This is because it was merging a real diff with an empty diff from PF and selecting the PF one incorrectly. I since switched PF to return NotImplemented instead of a dummy empty response. I think this is how it should have been. With this change to NotImplemented in place I think the muxer needs to treat NotImplemented as a special error. dominatingDiffResponse is one way to do it but not the only way.

Comment on lines 606 to 607
schemaPath := PropertyPathToSchemaPath(path, p.schemaMap, p.schemaInfos)
schema, info, err := LookupSchemas(schemaPath, p.schemaMap, p.schemaInfos)
Copy link
Member

Choose a reason for hiding this comment

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

I love how easy PropertyPathToSchemaPath and LookupSchemas make this!

pkg/tfbridge/provider_test.go Outdated Show resolved Hide resolved
Copy link
Member

@iwahbe iwahbe left a comment

Choose a reason for hiding this comment

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

LGTM

pkg/tfbridge/provider.go Outdated Show resolved Hide resolved
@t0yv0 t0yv0 merged commit 5e6c1ad into master Feb 21, 2024
7 checks passed
@t0yv0 t0yv0 deleted the t0yv0/diffconfig branch February 21, 2024 20:35
iwahbe added a commit that referenced this pull request Sep 11, 2024
As part of #2148, this PR removes the duplicate implementation of
`pulumigrpc.ResourceProviderServer` copied over from pulumi/pulumi and then modified.

This is a post #2258 version of #2195, and is much less invasive.

Addressing previous edits in response to
#2195 (comment):

- #1716: This change accommodated for a previous edit (`ProviderWithContext`) and is no
  longer necessary. That said, the tests it introduced are still present (and continue to
  pass), so we are sure this commit did not break the functionality.
- #1683: Simply brings DiffConfig into line with pu/pu, which we get for free by not
  vendoring.
- #1047: This is still handled in `provider_server.go`, and is still under test.
- #1065: This has already been moved out of this area in #2258, so it is no longer
  relevant here.
iwahbe added a commit that referenced this pull request Sep 11, 2024
As part of #2148, this PR removes the duplicate implementation of
`pulumigrpc.ResourceProviderServer` copied over from pulumi/pulumi and then modified.

This is a post #2258 version of #2195, and is much less invasive.

Addressing previous edits in response to
#2195 (comment):

- #1716: This change accommodated for a previous edit (`ProviderWithContext`) and is no
  longer necessary. That said, the tests it introduced are still present (and continue to
  pass), so we are sure this commit did not break the functionality.
- #1683: Simply brings DiffConfig into line with pu/pu, which we get for free by not
  vendoring.
- #1047: This is still handled in `provider_server.go`, and is still under test.
- #1065: This has already been moved out of this area in #2258, so it is no longer
  relevant here.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Re-enable CheckConfig / DiffConfig
3 participants