-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix unknown collections of obj (#2061)
This changes the bridge to correctly return unknowns for objects and collections in sdkv2. fixes #1885 fixes #2032 stacked on #2158 Confirmed that TF sdkv2 supports both unknown blocks and unknown collections of blocks, so we should be fine to pass these into TF providers. The TF sdkv1 does not support unknowns for blocks and collections so we keep the old behaviour of passing empty/ collection of unknown. <details> ```hcl provider "google" { region = "us-central1" } resource "google_storage_bucket" "bucket" { name = "example-bucket12312322312" location = "US" } resource "google_storage_bucket" "bucket1" { name = "example-bucket123123223" location = "US" dynamic "lifecycle_rule" { for_each = google_storage_bucket.bucket.effective_labels content { action { type = lifecycle_rule.value } condition { age = 1 } } } } ``` </details> This returns `"lifecycle_rule":cty.UnknownVal(cty.List(cty.Object))` Our handling of collections containing unknowns and unknown collections is significantly better: Unknown collections: before: ``` + prov:index/test:Test: (create) [urn=urn:pulumi:test::test::prov:index/test:Test::mainRes] tests : [ [0]: {} ] ``` after: ``` + prov:index/test:Test: (create) [urn=urn:pulumi:test::test::prov:index/test:Test::mainRes] tests : output<string> ``` Note that the array being output as an `output<string>` is an engine limitation. Nested unknown collections: before: ``` + prov:index/nestedTest:NestedTest: (create) [urn=urn:pulumi:test::test::prov:index/nestedTest:NestedTest::mainRes] tests : [ [0]: { nestedProps: [ [0]: { testProps : [ [0]: output<string> ] } ] } ] ``` after: ``` + prov:index/nestedTest:NestedTest: (create) [urn=urn:pulumi:test::test::prov:index/nestedTest:NestedTest::mainRes] tests : [ [0]: { nestedProps: [ [0]: { testProps : output<string> } ] } ] ``` The unknown was being put one level lower than it should be. Quite a few other very wrong outputs in #2140, including diff duplications, missing diffs etc.
- Loading branch information
1 parent
97c9899
commit 4c5493a
Showing
17 changed files
with
320 additions
and
118 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package schemaconvert | ||
|
||
import ( | ||
v1Schema "github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
v2Schema "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" | ||
) | ||
|
||
func Sdkv2ToV1Type(t v2Schema.ValueType) v1Schema.ValueType { | ||
return v1Schema.ValueType(t) | ||
} | ||
|
||
func Sdkv2ToV1SchemaOrResource(elem interface{}) interface{} { | ||
switch elem := elem.(type) { | ||
case nil: | ||
return nil | ||
case *v2Schema.Schema: | ||
return Sdkv2ToV1Schema(elem) | ||
case *v2Schema.Resource: | ||
return Sdkv2ToV1Resource(elem) | ||
default: | ||
contract.Failf("unexpected type %T", elem) | ||
return nil | ||
} | ||
} | ||
|
||
func Sdkv2ToV1Resource(sch *v2Schema.Resource) *v1Schema.Resource { | ||
//nolint:staticcheck | ||
if sch.MigrateState != nil { | ||
contract.Failf("MigrateState is not supported in conversion") | ||
} | ||
if sch.StateUpgraders != nil { | ||
contract.Failf("StateUpgraders is not supported in conversion") | ||
} | ||
//nolint:staticcheck | ||
if sch.Create != nil || sch.Read != nil || sch.Update != nil || sch.Delete != nil || sch.Exists != nil || | ||
sch.CreateContext != nil || sch.ReadContext != nil || sch.UpdateContext != nil || | ||
sch.DeleteContext != nil || sch.Importer != nil { | ||
contract.Failf("runtime methods not supported in conversion") | ||
} | ||
|
||
if sch.CustomizeDiff != nil { | ||
contract.Failf("CustomizeDiff is not supported in conversion") | ||
} | ||
|
||
timeouts := v1Schema.ResourceTimeout{} | ||
if sch.Timeouts != nil { | ||
timeouts = v1Schema.ResourceTimeout{ | ||
Create: sch.Timeouts.Create, | ||
Read: sch.Timeouts.Read, | ||
Update: sch.Timeouts.Update, | ||
Delete: sch.Timeouts.Delete, | ||
Default: sch.Timeouts.Default, | ||
} | ||
} | ||
timoutsPtr := &timeouts | ||
if sch.Timeouts == nil { | ||
timoutsPtr = nil | ||
} | ||
|
||
return &v1Schema.Resource{ | ||
Schema: Sdkv2ToV1SchemaMap(sch.Schema), | ||
SchemaVersion: sch.SchemaVersion, | ||
DeprecationMessage: sch.DeprecationMessage, | ||
Timeouts: timoutsPtr, | ||
} | ||
} | ||
|
||
func Sdkv2ToV1Schema(sch *v2Schema.Schema) *v1Schema.Schema { | ||
if sch.DiffSuppressFunc != nil { | ||
contract.Failf("DiffSuppressFunc is not supported in conversion") | ||
} | ||
|
||
defaultFunc := v1Schema.SchemaDefaultFunc(nil) | ||
if sch.DefaultFunc != nil { | ||
defaultFunc = func() (interface{}, error) { | ||
return sch.DefaultFunc() | ||
} | ||
} | ||
|
||
stateFunc := v1Schema.SchemaStateFunc(nil) | ||
if sch.StateFunc != nil { | ||
stateFunc = func(i interface{}) string { | ||
return sch.StateFunc(i) | ||
} | ||
} | ||
|
||
set := v1Schema.SchemaSetFunc(nil) | ||
if sch.Set != nil { | ||
set = func(i interface{}) int { | ||
return sch.Set(i) | ||
} | ||
} | ||
|
||
validateFunc := v1Schema.SchemaValidateFunc(nil) | ||
if sch.ValidateFunc != nil { | ||
validateFunc = func(i interface{}, s string) ([]string, []error) { | ||
return sch.ValidateFunc(i, s) | ||
} | ||
} | ||
|
||
return &v1Schema.Schema{ | ||
Type: Sdkv2ToV1Type(sch.Type), | ||
Optional: sch.Optional, | ||
Required: sch.Required, | ||
Default: sch.Default, | ||
DefaultFunc: defaultFunc, | ||
Description: sch.Description, | ||
InputDefault: sch.InputDefault, | ||
Computed: sch.Computed, | ||
ForceNew: sch.ForceNew, | ||
StateFunc: stateFunc, | ||
Elem: Sdkv2ToV1SchemaOrResource(sch.Elem), | ||
MaxItems: sch.MaxItems, | ||
MinItems: sch.MinItems, | ||
Set: set, | ||
//nolint:staticcheck | ||
ComputedWhen: sch.ComputedWhen, | ||
ConflictsWith: sch.ConflictsWith, | ||
ExactlyOneOf: sch.ExactlyOneOf, | ||
AtLeastOneOf: sch.AtLeastOneOf, | ||
Deprecated: sch.Deprecated, | ||
ValidateFunc: validateFunc, | ||
Sensitive: sch.Sensitive, | ||
} | ||
} | ||
|
||
func Sdkv2ToV1SchemaMap(sch map[string]*v2Schema.Schema) map[string]*v1Schema.Schema { | ||
res := make(map[string]*v1Schema.Schema) | ||
for k, v := range sch { | ||
res[k] = Sdkv2ToV1Schema(v) | ||
} | ||
return res | ||
} |
Oops, something went wrong.