From 3ec60c393fc2d7671902d7d04d61cf5736bdb666 Mon Sep 17 00:00:00 2001 From: VenelinMartinov Date: Mon, 25 Nov 2024 17:43:30 +0000 Subject: [PATCH] Add PF provider options and accurate previews flag (#2663) This change adds provider options for the PF bridge, similar to the SDKv2 bridge provider options, as well as a flag for accurate bridge previews. I've also enabled the flag for all diff tests. --- dynamic/provider_test.go | 23 +++++++-------- pkg/pf/tests/genrandom_test.go | 1 + pkg/pf/tests/genupdate_test.go | 4 ++- pkg/pf/tests/internal/cross-tests/diff.go | 2 +- pkg/pf/tests/internal/cross-tests/util.go | 15 ++++++---- pkg/pf/tests/provider_diff_test.go | 8 ++++-- pkg/pf/tfbridge/provider.go | 34 +++++++++++++++++++++++ pkg/pf/tfbridge/provider_diff.go | 19 +++++++++---- 8 files changed, 80 insertions(+), 26 deletions(-) diff --git a/dynamic/provider_test.go b/dynamic/provider_test.go index 484120d64..101cb59b4 100644 --- a/dynamic/provider_test.go +++ b/dynamic/provider_test.go @@ -62,8 +62,9 @@ func TestStacktraceDisplayed(t *testing.T) { } func TestPrimitiveTypes(t *testing.T) { - t.Parallel() skipWindows(t) + // TODO[pulumi/pulumi-terraform-bridge#2517]: fix once accurate bridge previews are enabled by default + t.Setenv("PULUMI_TF_BRIDGE_ACCURATE_BRIDGE_PREVIEW", "true") ctx := context.Background() @@ -114,18 +115,18 @@ func TestPrimitiveTypes(t *testing.T) { t.Run("check", assertGRPCCall(grpc.Check, &pulumirpc.CheckRequest{ Urn: urn, News: inputs(), - })) + }, noParallel)) t.Run("create(preview)", assertGRPCCall(grpc.Create, &pulumirpc.CreateRequest{ Preview: true, Urn: urn, Properties: inputs(), - })) + }, noParallel)) t.Run("create", assertGRPCCall(grpc.Create, &pulumirpc.CreateRequest{ Urn: urn, Properties: inputs(), - })) + }, noParallel)) t.Run("diff(none)", assertGRPCCall(grpc.Diff, &pulumirpc.DiffRequest{ Id: "example-id-0", @@ -133,7 +134,7 @@ func TestPrimitiveTypes(t *testing.T) { Olds: outputs(), News: inputs(), OldInputs: inputs(), - })) + }, noParallel)) t.Run("diff(some)", assertGRPCCall(grpc.Diff, &pulumirpc.DiffRequest{ Id: "example-id-1", @@ -155,7 +156,7 @@ func TestPrimitiveTypes(t *testing.T) { "attrStringDefaultOverridden": resource.NewProperty("overridden"), }), OldInputs: inputs(), - })) + }, noParallel)) t.Run("diff(all)", assertGRPCCall(grpc.Diff, &pulumirpc.DiffRequest{ Id: "example-id-2", @@ -177,13 +178,13 @@ func TestPrimitiveTypes(t *testing.T) { "attrNumberRequired": resource.NewProperty(12.3456789), }), OldInputs: inputs(), - })) + }, noParallel)) t.Run("delete", assertGRPCCall(grpc.Delete, &pulumirpc.DeleteRequest{ Id: "example-id-delete", Urn: urn, Properties: outputs(), - })) + }, noParallel)) t.Run("update", assertGRPCCall(grpc.Update, &pulumirpc.UpdateRequest{ Id: "example-update-id", @@ -192,18 +193,18 @@ func TestPrimitiveTypes(t *testing.T) { News: marshal(with(outputProps(), resource.PropertyMap{ "attrBoolRequired": resource.NewProperty(false), })), - })) + }, noParallel)) t.Run("read", assertGRPCCall(grpc.Read, &pulumirpc.ReadRequest{ Id: "example-read-id", Urn: urn, Properties: outputs(), - })) + }, noParallel)) t.Run("import", assertGRPCCall(grpc.Read, &pulumirpc.ReadRequest{ Id: "example-read-id", Urn: urn, - })) + }, noParallel)) } func TestConfigure(t *testing.T) { diff --git a/pkg/pf/tests/genrandom_test.go b/pkg/pf/tests/genrandom_test.go index 2f012782f..be13048b1 100644 --- a/pkg/pf/tests/genrandom_test.go +++ b/pkg/pf/tests/genrandom_test.go @@ -48,6 +48,7 @@ func TestGenRandom(t *testing.T) { t.Run(trace, func(t *testing.T) { p := testprovider.RandomProvider() + p.EnableAccurateBridgePreview = true server, err := newProviderServer(t, p) require.NoError(t, err) testutils.ReplayFile(t, server, trace) diff --git a/pkg/pf/tests/genupdate_test.go b/pkg/pf/tests/genupdate_test.go index 518e2347b..31eb8a00b 100644 --- a/pkg/pf/tests/genupdate_test.go +++ b/pkg/pf/tests/genupdate_test.go @@ -34,7 +34,9 @@ func TestGenUpdates(t *testing.T) { t.Parallel() trace := "testdata/updateprogram.json" - server, err := newProviderServer(t, testprovider.SyntheticTestBridgeProvider()) + info := testprovider.SyntheticTestBridgeProvider() + info.EnableAccurateBridgePreview = true + server, err := newProviderServer(t, info) require.NoError(t, err) testutils.ReplayFile(t, server, trace) } diff --git a/pkg/pf/tests/internal/cross-tests/diff.go b/pkg/pf/tests/internal/cross-tests/diff.go index e8b2c1ec0..f0070cc8c 100644 --- a/pkg/pf/tests/internal/cross-tests/diff.go +++ b/pkg/pf/tests/internal/cross-tests/diff.go @@ -109,7 +109,7 @@ func Diff(t T, res pb.Resource, tfConfig1, tfConfig2 map[string]cty.Value, optio require.NoError(t, err) t.Logf("Pulumi.yaml:\n%s", string(bytes)) - pt, err := pulcheck.PulCheck(t, bridgedProvider(prov), string(bytes)) + pt, err := pulcheck.PulCheck(t, bridgedProvider(prov, bridgedProviderOpts{enableAccurateBridgePreview: true}), string(bytes)) require.NoError(t, err) pt.Up(t) diff --git a/pkg/pf/tests/internal/cross-tests/util.go b/pkg/pf/tests/internal/cross-tests/util.go index c8f0295f7..858a26c28 100644 --- a/pkg/pf/tests/internal/cross-tests/util.go +++ b/pkg/pf/tests/internal/cross-tests/util.go @@ -58,14 +58,19 @@ func skipUnlessLinux(t T) { } } -func bridgedProvider(prov *providerbuilder.Provider) info.Provider { +type bridgedProviderOpts struct { + enableAccurateBridgePreview bool +} + +func bridgedProvider(prov *providerbuilder.Provider, opts bridgedProviderOpts) info.Provider { shimProvider := tfbridge.ShimProvider(prov) provider := tfbridge0.ProviderInfo{ - P: shimProvider, - Name: prov.TypeName, - Version: prov.Version, - MetadataInfo: &tfbridge0.MetadataInfo{}, + P: shimProvider, + Name: prov.TypeName, + Version: prov.Version, + MetadataInfo: &tfbridge0.MetadataInfo{}, + EnableAccurateBridgePreview: opts.enableAccurateBridgePreview, } provider.MustComputeTokens(tokens.SingleModule(prov.TypeName, "index", tokens.MakeStandard(prov.TypeName))) diff --git a/pkg/pf/tests/provider_diff_test.go b/pkg/pf/tests/provider_diff_test.go index 29ff44f0f..c3158eefc 100644 --- a/pkg/pf/tests/provider_diff_test.go +++ b/pkg/pf/tests/provider_diff_test.go @@ -56,7 +56,9 @@ func TestEmptyTestresDiff(t *testing.T) { // Test removing an optional input. func TestOptionRemovalTestresDiff(t *testing.T) { t.Parallel() - server, err := newProviderServer(t, testprovider.SyntheticTestBridgeProvider()) + info := testprovider.SyntheticTestBridgeProvider() + info.EnableAccurateBridgePreview = true + server, err := newProviderServer(t, info) require.NoError(t, err) testCase := ` { @@ -270,7 +272,9 @@ func TestSetNestedObjectAdded(t *testing.T) { func TestSetNestedObjectAddedOtherDiff(t *testing.T) { t.Parallel() - server, err := newProviderServer(t, testprovider.SyntheticTestBridgeProvider()) + info := testprovider.SyntheticTestBridgeProvider() + info.EnableAccurateBridgePreview = true + server, err := newProviderServer(t, info) require.NoError(t, err) testCase := ` { diff --git a/pkg/pf/tfbridge/provider.go b/pkg/pf/tfbridge/provider.go index 1e51ee815..bb7822463 100644 --- a/pkg/pf/tfbridge/provider.go +++ b/pkg/pf/tfbridge/provider.go @@ -17,6 +17,7 @@ package tfbridge import ( "context" "fmt" + "os" "github.com/blang/semver" pfprovider "github.com/hashicorp/terraform-plugin-framework/provider" @@ -27,6 +28,7 @@ import ( "github.com/pulumi/pulumi/sdk/v3/go/common/resource" "github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin" "github.com/pulumi/pulumi/sdk/v3/go/common/tokens" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/cmdutil" "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" "github.com/pulumi/pulumi/sdk/v3/go/common/workspace" pulumirpc "github.com/pulumi/pulumi/sdk/v3/proto/go" @@ -42,6 +44,31 @@ import ( "github.com/pulumi/pulumi-terraform-bridge/v3/unstable/logging" ) +type providerOptions struct { + enableAccurateBridgePreview bool +} + +type providerOption func(providerOptions) (providerOptions, error) + +func withAccurateBridgePreview() providerOption { + return func(opts providerOptions) (providerOptions, error) { + opts.enableAccurateBridgePreview = true + return opts, nil + } +} + +func getProviderOptions(opts []providerOption) (providerOptions, error) { + res := providerOptions{} + for _, o := range opts { + var err error + res, err = o(res) + if err != nil { + return res, err + } + } + return res, nil +} + // Provider implements the Pulumi resource provider operations for any // Terraform plugin built with Terraform Plugin Framework. // @@ -66,6 +93,7 @@ type provider struct { lastKnownProviderConfig resource.PropertyMap schemaOnlyProvider shim.Provider + providerOpts []providerOption } var _ pl.ProviderWithContext = &provider{} @@ -148,6 +176,11 @@ func newProviderWithContext(ctx context.Context, info tfbridge.ProviderInfo, } } + opts := []providerOption{} + if info.EnableAccurateBridgePreview || cmdutil.IsTruthy(os.Getenv("PULUMI_TF_BRIDGE_ACCURATE_BRIDGE_PREVIEW")) { + opts = append(opts, withAccurateBridgePreview()) + } + p := &provider{ tfServer: server6, info: info, @@ -160,6 +193,7 @@ func newProviderWithContext(ctx context.Context, info tfbridge.ProviderInfo, version: semverVersion, schemaOnlyProvider: info.P, parameterize: meta.XParamaterize, + providerOpts: opts, } return configencoding.New(p), nil diff --git a/pkg/pf/tfbridge/provider_diff.go b/pkg/pf/tfbridge/provider_diff.go index cf045c559..5341813cb 100644 --- a/pkg/pf/tfbridge/provider_diff.go +++ b/pkg/pf/tfbridge/provider_diff.go @@ -122,17 +122,24 @@ func (p *provider) DiffWithContext( changes = plugin.DiffSome } - pluginDetailedDiff, err := calculateDetailedDiff(ctx, &rh, priorState, plannedStateValue, checkedInputs) - if err != nil { - return plugin.DiffResult{}, err - } - diffResult := plugin.DiffResult{ Changes: changes, ReplaceKeys: replaceKeys, ChangedKeys: changedKeys, DeleteBeforeReplace: deleteBeforeReplace, - DetailedDiff: pluginDetailedDiff, + } + + providerOpts, err := getProviderOptions(p.providerOpts) + if err != nil { + return plugin.DiffResult{}, err + } + + if providerOpts.enableAccurateBridgePreview { + pluginDetailedDiff, err := calculateDetailedDiff(ctx, &rh, priorState, plannedStateValue, checkedInputs) + if err != nil { + return plugin.DiffResult{}, err + } + diffResult.DetailedDiff = pluginDetailedDiff } // TODO[pulumi/pulumi-terraform-bridge#824] StableKeys