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

Fix unknown collections of obj #2061

Merged
merged 61 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
63a9bff
unknown tests
VenelinMartinov Jun 4, 2024
1c3797a
rename accidentally repeated test name
VenelinMartinov Jun 4, 2024
9cca15c
add description for the tests
VenelinMartinov Jun 4, 2024
989d6f1
correct test case
VenelinMartinov Jun 5, 2024
d77e1a0
fix proposed new unknown blocks
VenelinMartinov Jun 5, 2024
c76fba8
correct set test
VenelinMartinov Jun 5, 2024
143b87b
remove duplicated known check
VenelinMartinov Jun 5, 2024
8257844
add check test
VenelinMartinov Jun 5, 2024
2146474
fix unknown collection of obj
VenelinMartinov Jun 5, 2024
6ae7900
uncomment test
VenelinMartinov Jun 5, 2024
9ebe339
fix non prc tests
VenelinMartinov Jun 5, 2024
da0353b
Merge branch 'master' into vvm/fix_unknown_collections_of_obj
VenelinMartinov Jun 18, 2024
f596124
support all types of unknowns
VenelinMartinov Jun 25, 2024
a572732
use autogold for the cli output
VenelinMartinov Jun 25, 2024
65e1e4a
Merge branch 'master' into vvm/fix_unknown_collections_of_obj
VenelinMartinov Jun 25, 2024
9a70d46
Merge branch 'master' into vvm/fix_unknown_collections_of_obj
VenelinMartinov Jun 26, 2024
e5f0908
lint
VenelinMartinov Jun 26, 2024
a322aac
add test with unknown and known in a list
VenelinMartinov Jun 26, 2024
d980b07
nested tests
VenelinMartinov Jun 26, 2024
7624356
Merge branch 'master' into vvm/fix_unknown_collections_of_obj
VenelinMartinov Jun 27, 2024
67e2bae
add some more tests, debugging
VenelinMartinov Jun 27, 2024
ff51402
add note about plugin sdk behaviour
VenelinMartinov Jun 27, 2024
6931e6a
more tests for updating with computed
VenelinMartinov Jun 27, 2024
6524b9d
commit tests
VenelinMartinov Jun 27, 2024
3e9a8a8
update tests
VenelinMartinov Jun 27, 2024
e61d153
Merge branch 'vvm/more_unknown_tests' into vvm/fix_unknown_collection…
VenelinMartinov Jun 27, 2024
ac7747f
inline tf unknown
VenelinMartinov Jun 27, 2024
c4dde52
update test
VenelinMartinov Jun 27, 2024
a96ce40
remove debug logging
VenelinMartinov Jun 27, 2024
6b1e2be
remove debug logging
VenelinMartinov Jun 27, 2024
026a0df
update resources
VenelinMartinov Jun 27, 2024
2a6ebd3
update test
VenelinMartinov Jun 27, 2024
68de606
update unused code
VenelinMartinov Jun 27, 2024
480acc6
add todos
VenelinMartinov Jun 27, 2024
bc61456
another todo
VenelinMartinov Jun 27, 2024
a44380f
add note about odd test
VenelinMartinov Jun 27, 2024
ef39d9d
lint
VenelinMartinov Jul 1, 2024
54f438b
fix todo
VenelinMartinov Jul 1, 2024
06929b5
fix needs update check
VenelinMartinov Jul 1, 2024
4b4fc3b
Merge branch 'master' into vvm/fix_unknown_collections_of_obj
VenelinMartinov Jul 1, 2024
8a48049
fix test
VenelinMartinov Jul 1, 2024
f91d224
more lint
VenelinMartinov Jul 2, 2024
725ea59
diff tests for sdkv2
VenelinMartinov Jul 3, 2024
d8395ff
make new config and state for each test
VenelinMartinov Jul 3, 2024
9d05430
separate setup for each test
VenelinMartinov Jul 3, 2024
0573b9b
move schemaconvert
VenelinMartinov Jul 3, 2024
b5177ec
lint
VenelinMartinov Jul 3, 2024
1973687
lint
VenelinMartinov Jul 3, 2024
fc38c75
add a v2 override
VenelinMartinov Jul 3, 2024
f97793e
Merge branch 'vvm/diff_tests_for_sdkv2' into vvm/fix_unknown_collecti…
VenelinMartinov Jul 3, 2024
beea3a3
go mod tidy
VenelinMartinov Jul 3, 2024
8e17f48
rework schema.go to support both strategies for unknowns
VenelinMartinov Jul 3, 2024
bae090b
implement all providers
VenelinMartinov Jul 3, 2024
82616ba
update tests
VenelinMartinov Jul 3, 2024
71cdfd0
Revert "add a v2 override"
VenelinMartinov Jul 3, 2024
faeb1d4
go mod tidy
VenelinMartinov Jul 3, 2024
4692119
Merge branch 'vvm/diff_tests_for_sdkv2' into vvm/fix_unknown_collecti…
VenelinMartinov Jul 3, 2024
3affc4a
lint
VenelinMartinov Jul 3, 2024
d029d6e
lint
VenelinMartinov Jul 3, 2024
c910839
address review comments
VenelinMartinov Jul 17, 2024
ddc6c06
Merge branch 'master' into vvm/fix_unknown_collections_of_obj
VenelinMartinov Jul 17, 2024
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
4 changes: 4 additions & 0 deletions pf/internal/schemashim/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,7 @@ func (p *SchemaOnlyProvider) NewResourceConfig(context.Context, map[string]inter
func (p *SchemaOnlyProvider) IsSet(context.Context, interface{}) ([]interface{}, bool) {
panic("schemaOnlyProvider does not implement runtime operation IsSet")
}

func (p *SchemaOnlyProvider) SupportsUnknownCollections() bool {
return true
}
4 changes: 4 additions & 0 deletions pf/proto/unsupported.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,7 @@ func (Provider) NewResourceConfig(ctx context.Context, object map[string]interfa
func (Provider) IsSet(ctx context.Context, v interface{}) ([]interface{}, bool) {
panic("Unimplemented")
}

func (Provider) SupportsUnknownCollections() bool {
panic("Unimplemented")
}
30 changes: 26 additions & 4 deletions pkg/tests/internal/pulcheck/pulcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@ import (
"gotest.tools/assert"
)

func propNeedsUpdate(prop *schema.Schema) bool {
if prop.Computed && !prop.Optional {
return false
}
if prop.ForceNew {
return false
}
return true
}

func resourceNeedsUpdate(res *schema.Resource) bool {
// If any of the properties need an update, then the resource needs an update.
for _, s := range res.Schema {
if propNeedsUpdate(s) {
return true
}
}
return false
}

// This is an experimental API.
func EnsureProviderValid(t T, tfp *schema.Provider) {
for _, r := range tfp.ResourcesMap {
Expand All @@ -54,10 +74,12 @@ func EnsureProviderValid(t T, tfp *schema.Provider) {
}
}

r.UpdateContext = func(
ctx context.Context, rd *schema.ResourceData, i interface{},
) diag.Diagnostics {
return diag.Diagnostics{}
if resourceNeedsUpdate(r) && r.UpdateContext == nil {
r.UpdateContext = func(
ctx context.Context, rd *schema.ResourceData, i interface{},
) diag.Diagnostics {
return diag.Diagnostics{}
}
}
}
require.NoError(t, tfp.InternalValidate())
Expand Down
74 changes: 30 additions & 44 deletions pkg/tests/schema_pulumi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -852,9 +852,7 @@ resources:
[urn=urn:pulumi:test::test::prov:index/aux:Aux::auxRes]
+ prov:index/test:Test: (create)
[urn=urn:pulumi:test::test::prov:index/test:Test::mainRes]
tests : [
[0]: {}
]
tests : output<string>
iwahbe marked this conversation as resolved.
Show resolved Hide resolved
Resources:
+ 3 to create
`),
Expand All @@ -866,11 +864,12 @@ Resources:
~ prov:index/test:Test: (update)
[id=newid]
[urn=urn:pulumi:test::test::prov:index/test:Test::mainRes]
~ tests: [
~ [0]: {
- testProp: "known_val"
}
- tests: [
- [0]: {
- testProp: "known_val"
}
]
+ tests: output<string>
Resources:
+ 1 to create
~ 1 to update
Expand Down Expand Up @@ -1012,9 +1011,7 @@ resources:
[urn=urn:pulumi:test::test::prov:index/aux:Aux::auxRes]
+ prov:index/nestedTest:NestedTest: (create)
[urn=urn:pulumi:test::test::prov:index/nestedTest:NestedTest::mainRes]
tests : [
[0]: {}
]
tests : output<string>
Resources:
+ 3 to create
`),
Expand All @@ -1026,24 +1023,18 @@ Resources:
~ prov:index/nestedTest:NestedTest: (update)
[id=newid]
[urn=urn:pulumi:test::test::prov:index/nestedTest:NestedTest::mainRes]
~ tests: [
~ [0]: {
- nestedProps: [
- [0]: {
- testProps: [
- [0]: "known_val"
]
}
]
- nestedProps: [
- [0]: {
- testProps: [
- [0]: "known_val"
]
}
]
}
- tests: [
- [0]: {
- nestedProps: [
- [0]: {
- testProps: [
- [0]: "known_val"
]
}
]
}
]
+ tests: output<string>
Resources:
+ 1 to create
~ 1 to update
Expand Down Expand Up @@ -1134,9 +1125,7 @@ resources:
[urn=urn:pulumi:test::test::prov:index/nestedTest:NestedTest::mainRes]
tests : [
[0]: {
nestedProps: [
[0]: {}
]
nestedProps: output<string>
}
]
Resources:
Expand All @@ -1152,16 +1141,14 @@ Resources:
[urn=urn:pulumi:test::test::prov:index/nestedTest:NestedTest::mainRes]
~ tests: [
~ [0]: {
~ nestedProps: [
~ [0]: {
- testProps: [
- [0]: "known_val"
]
- testProps: [
- [0]: "known_val"
]
}
- nestedProps: [
- [0]: {
- testProps: [
- [0]: "known_val"
]
}
]
+ nestedProps: output<string>
}
]
Resources:
Expand Down Expand Up @@ -1262,9 +1249,7 @@ resources:
[0]: {
nestedProps: [
[0]: {
testProps : [
[0]: output<string>
]
testProps : output<string>
}
]
}
Expand All @@ -1284,9 +1269,10 @@ Resources:
~ [0]: {
~ nestedProps: [
~ [0]: {
~ testProps: [
~ [0]: "known_val" => output<string>
- testProps: [
- [0]: "known_val"
]
+ testProps: output<string>
}
]
}
Expand Down
14 changes: 8 additions & 6 deletions pkg/tfbridge/diff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func TestCustomizeDiff(t *testing.T) {
Schema: &ResourceInfo{Fields: info},
}
tfState, err := makeTerraformStateWithOpts(ctx, r, "id", stateMap,
makeTerraformStateOptions{defaultZeroSchemaVersion: true})
makeTerraformStateOptions{defaultZeroSchemaVersion: true, unknownCollectionsSupported: true})
assert.NoError(t, err)

config, _, err := MakeTerraformConfig(ctx, &Provider{tf: provider}, inputsMap, sch, info)
Expand Down Expand Up @@ -130,7 +130,7 @@ func TestCustomizeDiff(t *testing.T) {
Schema: &ResourceInfo{Fields: info},
}
tfState, err := makeTerraformStateWithOpts(ctx, r, "id", stateMap,
makeTerraformStateOptions{defaultZeroSchemaVersion: true})
makeTerraformStateOptions{defaultZeroSchemaVersion: true, unknownCollectionsSupported: true})
assert.NoError(t, err)

config, _, err := MakeTerraformConfig(ctx, &Provider{tf: provider}, inputsMap, sch, info)
Expand Down Expand Up @@ -184,7 +184,7 @@ func TestCustomizeDiff(t *testing.T) {
Schema: &ResourceInfo{Fields: info},
}
tfState, err := makeTerraformStateWithOpts(ctx, r, "id", stateMap,
makeTerraformStateOptions{defaultZeroSchemaVersion: true})
makeTerraformStateOptions{defaultZeroSchemaVersion: true, unknownCollectionsSupported: true})
assert.NoError(t, err)

config, _, err := MakeTerraformConfig(ctx, &Provider{tf: provider}, inputsMap, sch, info)
Expand Down Expand Up @@ -289,7 +289,8 @@ func diffTest(t *testing.T, tfs map[string]*v2Schema.Schema, inputs,
sch, r, provider, info := s.setup(tfs)

tfState, err := makeTerraformStateWithOpts(ctx, r, "id", stateMap,
makeTerraformStateOptions{defaultZeroSchemaVersion: true})
makeTerraformStateOptions{
defaultZeroSchemaVersion: true, unknownCollectionsSupported: provider.SupportsUnknownCollections()})
assert.NoError(t, err)

config, _, err := MakeTerraformConfig(ctx, &Provider{tf: provider}, inputsMap, sch, info)
Expand Down Expand Up @@ -318,7 +319,8 @@ func diffTest(t *testing.T, tfs map[string]*v2Schema.Schema, inputs,
t.Run("withIgnoreAllExpected", func(t *testing.T) {
sch, r, provider, info := s.setup(tfs)
tfState, err := makeTerraformStateWithOpts(ctx, r, "id", stateMap,
makeTerraformStateOptions{defaultZeroSchemaVersion: true})
makeTerraformStateOptions{
defaultZeroSchemaVersion: true, unknownCollectionsSupported: provider.SupportsUnknownCollections()})
assert.NoError(t, err)

config, _, err := MakeTerraformConfig(ctx, &Provider{tf: provider}, inputsMap, sch, info)
Expand Down Expand Up @@ -1361,7 +1363,7 @@ func TestComputedListUpdate(t *testing.T) {
"prop": []interface{}{"foo"},
"outp": "bar",
},
map[string]DiffKind{
map[string]pulumirpc.PropertyDiff_Kind{
"prop": U,
},
pulumirpc.DiffResponse_DIFF_SOME)
Expand Down
134 changes: 134 additions & 0 deletions pkg/tfbridge/internal/schemaconvert/schemaconvert.go
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
}
Loading