Skip to content

Commit

Permalink
Fix #2442
Browse files Browse the repository at this point in the history
  • Loading branch information
t0yv0 committed Mar 19, 2024
1 parent 385fe01 commit 6e1b56e
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 7 deletions.
99 changes: 99 additions & 0 deletions provider/pkg/rds/parameter_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Copyright 2016-2024, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package rds

import (
"context"
"fmt"
"regexp"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

// Customize resources in the rds module.
func ReconfigureResources(p *schema.Provider) {
parameterGroupReconfigure(p)
}

var (
parameterGroupApplyMethodRegexp = regexp.MustCompile(`^parameter\.(\d+)\.apply_method$`)
)

// Customize the aws_db_parameter_group resource.
func parameterGroupReconfigure(p *schema.Provider) {
parameterGroup, ok := p.ResourcesMap["aws_db_parameter_group"]
if !ok {
return
}
// Need to mark apply_method as Computed so that the diff customizer is allowed to clear it.
parameterGroup.Schema["parameter"].Elem.(*schema.Resource).Schema["apply_method"].Computed = true
// Need to exclude apply_method from the set hash.
oldSetFunc := parameterGroup.Schema["parameter"].Set
parameterGroup.Schema["parameter"].Set = parameterGroupParameterSetFunc(oldSetFunc)
addDiffCustomizer(parameterGroup, parameterGroupCustomizeDiff)
}

// Exclude "apply_method" from influencing the set element hash for a parameter.
func parameterGroupParameterSetFunc(oldSetFunc schema.SchemaSetFunc) schema.SchemaSetFunc {
return func(v interface{}) int {
m := v.(map[string]interface{})
// Pretend apply_method is always "immediate" to avoid changing the hash
copy := make(map[string]interface{}, len(m))
for k, v := range m {
copy[k] = v
}
copy["apply_method"] = "immediate"
return oldSetFunc(copy)
}
}

// Customize the diff to pretend that no changes are happening for a parameter that changes its apply_method but not its
// value. This makes the provider match cloud behavior better.
func parameterGroupCustomizeDiff(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error {
// If the apply_method is changed, and the value is not, then clear the apply_method change to ignore it.
for _, changedKey := range diff.GetChangedKeysPrefix("parameter") {
// Surprisingly GetChangedKeysPrefix returns keys that did not actually change, so skip those.
if !diff.HasChange(changedKey) {
continue
}
if m := parameterGroupApplyMethodRegexp.FindStringSubmatch(changedKey); m != nil {
parameterIndex := m[1]
matchingValueKey := fmt.Sprintf("parameter.%s.value", parameterIndex)
if !diff.HasChange(matchingValueKey) {
if err := diff.Clear(changedKey); err != nil {
return fmt.Errorf("Failed clearing %s: %w", changedKey, err)
}
}
}
}
return nil
}

// This could have been a helper function in pulumi-terraform-bridge somewhere.
func addDiffCustomizer(r *schema.Resource, cdf schema.CustomizeDiffFunc) {
// Just set it if it is not yet customized.
if r.CustomizeDiff == nil {
r.CustomizeDiff = cdf
return
}
// Sequence to compose the custom diff functions otherwise.
oldCDF := r.CustomizeDiff
r.CustomizeDiff = func(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error {
if err := oldCDF(ctx, diff, meta); err != nil {
return err
}
return cdf(ctx, diff, meta)
}
}
7 changes: 0 additions & 7 deletions provider/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
awsbase "github.com/hashicorp/aws-sdk-go-base/v2"
tfschema "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
awsShim "github.com/hashicorp/terraform-provider-aws/shim"
"github.com/mitchellh/go-homedir"
"github.com/pulumi/pulumi-aws/provider/v6/pkg/version"

Expand Down Expand Up @@ -780,12 +779,6 @@ func Provider() *tfbridge.ProviderInfo {
return ProviderFromMeta(tfbridge.NewProviderMetadata(runtimeMetadata))
}

func newUpstreamProvider(ctx context.Context) awsShim.UpstreamProvider {
upstreamProvider, err := awsShim.NewUpstreamProvider(ctx)
contract.AssertNoErrorf(err, "NewUpstreamProvider failed to initialize")
return upstreamProvider
}

func deprecateRuntime(value, name string) schema.EnumValueSpec {
s := schema.EnumValueSpec{Value: value, Name: name}
s.DeprecationMessage = "This runtime is now deprecated"
Expand Down
37 changes: 37 additions & 0 deletions provider/upstream_provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2016-2024, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package provider

import (
"context"

awsShim "github.com/hashicorp/terraform-provider-aws/shim"
"github.com/pulumi/pulumi-aws/provider/v6/pkg/rds"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
)

// Initialize a representation of the upstream provider.
//
// Lightly modifies the upstream provider to fix behavior that did not yet make it upstream.
//
// NOTE that this code runs in two contexts, during schema generation and during provider startup at runtime. The
// runtime startup is somewhat performance sensitive. Therefore any modifications undertaken here should complete
// quickly.
func newUpstreamProvider(ctx context.Context) awsShim.UpstreamProvider {
upstreamProvider, err := awsShim.NewUpstreamProvider(ctx)
contract.AssertNoErrorf(err, "NewUpstreamProvider failed to initialize")
rds.ReconfigureResources(upstreamProvider.SDKV2Provider)
return upstreamProvider
}

0 comments on commit 6e1b56e

Please sign in to comment.