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

Remove v2Provider and v2InstanceDiff #2870

Draft
wants to merge 1 commit into
base: vvm/instance_diff2_shim_diff
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 0 additions & 136 deletions pkg/tfshim/sdk-v2/instance_diff.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,11 @@
package sdkv2

import (
"fmt"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"

shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim"
)

var _ = shim.InstanceDiff(v2InstanceDiff{})

func resourceAttrDiffToShim(d *terraform.ResourceAttrDiff) *shim.ResourceAttrDiff {
if d == nil {
return nil
Expand All @@ -29,131 +21,3 @@ func resourceAttrDiffToShim(d *terraform.ResourceAttrDiff) *shim.ResourceAttrDif
Type: shim.DiffAttrUnknown,
}
}

type v2InstanceDiff struct {
tf *terraform.InstanceDiff
}

func (d v2InstanceDiff) DiffEqualDecisionOverride() shim.DiffOverride {
return shim.DiffNoOverride
}

func (d v2InstanceDiff) applyTimeoutOptions(opts shim.TimeoutOptions) {
// This method is no longer used with PlanResourceChange; we handle timeouts more directly.
if opts.ResourceTimeout != nil {
err := d.encodeTimeouts(opts.ResourceTimeout)
contract.AssertNoErrorf(err, "encodeTimeouts should never fail")
}
for timeoutKey, dur := range opts.TimeoutOverrides {
d.setTimeout(dur, timeoutKey)
}
}

func (d v2InstanceDiff) Attribute(key string) *shim.ResourceAttrDiff {
return resourceAttrDiffToShim(d.tf.Attributes[key])
}

func (d v2InstanceDiff) HasNoChanges() bool {
return len(d.Attributes()) == 0
}

func (d v2InstanceDiff) Attributes() map[string]shim.ResourceAttrDiff {
m := map[string]shim.ResourceAttrDiff{}
for k, v := range d.tf.Attributes {
if v != nil {
m[k] = *resourceAttrDiffToShim(v)
}
}
return m
}

func (d v2InstanceDiff) ProposedState(res shim.Resource, priorState shim.InstanceState) (shim.InstanceState, error) {
var prior *terraform.InstanceState
if priorState != nil {
prior = priorState.(v2InstanceState).tf
} else {
prior = &terraform.InstanceState{
Attributes: map[string]string{},
Meta: map[string]interface{}{},
}
}

return v2InstanceState{
resource: res.(v2Resource).tf,
tf: prior,
diff: d.tf,
}, nil
}

func (d v2InstanceDiff) PriorState() (shim.InstanceState, error) {
return nil, fmt.Errorf("prior state is not available")
}

func (d v2InstanceDiff) Destroy() bool {
return d.tf.Destroy
}

func (d v2InstanceDiff) RequiresNew() bool {
return d.tf.RequiresNew()
}

func (d v2InstanceDiff) processIgnoreChanges(ignored shim.IgnoreChanges) {
i := ignored()
for k := range d.tf.Attributes {
if _, ok := i[k]; ok {
delete(d.tf.Attributes, k)
} else {
for attr := range i {
if strings.HasPrefix(k, attr+".") {
delete(d.tf.Attributes, k)
break
}
}
}
}
}

func (d v2InstanceDiff) encodeTimeouts(timeouts *shim.ResourceTimeout) error {
v2Timeouts := &schema.ResourceTimeout{}
if timeouts != nil {
v2Timeouts.Create = timeouts.Create
v2Timeouts.Read = timeouts.Read
v2Timeouts.Update = timeouts.Update
v2Timeouts.Delete = timeouts.Delete
v2Timeouts.Default = timeouts.Default
}
return v2Timeouts.DiffEncode(d.tf)
}

func (d v2InstanceDiff) setTimeout(timeout time.Duration, timeoutKey shim.TimeoutKey) {
// this turns seconds to nanoseconds - TF wants it in this format
timeoutValue := timeout.Nanoseconds()

switch timeoutKey {
case shim.TimeoutCreate:
timeoutKey = schema.TimeoutCreate
case shim.TimeoutRead:
timeoutKey = schema.TimeoutRead
case shim.TimeoutUpdate:
timeoutKey = schema.TimeoutUpdate
case shim.TimeoutDelete:
timeoutKey = schema.TimeoutDelete
case shim.TimeoutDefault:
timeoutKey = schema.TimeoutDefault
default:
return
}

if d.tf.Meta == nil {
d.tf.Meta = map[string]interface{}{}
}

timeouts, ok := d.tf.Meta[schema.TimeoutKey].(map[string]interface{})
if !ok {
d.tf.Meta[schema.TimeoutKey] = map[string]interface{}{
string(timeoutKey): timeoutValue,
}
} else {
timeouts[string(timeoutKey)] = timeoutValue
}
}
199 changes: 2 additions & 197 deletions pkg/tfshim/sdk-v2/provider.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,19 @@
package sdkv2

import (
"context"
"fmt"

"github.com/golang/glog"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
testing "github.com/mitchellh/go-testing-interface"

shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim"
)

var _ = shim.Provider(v2Provider{})

func configFromShim(c shim.ResourceConfig) *terraform.ResourceConfig {
if c == nil {
return nil
}
return c.(v2ResourceConfig).tf
}

func stateFromShim(s shim.InstanceState) *terraform.InstanceState {
if s == nil {
return nil
}
return s.(v2InstanceState).tf
}

func stateToShim(r *schema.Resource, s *terraform.InstanceState) shim.InstanceState {
if s == nil {
return nil
Expand All @@ -40,192 +25,12 @@ func diffFromShim(d shim.InstanceDiff) *terraform.InstanceDiff {
if d == nil {
return nil
}
return d.(v2InstanceDiff).tf
return d.(*v2InstanceDiff2).tf
}

func diffToShim(d *terraform.InstanceDiff) shim.InstanceDiff {
if d == nil {
return nil
}
return v2InstanceDiff{d}
}

type v2Provider struct {
tf *schema.Provider
}

var _ shim.Provider = (*v2Provider)(nil)

func (p v2Provider) Schema() shim.SchemaMap {
return v2SchemaMap(p.tf.Schema)
}

func (p v2Provider) ResourcesMap() shim.ResourceMap {
return v2ResourceMap(p.tf.ResourcesMap)
}

func (p v2Provider) DataSourcesMap() shim.ResourceMap {
return v2ResourceMap(p.tf.DataSourcesMap)
}

func (p v2Provider) InternalValidate() error {
return p.tf.InternalValidate()
}

func (p v2Provider) Validate(_ context.Context, c shim.ResourceConfig) ([]string, []error) {
return warningsAndErrors(p.tf.Validate(configFromShim(c)))
}

func (p v2Provider) ValidateResource(_ context.Context, t string, c shim.ResourceConfig) ([]string, []error) {
return warningsAndErrors(p.tf.ValidateResource(t, configFromShim(c)))
}

func (p v2Provider) ValidateDataSource(_ context.Context, t string, c shim.ResourceConfig) ([]string, []error) {
return warningsAndErrors(p.tf.ValidateDataSource(t, configFromShim(c)))
}

func (p v2Provider) Configure(ctx context.Context, c shim.ResourceConfig) error {
// See ConfigureProvider e.g.
// https://github.com/hashicorp/terraform-plugin-sdk/blob/main/helper/schema/grpc_provider.go#L564
ctxHack := context.WithValue(ctx, schema.StopContextKey, p.stopContext(context.Background()))
return errors(p.tf.Configure(ctxHack, configFromShim(c)))
}

func (p v2Provider) stopContext(ctx context.Context) context.Context {
// TODO may want to follow StopContext implementation to make sure calling calling p.Stop()
// cancels the context returned here.
//
// See: https://github.com/hashicorp/terraform-plugin-sdk/blob/main/helper/schema/grpc_provider.go#L60C1-L60C80
return ctx
}

func (p v2Provider) Apply(
ctx context.Context,
t string,
s shim.InstanceState,
d shim.InstanceDiff,
) (shim.InstanceState, error) {
r, ok := p.tf.ResourcesMap[t]
if !ok {
return nil, fmt.Errorf("unknown resource %v", t)
}
state, err := upgradeResourceState(ctx, t, p.tf, r, stateFromShim(s))
if err != nil {
return nil, fmt.Errorf("failed to upgrade resource state: %w", err)
}
state, diags := r.Apply(ctx, state, diffFromShim(d), p.tf.Meta())
return stateToShim(r, state), errors(diags)
}

func (p v2Provider) Refresh(
ctx context.Context,
t string,
s shim.InstanceState,
c shim.ResourceConfig,
) (shim.InstanceState, error) {
r, ok := p.tf.ResourcesMap[t]
if !ok {
return nil, fmt.Errorf("unknown resource %v", t)
}

state, err := upgradeResourceState(ctx, t, p.tf, r, stateFromShim(s))
if err != nil {
return nil, fmt.Errorf("failed to upgrade resource state: %w", err)
}

if c != nil {
state.RawConfig = makeResourceRawConfig(configFromShim(c), r)
}

state, diags := r.RefreshWithoutUpgrade(context.TODO(), state, p.tf.Meta())
return stateToShim(r, state), errors(diags)
}

func (p v2Provider) ReadDataDiff(
ctx context.Context,
t string,
c shim.ResourceConfig,
) (shim.InstanceDiff, error) {
resource, ok := p.tf.DataSourcesMap[t]
if !ok {
return nil, fmt.Errorf("unknown resource %v", t)
}

config := configFromShim(c)
rawConfig := makeResourceRawConfig(config, resource)

diff, err := resource.Diff(ctx, nil, config, p.tf.Meta())
if diff != nil {
diff.RawConfig = rawConfig
}
return diffToShim(diff), err
}

func (p v2Provider) ReadDataApply(
ctx context.Context,
t string,
d shim.InstanceDiff,
) (shim.InstanceState, error) {
r, ok := p.tf.DataSourcesMap[t]
if !ok {
return nil, fmt.Errorf("unknown resource %v", t)
}
state, diags := r.ReadDataApply(ctx, diffFromShim(d), p.tf.Meta())
return stateToShim(r, state), errors(diags)
}

func (p v2Provider) Meta(_ context.Context) interface{} {
return p.tf.Meta()
}

func (p v2Provider) Stop(_ context.Context) error {
return nil
}

func (p v2Provider) InitLogging(_ context.Context) {
logging.SetOutput(&testing.RuntimeT{})
}

func (p v2Provider) NewDestroyDiff(_ context.Context, t string, opts shim.TimeoutOptions) shim.InstanceDiff {
d := v2InstanceDiff{&terraform.InstanceDiff{Destroy: true}}
d.applyTimeoutOptions(opts)
return d
}

func (p v2Provider) NewResourceConfig(
_ context.Context, object map[string]interface{},
) shim.ResourceConfig {
return v2ResourceConfig{&terraform.ResourceConfig{
Raw: object,
Config: object,
}}
}

func (p v2Provider) NewProviderConfig(
_ context.Context, object map[string]interface{},
) shim.ResourceConfig {
tfConfig := &terraform.ResourceConfig{
Raw: object,
Config: object,
}
typ := schema.InternalMap(p.tf.Schema).CoreConfigSchema().ImpliedType()
ctyVal, err := recoverCtyValueOfObjectType(typ, object)
if err != nil {
glog.V(9).Infof("Failed to recover cty value of object type: %v, falling back to old behaviour", err)
return v2ResourceConfig{tfConfig}
}

tfConfig.CtyValue = ctyVal
return v2ResourceConfig{tfConfig}
}

func (p v2Provider) IsSet(_ context.Context, v interface{}) ([]interface{}, bool) {
if set, ok := v.(*schema.Set); ok {
return set.List(), true
}
return nil, false
}

func (p v2Provider) SupportsUnknownCollections() bool {
return true
return &v2InstanceDiff2{tf: d}
}
Loading
Loading