diff --git a/pkg/pf/internal/schemashim/attr_schema.go b/pkg/pf/internal/schemashim/attr_schema.go index f9a9cf362..c5b834492 100644 --- a/pkg/pf/internal/schemashim/attr_schema.go +++ b/pkg/pf/internal/schemashim/attr_schema.go @@ -36,10 +36,6 @@ func newAttrSchema(key string, attr pfutils.Attr) *attrSchema { var _ shim.Schema = (*attrSchema)(nil) -var _ shim.SchemaWithWriteOnly = (*attrSchema)(nil) - -var _ shim.SchemaWithHasDefault = (*attrSchema)(nil) - func (s *attrSchema) Type() shim.ValueType { ty := s.attr.GetType() vt, err := convertType(ty) @@ -164,3 +160,11 @@ func (*attrSchema) SetElement(config interface{}) (interface{}, error) { func (*attrSchema) SetHash(v interface{}) int { panic("SetHash() should not be called during schema generation") } + +func (*attrSchema) SetElementHash(v interface{}) (int, error) { + panic("SetElementHash() should not be called during schema generation") +} + +func (*attrSchema) NewSet(v []interface{}) interface{} { + panic("NewSet() should not be called during schema generation") +} diff --git a/pkg/pf/internal/schemashim/block_schema.go b/pkg/pf/internal/schemashim/block_schema.go index 63c4f0bc8..f361236f5 100644 --- a/pkg/pf/internal/schemashim/block_schema.go +++ b/pkg/pf/internal/schemashim/block_schema.go @@ -136,6 +136,10 @@ func (*blockSchema) DefaultValue() (interface{}, error) { return nil, bridge.ErrSchemaDefaultValue } +func (s *blockSchema) HasDefault() bool { + return false +} + func (*blockSchema) ExactlyOneOf() []string { panic("ExactlyOneOf() should not be called during schema generation") } @@ -148,6 +152,18 @@ func (*blockSchema) SetHash(v interface{}) int { panic("SetHash() should not be called during schema generation") } +func (*blockSchema) SetElementHash(v interface{}) (int, error) { + panic("SetElementHash() should not be called during schema generation") +} + +func (*blockSchema) NewSet(v []interface{}) interface{} { + panic("NewSet() should not be called during schema generation") +} + func (*blockSchema) StateFunc() shim.SchemaStateFunc { panic("StateFunc() should not be called during schema generation") } + +func (*blockSchema) WriteOnly() bool { + return false +} diff --git a/pkg/pf/internal/schemashim/type_schema.go b/pkg/pf/internal/schemashim/type_schema.go index d4df23523..1780a1f32 100644 --- a/pkg/pf/internal/schemashim/type_schema.go +++ b/pkg/pf/internal/schemashim/type_schema.go @@ -94,6 +94,10 @@ func (*typeSchema) DefaultValue() (interface{}, error) { return nil, bridge.ErrSchemaDefaultValue } +func (*typeSchema) HasDefault() bool { + return false +} + func (*typeSchema) Description() string { return "" } @@ -120,3 +124,15 @@ func (*typeSchema) SetElement(config interface{}) (interface{}, error) { func (*typeSchema) SetHash(v interface{}) int { panic("SetHash() should not be called during schema generation") } + +func (*typeSchema) SetElementHash(v interface{}) (int, error) { + panic("SetElementHash() should not be called during schema generation") +} + +func (*typeSchema) NewSet(v []interface{}) interface{} { + panic("NewSet() should not be called during schema generation") +} + +func (*typeSchema) WriteOnly() bool { + return false +} diff --git a/pkg/pf/proto/attribute.go b/pkg/pf/proto/attribute.go index 88c5d0e93..e31b50ea6 100644 --- a/pkg/pf/proto/attribute.go +++ b/pkg/pf/proto/attribute.go @@ -22,10 +22,7 @@ import ( shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim" ) -var ( - _ = shim.Schema(attribute{}) - _ = shim.SchemaWithWriteOnly(attribute{}) -) +var _ = shim.Schema(attribute{}) type attribute struct { attr tfprotov6.SchemaAttribute @@ -101,13 +98,14 @@ func (a attribute) Elem() interface{} { func (a attribute) Default() interface{} { return nil } func (a attribute) DefaultFunc() shim.SchemaDefaultFunc { return nil } func (a attribute) DefaultValue() (interface{}, error) { return nil, nil } +func (a attribute) HasDefault() bool { return false } func (a attribute) StateFunc() shim.SchemaStateFunc { return nil } func (a attribute) ConflictsWith() []string { return nil } func (a attribute) ExactlyOneOf() []string { return nil } -func (a attribute) SetElement(config interface{}) (interface{}, error) { - panic("UNIMPLIMENTED") -} - -func (a attribute) SetHash(v interface{}) int { panic("UNIMPLIMENTED") } +// Set functions are unused for PF - could be needed if PF opts into detailed diffs +func (a attribute) SetElement(config interface{}) (interface{}, error) { panic("UNIMPLIMENTED") } +func (a attribute) SetHash(v interface{}) int { panic("UNIMPLIMENTED") } +func (a attribute) SetElementHash(v interface{}) (int, error) { panic("UNIMPLIMENTED") } +func (a attribute) NewSet(v []interface{}) interface{} { panic("UNIMPLIMENTED") } diff --git a/pkg/pf/proto/block.go b/pkg/pf/proto/block.go index 3a3378343..a917f6b87 100644 --- a/pkg/pf/proto/block.go +++ b/pkg/pf/proto/block.go @@ -134,6 +134,7 @@ func (m blockSchema) Required() bool { func (m blockSchema) Default() interface{} { return nil } func (m blockSchema) DefaultFunc() shim.SchemaDefaultFunc { return nil } func (m blockSchema) DefaultValue() (interface{}, error) { return nil, nil } +func (m blockSchema) HasDefault() bool { return false } func (m blockSchema) Description() string { return m.block.Block.Description } func (m blockSchema) Computed() bool { return false } func (m blockSchema) ForceNew() bool { return false } @@ -150,3 +151,12 @@ func (m blockSchema) SetElement(config interface{}) (interface{}, error) { panic("Cannot set a an element for a map type") } func (m blockSchema) SetHash(v interface{}) int { panic("Cannot set an hash for an object type") } +func (m blockSchema) SetElementHash(v interface{}) (int, error) { + panic("UNIMPLIMENTED") +} + +func (m blockSchema) NewSet(v []interface{}) interface{} { + panic("UNIMPLIMENTED") +} + +func (m blockSchema) WriteOnly() bool { return false } diff --git a/pkg/pf/proto/element.go b/pkg/pf/proto/element.go index 1bd302fa8..9e8d421f7 100644 --- a/pkg/pf/proto/element.go +++ b/pkg/pf/proto/element.go @@ -90,6 +90,7 @@ func (e element) Required() bool { return false } func (e element) Default() interface{} { return nil } func (e element) DefaultFunc() shim.SchemaDefaultFunc { return nil } func (e element) DefaultValue() (interface{}, error) { return nil, nil } +func (e element) HasDefault() bool { return false } func (e element) Description() string { return "" } func (e element) Computed() bool { return false } func (e element) ForceNew() bool { return false } @@ -103,6 +104,9 @@ func (e element) Removed() string { return "" } func (e element) Sensitive() bool { return false } func (e element) SetElement(interface{}) (interface{}, error) { return nil, nil } func (e element) SetHash(interface{}) int { return 0 } +func (e element) SetElementHash(interface{}) (int, error) { return 0, nil } +func (e element) NewSet([]interface{}) interface{} { return nil } +func (e element) WriteOnly() bool { return false } func (o elementObject) DeprecationMessage() string { return "" } func (o elementObject) Schema() shim.SchemaMap { diff --git a/pkg/tfbridge/detailed_diff.go b/pkg/tfbridge/detailed_diff.go index 0ba2bcf0b..3f573462b 100644 --- a/pkg/tfbridge/detailed_diff.go +++ b/pkg/tfbridge/detailed_diff.go @@ -363,9 +363,6 @@ func (differ detailedDiffer) calculateSetHashIndexMap( convertedElements = append(convertedElements, convertedElem) } - tfsh, ok := tfs.(shim.SchemaWithSetElementHash) - contract.Assertf(ok, "expected SchemaWithSetElementHash") - // Calculate the identity of each element. Note that the SetHash function can panic // in the case of custom SetHash functions which get unexpected inputs. for i, newElem := range convertedElements { @@ -377,7 +374,7 @@ func (differ detailedDiffer) calculateSetHashIndexMap( path.String(), r)) } }() - setHash, err := tfsh.SetElementHash(newElem) + setHash, err := tfs.SetElementHash(newElem) contract.AssertNoErrorf( err, "Failed to calculate preview for element in %s: Failed to convert set element", path.String()) return setHash diff --git a/pkg/tfbridge/diff.go b/pkg/tfbridge/diff.go index 0a7c22ce1..143cbf5b6 100644 --- a/pkg/tfbridge/diff.go +++ b/pkg/tfbridge/diff.go @@ -21,7 +21,6 @@ import ( "strings" "github.com/pulumi/pulumi/sdk/v3/go/common/resource" - "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" pulumirpc "github.com/pulumi/pulumi/sdk/v3/proto/go" shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim" @@ -109,9 +108,6 @@ func visitPropertyValue( } if !e.IsComputed() && !e.IsOutput() { - tfs, ok := tfs.(shim.SchemaWithSetElementHash) - contract.Assertf(ok, "expected SchemaWithSetElementHash") - // We cannot compute the hash for computed values because they are represented by the UnknownVariableValue // sentinel string, which may not be a legal value of the corresponding schema type, and SetHash does not // account for computed values. Skipping this for unknown values will result in computing a diff only on the diff --git a/pkg/tfbridge/schema.go b/pkg/tfbridge/schema.go index 7bcea1ce6..7d6049ab1 100644 --- a/pkg/tfbridge/schema.go +++ b/pkg/tfbridge/schema.go @@ -291,7 +291,6 @@ type conversionContext struct { // UseTFSetTypes will output TF Set types when converting sets. // For example, if called on []string{"val1", "val2"}, it will output a TF Set with // the same values: schema.NewSet([]interface{}{"val1", "val2"}). - // Note that this only works for schemas which implement shim.SchemaWithNewSet. UseTFSetTypes bool // DropUnknowns will drop unknown values from the input. DropUnknowns bool @@ -471,9 +470,8 @@ func (ctx *conversionContext) makeTerraformInput( } } - newSetSchema, ok := tfs.(shim.SchemaWithNewSet) - if ok && tfs.Type() == shim.TypeSet && ctx.UseTFSetTypes { - return newSetSchema.NewSet(arr), nil + if tfs.Type() == shim.TypeSet && ctx.UseTFSetTypes { + return tfs.NewSet(arr), nil } return arr, nil diff --git a/pkg/tfgen/generate.go b/pkg/tfgen/generate.go index e2ba03223..164199a18 100644 --- a/pkg/tfgen/generate.go +++ b/pkg/tfgen/generate.go @@ -1876,18 +1876,16 @@ func (g *Generator) propertyVariable(parentPath paths.TypePath, key string, } // Suppress write-only attributes via SchemaInfo.Omit // TODO[pulumi/pulumi-terraform-bridge#2938] remove when the bridge fully supports write-only fields. - schemaWithWriteOnly, ok := shimSchema.(shim.SchemaWithWriteOnly) - if ok { - if schemaWithWriteOnly.WriteOnly() { - if info == nil { - info = make(map[string]*tfbridge.SchemaInfo) - } - if val, ok := info[key]; ok { - val.Omit = true - } else { - info[key] = &tfbridge.SchemaInfo{ - Omit: true, - } + + if shimSchema.WriteOnly() { + if info == nil { + info = make(map[string]*tfbridge.SchemaInfo) + } + if val, ok := info[key]; ok { + val.Omit = true + } else { + info[key] = &tfbridge.SchemaInfo{ + Omit: true, } } } diff --git a/pkg/tfgen/generate_schema.go b/pkg/tfgen/generate_schema.go index 6a956c72f..3070c5706 100644 --- a/pkg/tfgen/generate_schema.go +++ b/pkg/tfgen/generate_schema.go @@ -44,7 +44,6 @@ import ( "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfbridge" "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfgen/internal/paths" - shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim" "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/x/muxer" "github.com/pulumi/pulumi-terraform-bridge/v3/unstable/metadata" ) @@ -867,8 +866,8 @@ func (g *schemaGenerator) genResourceType(mod tokens.Module, res *resourceType) spec.InputProperties[prop.name] = g.genProperty(prop) hasDefault := false - if s, ok := prop.schema.(shim.SchemaWithHasDefault); ok && !g.info.DisableRequiredWithDefaultTurningOptional { - hasDefault = s.HasDefault() + if !g.info.DisableRequiredWithDefaultTurningOptional { + hasDefault = prop.schema.HasDefault() } if !prop.optional() && !hasDefault { diff --git a/pkg/tfshim/schema/schema.go b/pkg/tfshim/schema/schema.go index e41bdb08c..e2d05eeeb 100644 --- a/pkg/tfshim/schema/schema.go +++ b/pkg/tfshim/schema/schema.go @@ -1,6 +1,8 @@ package schema import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/internal/internalinter" shim "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfshim" ) @@ -74,6 +76,10 @@ func (s SchemaShim) DefaultValue() (interface{}, error) { return nil, nil } +func (s SchemaShim) HasDefault() bool { + return s.V.Default != nil || s.V.DefaultFunc != nil +} + func (s SchemaShim) Description() string { return s.V.Description } @@ -134,6 +140,18 @@ func (s SchemaShim) SetHash(v interface{}) int { return 0 } +func (s SchemaShim) NewSet(v []interface{}) interface{} { + return schema.NewSet(s.SetHash, v) +} + +func (s SchemaShim) SetElementHash(v interface{}) (int, error) { + v, err := s.SetElement(v) + if err != nil { + return 0, err + } + return s.SetHash(v), nil +} + //nolint:revive type SchemaMap map[string]shim.Schema diff --git a/pkg/tfshim/sdk-v1/schema.go b/pkg/tfshim/sdk-v1/schema.go index eb657ae14..4bce45030 100644 --- a/pkg/tfshim/sdk-v1/schema.go +++ b/pkg/tfshim/sdk-v1/schema.go @@ -10,8 +10,6 @@ import ( var ( _ = shim.Schema(v1Schema{}) - _ = shim.SchemaWithNewSet(v1Schema{}) - _ = shim.SchemaWithSetElementHash(v1Schema{}) _ = shim.SchemaMap(v1SchemaMap{}) ) @@ -71,6 +69,10 @@ func (s v1Schema) DefaultValue() (interface{}, error) { return s.tf.DefaultValue() } +func (s v1Schema) HasDefault() bool { + return s.tf.Default != nil || s.tf.DefaultFunc != nil +} + func (s v1Schema) Description() string { return s.tf.Description } @@ -159,6 +161,10 @@ func (s v1Schema) NewSet(v []interface{}) interface{} { return schema.NewSet(s.SetHash, v) } +func (s v1Schema) WriteOnly() bool { + return false +} + type v1SchemaMap map[string]*schema.Schema func NewSchemaMap(m map[string]*schema.Schema) shim.SchemaMap { diff --git a/pkg/tfshim/sdk-v2/schema.go b/pkg/tfshim/sdk-v2/schema.go index f37f64b67..9dc0755d2 100644 --- a/pkg/tfshim/sdk-v2/schema.go +++ b/pkg/tfshim/sdk-v2/schema.go @@ -9,12 +9,8 @@ import ( var ( _ = shim.Schema(v2Schema{}) - _ = shim.SchemaWithNewSet(v2Schema{}) _ = shim.SchemaWithUnknownCollectionSupported(v2Schema{}) _ = shim.SchemaMap(v2SchemaMap{}) - _ = shim.SchemaWithWriteOnly(v2Schema{}) - _ = shim.SchemaWithSetElementHash(v2Schema{}) - _ = shim.SchemaWithHasDefault(v2Schema{}) ) // UnknownVariableValue is the sentinal defined in github.com/hashicorp/terraform/configs/hcl2shim, diff --git a/pkg/tfshim/shim.go b/pkg/tfshim/shim.go index 7fadb0518..3bba20a91 100644 --- a/pkg/tfshim/shim.go +++ b/pkg/tfshim/shim.go @@ -209,34 +209,19 @@ type Schema interface { SetElement(config interface{}) (interface{}, error) // Deprecated: use [SchemaWithSetElementHash] and [SetElementHash] instead. SetHash(v interface{}) int - // This is a no-op internal interface to prevent external users from implementing the interface. - internalinter.InternalInterface -} - -type SchemaWithWriteOnly interface { - Schema - WriteOnly() bool -} - -type SchemaWithNewSet interface { - Schema NewSet(v []interface{}) interface{} -} -type SchemaWithUnknownCollectionSupported interface { - Schema - SupportsUnknownCollections() -} - -type SchemaWithSetElementHash interface { - Schema // SetElementHash returns a hash of the given set element. // Note that it expects a set element without any unknown values. SetElementHash(v interface{}) (int, error) + WriteOnly() bool + HasDefault() bool + // This is a no-op internal interface to prevent external users from implementing the interface. + internalinter.InternalInterface } -type SchemaWithHasDefault interface { +type SchemaWithUnknownCollectionSupported interface { Schema - HasDefault() bool + SupportsUnknownCollections() } type SchemaMap interface {