From 28f4719e711c568f2e6216f37a0afc7d576f4a98 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 24 Feb 2025 09:42:02 -0500 Subject: [PATCH 01/14] new attribute additions (breaks build for existing internal schema attributes) --- go.mod | 10 ++++----- go.sum | 40 +++++++++++++++++----------------- internal/fwschema/attribute.go | 18 +++++++++++++++ 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/go.mod b/go.mod index 207c0347..a6671ad8 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.22.7 require ( github.com/google/go-cmp v0.6.0 - github.com/hashicorp/terraform-plugin-go v0.26.0 + github.com/hashicorp/terraform-plugin-go v0.26.1-0.20250219133416-0561ec7f0caf github.com/hashicorp/terraform-plugin-log v0.9.0 ) @@ -14,7 +14,7 @@ require ( github.com/fatih/color v1.13.0 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect - github.com/hashicorp/go-plugin v1.6.2 // indirect + github.com/hashicorp/go-plugin v1.6.3 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/terraform-registry-address v0.2.4 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect @@ -28,7 +28,7 @@ require ( golang.org/x/net v0.34.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect - google.golang.org/grpc v1.69.4 // indirect - google.golang.org/protobuf v1.36.3 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect + google.golang.org/grpc v1.70.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect ) diff --git a/go.sum b/go.sum index 5a586522..e4488905 100644 --- a/go.sum +++ b/go.sum @@ -17,12 +17,12 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog= -github.com/hashicorp/go-plugin v1.6.2/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= +github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg= +github.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/terraform-plugin-go v0.26.0 h1:cuIzCv4qwigug3OS7iKhpGAbZTiypAfFQmw8aE65O2M= -github.com/hashicorp/terraform-plugin-go v0.26.0/go.mod h1:+CXjuLDiFgqR+GcrM5a2E2Kal5t5q2jb0E3D57tTdNY= +github.com/hashicorp/terraform-plugin-go v0.26.1-0.20250219133416-0561ec7f0caf h1:qsHBfGoRp15P8vc95eAVMVO6erkMfpLKZ/6A5lLcR1w= +github.com/hashicorp/terraform-plugin-go v0.26.1-0.20250219133416-0561ec7f0caf/go.mod h1:dUu1RU16sOSKn6w4g+xaAnV0S0wHsVBEY/XH8jv1kx4= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= github.com/hashicorp/terraform-registry-address v0.2.4 h1:JXu/zHB2Ymg/TGVCRu10XqNa4Sh2bWcqCNyKWjnCPJA= @@ -54,16 +54,16 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= -go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= -go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= -go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= -go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= -go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= -go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= -go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= -go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= -go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= +go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= +go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= +go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= +go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= +go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= +go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= +go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= +go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= +go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -76,12 +76,12 @@ golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= -google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= -google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= -google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1:hgh8P4EuoxpsuKMXX/To36nOFD7vixReXgn8lPGnt+o= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/internal/fwschema/attribute.go b/internal/fwschema/attribute.go index 6c440b31..b9fe3112 100644 --- a/internal/fwschema/attribute.go +++ b/internal/fwschema/attribute.go @@ -71,6 +71,16 @@ type Attribute interface { // // Write-only attributes are a managed-resource schema concept only. IsWriteOnly() bool + + // IsOptionalForImport should return true if the identity attribute is optional to be set by + // the practitioner when importing by identity. This is named differently than OptionalForImport + // to prevent a conflict with the relevant field name. + IsOptionalForImport() bool + + // IsRequiredForImport should return true if the identity attribute must be set by + // the practitioner when importing by identity. This is named differently than RequiredForImport + // to prevent a conflict with the relevant field name. + IsRequiredForImport() bool } // AttributesEqual is a helper function to perform equality testing on two @@ -113,5 +123,13 @@ func AttributesEqual(a, b Attribute) bool { return false } + if a.IsOptionalForImport() != b.IsOptionalForImport() { + return false + } + + if a.IsRequiredForImport() != b.IsRequiredForImport() { + return false + } + return true } From c4ad0c5bb9729f62d5a27dc2f6fd2f97b2069fe6 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 24 Feb 2025 09:42:29 -0500 Subject: [PATCH 02/14] update internal testing/testschema --- .../testing/testschema/attributewithbooldefault.go | 12 ++++++++++++ .../testschema/attributewithboolplanmodifiers.go | 12 ++++++++++++ .../testschema/attributewithboolvalidators.go | 12 ++++++++++++ .../testschema/attributewithdynamicdefault.go | 12 ++++++++++++ .../testschema/attributewithdynamicplanmodifiers.go | 12 ++++++++++++ .../testschema/attributewithdynamicvalidators.go | 12 ++++++++++++ .../testschema/attributewithfloat32default.go | 12 ++++++++++++ .../testschema/attributewithfloat32planmodifiers.go | 12 ++++++++++++ .../testschema/attributewithfloat32validators.go | 12 ++++++++++++ .../testschema/attributewithfloat64default.go | 12 ++++++++++++ .../testschema/attributewithfloat64planmodifiers.go | 12 ++++++++++++ .../testschema/attributewithfloat64validators.go | 12 ++++++++++++ .../testing/testschema/attributewithint32default.go | 12 ++++++++++++ .../testschema/attributewithint32planmodifiers.go | 12 ++++++++++++ .../testschema/attributewithint32validators.go | 12 ++++++++++++ .../testing/testschema/attributewithint64default.go | 12 ++++++++++++ .../testschema/attributewithint64planmodifiers.go | 12 ++++++++++++ .../testschema/attributewithint64validators.go | 12 ++++++++++++ .../testing/testschema/attributewithlistdefault.go | 12 ++++++++++++ .../testschema/attributewithlistplanmodifiers.go | 12 ++++++++++++ .../testschema/attributewithlistvalidators.go | 12 ++++++++++++ .../testing/testschema/attributewithmapdefault.go | 12 ++++++++++++ .../testschema/attributewithmapplanmodifiers.go | 12 ++++++++++++ .../testing/testschema/attributewithmapvalidators.go | 12 ++++++++++++ .../testing/testschema/attributewithnumberdefault.go | 12 ++++++++++++ .../testschema/attributewithnumberplanmodifiers.go | 12 ++++++++++++ .../testschema/attributewithnumbervalidators.go | 12 ++++++++++++ .../testing/testschema/attributewithobjectdefault.go | 12 ++++++++++++ .../testschema/attributewithobjectplanmodifiers.go | 12 ++++++++++++ .../testschema/attributewithobjectvalidators.go | 12 ++++++++++++ .../testing/testschema/attributewithsetdefault.go | 12 ++++++++++++ .../testschema/attributewithsetplanmodifiers.go | 12 ++++++++++++ .../testing/testschema/attributewithsetvalidators.go | 12 ++++++++++++ .../testing/testschema/attributewithstringdefault.go | 12 ++++++++++++ .../testschema/attributewithstringplanmodifiers.go | 12 ++++++++++++ .../testschema/attributewithstringvalidators.go | 12 ++++++++++++ internal/testing/testschema/nested_attribute.go | 12 ++++++++++++ .../testschema/nested_attribute_with_list_default.go | 12 ++++++++++++ .../nested_attribute_with_list_plan_modifiers.go | 12 ++++++++++++ .../testschema/nested_attribute_with_map_default.go | 12 ++++++++++++ .../nested_attribute_with_map_plan_modifiers.go | 12 ++++++++++++ .../nested_attribute_with_object_default.go | 12 ++++++++++++ .../nested_attribute_with_object_plan_modifiers.go | 12 ++++++++++++ .../testschema/nested_attribute_with_set_default.go | 12 ++++++++++++ .../nested_attribute_with_set_plan_modifiers.go | 12 ++++++++++++ 45 files changed, 540 insertions(+) diff --git a/internal/testing/testschema/attributewithbooldefault.go b/internal/testing/testschema/attributewithbooldefault.go index 66edc07e..e1ca0627 100644 --- a/internal/testing/testschema/attributewithbooldefault.go +++ b/internal/testing/testschema/attributewithbooldefault.go @@ -23,6 +23,8 @@ type AttributeWithBoolDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Bool } @@ -91,3 +93,13 @@ func (a AttributeWithBoolDefaultValue) IsSensitive() bool { func (a AttributeWithBoolDefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithBoolDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithBoolDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithboolplanmodifiers.go b/internal/testing/testschema/attributewithboolplanmodifiers.go index 397f1818..812697fb 100644 --- a/internal/testing/testschema/attributewithboolplanmodifiers.go +++ b/internal/testing/testschema/attributewithboolplanmodifiers.go @@ -24,6 +24,8 @@ type AttributeWithBoolPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Bool } @@ -92,3 +94,13 @@ func (a AttributeWithBoolPlanModifiers) IsSensitive() bool { func (a AttributeWithBoolPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithBoolPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithBoolPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithboolvalidators.go b/internal/testing/testschema/attributewithboolvalidators.go index 044c25cf..5da14352 100644 --- a/internal/testing/testschema/attributewithboolvalidators.go +++ b/internal/testing/testschema/attributewithboolvalidators.go @@ -24,6 +24,8 @@ type AttributeWithBoolValidators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Bool } @@ -92,3 +94,13 @@ func (a AttributeWithBoolValidators) IsSensitive() bool { func (a AttributeWithBoolValidators) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithBoolValidators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithBoolValidators) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithdynamicdefault.go b/internal/testing/testschema/attributewithdynamicdefault.go index b562132a..ae3690aa 100644 --- a/internal/testing/testschema/attributewithdynamicdefault.go +++ b/internal/testing/testschema/attributewithdynamicdefault.go @@ -23,6 +23,8 @@ type AttributeWithDynamicDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Dynamic } @@ -91,3 +93,13 @@ func (a AttributeWithDynamicDefaultValue) IsSensitive() bool { func (a AttributeWithDynamicDefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithDynamicDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithDynamicDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithdynamicplanmodifiers.go b/internal/testing/testschema/attributewithdynamicplanmodifiers.go index 74a80587..f510ba12 100644 --- a/internal/testing/testschema/attributewithdynamicplanmodifiers.go +++ b/internal/testing/testschema/attributewithdynamicplanmodifiers.go @@ -23,6 +23,8 @@ type AttributeWithDynamicPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Dynamic } @@ -91,3 +93,13 @@ func (a AttributeWithDynamicPlanModifiers) DynamicPlanModifiers() []planmodifier func (a AttributeWithDynamicPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithDynamicPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithDynamicPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithdynamicvalidators.go b/internal/testing/testschema/attributewithdynamicvalidators.go index e4ef1024..cca5e5fc 100644 --- a/internal/testing/testschema/attributewithdynamicvalidators.go +++ b/internal/testing/testschema/attributewithdynamicvalidators.go @@ -24,6 +24,8 @@ type AttributeWithDynamicValidators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Dynamic } @@ -92,3 +94,13 @@ func (a AttributeWithDynamicValidators) DynamicValidators() []validator.Dynamic func (a AttributeWithDynamicValidators) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithDynamicValidators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithDynamicValidators) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithfloat32default.go b/internal/testing/testschema/attributewithfloat32default.go index c3aeb627..6798180f 100644 --- a/internal/testing/testschema/attributewithfloat32default.go +++ b/internal/testing/testschema/attributewithfloat32default.go @@ -23,6 +23,8 @@ type AttributeWithFloat32DefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Float32 } @@ -91,3 +93,13 @@ func (a AttributeWithFloat32DefaultValue) IsSensitive() bool { func (a AttributeWithFloat32DefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat32DefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat32DefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithfloat32planmodifiers.go b/internal/testing/testschema/attributewithfloat32planmodifiers.go index f93d8722..d01c9ca8 100644 --- a/internal/testing/testschema/attributewithfloat32planmodifiers.go +++ b/internal/testing/testschema/attributewithfloat32planmodifiers.go @@ -24,6 +24,8 @@ type AttributeWithFloat32PlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Float32 } @@ -92,3 +94,13 @@ func (a AttributeWithFloat32PlanModifiers) IsSensitive() bool { func (a AttributeWithFloat32PlanModifiers) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat32PlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat32PlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithfloat32validators.go b/internal/testing/testschema/attributewithfloat32validators.go index 7fb02a5a..fbf46068 100644 --- a/internal/testing/testschema/attributewithfloat32validators.go +++ b/internal/testing/testschema/attributewithfloat32validators.go @@ -24,6 +24,8 @@ type AttributeWithFloat32Validators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Float32 } @@ -92,3 +94,13 @@ func (a AttributeWithFloat32Validators) IsSensitive() bool { func (a AttributeWithFloat32Validators) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat32Validators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat32Validators) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithfloat64default.go b/internal/testing/testschema/attributewithfloat64default.go index 484ec37d..9a9cca0a 100644 --- a/internal/testing/testschema/attributewithfloat64default.go +++ b/internal/testing/testschema/attributewithfloat64default.go @@ -23,6 +23,8 @@ type AttributeWithFloat64DefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Float64 } @@ -91,3 +93,13 @@ func (a AttributeWithFloat64DefaultValue) IsSensitive() bool { func (a AttributeWithFloat64DefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat64DefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat64DefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithfloat64planmodifiers.go b/internal/testing/testschema/attributewithfloat64planmodifiers.go index ba04291d..fe9a0077 100644 --- a/internal/testing/testschema/attributewithfloat64planmodifiers.go +++ b/internal/testing/testschema/attributewithfloat64planmodifiers.go @@ -23,6 +23,8 @@ type AttributeWithFloat64PlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Float64 } @@ -91,3 +93,13 @@ func (a AttributeWithFloat64PlanModifiers) IsSensitive() bool { func (a AttributeWithFloat64PlanModifiers) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat64PlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat64PlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithfloat64validators.go b/internal/testing/testschema/attributewithfloat64validators.go index 02ef1770..309dbd1b 100644 --- a/internal/testing/testschema/attributewithfloat64validators.go +++ b/internal/testing/testschema/attributewithfloat64validators.go @@ -23,6 +23,8 @@ type AttributeWithFloat64Validators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Float64 } @@ -91,3 +93,13 @@ func (a AttributeWithFloat64Validators) IsSensitive() bool { func (a AttributeWithFloat64Validators) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat64Validators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithFloat64Validators) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithint32default.go b/internal/testing/testschema/attributewithint32default.go index f332bae4..e9d6a8e9 100644 --- a/internal/testing/testschema/attributewithint32default.go +++ b/internal/testing/testschema/attributewithint32default.go @@ -23,6 +23,8 @@ type AttributeWithInt32DefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Int32 } @@ -91,3 +93,13 @@ func (a AttributeWithInt32DefaultValue) IsSensitive() bool { func (a AttributeWithInt32DefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt32DefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt32DefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithint32planmodifiers.go b/internal/testing/testschema/attributewithint32planmodifiers.go index 7f131df5..4cef7d2c 100644 --- a/internal/testing/testschema/attributewithint32planmodifiers.go +++ b/internal/testing/testschema/attributewithint32planmodifiers.go @@ -24,6 +24,8 @@ type AttributeWithInt32PlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Int32 } @@ -92,3 +94,13 @@ func (a AttributeWithInt32PlanModifiers) IsSensitive() bool { func (a AttributeWithInt32PlanModifiers) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt32PlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt32PlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithint32validators.go b/internal/testing/testschema/attributewithint32validators.go index 8a4546e9..62366de9 100644 --- a/internal/testing/testschema/attributewithint32validators.go +++ b/internal/testing/testschema/attributewithint32validators.go @@ -24,6 +24,8 @@ type AttributeWithInt32Validators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Int32 } @@ -92,3 +94,13 @@ func (a AttributeWithInt32Validators) IsSensitive() bool { func (a AttributeWithInt32Validators) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt32Validators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt32Validators) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithint64default.go b/internal/testing/testschema/attributewithint64default.go index 574a88a5..bb3f12f0 100644 --- a/internal/testing/testschema/attributewithint64default.go +++ b/internal/testing/testschema/attributewithint64default.go @@ -23,6 +23,8 @@ type AttributeWithInt64DefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Int64 } @@ -91,3 +93,13 @@ func (a AttributeWithInt64DefaultValue) IsSensitive() bool { func (a AttributeWithInt64DefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt64DefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt64DefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithint64planmodifiers.go b/internal/testing/testschema/attributewithint64planmodifiers.go index e21a4325..ef315b3a 100644 --- a/internal/testing/testschema/attributewithint64planmodifiers.go +++ b/internal/testing/testschema/attributewithint64planmodifiers.go @@ -23,6 +23,8 @@ type AttributeWithInt64PlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Int64 } @@ -91,3 +93,13 @@ func (a AttributeWithInt64PlanModifiers) IsSensitive() bool { func (a AttributeWithInt64PlanModifiers) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt64PlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt64PlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithint64validators.go b/internal/testing/testschema/attributewithint64validators.go index c4e23e16..5ccb40aa 100644 --- a/internal/testing/testschema/attributewithint64validators.go +++ b/internal/testing/testschema/attributewithint64validators.go @@ -23,6 +23,8 @@ type AttributeWithInt64Validators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Int64 } @@ -91,3 +93,13 @@ func (a AttributeWithInt64Validators) IsSensitive() bool { func (a AttributeWithInt64Validators) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt64Validators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithInt64Validators) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithlistdefault.go b/internal/testing/testschema/attributewithlistdefault.go index ff23c521..3676ca7b 100644 --- a/internal/testing/testschema/attributewithlistdefault.go +++ b/internal/testing/testschema/attributewithlistdefault.go @@ -24,6 +24,8 @@ type AttributeWithListDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.List } @@ -94,3 +96,13 @@ func (a AttributeWithListDefaultValue) IsSensitive() bool { func (a AttributeWithListDefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithListDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithListDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithlistplanmodifiers.go b/internal/testing/testschema/attributewithlistplanmodifiers.go index fbb50c33..eafa1093 100644 --- a/internal/testing/testschema/attributewithlistplanmodifiers.go +++ b/internal/testing/testschema/attributewithlistplanmodifiers.go @@ -24,6 +24,8 @@ type AttributeWithListPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.List } @@ -94,3 +96,13 @@ func (a AttributeWithListPlanModifiers) IsWriteOnly() bool { func (a AttributeWithListPlanModifiers) ListPlanModifiers() []planmodifier.List { return a.PlanModifiers } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithListPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithListPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithlistvalidators.go b/internal/testing/testschema/attributewithlistvalidators.go index fefa2eb0..36182c4a 100644 --- a/internal/testing/testschema/attributewithlistvalidators.go +++ b/internal/testing/testschema/attributewithlistvalidators.go @@ -24,6 +24,8 @@ type AttributeWithListValidators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.List } @@ -94,3 +96,13 @@ func (a AttributeWithListValidators) IsWriteOnly() bool { func (a AttributeWithListValidators) ListValidators() []validator.List { return a.Validators } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithListValidators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithListValidators) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithmapdefault.go b/internal/testing/testschema/attributewithmapdefault.go index 2b223cd1..0ca52972 100644 --- a/internal/testing/testschema/attributewithmapdefault.go +++ b/internal/testing/testschema/attributewithmapdefault.go @@ -24,6 +24,8 @@ type AttributeWithMapDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Map } @@ -94,3 +96,13 @@ func (a AttributeWithMapDefaultValue) IsSensitive() bool { func (a AttributeWithMapDefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithMapDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithMapDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithmapplanmodifiers.go b/internal/testing/testschema/attributewithmapplanmodifiers.go index 06c7b2fe..b57d597c 100644 --- a/internal/testing/testschema/attributewithmapplanmodifiers.go +++ b/internal/testing/testschema/attributewithmapplanmodifiers.go @@ -24,6 +24,8 @@ type AttributeWithMapPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Map } @@ -94,3 +96,13 @@ func (a AttributeWithMapPlanModifiers) IsWriteOnly() bool { func (a AttributeWithMapPlanModifiers) MapPlanModifiers() []planmodifier.Map { return a.PlanModifiers } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithMapPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithMapPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithmapvalidators.go b/internal/testing/testschema/attributewithmapvalidators.go index 5e3a9dac..8b2ec6b1 100644 --- a/internal/testing/testschema/attributewithmapvalidators.go +++ b/internal/testing/testschema/attributewithmapvalidators.go @@ -24,6 +24,8 @@ type AttributeWithMapValidators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Map } @@ -90,6 +92,16 @@ func (a AttributeWithMapValidators) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithMapValidators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithMapValidators) IsOptionalForImport() bool { + return a.OptionalForImport +} + // MapValidators satisfies the fwxschema.AttributeWithMapValidators interface. func (a AttributeWithMapValidators) MapValidators() []validator.Map { return a.Validators diff --git a/internal/testing/testschema/attributewithnumberdefault.go b/internal/testing/testschema/attributewithnumberdefault.go index effa7950..bdb16149 100644 --- a/internal/testing/testschema/attributewithnumberdefault.go +++ b/internal/testing/testschema/attributewithnumberdefault.go @@ -23,6 +23,8 @@ type AttributeWithNumberDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Number } @@ -91,3 +93,13 @@ func (a AttributeWithNumberDefaultValue) IsSensitive() bool { func (a AttributeWithNumberDefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithNumberDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithNumberDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithnumberplanmodifiers.go b/internal/testing/testschema/attributewithnumberplanmodifiers.go index cf929977..db6bf3d4 100644 --- a/internal/testing/testschema/attributewithnumberplanmodifiers.go +++ b/internal/testing/testschema/attributewithnumberplanmodifiers.go @@ -23,6 +23,8 @@ type AttributeWithNumberPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Number } @@ -87,6 +89,16 @@ func (a AttributeWithNumberPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithNumberPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithNumberPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} + // NumberPlanModifiers satisfies the fwxschema.AttributeWithNumberPlanModifiers interface. func (a AttributeWithNumberPlanModifiers) NumberPlanModifiers() []planmodifier.Number { return a.PlanModifiers diff --git a/internal/testing/testschema/attributewithnumbervalidators.go b/internal/testing/testschema/attributewithnumbervalidators.go index af1869d3..d5ba9bc7 100644 --- a/internal/testing/testschema/attributewithnumbervalidators.go +++ b/internal/testing/testschema/attributewithnumbervalidators.go @@ -23,6 +23,8 @@ type AttributeWithNumberValidators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Number } @@ -87,6 +89,16 @@ func (a AttributeWithNumberValidators) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithNumberValidators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithNumberValidators) IsOptionalForImport() bool { + return a.OptionalForImport +} + // NumberValidators satisfies the fwxschema.AttributeWithNumberValidators interface. func (a AttributeWithNumberValidators) NumberValidators() []validator.Number { return a.Validators diff --git a/internal/testing/testschema/attributewithobjectdefault.go b/internal/testing/testschema/attributewithobjectdefault.go index ed25e0a9..c8ae9e04 100644 --- a/internal/testing/testschema/attributewithobjectdefault.go +++ b/internal/testing/testschema/attributewithobjectdefault.go @@ -24,6 +24,8 @@ type AttributeWithObjectDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Object } @@ -94,3 +96,13 @@ func (a AttributeWithObjectDefaultValue) IsSensitive() bool { func (a AttributeWithObjectDefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithObjectDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithObjectDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithobjectplanmodifiers.go b/internal/testing/testschema/attributewithobjectplanmodifiers.go index e4ec023b..625746b4 100644 --- a/internal/testing/testschema/attributewithobjectplanmodifiers.go +++ b/internal/testing/testschema/attributewithobjectplanmodifiers.go @@ -24,6 +24,8 @@ type AttributeWithObjectPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Object } @@ -90,6 +92,16 @@ func (a AttributeWithObjectPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithObjectPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithObjectPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} + // ObjectPlanModifiers satisfies the fwxschema.AttributeWithObjectPlanModifiers interface. func (a AttributeWithObjectPlanModifiers) ObjectPlanModifiers() []planmodifier.Object { return a.PlanModifiers diff --git a/internal/testing/testschema/attributewithobjectvalidators.go b/internal/testing/testschema/attributewithobjectvalidators.go index 534c47cf..03bab115 100644 --- a/internal/testing/testschema/attributewithobjectvalidators.go +++ b/internal/testing/testschema/attributewithobjectvalidators.go @@ -24,6 +24,8 @@ type AttributeWithObjectValidators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Object } @@ -90,6 +92,16 @@ func (a AttributeWithObjectValidators) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithObjectValidators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithObjectValidators) IsOptionalForImport() bool { + return a.OptionalForImport +} + // ObjectValidators satisfies the fwxschema.AttributeWithObjectValidators interface. func (a AttributeWithObjectValidators) ObjectValidators() []validator.Object { return a.Validators diff --git a/internal/testing/testschema/attributewithsetdefault.go b/internal/testing/testschema/attributewithsetdefault.go index f770f956..d5d557ce 100644 --- a/internal/testing/testschema/attributewithsetdefault.go +++ b/internal/testing/testschema/attributewithsetdefault.go @@ -24,6 +24,8 @@ type AttributeWithSetDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.Set } @@ -94,3 +96,13 @@ func (a AttributeWithSetDefaultValue) IsSensitive() bool { func (a AttributeWithSetDefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithSetDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithSetDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithsetplanmodifiers.go b/internal/testing/testschema/attributewithsetplanmodifiers.go index a36f5adc..68570912 100644 --- a/internal/testing/testschema/attributewithsetplanmodifiers.go +++ b/internal/testing/testschema/attributewithsetplanmodifiers.go @@ -25,6 +25,8 @@ type AttributeWithSetPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.Set } @@ -91,6 +93,16 @@ func (a AttributeWithSetPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithSetPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithSetPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} + // SetPlanModifiers satisfies the fwxschema.AttributeWithSetPlanModifiers interface. func (a AttributeWithSetPlanModifiers) SetPlanModifiers() []planmodifier.Set { return a.PlanModifiers diff --git a/internal/testing/testschema/attributewithsetvalidators.go b/internal/testing/testschema/attributewithsetvalidators.go index 32bc5256..ed18808c 100644 --- a/internal/testing/testschema/attributewithsetvalidators.go +++ b/internal/testing/testschema/attributewithsetvalidators.go @@ -24,6 +24,8 @@ type AttributeWithSetValidators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.Set } @@ -90,6 +92,16 @@ func (a AttributeWithSetValidators) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithSetValidators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithSetValidators) IsOptionalForImport() bool { + return a.OptionalForImport +} + // SetValidators satisfies the fwxschema.AttributeWithSetValidators interface. func (a AttributeWithSetValidators) SetValidators() []validator.Set { return a.Validators diff --git a/internal/testing/testschema/attributewithstringdefault.go b/internal/testing/testschema/attributewithstringdefault.go index 01e1e6f4..28131c39 100644 --- a/internal/testing/testschema/attributewithstringdefault.go +++ b/internal/testing/testschema/attributewithstringdefault.go @@ -23,6 +23,8 @@ type AttributeWithStringDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Default defaults.String } @@ -91,3 +93,13 @@ func (a AttributeWithStringDefaultValue) IsSensitive() bool { func (a AttributeWithStringDefaultValue) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithStringDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithStringDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/attributewithstringplanmodifiers.go b/internal/testing/testschema/attributewithstringplanmodifiers.go index d1b5af8d..f88a93cf 100644 --- a/internal/testing/testschema/attributewithstringplanmodifiers.go +++ b/internal/testing/testschema/attributewithstringplanmodifiers.go @@ -23,6 +23,8 @@ type AttributeWithStringPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool PlanModifiers []planmodifier.String } @@ -87,6 +89,16 @@ func (a AttributeWithStringPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithStringPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithStringPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} + // StringPlanModifiers satisfies the fwxschema.AttributeWithStringPlanModifiers interface. func (a AttributeWithStringPlanModifiers) StringPlanModifiers() []planmodifier.String { return a.PlanModifiers diff --git a/internal/testing/testschema/attributewithstringvalidators.go b/internal/testing/testschema/attributewithstringvalidators.go index e1ddf7e5..21efefe3 100644 --- a/internal/testing/testschema/attributewithstringvalidators.go +++ b/internal/testing/testschema/attributewithstringvalidators.go @@ -23,6 +23,8 @@ type AttributeWithStringValidators struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Validators []validator.String } @@ -87,6 +89,16 @@ func (a AttributeWithStringValidators) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithStringValidators) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a AttributeWithStringValidators) IsOptionalForImport() bool { + return a.OptionalForImport +} + // StringValidators satisfies the fwxschema.AttributeWithStringValidators interface. func (a AttributeWithStringValidators) StringValidators() []validator.String { return a.Validators diff --git a/internal/testing/testschema/nested_attribute.go b/internal/testing/testschema/nested_attribute.go index f3730135..2a638bcb 100644 --- a/internal/testing/testschema/nested_attribute.go +++ b/internal/testing/testschema/nested_attribute.go @@ -28,6 +28,8 @@ type NestedAttribute struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -163,3 +165,13 @@ func (a NestedAttribute) IsSensitive() bool { func (a NestedAttribute) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a NestedAttribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a NestedAttribute) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/internal/testing/testschema/nested_attribute_with_list_default.go b/internal/testing/testschema/nested_attribute_with_list_default.go index a1b70cd8..2621e9d3 100644 --- a/internal/testing/testschema/nested_attribute_with_list_default.go +++ b/internal/testing/testschema/nested_attribute_with_list_default.go @@ -28,6 +28,8 @@ type NestedAttributeWithListDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -108,6 +110,16 @@ func (a NestedAttributeWithListDefaultValue) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithListDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithListDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} + // ListDefaultValue satisfies the fwschema.AttributeWithListDefaultValue interface. func (a NestedAttributeWithListDefaultValue) ListDefaultValue() defaults.List { return a.Default diff --git a/internal/testing/testschema/nested_attribute_with_list_plan_modifiers.go b/internal/testing/testschema/nested_attribute_with_list_plan_modifiers.go index 2904c21e..e754a7a6 100644 --- a/internal/testing/testschema/nested_attribute_with_list_plan_modifiers.go +++ b/internal/testing/testschema/nested_attribute_with_list_plan_modifiers.go @@ -28,6 +28,8 @@ type NestedAttributeWithListPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -108,6 +110,16 @@ func (a NestedAttributeWithListPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithListPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithListPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} + // ListPlanModifiers satisfies the fwxschema.AttributeWithListPlanModifiers interface. func (a NestedAttributeWithListPlanModifiers) ListPlanModifiers() []planmodifier.List { return a.PlanModifiers diff --git a/internal/testing/testschema/nested_attribute_with_map_default.go b/internal/testing/testschema/nested_attribute_with_map_default.go index 6eac9d3f..be51d0a3 100644 --- a/internal/testing/testschema/nested_attribute_with_map_default.go +++ b/internal/testing/testschema/nested_attribute_with_map_default.go @@ -28,6 +28,8 @@ type NestedAttributeWithMapDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -108,6 +110,16 @@ func (a NestedAttributeWithMapDefaultValue) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithMapDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithMapDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} + // MapDefaultValue satisfies the fwschema.AttributeWithMapDefaultValue interface. func (a NestedAttributeWithMapDefaultValue) MapDefaultValue() defaults.Map { return a.Default diff --git a/internal/testing/testschema/nested_attribute_with_map_plan_modifiers.go b/internal/testing/testschema/nested_attribute_with_map_plan_modifiers.go index 35f2a073..855ef49d 100644 --- a/internal/testing/testschema/nested_attribute_with_map_plan_modifiers.go +++ b/internal/testing/testschema/nested_attribute_with_map_plan_modifiers.go @@ -28,6 +28,8 @@ type NestedAttributeWithMapPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -108,6 +110,16 @@ func (a NestedAttributeWithMapPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithMapPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithMapPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} + // MapPlanModifiers satisfies the fwxschema.AttributeWithMapPlanModifiers interface. func (a NestedAttributeWithMapPlanModifiers) MapPlanModifiers() []planmodifier.Map { return a.PlanModifiers diff --git a/internal/testing/testschema/nested_attribute_with_object_default.go b/internal/testing/testschema/nested_attribute_with_object_default.go index e8579c2a..5d83fb9d 100644 --- a/internal/testing/testschema/nested_attribute_with_object_default.go +++ b/internal/testing/testschema/nested_attribute_with_object_default.go @@ -29,6 +29,8 @@ type NestedAttributeWithObjectDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -111,6 +113,16 @@ func (a NestedAttributeWithObjectDefaultValue) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithObjectDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithObjectDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} + // ObjectDefaultValue satisfies the fwschema.AttributeWithListDefaultValue interface. func (a NestedAttributeWithObjectDefaultValue) ObjectDefaultValue() defaults.Object { return a.Default diff --git a/internal/testing/testschema/nested_attribute_with_object_plan_modifiers.go b/internal/testing/testschema/nested_attribute_with_object_plan_modifiers.go index 2d86af98..5f70c1fd 100644 --- a/internal/testing/testschema/nested_attribute_with_object_plan_modifiers.go +++ b/internal/testing/testschema/nested_attribute_with_object_plan_modifiers.go @@ -27,6 +27,8 @@ type NestedAttributeWithObjectPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -105,6 +107,16 @@ func (a NestedAttributeWithObjectPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithObjectPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithObjectPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} + // ObjectPlanModifiers satisfies the fwxschema.AttributeWithObjectPlanModifiers interface. func (a NestedAttributeWithObjectPlanModifiers) ObjectPlanModifiers() []planmodifier.Object { return a.PlanModifiers diff --git a/internal/testing/testschema/nested_attribute_with_set_default.go b/internal/testing/testschema/nested_attribute_with_set_default.go index 3a80c28a..16fc98d1 100644 --- a/internal/testing/testschema/nested_attribute_with_set_default.go +++ b/internal/testing/testschema/nested_attribute_with_set_default.go @@ -28,6 +28,8 @@ type NestedAttributeWithSetDefaultValue struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -108,6 +110,16 @@ func (a NestedAttributeWithSetDefaultValue) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithSetDefaultValue) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithSetDefaultValue) IsOptionalForImport() bool { + return a.OptionalForImport +} + // MapDefaultValue satisfies the fwschema.AttributeWithMapDefaultValue interface. func (a NestedAttributeWithSetDefaultValue) SetDefaultValue() defaults.Set { return a.Default diff --git a/internal/testing/testschema/nested_attribute_with_set_plan_modifiers.go b/internal/testing/testschema/nested_attribute_with_set_plan_modifiers.go index 1d886e70..a92acd39 100644 --- a/internal/testing/testschema/nested_attribute_with_set_plan_modifiers.go +++ b/internal/testing/testschema/nested_attribute_with_set_plan_modifiers.go @@ -28,6 +28,8 @@ type NestedAttributeWithSetPlanModifiers struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -108,6 +110,16 @@ func (a NestedAttributeWithSetPlanModifiers) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithSetPlanModifiers) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a NestedAttributeWithSetPlanModifiers) IsOptionalForImport() bool { + return a.OptionalForImport +} + // SetPlanModifiers satisfies the fwxschema.AttributeWithSetPlanModifiers interface. func (a NestedAttributeWithSetPlanModifiers) SetPlanModifiers() []planmodifier.Set { return a.PlanModifiers From 2950f20148adbbb50cde9244b19afc153bd5d991 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 24 Feb 2025 09:52:48 -0500 Subject: [PATCH 03/14] implement in datasource/schema --- datasource/schema/bool_attribute.go | 12 +++++ datasource/schema/bool_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/dynamic_attribute.go | 12 +++++ datasource/schema/dynamic_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/float32_attribute.go | 12 +++++ datasource/schema/float32_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/float64_attribute.go | 12 +++++ datasource/schema/float64_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/int32_attribute.go | 12 +++++ datasource/schema/int32_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/int64_attribute.go | 12 +++++ datasource/schema/int64_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/list_attribute.go | 12 +++++ datasource/schema/list_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/list_nested_attribute.go | 12 +++++ .../schema/list_nested_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/map_attribute.go | 12 +++++ datasource/schema/map_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/map_nested_attribute.go | 12 +++++ .../schema/map_nested_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/number_attribute.go | 12 +++++ datasource/schema/number_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/object_attribute.go | 12 +++++ datasource/schema/object_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/set_attribute.go | 12 +++++ datasource/schema/set_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/set_nested_attribute.go | 12 +++++ .../schema/set_nested_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/single_nested_attribute.go | 12 +++++ .../schema/single_nested_attribute_test.go | 52 +++++++++++++++++++ datasource/schema/string_attribute.go | 12 +++++ datasource/schema/string_attribute_test.go | 52 +++++++++++++++++++ 32 files changed, 1024 insertions(+) diff --git a/datasource/schema/bool_attribute.go b/datasource/schema/bool_attribute.go index 1d984a8d..55a98257 100644 --- a/datasource/schema/bool_attribute.go +++ b/datasource/schema/bool_attribute.go @@ -191,3 +191,15 @@ func (a BoolAttribute) IsWriteOnly() bool { func (a BoolAttribute) IsSensitive() bool { return a.Sensitive } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsOptionalForImport() bool { + return false +} diff --git a/datasource/schema/bool_attribute_test.go b/datasource/schema/bool_attribute_test.go index ea22a21f..e2fa2d2a 100644 --- a/datasource/schema/bool_attribute_test.go +++ b/datasource/schema/bool_attribute_test.go @@ -428,3 +428,55 @@ func TestBoolAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestBoolAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.BoolAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.BoolAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/dynamic_attribute.go b/datasource/schema/dynamic_attribute.go index 4659cadf..52649038 100644 --- a/datasource/schema/dynamic_attribute.go +++ b/datasource/schema/dynamic_attribute.go @@ -188,6 +188,18 @@ func (a DynamicAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a DynamicAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a DynamicAttribute) IsOptionalForImport() bool { + return false +} + // DynamicValidators returns the Validators field value. func (a DynamicAttribute) DynamicValidators() []validator.Dynamic { return a.Validators diff --git a/datasource/schema/dynamic_attribute_test.go b/datasource/schema/dynamic_attribute_test.go index 7166ae9c..05cd9e34 100644 --- a/datasource/schema/dynamic_attribute_test.go +++ b/datasource/schema/dynamic_attribute_test.go @@ -428,3 +428,55 @@ func TestDynamicAttributeDynamicValidators(t *testing.T) { }) } } + +func TestDynamicAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.DynamicAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.DynamicAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestDynamicAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.DynamicAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.DynamicAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/float32_attribute.go b/datasource/schema/float32_attribute.go index d2510f5c..4ad4203c 100644 --- a/datasource/schema/float32_attribute.go +++ b/datasource/schema/float32_attribute.go @@ -194,3 +194,15 @@ func (a Float32Attribute) IsSensitive() bool { func (a Float32Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float32Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float32Attribute) IsOptionalForImport() bool { + return false +} diff --git a/datasource/schema/float32_attribute_test.go b/datasource/schema/float32_attribute_test.go index 3149803e..152ef32c 100644 --- a/datasource/schema/float32_attribute_test.go +++ b/datasource/schema/float32_attribute_test.go @@ -428,3 +428,55 @@ func TestFloat32AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestFloat32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/float64_attribute.go b/datasource/schema/float64_attribute.go index 1d893dd3..6e965edf 100644 --- a/datasource/schema/float64_attribute.go +++ b/datasource/schema/float64_attribute.go @@ -194,3 +194,15 @@ func (a Float64Attribute) IsSensitive() bool { func (a Float64Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsOptionalForImport() bool { + return false +} diff --git a/datasource/schema/float64_attribute_test.go b/datasource/schema/float64_attribute_test.go index c7319338..a99d9154 100644 --- a/datasource/schema/float64_attribute_test.go +++ b/datasource/schema/float64_attribute_test.go @@ -428,3 +428,55 @@ func TestFloat64AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestFloat64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/int32_attribute.go b/datasource/schema/int32_attribute.go index d06a9b8c..67b355d2 100644 --- a/datasource/schema/int32_attribute.go +++ b/datasource/schema/int32_attribute.go @@ -194,3 +194,15 @@ func (a Int32Attribute) IsSensitive() bool { func (a Int32Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int32Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int32Attribute) IsOptionalForImport() bool { + return false +} diff --git a/datasource/schema/int32_attribute_test.go b/datasource/schema/int32_attribute_test.go index 15404c9e..2e38dc91 100644 --- a/datasource/schema/int32_attribute_test.go +++ b/datasource/schema/int32_attribute_test.go @@ -428,3 +428,55 @@ func TestInt32AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestInt32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/int64_attribute.go b/datasource/schema/int64_attribute.go index 85bd4a44..535f1f8a 100644 --- a/datasource/schema/int64_attribute.go +++ b/datasource/schema/int64_attribute.go @@ -194,3 +194,15 @@ func (a Int64Attribute) IsSensitive() bool { func (a Int64Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsOptionalForImport() bool { + return false +} diff --git a/datasource/schema/int64_attribute_test.go b/datasource/schema/int64_attribute_test.go index ed0544c6..c692c2b3 100644 --- a/datasource/schema/int64_attribute_test.go +++ b/datasource/schema/int64_attribute_test.go @@ -428,3 +428,55 @@ func TestInt64AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestInt64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/list_attribute.go b/datasource/schema/list_attribute.go index 2e514060..de211ed6 100644 --- a/datasource/schema/list_attribute.go +++ b/datasource/schema/list_attribute.go @@ -213,6 +213,18 @@ func (a ListAttribute) ListValidators() []validator.List { return a.Validators } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC diff --git a/datasource/schema/list_attribute_test.go b/datasource/schema/list_attribute_test.go index c38c41e2..d28a3732 100644 --- a/datasource/schema/list_attribute_test.go +++ b/datasource/schema/list_attribute_test.go @@ -524,3 +524,55 @@ func TestListAttributeValidateImplementation(t *testing.T) { }) } } + +func TestListAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/list_nested_attribute.go b/datasource/schema/list_nested_attribute.go index 92232062..4e844574 100644 --- a/datasource/schema/list_nested_attribute.go +++ b/datasource/schema/list_nested_attribute.go @@ -236,6 +236,18 @@ func (a ListNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsOptionalForImport() bool { + return false +} + // ListValidators returns the Validators field value. func (a ListNestedAttribute) ListValidators() []validator.List { return a.Validators diff --git a/datasource/schema/list_nested_attribute_test.go b/datasource/schema/list_nested_attribute_test.go index b7ea5be2..70725f0e 100644 --- a/datasource/schema/list_nested_attribute_test.go +++ b/datasource/schema/list_nested_attribute_test.go @@ -689,3 +689,55 @@ func TestListNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestListNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/map_attribute.go b/datasource/schema/map_attribute.go index 3d6c5768..8e703088 100644 --- a/datasource/schema/map_attribute.go +++ b/datasource/schema/map_attribute.go @@ -211,6 +211,18 @@ func (a MapAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsOptionalForImport() bool { + return false +} + // MapValidators returns the Validators field value. func (a MapAttribute) MapValidators() []validator.Map { return a.Validators diff --git a/datasource/schema/map_attribute_test.go b/datasource/schema/map_attribute_test.go index af361a63..f72a8b49 100644 --- a/datasource/schema/map_attribute_test.go +++ b/datasource/schema/map_attribute_test.go @@ -524,3 +524,55 @@ func TestMapAttributeValidateImplementation(t *testing.T) { }) } } + +func TestMapAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/map_nested_attribute.go b/datasource/schema/map_nested_attribute.go index 9bf1bb95..b9a8bb90 100644 --- a/datasource/schema/map_nested_attribute.go +++ b/datasource/schema/map_nested_attribute.go @@ -236,6 +236,18 @@ func (a MapNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsOptionalForImport() bool { + return false +} + // MapValidators returns the Validators field value. func (a MapNestedAttribute) MapValidators() []validator.Map { return a.Validators diff --git a/datasource/schema/map_nested_attribute_test.go b/datasource/schema/map_nested_attribute_test.go index d691cda8..e5db0a5c 100644 --- a/datasource/schema/map_nested_attribute_test.go +++ b/datasource/schema/map_nested_attribute_test.go @@ -689,3 +689,55 @@ func TestMapNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestMapNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/number_attribute.go b/datasource/schema/number_attribute.go index c21f74a1..61e9184e 100644 --- a/datasource/schema/number_attribute.go +++ b/datasource/schema/number_attribute.go @@ -191,6 +191,18 @@ func (a NumberAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsOptionalForImport() bool { + return false +} + // NumberValidators returns the Validators field value. func (a NumberAttribute) NumberValidators() []validator.Number { return a.Validators diff --git a/datasource/schema/number_attribute_test.go b/datasource/schema/number_attribute_test.go index c30b711e..87c10c32 100644 --- a/datasource/schema/number_attribute_test.go +++ b/datasource/schema/number_attribute_test.go @@ -428,3 +428,55 @@ func TestNumberAttributeNumberValidators(t *testing.T) { }) } } + +func TestNumberAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.NumberAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.NumberAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/object_attribute.go b/datasource/schema/object_attribute.go index a004329a..98128518 100644 --- a/datasource/schema/object_attribute.go +++ b/datasource/schema/object_attribute.go @@ -210,6 +210,18 @@ func (a ObjectAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsOptionalForImport() bool { + return false +} + // ObjectValidators returns the Validators field value. func (a ObjectAttribute) ObjectValidators() []validator.Object { return a.Validators diff --git a/datasource/schema/object_attribute_test.go b/datasource/schema/object_attribute_test.go index d5c45ee6..a4b30d2f 100644 --- a/datasource/schema/object_attribute_test.go +++ b/datasource/schema/object_attribute_test.go @@ -557,3 +557,55 @@ func TestObjectAttributeValidateImplementation(t *testing.T) { }) } } + +func TestObjectAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ObjectAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestObjectAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ObjectAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/set_attribute.go b/datasource/schema/set_attribute.go index 859b0558..714a9602 100644 --- a/datasource/schema/set_attribute.go +++ b/datasource/schema/set_attribute.go @@ -206,6 +206,18 @@ func (a SetAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsOptionalForImport() bool { + return false +} + // SetValidators returns the Validators field value. func (a SetAttribute) SetValidators() []validator.Set { return a.Validators diff --git a/datasource/schema/set_attribute_test.go b/datasource/schema/set_attribute_test.go index 02fcb830..29f2effe 100644 --- a/datasource/schema/set_attribute_test.go +++ b/datasource/schema/set_attribute_test.go @@ -524,3 +524,55 @@ func TestSetAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSetAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/set_nested_attribute.go b/datasource/schema/set_nested_attribute.go index 26b14e44..30ed7573 100644 --- a/datasource/schema/set_nested_attribute.go +++ b/datasource/schema/set_nested_attribute.go @@ -231,6 +231,18 @@ func (a SetNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsOptionalForImport() bool { + return false +} + // SetValidators returns the Validators field value. func (a SetNestedAttribute) SetValidators() []validator.Set { return a.Validators diff --git a/datasource/schema/set_nested_attribute_test.go b/datasource/schema/set_nested_attribute_test.go index 1a50cac0..083eba85 100644 --- a/datasource/schema/set_nested_attribute_test.go +++ b/datasource/schema/set_nested_attribute_test.go @@ -689,3 +689,55 @@ func TestSetNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSetNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/single_nested_attribute.go b/datasource/schema/single_nested_attribute.go index b6f4e7f3..290d2107 100644 --- a/datasource/schema/single_nested_attribute.go +++ b/datasource/schema/single_nested_attribute.go @@ -245,6 +245,18 @@ func (a SingleNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsOptionalForImport() bool { + return false +} + // ObjectValidators returns the Validators field value. func (a SingleNestedAttribute) ObjectValidators() []validator.Object { return a.Validators diff --git a/datasource/schema/single_nested_attribute_test.go b/datasource/schema/single_nested_attribute_test.go index 0a7a0b66..73a00739 100644 --- a/datasource/schema/single_nested_attribute_test.go +++ b/datasource/schema/single_nested_attribute_test.go @@ -570,3 +570,55 @@ func TestSingleNestedAttributeObjectValidators(t *testing.T) { }) } } + +func TestSingleNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SingleNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSingleNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SingleNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/datasource/schema/string_attribute.go b/datasource/schema/string_attribute.go index 95534fec..250fb5ff 100644 --- a/datasource/schema/string_attribute.go +++ b/datasource/schema/string_attribute.go @@ -187,6 +187,18 @@ func (a StringAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsOptionalForImport() bool { + return false +} + // StringValidators returns the Validators field value. func (a StringAttribute) StringValidators() []validator.String { return a.Validators diff --git a/datasource/schema/string_attribute_test.go b/datasource/schema/string_attribute_test.go index 09ea194f..6ccf2a9b 100644 --- a/datasource/schema/string_attribute_test.go +++ b/datasource/schema/string_attribute_test.go @@ -428,3 +428,55 @@ func TestStringAttributeStringValidators(t *testing.T) { }) } } + +func TestStringAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.StringAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.StringAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} From f2243bade5fb89fe49df06d9dd025ebea996ff28 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 24 Feb 2025 10:04:06 -0500 Subject: [PATCH 04/14] implement in ephemeral/schema --- ephemeral/schema/bool_attribute.go | 12 +++++ ephemeral/schema/bool_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/dynamic_attribute.go | 12 +++++ ephemeral/schema/dynamic_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/float32_attribute.go | 12 +++++ ephemeral/schema/float32_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/float64_attribute.go | 12 +++++ ephemeral/schema/float64_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/int32_attribute.go | 12 +++++ ephemeral/schema/int32_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/int64_attribute.go | 12 +++++ ephemeral/schema/int64_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/list_attribute.go | 12 +++++ ephemeral/schema/list_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/list_nested_attribute.go | 12 +++++ .../schema/list_nested_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/map_attribute.go | 12 +++++ ephemeral/schema/map_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/map_nested_attribute.go | 12 +++++ ephemeral/schema/map_nested_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/number_attribute.go | 12 +++++ ephemeral/schema/number_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/object_attribute.go | 12 +++++ ephemeral/schema/object_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/set_attribute.go | 12 +++++ ephemeral/schema/set_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/set_nested_attribute.go | 12 +++++ ephemeral/schema/set_nested_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/single_nested_attribute.go | 12 +++++ .../schema/single_nested_attribute_test.go | 52 +++++++++++++++++++ ephemeral/schema/string_attribute.go | 12 +++++ ephemeral/schema/string_attribute_test.go | 52 +++++++++++++++++++ 32 files changed, 1024 insertions(+) diff --git a/ephemeral/schema/bool_attribute.go b/ephemeral/schema/bool_attribute.go index 56790dee..4ff3b43b 100644 --- a/ephemeral/schema/bool_attribute.go +++ b/ephemeral/schema/bool_attribute.go @@ -190,3 +190,15 @@ func (a BoolAttribute) IsSensitive() bool { func (a BoolAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsOptionalForImport() bool { + return false +} diff --git a/ephemeral/schema/bool_attribute_test.go b/ephemeral/schema/bool_attribute_test.go index 30cc54aa..7a9b27f6 100644 --- a/ephemeral/schema/bool_attribute_test.go +++ b/ephemeral/schema/bool_attribute_test.go @@ -428,3 +428,55 @@ func TestBoolAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestBoolAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.BoolAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.BoolAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/dynamic_attribute.go b/ephemeral/schema/dynamic_attribute.go index 9cd22e70..205c73ea 100644 --- a/ephemeral/schema/dynamic_attribute.go +++ b/ephemeral/schema/dynamic_attribute.go @@ -191,3 +191,15 @@ func (a DynamicAttribute) IsWriteOnly() bool { func (a DynamicAttribute) DynamicValidators() []validator.Dynamic { return a.Validators } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a DynamicAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a DynamicAttribute) IsOptionalForImport() bool { + return false +} diff --git a/ephemeral/schema/dynamic_attribute_test.go b/ephemeral/schema/dynamic_attribute_test.go index 4d01e95a..48fc4da0 100644 --- a/ephemeral/schema/dynamic_attribute_test.go +++ b/ephemeral/schema/dynamic_attribute_test.go @@ -427,3 +427,55 @@ func TestDynamicAttributeDynamicValidators(t *testing.T) { }) } } + +func TestDynamicAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.DynamicAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.DynamicAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestDynamicAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.DynamicAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.DynamicAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/float32_attribute.go b/ephemeral/schema/float32_attribute.go index 46af5bae..cb5de0fb 100644 --- a/ephemeral/schema/float32_attribute.go +++ b/ephemeral/schema/float32_attribute.go @@ -193,3 +193,15 @@ func (a Float32Attribute) IsSensitive() bool { func (a Float32Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float32Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float32Attribute) IsOptionalForImport() bool { + return false +} diff --git a/ephemeral/schema/float32_attribute_test.go b/ephemeral/schema/float32_attribute_test.go index 1617d12a..90f9afe9 100644 --- a/ephemeral/schema/float32_attribute_test.go +++ b/ephemeral/schema/float32_attribute_test.go @@ -428,3 +428,55 @@ func TestFloat32AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestFloat32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/float64_attribute.go b/ephemeral/schema/float64_attribute.go index f4699e21..a295ace3 100644 --- a/ephemeral/schema/float64_attribute.go +++ b/ephemeral/schema/float64_attribute.go @@ -193,3 +193,15 @@ func (a Float64Attribute) IsSensitive() bool { func (a Float64Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsOptionalForImport() bool { + return false +} diff --git a/ephemeral/schema/float64_attribute_test.go b/ephemeral/schema/float64_attribute_test.go index 4bfb2ebd..29b240f7 100644 --- a/ephemeral/schema/float64_attribute_test.go +++ b/ephemeral/schema/float64_attribute_test.go @@ -428,3 +428,55 @@ func TestFloat54AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestFloat64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/int32_attribute.go b/ephemeral/schema/int32_attribute.go index 76f6e019..1f948eaf 100644 --- a/ephemeral/schema/int32_attribute.go +++ b/ephemeral/schema/int32_attribute.go @@ -193,3 +193,15 @@ func (a Int32Attribute) IsSensitive() bool { func (a Int32Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int32Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int32Attribute) IsOptionalForImport() bool { + return false +} diff --git a/ephemeral/schema/int32_attribute_test.go b/ephemeral/schema/int32_attribute_test.go index b4d3cc6d..3e88ea4d 100644 --- a/ephemeral/schema/int32_attribute_test.go +++ b/ephemeral/schema/int32_attribute_test.go @@ -428,3 +428,55 @@ func TestInt2AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestInt32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/int64_attribute.go b/ephemeral/schema/int64_attribute.go index 27cb2dd2..95b96fe2 100644 --- a/ephemeral/schema/int64_attribute.go +++ b/ephemeral/schema/int64_attribute.go @@ -193,3 +193,15 @@ func (a Int64Attribute) IsSensitive() bool { func (a Int64Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsOptionalForImport() bool { + return false +} diff --git a/ephemeral/schema/int64_attribute_test.go b/ephemeral/schema/int64_attribute_test.go index 6b7c1849..ef637140 100644 --- a/ephemeral/schema/int64_attribute_test.go +++ b/ephemeral/schema/int64_attribute_test.go @@ -428,3 +428,55 @@ func TestInt64AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestInt64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/list_attribute.go b/ephemeral/schema/list_attribute.go index 258757f9..05cc6895 100644 --- a/ephemeral/schema/list_attribute.go +++ b/ephemeral/schema/list_attribute.go @@ -206,6 +206,18 @@ func (a ListAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsOptionalForImport() bool { + return false +} + // ListValidators returns the Validators field value. func (a ListAttribute) ListValidators() []validator.List { return a.Validators diff --git a/ephemeral/schema/list_attribute_test.go b/ephemeral/schema/list_attribute_test.go index cdbc9feb..9ee0e5c8 100644 --- a/ephemeral/schema/list_attribute_test.go +++ b/ephemeral/schema/list_attribute_test.go @@ -523,3 +523,55 @@ func TestListAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestListAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/list_nested_attribute.go b/ephemeral/schema/list_nested_attribute.go index a4478fb4..ea4954da 100644 --- a/ephemeral/schema/list_nested_attribute.go +++ b/ephemeral/schema/list_nested_attribute.go @@ -235,6 +235,18 @@ func (a ListNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsOptionalForImport() bool { + return false +} + // ListValidators returns the Validators field value. func (a ListNestedAttribute) ListValidators() []validator.List { return a.Validators diff --git a/ephemeral/schema/list_nested_attribute_test.go b/ephemeral/schema/list_nested_attribute_test.go index 914af418..daba7e11 100644 --- a/ephemeral/schema/list_nested_attribute_test.go +++ b/ephemeral/schema/list_nested_attribute_test.go @@ -688,3 +688,55 @@ func TestListNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestListNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/map_attribute.go b/ephemeral/schema/map_attribute.go index 0741747a..018e83c4 100644 --- a/ephemeral/schema/map_attribute.go +++ b/ephemeral/schema/map_attribute.go @@ -210,6 +210,18 @@ func (a MapAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsOptionalForImport() bool { + return false +} + // MapValidators returns the Validators field value. func (a MapAttribute) MapValidators() []validator.Map { return a.Validators diff --git a/ephemeral/schema/map_attribute_test.go b/ephemeral/schema/map_attribute_test.go index f750b5f5..ed234855 100644 --- a/ephemeral/schema/map_attribute_test.go +++ b/ephemeral/schema/map_attribute_test.go @@ -523,3 +523,55 @@ func TestMapAttributeValidateImplementation(t *testing.T) { }) } } + +func TestMapAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/map_nested_attribute.go b/ephemeral/schema/map_nested_attribute.go index de057e10..f935c12c 100644 --- a/ephemeral/schema/map_nested_attribute.go +++ b/ephemeral/schema/map_nested_attribute.go @@ -235,6 +235,18 @@ func (a MapNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsOptionalForImport() bool { + return false +} + // MapValidators returns the Validators field value. func (a MapNestedAttribute) MapValidators() []validator.Map { return a.Validators diff --git a/ephemeral/schema/map_nested_attribute_test.go b/ephemeral/schema/map_nested_attribute_test.go index 37c2f1aa..2bbaa15d 100644 --- a/ephemeral/schema/map_nested_attribute_test.go +++ b/ephemeral/schema/map_nested_attribute_test.go @@ -688,3 +688,55 @@ func TestMapNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestMapNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/number_attribute.go b/ephemeral/schema/number_attribute.go index 17d55739..6b5de920 100644 --- a/ephemeral/schema/number_attribute.go +++ b/ephemeral/schema/number_attribute.go @@ -190,6 +190,18 @@ func (a NumberAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsOptionalForImport() bool { + return false +} + // NumberValidators returns the Validators field value. func (a NumberAttribute) NumberValidators() []validator.Number { return a.Validators diff --git a/ephemeral/schema/number_attribute_test.go b/ephemeral/schema/number_attribute_test.go index a15142af..2b07635a 100644 --- a/ephemeral/schema/number_attribute_test.go +++ b/ephemeral/schema/number_attribute_test.go @@ -428,3 +428,55 @@ func TestNumberAttributeNumberValidators(t *testing.T) { }) } } + +func TestNumberAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.NumberAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.NumberAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/object_attribute.go b/ephemeral/schema/object_attribute.go index fa808e4b..32776907 100644 --- a/ephemeral/schema/object_attribute.go +++ b/ephemeral/schema/object_attribute.go @@ -208,6 +208,18 @@ func (a ObjectAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsOptionalForImport() bool { + return false +} + // ObjectValidators returns the Validators field value. func (a ObjectAttribute) ObjectValidators() []validator.Object { return a.Validators diff --git a/ephemeral/schema/object_attribute_test.go b/ephemeral/schema/object_attribute_test.go index f49e4afc..cff690c6 100644 --- a/ephemeral/schema/object_attribute_test.go +++ b/ephemeral/schema/object_attribute_test.go @@ -557,3 +557,55 @@ func TestObjectAttributeValidateImplementation(t *testing.T) { }) } } + +func TestObjectAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ObjectAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestObjectAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ObjectAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/set_attribute.go b/ephemeral/schema/set_attribute.go index 7ecd08ff..a0523502 100644 --- a/ephemeral/schema/set_attribute.go +++ b/ephemeral/schema/set_attribute.go @@ -205,6 +205,18 @@ func (a SetAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsOptionalForImport() bool { + return false +} + // SetValidators returns the Validators field value. func (a SetAttribute) SetValidators() []validator.Set { return a.Validators diff --git a/ephemeral/schema/set_attribute_test.go b/ephemeral/schema/set_attribute_test.go index d3c158fd..af56ab90 100644 --- a/ephemeral/schema/set_attribute_test.go +++ b/ephemeral/schema/set_attribute_test.go @@ -523,3 +523,55 @@ func TestSetAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSetAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/set_nested_attribute.go b/ephemeral/schema/set_nested_attribute.go index 658dc0df..f5740cd5 100644 --- a/ephemeral/schema/set_nested_attribute.go +++ b/ephemeral/schema/set_nested_attribute.go @@ -230,6 +230,18 @@ func (a SetNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsOptionalForImport() bool { + return false +} + // SetValidators returns the Validators field value. func (a SetNestedAttribute) SetValidators() []validator.Set { return a.Validators diff --git a/ephemeral/schema/set_nested_attribute_test.go b/ephemeral/schema/set_nested_attribute_test.go index 3abd5983..a049ade7 100644 --- a/ephemeral/schema/set_nested_attribute_test.go +++ b/ephemeral/schema/set_nested_attribute_test.go @@ -689,3 +689,55 @@ func TestSetNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSetNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/single_nested_attribute.go b/ephemeral/schema/single_nested_attribute.go index 167b8c13..16cc31fc 100644 --- a/ephemeral/schema/single_nested_attribute.go +++ b/ephemeral/schema/single_nested_attribute.go @@ -244,6 +244,18 @@ func (a SingleNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsOptionalForImport() bool { + return false +} + // ObjectValidators returns the Validators field value. func (a SingleNestedAttribute) ObjectValidators() []validator.Object { return a.Validators diff --git a/ephemeral/schema/single_nested_attribute_test.go b/ephemeral/schema/single_nested_attribute_test.go index 8f4e4e78..f97ba872 100644 --- a/ephemeral/schema/single_nested_attribute_test.go +++ b/ephemeral/schema/single_nested_attribute_test.go @@ -569,3 +569,55 @@ func TestSingleNestedAttributeObjectValidators(t *testing.T) { }) } } + +func TestSingleNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SingleNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSingleNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SingleNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/ephemeral/schema/string_attribute.go b/ephemeral/schema/string_attribute.go index 3cfefe97..c751c987 100644 --- a/ephemeral/schema/string_attribute.go +++ b/ephemeral/schema/string_attribute.go @@ -186,6 +186,18 @@ func (a StringAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsOptionalForImport() bool { + return false +} + // StringValidators returns the Validators field value. func (a StringAttribute) StringValidators() []validator.String { return a.Validators diff --git a/ephemeral/schema/string_attribute_test.go b/ephemeral/schema/string_attribute_test.go index 9f8532f3..95a34c24 100644 --- a/ephemeral/schema/string_attribute_test.go +++ b/ephemeral/schema/string_attribute_test.go @@ -427,3 +427,55 @@ func TestStringAttributeStringValidators(t *testing.T) { }) } } + +func TestStringAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.StringAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.StringAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} From 057093a4987a1dc48740415a26dca731c109e9a7 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 24 Feb 2025 10:13:51 -0500 Subject: [PATCH 05/14] implement in provider/metaschema --- provider/metaschema/bool_attribute.go | 12 +++++ provider/metaschema/bool_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/float64_attribute.go | 12 +++++ provider/metaschema/float64_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/int64_attribute.go | 12 +++++ provider/metaschema/int64_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/list_attribute.go | 12 +++++ provider/metaschema/list_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/list_nested_attribute.go | 12 +++++ .../metaschema/list_nested_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/map_attribute.go | 12 +++++ provider/metaschema/map_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/map_nested_attribute.go | 12 +++++ .../metaschema/map_nested_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/number_attribute.go | 12 +++++ provider/metaschema/number_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/object_attribute.go | 12 +++++ provider/metaschema/object_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/set_attribute.go | 12 +++++ provider/metaschema/set_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/set_nested_attribute.go | 12 +++++ .../metaschema/set_nested_attribute_test.go | 52 +++++++++++++++++++ .../metaschema/single_nested_attribute.go | 12 +++++ .../single_nested_attribute_test.go | 52 +++++++++++++++++++ provider/metaschema/string_attribute.go | 12 +++++ provider/metaschema/string_attribute_test.go | 52 +++++++++++++++++++ 26 files changed, 832 insertions(+) diff --git a/provider/metaschema/bool_attribute.go b/provider/metaschema/bool_attribute.go index 37429634..811a94e3 100644 --- a/provider/metaschema/bool_attribute.go +++ b/provider/metaschema/bool_attribute.go @@ -124,3 +124,15 @@ func (a BoolAttribute) IsSensitive() bool { func (a BoolAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/metaschema/bool_attribute_test.go b/provider/metaschema/bool_attribute_test.go index f679fc1a..caeefaeb 100644 --- a/provider/metaschema/bool_attribute_test.go +++ b/provider/metaschema/bool_attribute_test.go @@ -377,3 +377,55 @@ func TestBoolAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestBoolAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.BoolAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.BoolAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/float64_attribute.go b/provider/metaschema/float64_attribute.go index ac2b79b0..a4eb9e9d 100644 --- a/provider/metaschema/float64_attribute.go +++ b/provider/metaschema/float64_attribute.go @@ -127,3 +127,15 @@ func (a Float64Attribute) IsSensitive() bool { func (a Float64Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/metaschema/float64_attribute_test.go b/provider/metaschema/float64_attribute_test.go index 8a73c922..0ee1b3d4 100644 --- a/provider/metaschema/float64_attribute_test.go +++ b/provider/metaschema/float64_attribute_test.go @@ -377,3 +377,55 @@ func TestFloat64AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestFloat64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.Float64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.Float64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/int64_attribute.go b/provider/metaschema/int64_attribute.go index aeccd703..25a21493 100644 --- a/provider/metaschema/int64_attribute.go +++ b/provider/metaschema/int64_attribute.go @@ -127,3 +127,15 @@ func (a Int64Attribute) IsSensitive() bool { func (a Int64Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/metaschema/int64_attribute_test.go b/provider/metaschema/int64_attribute_test.go index 69439d02..ab7a5bdf 100644 --- a/provider/metaschema/int64_attribute_test.go +++ b/provider/metaschema/int64_attribute_test.go @@ -377,3 +377,55 @@ func TestInt64AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestInt64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.Int64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.Int64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/list_attribute.go b/provider/metaschema/list_attribute.go index 187d9c47..2149c212 100644 --- a/provider/metaschema/list_attribute.go +++ b/provider/metaschema/list_attribute.go @@ -141,6 +141,18 @@ func (a ListAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC diff --git a/provider/metaschema/list_attribute_test.go b/provider/metaschema/list_attribute_test.go index 93f213ce..66f5e6b6 100644 --- a/provider/metaschema/list_attribute_test.go +++ b/provider/metaschema/list_attribute_test.go @@ -451,3 +451,55 @@ func TestListAttributeValidateImplementation(t *testing.T) { }) } } + +func TestListAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.ListAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.ListAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/list_nested_attribute.go b/provider/metaschema/list_nested_attribute.go index 0fa1b822..bf9b2f94 100644 --- a/provider/metaschema/list_nested_attribute.go +++ b/provider/metaschema/list_nested_attribute.go @@ -166,3 +166,15 @@ func (a ListNestedAttribute) IsSensitive() bool { func (a ListNestedAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/metaschema/list_nested_attribute_test.go b/provider/metaschema/list_nested_attribute_test.go index 1c3576a3..fe587af0 100644 --- a/provider/metaschema/list_nested_attribute_test.go +++ b/provider/metaschema/list_nested_attribute_test.go @@ -551,3 +551,55 @@ func TestListNestedAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestListNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.ListNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.ListNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/map_attribute.go b/provider/metaschema/map_attribute.go index 9103231f..18a3e986 100644 --- a/provider/metaschema/map_attribute.go +++ b/provider/metaschema/map_attribute.go @@ -144,6 +144,18 @@ func (a MapAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC diff --git a/provider/metaschema/map_attribute_test.go b/provider/metaschema/map_attribute_test.go index 7d137ef1..11ec28d0 100644 --- a/provider/metaschema/map_attribute_test.go +++ b/provider/metaschema/map_attribute_test.go @@ -451,3 +451,55 @@ func TestMapAttributeValidateImplementation(t *testing.T) { }) } } + +func TestMapAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.MapAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.MapAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/map_nested_attribute.go b/provider/metaschema/map_nested_attribute.go index 587c56c0..5962d38a 100644 --- a/provider/metaschema/map_nested_attribute.go +++ b/provider/metaschema/map_nested_attribute.go @@ -166,3 +166,15 @@ func (a MapNestedAttribute) IsSensitive() bool { func (a MapNestedAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/metaschema/map_nested_attribute_test.go b/provider/metaschema/map_nested_attribute_test.go index 99c5ae55..b2cc9a21 100644 --- a/provider/metaschema/map_nested_attribute_test.go +++ b/provider/metaschema/map_nested_attribute_test.go @@ -551,3 +551,55 @@ func TestMapNestedAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestMapNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.MapNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.MapNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/number_attribute.go b/provider/metaschema/number_attribute.go index 511e7000..829c0a50 100644 --- a/provider/metaschema/number_attribute.go +++ b/provider/metaschema/number_attribute.go @@ -128,3 +128,15 @@ func (a NumberAttribute) IsSensitive() bool { func (a NumberAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/metaschema/number_attribute_test.go b/provider/metaschema/number_attribute_test.go index 676db8e1..53a09412 100644 --- a/provider/metaschema/number_attribute_test.go +++ b/provider/metaschema/number_attribute_test.go @@ -377,3 +377,55 @@ func TestNumberAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestNumberAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.NumberAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.NumberAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/object_attribute.go b/provider/metaschema/object_attribute.go index aabe40d4..091fff81 100644 --- a/provider/metaschema/object_attribute.go +++ b/provider/metaschema/object_attribute.go @@ -143,6 +143,18 @@ func (a ObjectAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC diff --git a/provider/metaschema/object_attribute_test.go b/provider/metaschema/object_attribute_test.go index 6b3bb447..7b47aa5c 100644 --- a/provider/metaschema/object_attribute_test.go +++ b/provider/metaschema/object_attribute_test.go @@ -459,3 +459,55 @@ func TestObjectAttributeValidateImplementation(t *testing.T) { }) } } + +func TestObjectAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.ObjectAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestObjectAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.ObjectAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/set_attribute.go b/provider/metaschema/set_attribute.go index f7d3e411..a4b8365c 100644 --- a/provider/metaschema/set_attribute.go +++ b/provider/metaschema/set_attribute.go @@ -139,6 +139,18 @@ func (a SetAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC diff --git a/provider/metaschema/set_attribute_test.go b/provider/metaschema/set_attribute_test.go index 975b3b71..94bf6346 100644 --- a/provider/metaschema/set_attribute_test.go +++ b/provider/metaschema/set_attribute_test.go @@ -451,3 +451,55 @@ func TestSetAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSetAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.SetAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.SetAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/set_nested_attribute.go b/provider/metaschema/set_nested_attribute.go index a3c6fbf9..a137deda 100644 --- a/provider/metaschema/set_nested_attribute.go +++ b/provider/metaschema/set_nested_attribute.go @@ -161,3 +161,15 @@ func (a SetNestedAttribute) IsSensitive() bool { func (a SetNestedAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/metaschema/set_nested_attribute_test.go b/provider/metaschema/set_nested_attribute_test.go index 225a936f..5e7c46f6 100644 --- a/provider/metaschema/set_nested_attribute_test.go +++ b/provider/metaschema/set_nested_attribute_test.go @@ -551,3 +551,55 @@ func TestSetNestedAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestSetNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.SetNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.SetNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/single_nested_attribute.go b/provider/metaschema/single_nested_attribute.go index 160fb1c8..a10d2368 100644 --- a/provider/metaschema/single_nested_attribute.go +++ b/provider/metaschema/single_nested_attribute.go @@ -181,3 +181,15 @@ func (a SingleNestedAttribute) IsSensitive() bool { func (a SingleNestedAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/metaschema/single_nested_attribute_test.go b/provider/metaschema/single_nested_attribute_test.go index d590cbba..82b57349 100644 --- a/provider/metaschema/single_nested_attribute_test.go +++ b/provider/metaschema/single_nested_attribute_test.go @@ -515,3 +515,55 @@ func TestSingleNestedAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestSingleNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.SingleNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSingleNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.SingleNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/metaschema/string_attribute.go b/provider/metaschema/string_attribute.go index fe25c501..5efcba28 100644 --- a/provider/metaschema/string_attribute.go +++ b/provider/metaschema/string_attribute.go @@ -124,3 +124,15 @@ func (a StringAttribute) IsSensitive() bool { func (a StringAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/metaschema/string_attribute_test.go b/provider/metaschema/string_attribute_test.go index c360462a..2d12a2f5 100644 --- a/provider/metaschema/string_attribute_test.go +++ b/provider/metaschema/string_attribute_test.go @@ -377,3 +377,55 @@ func TestStringAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestStringAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.StringAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: metaschema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute metaschema.StringAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: metaschema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} From 2fed09114c3a15a0289c7cf7dfd4f0c15ce594a6 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 24 Feb 2025 10:23:12 -0500 Subject: [PATCH 06/14] implement in provider/schema --- provider/schema/bool_attribute.go | 12 +++++ provider/schema/bool_attribute_test.go | 52 +++++++++++++++++++ provider/schema/dynamic_attribute.go | 12 +++++ provider/schema/dynamic_attribute_test.go | 52 +++++++++++++++++++ provider/schema/float32_attribute.go | 12 +++++ provider/schema/float32_attribute_test.go | 52 +++++++++++++++++++ provider/schema/float64_attribute.go | 12 +++++ provider/schema/float64_attribute_test.go | 52 +++++++++++++++++++ provider/schema/int32_attribute.go | 12 +++++ provider/schema/int32_attribute_test.go | 52 +++++++++++++++++++ provider/schema/int64_attribute.go | 12 +++++ provider/schema/int64_attribute_test.go | 52 +++++++++++++++++++ provider/schema/list_attribute.go | 12 +++++ provider/schema/list_attribute_test.go | 52 +++++++++++++++++++ provider/schema/list_nested_attribute.go | 12 +++++ provider/schema/list_nested_attribute_test.go | 52 +++++++++++++++++++ provider/schema/map_attribute.go | 12 +++++ provider/schema/map_attribute_test.go | 52 +++++++++++++++++++ provider/schema/map_nested_attribute.go | 12 +++++ provider/schema/map_nested_attribute_test.go | 52 +++++++++++++++++++ provider/schema/number_attribute.go | 12 +++++ provider/schema/number_attribute_test.go | 52 +++++++++++++++++++ provider/schema/object_attribute.go | 12 +++++ provider/schema/object_attribute_test.go | 52 +++++++++++++++++++ provider/schema/set_attribute.go | 12 +++++ provider/schema/set_attribute_test.go | 52 +++++++++++++++++++ provider/schema/set_nested_attribute.go | 12 +++++ provider/schema/set_nested_attribute_test.go | 52 +++++++++++++++++++ provider/schema/single_nested_attribute.go | 12 +++++ .../schema/single_nested_attribute_test.go | 52 +++++++++++++++++++ provider/schema/string_attribute.go | 12 +++++ provider/schema/string_attribute_test.go | 52 +++++++++++++++++++ 32 files changed, 1024 insertions(+) diff --git a/provider/schema/bool_attribute.go b/provider/schema/bool_attribute.go index 0502821c..ea1eb8f9 100644 --- a/provider/schema/bool_attribute.go +++ b/provider/schema/bool_attribute.go @@ -185,3 +185,15 @@ func (a BoolAttribute) IsSensitive() bool { func (a BoolAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/schema/bool_attribute_test.go b/provider/schema/bool_attribute_test.go index 3e134f21..07291287 100644 --- a/provider/schema/bool_attribute_test.go +++ b/provider/schema/bool_attribute_test.go @@ -422,3 +422,55 @@ func TestBoolAttributeIsWriteOnly(t *testing.T) { }) } } + +func TestBoolAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.BoolAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.BoolAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/dynamic_attribute.go b/provider/schema/dynamic_attribute.go index 4b31279f..5e5c07ed 100644 --- a/provider/schema/dynamic_attribute.go +++ b/provider/schema/dynamic_attribute.go @@ -182,3 +182,15 @@ func (a DynamicAttribute) DynamicValidators() []validator.Dynamic { func (a DynamicAttribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a DynamicAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a DynamicAttribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/schema/dynamic_attribute_test.go b/provider/schema/dynamic_attribute_test.go index 66c7d855..bd6ec94a 100644 --- a/provider/schema/dynamic_attribute_test.go +++ b/provider/schema/dynamic_attribute_test.go @@ -422,3 +422,55 @@ func TestDynamicAttributeDynamicValidators(t *testing.T) { }) } } + +func TestDynamicAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.DynamicAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.DynamicAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestDynamicAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.DynamicAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.DynamicAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/float32_attribute.go b/provider/schema/float32_attribute.go index 8e62dc96..f272539b 100644 --- a/provider/schema/float32_attribute.go +++ b/provider/schema/float32_attribute.go @@ -188,3 +188,15 @@ func (a Float32Attribute) IsSensitive() bool { func (a Float32Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float32Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float32Attribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/schema/float32_attribute_test.go b/provider/schema/float32_attribute_test.go index 70d13db0..2793464d 100644 --- a/provider/schema/float32_attribute_test.go +++ b/provider/schema/float32_attribute_test.go @@ -422,3 +422,55 @@ func TestFloat32AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestFloat32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/float64_attribute.go b/provider/schema/float64_attribute.go index f0c0cc00..33615446 100644 --- a/provider/schema/float64_attribute.go +++ b/provider/schema/float64_attribute.go @@ -188,3 +188,15 @@ func (a Float64Attribute) IsSensitive() bool { func (a Float64Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/schema/float64_attribute_test.go b/provider/schema/float64_attribute_test.go index 8ff796cd..01db35d4 100644 --- a/provider/schema/float64_attribute_test.go +++ b/provider/schema/float64_attribute_test.go @@ -422,3 +422,55 @@ func TestFloat64AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestFloat64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/int32_attribute.go b/provider/schema/int32_attribute.go index 1f8c60c3..3b97a0f3 100644 --- a/provider/schema/int32_attribute.go +++ b/provider/schema/int32_attribute.go @@ -188,3 +188,15 @@ func (a Int32Attribute) IsSensitive() bool { func (a Int32Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int32Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int32Attribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/schema/int32_attribute_test.go b/provider/schema/int32_attribute_test.go index b9fa878b..f93d28ef 100644 --- a/provider/schema/int32_attribute_test.go +++ b/provider/schema/int32_attribute_test.go @@ -422,3 +422,55 @@ func TestInt32AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestInt32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/int64_attribute.go b/provider/schema/int64_attribute.go index 25243bbf..1dc1f85e 100644 --- a/provider/schema/int64_attribute.go +++ b/provider/schema/int64_attribute.go @@ -188,3 +188,15 @@ func (a Int64Attribute) IsSensitive() bool { func (a Int64Attribute) IsWriteOnly() bool { return false } + +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsOptionalForImport() bool { + return false +} diff --git a/provider/schema/int64_attribute_test.go b/provider/schema/int64_attribute_test.go index c5ebec88..c2bdc7d1 100644 --- a/provider/schema/int64_attribute_test.go +++ b/provider/schema/int64_attribute_test.go @@ -422,3 +422,55 @@ func TestInt64AttributeIsWriteOnly(t *testing.T) { }) } } + +func TestInt64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/list_attribute.go b/provider/schema/list_attribute.go index b85848b5..e9482597 100644 --- a/provider/schema/list_attribute.go +++ b/provider/schema/list_attribute.go @@ -202,6 +202,18 @@ func (a ListAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsOptionalForImport() bool { + return false +} + // ListValidators returns the Validators field value. func (a ListAttribute) ListValidators() []validator.List { return a.Validators diff --git a/provider/schema/list_attribute_test.go b/provider/schema/list_attribute_test.go index d0ab91c5..bb845184 100644 --- a/provider/schema/list_attribute_test.go +++ b/provider/schema/list_attribute_test.go @@ -518,3 +518,55 @@ func TestListAttributeValidateImplementation(t *testing.T) { }) } } + +func TestListAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/list_nested_attribute.go b/provider/schema/list_nested_attribute.go index 700299c0..07d6ebd4 100644 --- a/provider/schema/list_nested_attribute.go +++ b/provider/schema/list_nested_attribute.go @@ -230,6 +230,18 @@ func (a ListNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsOptionalForImport() bool { + return false +} + // ListValidators returns the Validators field value. func (a ListNestedAttribute) ListValidators() []validator.List { return a.Validators diff --git a/provider/schema/list_nested_attribute_test.go b/provider/schema/list_nested_attribute_test.go index 1f3715c7..b6130073 100644 --- a/provider/schema/list_nested_attribute_test.go +++ b/provider/schema/list_nested_attribute_test.go @@ -683,3 +683,55 @@ func TestListNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestListNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/map_attribute.go b/provider/schema/map_attribute.go index 82b5a05d..a43108d1 100644 --- a/provider/schema/map_attribute.go +++ b/provider/schema/map_attribute.go @@ -205,6 +205,18 @@ func (a MapAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsOptionalForImport() bool { + return false +} + // MapValidators returns the Validators field value. func (a MapAttribute) MapValidators() []validator.Map { return a.Validators diff --git a/provider/schema/map_attribute_test.go b/provider/schema/map_attribute_test.go index f2e1e6a2..bf46b6c5 100644 --- a/provider/schema/map_attribute_test.go +++ b/provider/schema/map_attribute_test.go @@ -518,3 +518,55 @@ func TestMapAttributeValidateImplementation(t *testing.T) { }) } } + +func TestMapAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/map_nested_attribute.go b/provider/schema/map_nested_attribute.go index 14fb4092..d2ee6ece 100644 --- a/provider/schema/map_nested_attribute.go +++ b/provider/schema/map_nested_attribute.go @@ -229,6 +229,18 @@ func (a MapNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsOptionalForImport() bool { + return false +} + // MapValidators returns the Validators field value. func (a MapNestedAttribute) MapValidators() []validator.Map { return a.Validators diff --git a/provider/schema/map_nested_attribute_test.go b/provider/schema/map_nested_attribute_test.go index bfbdb86c..26812fc0 100644 --- a/provider/schema/map_nested_attribute_test.go +++ b/provider/schema/map_nested_attribute_test.go @@ -683,3 +683,55 @@ func TestMapNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestMapNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/number_attribute.go b/provider/schema/number_attribute.go index bb6ffc6d..d8b467cc 100644 --- a/provider/schema/number_attribute.go +++ b/provider/schema/number_attribute.go @@ -185,6 +185,18 @@ func (a NumberAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsOptionalForImport() bool { + return false +} + // NumberValidators returns the Validators field value. func (a NumberAttribute) NumberValidators() []validator.Number { return a.Validators diff --git a/provider/schema/number_attribute_test.go b/provider/schema/number_attribute_test.go index 80dba9dd..daff176a 100644 --- a/provider/schema/number_attribute_test.go +++ b/provider/schema/number_attribute_test.go @@ -422,3 +422,55 @@ func TestNumberAttributeNumberValidators(t *testing.T) { }) } } + +func TestNumberAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.NumberAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.NumberAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/object_attribute.go b/provider/schema/object_attribute.go index c5c81a1b..ddd0e1b2 100644 --- a/provider/schema/object_attribute.go +++ b/provider/schema/object_attribute.go @@ -204,6 +204,18 @@ func (a ObjectAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsOptionalForImport() bool { + return false +} + // ObjectValidators returns the Validators field value. func (a ObjectAttribute) ObjectValidators() []validator.Object { return a.Validators diff --git a/provider/schema/object_attribute_test.go b/provider/schema/object_attribute_test.go index a53bc6bf..2ae9d0ee 100644 --- a/provider/schema/object_attribute_test.go +++ b/provider/schema/object_attribute_test.go @@ -551,3 +551,55 @@ func TestObjectAttributeValidateImplementation(t *testing.T) { }) } } + +func TestObjectAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ObjectAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestObjectAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ObjectAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/set_attribute.go b/provider/schema/set_attribute.go index eaf73344..87ee7363 100644 --- a/provider/schema/set_attribute.go +++ b/provider/schema/set_attribute.go @@ -200,6 +200,18 @@ func (a SetAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsOptionalForImport() bool { + return false +} + // SetValidators returns the Validators field value. func (a SetAttribute) SetValidators() []validator.Set { return a.Validators diff --git a/provider/schema/set_attribute_test.go b/provider/schema/set_attribute_test.go index bfa58193..efa665df 100644 --- a/provider/schema/set_attribute_test.go +++ b/provider/schema/set_attribute_test.go @@ -518,3 +518,55 @@ func TestSetAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSetAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/set_nested_attribute.go b/provider/schema/set_nested_attribute.go index a9dad64a..b879b40c 100644 --- a/provider/schema/set_nested_attribute.go +++ b/provider/schema/set_nested_attribute.go @@ -225,6 +225,18 @@ func (a SetNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsOptionalForImport() bool { + return false +} + // SetValidators returns the Validators field value. func (a SetNestedAttribute) SetValidators() []validator.Set { return a.Validators diff --git a/provider/schema/set_nested_attribute_test.go b/provider/schema/set_nested_attribute_test.go index 3471f42e..6dd17346 100644 --- a/provider/schema/set_nested_attribute_test.go +++ b/provider/schema/set_nested_attribute_test.go @@ -683,3 +683,55 @@ func TestSetNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSetNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/single_nested_attribute.go b/provider/schema/single_nested_attribute.go index aded0988..65f35310 100644 --- a/provider/schema/single_nested_attribute.go +++ b/provider/schema/single_nested_attribute.go @@ -239,6 +239,18 @@ func (a SingleNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsOptionalForImport() bool { + return false +} + // ObjectValidators returns the Validators field value. func (a SingleNestedAttribute) ObjectValidators() []validator.Object { return a.Validators diff --git a/provider/schema/single_nested_attribute_test.go b/provider/schema/single_nested_attribute_test.go index cbb2f3aa..a674a82a 100644 --- a/provider/schema/single_nested_attribute_test.go +++ b/provider/schema/single_nested_attribute_test.go @@ -564,3 +564,55 @@ func TestSingleNestedAttributeObjectValidators(t *testing.T) { }) } } + +func TestSingleNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SingleNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSingleNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SingleNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/provider/schema/string_attribute.go b/provider/schema/string_attribute.go index eda7a02c..db6667f0 100644 --- a/provider/schema/string_attribute.go +++ b/provider/schema/string_attribute.go @@ -181,6 +181,18 @@ func (a StringAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsOptionalForImport() bool { + return false +} + // StringValidators returns the Validators field value. func (a StringAttribute) StringValidators() []validator.String { return a.Validators diff --git a/provider/schema/string_attribute_test.go b/provider/schema/string_attribute_test.go index 35e9f03a..366f8411 100644 --- a/provider/schema/string_attribute_test.go +++ b/provider/schema/string_attribute_test.go @@ -422,3 +422,55 @@ func TestStringAttributeStringValidators(t *testing.T) { }) } } + +func TestStringAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.StringAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.StringAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} From 3c759ec580f1faef61752dbdc1c9bdc1559adc0b Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 24 Feb 2025 10:33:46 -0500 Subject: [PATCH 07/14] implement in resource/schema --- resource/schema/bool_attribute.go | 12 +++++ resource/schema/bool_attribute_test.go | 52 +++++++++++++++++++ resource/schema/dynamic_attribute.go | 12 +++++ resource/schema/dynamic_attribute_test.go | 52 +++++++++++++++++++ resource/schema/float32_attribute.go | 12 +++++ resource/schema/float32_attribute_test.go | 52 +++++++++++++++++++ resource/schema/float64_attribute.go | 12 +++++ resource/schema/float64_attribute_test.go | 52 +++++++++++++++++++ resource/schema/int32_attribute.go | 12 +++++ resource/schema/int32_attribute_test.go | 52 +++++++++++++++++++ resource/schema/int64_attribute.go | 12 +++++ resource/schema/int64_attribute_test.go | 52 +++++++++++++++++++ resource/schema/list_attribute.go | 12 +++++ resource/schema/list_attribute_test.go | 52 +++++++++++++++++++ resource/schema/list_nested_attribute.go | 12 +++++ resource/schema/list_nested_attribute_test.go | 52 +++++++++++++++++++ resource/schema/map_attribute.go | 12 +++++ resource/schema/map_attribute_test.go | 52 +++++++++++++++++++ resource/schema/map_nested_attribute.go | 12 +++++ resource/schema/map_nested_attribute_test.go | 52 +++++++++++++++++++ resource/schema/number_attribute.go | 12 +++++ resource/schema/number_attribute_test.go | 52 +++++++++++++++++++ resource/schema/object_attribute.go | 12 +++++ resource/schema/object_attribute_test.go | 52 +++++++++++++++++++ resource/schema/set_attribute.go | 12 +++++ resource/schema/set_attribute_test.go | 52 +++++++++++++++++++ resource/schema/set_nested_attribute.go | 12 +++++ resource/schema/set_nested_attribute_test.go | 52 +++++++++++++++++++ resource/schema/single_nested_attribute.go | 12 +++++ .../schema/single_nested_attribute_test.go | 52 +++++++++++++++++++ resource/schema/string_attribute.go | 12 +++++ resource/schema/string_attribute_test.go | 52 +++++++++++++++++++ 32 files changed, 1024 insertions(+) diff --git a/resource/schema/bool_attribute.go b/resource/schema/bool_attribute.go index fa80f565..b3d57ee7 100644 --- a/resource/schema/bool_attribute.go +++ b/resource/schema/bool_attribute.go @@ -244,6 +244,18 @@ func (a BoolAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a BoolAttribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC and diff --git a/resource/schema/bool_attribute_test.go b/resource/schema/bool_attribute_test.go index 9f2d2e86..e260c76d 100644 --- a/resource/schema/bool_attribute_test.go +++ b/resource/schema/bool_attribute_test.go @@ -580,3 +580,55 @@ func TestBoolAttributeValidateImplementation(t *testing.T) { }) } } + +func TestBoolAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.BoolAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.BoolAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/dynamic_attribute.go b/resource/schema/dynamic_attribute.go index e06600ab..72b74637 100644 --- a/resource/schema/dynamic_attribute.go +++ b/resource/schema/dynamic_attribute.go @@ -230,6 +230,18 @@ func (a DynamicAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a DynamicAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a DynamicAttribute) IsOptionalForImport() bool { + return false +} + // DynamicDefaultValue returns the Default field value. func (a DynamicAttribute) DynamicDefaultValue() defaults.Dynamic { return a.Default diff --git a/resource/schema/dynamic_attribute_test.go b/resource/schema/dynamic_attribute_test.go index c1340d49..4bacf972 100644 --- a/resource/schema/dynamic_attribute_test.go +++ b/resource/schema/dynamic_attribute_test.go @@ -580,3 +580,55 @@ func TestDynamicAttributeValidateImplementation(t *testing.T) { }) } } + +func TestDynamicAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.DynamicAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.DynamicAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestDynamicAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.DynamicAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.DynamicAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/float32_attribute.go b/resource/schema/float32_attribute.go index 3064b4ed..ed7e5fb9 100644 --- a/resource/schema/float32_attribute.go +++ b/resource/schema/float32_attribute.go @@ -247,6 +247,18 @@ func (a Float32Attribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float32Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float32Attribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC and diff --git a/resource/schema/float32_attribute_test.go b/resource/schema/float32_attribute_test.go index 4671b082..18b8d154 100644 --- a/resource/schema/float32_attribute_test.go +++ b/resource/schema/float32_attribute_test.go @@ -580,3 +580,55 @@ func TestFloat32AttributeValidateImplementation(t *testing.T) { }) } } + +func TestFloat32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/float64_attribute.go b/resource/schema/float64_attribute.go index 205af3f9..947c1695 100644 --- a/resource/schema/float64_attribute.go +++ b/resource/schema/float64_attribute.go @@ -247,6 +247,18 @@ func (a Float64Attribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Float64Attribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC and diff --git a/resource/schema/float64_attribute_test.go b/resource/schema/float64_attribute_test.go index 0a42d477..81d2ea52 100644 --- a/resource/schema/float64_attribute_test.go +++ b/resource/schema/float64_attribute_test.go @@ -580,3 +580,55 @@ func TestFloat64AttributeValidateImplementation(t *testing.T) { }) } } + +func TestFloat64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Float64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/int32_attribute.go b/resource/schema/int32_attribute.go index d3f97d60..102be037 100644 --- a/resource/schema/int32_attribute.go +++ b/resource/schema/int32_attribute.go @@ -247,6 +247,18 @@ func (a Int32Attribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int32Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int32Attribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC and diff --git a/resource/schema/int32_attribute_test.go b/resource/schema/int32_attribute_test.go index a151c940..2cd74f5d 100644 --- a/resource/schema/int32_attribute_test.go +++ b/resource/schema/int32_attribute_test.go @@ -580,3 +580,55 @@ func TestInt32AttributeValidateImplementation(t *testing.T) { }) } } + +func TestInt32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/int64_attribute.go b/resource/schema/int64_attribute.go index c65eb41f..3455b7a5 100644 --- a/resource/schema/int64_attribute.go +++ b/resource/schema/int64_attribute.go @@ -247,6 +247,18 @@ func (a Int64Attribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a Int64Attribute) IsOptionalForImport() bool { + return false +} + // ValidateImplementation contains logic for validating the // provider-defined implementation of the attribute to prevent unexpected // errors or panics. This logic runs during the GetProviderSchema RPC and diff --git a/resource/schema/int64_attribute_test.go b/resource/schema/int64_attribute_test.go index 1ce11e72..36b29096 100644 --- a/resource/schema/int64_attribute_test.go +++ b/resource/schema/int64_attribute_test.go @@ -580,3 +580,55 @@ func TestInt64AttributeValidateImplementation(t *testing.T) { }) } } + +func TestInt64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.Int64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/list_attribute.go b/resource/schema/list_attribute.go index 9c1536db..85dbc9a3 100644 --- a/resource/schema/list_attribute.go +++ b/resource/schema/list_attribute.go @@ -247,6 +247,18 @@ func (a ListAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListAttribute) IsOptionalForImport() bool { + return false +} + // ListDefaultValue returns the Default field value. func (a ListAttribute) ListDefaultValue() defaults.List { return a.Default diff --git a/resource/schema/list_attribute_test.go b/resource/schema/list_attribute_test.go index 1be15bbb..788ee84f 100644 --- a/resource/schema/list_attribute_test.go +++ b/resource/schema/list_attribute_test.go @@ -732,3 +732,55 @@ func TestListAttributeValidateImplementation(t *testing.T) { }) } } + +func TestListAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ListAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/list_nested_attribute.go b/resource/schema/list_nested_attribute.go index ee1845bb..74c739e9 100644 --- a/resource/schema/list_nested_attribute.go +++ b/resource/schema/list_nested_attribute.go @@ -278,6 +278,18 @@ func (a ListNestedAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ListNestedAttribute) IsOptionalForImport() bool { + return false +} + // ListDefaultValue returns the Default field value. func (a ListNestedAttribute) ListDefaultValue() defaults.List { return a.Default diff --git a/resource/schema/list_nested_attribute_test.go b/resource/schema/list_nested_attribute_test.go index 258d7cf4..e1eaa368 100644 --- a/resource/schema/list_nested_attribute_test.go +++ b/resource/schema/list_nested_attribute_test.go @@ -1016,3 +1016,55 @@ func TestListNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestListNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ListNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ListNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/map_attribute.go b/resource/schema/map_attribute.go index f76a295c..f045a6c8 100644 --- a/resource/schema/map_attribute.go +++ b/resource/schema/map_attribute.go @@ -250,6 +250,18 @@ func (a MapAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapAttribute) IsOptionalForImport() bool { + return false +} + // MapDefaultValue returns the Default field value. func (a MapAttribute) MapDefaultValue() defaults.Map { return a.Default diff --git a/resource/schema/map_attribute_test.go b/resource/schema/map_attribute_test.go index b6229335..ce5bfb7d 100644 --- a/resource/schema/map_attribute_test.go +++ b/resource/schema/map_attribute_test.go @@ -731,3 +731,55 @@ func TestMapAttributeValidateImplementation(t *testing.T) { }) } } + +func TestMapAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.MapAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/map_nested_attribute.go b/resource/schema/map_nested_attribute.go index db868f72..717140e6 100644 --- a/resource/schema/map_nested_attribute.go +++ b/resource/schema/map_nested_attribute.go @@ -278,6 +278,18 @@ func (a MapNestedAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a MapNestedAttribute) IsOptionalForImport() bool { + return false +} + // MapDefaultValue returns the Default field value. func (a MapNestedAttribute) MapDefaultValue() defaults.Map { return a.Default diff --git a/resource/schema/map_nested_attribute_test.go b/resource/schema/map_nested_attribute_test.go index 6f360d85..94d5ff59 100644 --- a/resource/schema/map_nested_attribute_test.go +++ b/resource/schema/map_nested_attribute_test.go @@ -1016,3 +1016,55 @@ func TestMapNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestMapNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestMapNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.MapNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.MapNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/number_attribute.go b/resource/schema/number_attribute.go index 8f367592..910b2f5a 100644 --- a/resource/schema/number_attribute.go +++ b/resource/schema/number_attribute.go @@ -233,6 +233,18 @@ func (a NumberAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a NumberAttribute) IsOptionalForImport() bool { + return false +} + // NumberDefaultValue returns the Default field value. func (a NumberAttribute) NumberDefaultValue() defaults.Number { return a.Default diff --git a/resource/schema/number_attribute_test.go b/resource/schema/number_attribute_test.go index 537bd1bf..02732422 100644 --- a/resource/schema/number_attribute_test.go +++ b/resource/schema/number_attribute_test.go @@ -585,3 +585,55 @@ func TestNumberAttributeValidateImplementation(t *testing.T) { }) } } + +func TestNumberAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.NumberAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.NumberAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/object_attribute.go b/resource/schema/object_attribute.go index 03f35aa0..896b2921 100644 --- a/resource/schema/object_attribute.go +++ b/resource/schema/object_attribute.go @@ -249,6 +249,18 @@ func (a ObjectAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a ObjectAttribute) IsOptionalForImport() bool { + return false +} + // ObjectDefaultValue returns the Default field value. func (a ObjectAttribute) ObjectDefaultValue() defaults.Object { return a.Default diff --git a/resource/schema/object_attribute_test.go b/resource/schema/object_attribute_test.go index 908c4839..fd6df413 100644 --- a/resource/schema/object_attribute_test.go +++ b/resource/schema/object_attribute_test.go @@ -785,3 +785,55 @@ func TestObjectAttributeValidateImplementation(t *testing.T) { }) } } + +func TestObjectAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ObjectAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestObjectAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.ObjectAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.ObjectAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/set_attribute.go b/resource/schema/set_attribute.go index b65656da..f33fd3df 100644 --- a/resource/schema/set_attribute.go +++ b/resource/schema/set_attribute.go @@ -235,6 +235,18 @@ func (a SetAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetAttribute) IsOptionalForImport() bool { + return false +} + // SetDefaultValue returns the Default field value. func (a SetAttribute) SetDefaultValue() defaults.Set { return a.Default diff --git a/resource/schema/set_attribute_test.go b/resource/schema/set_attribute_test.go index 2795fbde..268cb20b 100644 --- a/resource/schema/set_attribute_test.go +++ b/resource/schema/set_attribute_test.go @@ -715,3 +715,55 @@ func TestSetAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSetAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SetAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/set_nested_attribute.go b/resource/schema/set_nested_attribute.go index 5d408cf1..0d6eef59 100644 --- a/resource/schema/set_nested_attribute.go +++ b/resource/schema/set_nested_attribute.go @@ -260,6 +260,18 @@ func (a SetNestedAttribute) IsWriteOnly() bool { return false } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SetNestedAttribute) IsOptionalForImport() bool { + return false +} + // SetDefaultValue returns the Default field value. func (a SetNestedAttribute) SetDefaultValue() defaults.Set { return a.Default diff --git a/resource/schema/set_nested_attribute_test.go b/resource/schema/set_nested_attribute_test.go index a0210f41..406297a9 100644 --- a/resource/schema/set_nested_attribute_test.go +++ b/resource/schema/set_nested_attribute_test.go @@ -983,3 +983,55 @@ func TestSetNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSetNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSetNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SetNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SetNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/single_nested_attribute.go b/resource/schema/single_nested_attribute.go index 12cab980..4ad79ffe 100644 --- a/resource/schema/single_nested_attribute.go +++ b/resource/schema/single_nested_attribute.go @@ -286,6 +286,18 @@ func (a SingleNestedAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a SingleNestedAttribute) IsOptionalForImport() bool { + return false +} + // ObjectDefaultValue returns the Default field value. func (a SingleNestedAttribute) ObjectDefaultValue() defaults.Object { return a.Default diff --git a/resource/schema/single_nested_attribute_test.go b/resource/schema/single_nested_attribute_test.go index b03725b7..259102bf 100644 --- a/resource/schema/single_nested_attribute_test.go +++ b/resource/schema/single_nested_attribute_test.go @@ -918,3 +918,55 @@ func TestSingleNestedAttributeValidateImplementation(t *testing.T) { }) } } + +func TestSingleNestedAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SingleNestedAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSingleNestedAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.SingleNestedAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.SingleNestedAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/schema/string_attribute.go b/resource/schema/string_attribute.go index 69332701..50aad8a0 100644 --- a/resource/schema/string_attribute.go +++ b/resource/schema/string_attribute.go @@ -229,6 +229,18 @@ func (a StringAttribute) IsWriteOnly() bool { return a.WriteOnly } +// IsRequiredForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsRequiredForImport() bool { + return false +} + +// IsOptionalForImport returns false as this behavior is only revelant +// for managed resource identity schema attributes. +func (a StringAttribute) IsOptionalForImport() bool { + return false +} + // StringDefaultValue returns the Default field value. func (a StringAttribute) StringDefaultValue() defaults.String { return a.Default diff --git a/resource/schema/string_attribute_test.go b/resource/schema/string_attribute_test.go index 6bf70eda..c1dffa2f 100644 --- a/resource/schema/string_attribute_test.go +++ b/resource/schema/string_attribute_test.go @@ -580,3 +580,55 @@ func TestStringAttributeValidateImplementation(t *testing.T) { }) } } + +func TestStringAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.StringAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: schema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute schema.StringAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: schema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} From 167b8244f34c643151298c50ad7a2be845d237d6 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Mon, 24 Feb 2025 11:39:51 -0500 Subject: [PATCH 08/14] add to final internal/testing/testschema --- internal/testing/testschema/attribute.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/testing/testschema/attribute.go b/internal/testing/testschema/attribute.go index 979db68e..3f4e7470 100644 --- a/internal/testing/testschema/attribute.go +++ b/internal/testing/testschema/attribute.go @@ -21,6 +21,8 @@ type Attribute struct { Required bool Sensitive bool WriteOnly bool + RequiredForImport bool + OptionalForImport bool Type attr.Type } @@ -84,3 +86,13 @@ func (a Attribute) IsSensitive() bool { func (a Attribute) IsWriteOnly() bool { return a.WriteOnly } + +// IsRequiredForImport satisfies the fwschema.Attribute interface. +func (a Attribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport satisfies the fwschema.Attribute interface. +func (a Attribute) IsOptionalForImport() bool { + return a.OptionalForImport +} From 77ef5798e5ba9d31a7d1d4b2c43fbc4bdbf677be Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Thu, 6 Mar 2025 17:26:28 -0500 Subject: [PATCH 09/14] get resource identity schema implementation --- .../fromproto5/getresourceidentityschemas.go | 23 + .../getresourceidentityschemas_test.go | 44 + internal/fwserver/server.go | 45 + .../server_getresourceidentityschemas.go | 34 + .../server_getresourceidentityschemas_test.go | 229 +++++ .../server_getresourceidentityschemas.go | 27 + .../server_getresourceidentityschemas_test.go | 218 +++++ .../server_upgraderesourceidentity.go | 15 + .../testprovider/resourcewithidentity.go | 30 + .../toproto5/getresourceidentityschemas.go | 42 + .../getresourceidentityschemas_test.go | 367 +++++++ internal/toproto5/identity_schema.go | 52 + .../toproto5/identity_schema_attribute.go | 43 + .../identity_schema_attribute_test.go | 257 +++++ internal/toproto5/identity_schema_test.go | 138 +++ resource/identity_schema.go | 27 + resource/identityschema/attribute.go | 33 + resource/identityschema/bool_attribute.go | 127 +++ .../identityschema/bool_attribute_test.go | 431 +++++++++ resource/identityschema/doc.go | 11 + resource/identityschema/float32_attribute.go | 130 +++ .../identityschema/float32_attribute_test.go | 431 +++++++++ resource/identityschema/float64_attribute.go | 130 +++ .../identityschema/float64_attribute_test.go | 431 +++++++++ resource/identityschema/int32_attribute.go | 130 +++ .../identityschema/int32_attribute_test.go | 431 +++++++++ resource/identityschema/int64_attribute.go | 130 +++ .../identityschema/int64_attribute_test.go | 431 +++++++++ resource/identityschema/list_attribute.go | 173 ++++ .../identityschema/list_attribute_test.go | 520 ++++++++++ resource/identityschema/number_attribute.go | 131 +++ .../identityschema/number_attribute_test.go | 431 +++++++++ resource/identityschema/schema.go | 147 +++ resource/identityschema/schema_test.go | 915 ++++++++++++++++++ resource/identityschema/string_attribute.go | 127 +++ .../identityschema/string_attribute_test.go | 431 +++++++++ resource/resource.go | 10 + 37 files changed, 7322 insertions(+) create mode 100644 internal/fromproto5/getresourceidentityschemas.go create mode 100644 internal/fromproto5/getresourceidentityschemas_test.go create mode 100644 internal/fwserver/server_getresourceidentityschemas.go create mode 100644 internal/fwserver/server_getresourceidentityschemas_test.go create mode 100644 internal/proto5server/server_getresourceidentityschemas.go create mode 100644 internal/proto5server/server_getresourceidentityschemas_test.go create mode 100644 internal/proto5server/server_upgraderesourceidentity.go create mode 100644 internal/testing/testprovider/resourcewithidentity.go create mode 100644 internal/toproto5/getresourceidentityschemas.go create mode 100644 internal/toproto5/getresourceidentityschemas_test.go create mode 100644 internal/toproto5/identity_schema.go create mode 100644 internal/toproto5/identity_schema_attribute.go create mode 100644 internal/toproto5/identity_schema_attribute_test.go create mode 100644 internal/toproto5/identity_schema_test.go create mode 100644 resource/identity_schema.go create mode 100644 resource/identityschema/attribute.go create mode 100644 resource/identityschema/bool_attribute.go create mode 100644 resource/identityschema/bool_attribute_test.go create mode 100644 resource/identityschema/doc.go create mode 100644 resource/identityschema/float32_attribute.go create mode 100644 resource/identityschema/float32_attribute_test.go create mode 100644 resource/identityschema/float64_attribute.go create mode 100644 resource/identityschema/float64_attribute_test.go create mode 100644 resource/identityschema/int32_attribute.go create mode 100644 resource/identityschema/int32_attribute_test.go create mode 100644 resource/identityschema/int64_attribute.go create mode 100644 resource/identityschema/int64_attribute_test.go create mode 100644 resource/identityschema/list_attribute.go create mode 100644 resource/identityschema/list_attribute_test.go create mode 100644 resource/identityschema/number_attribute.go create mode 100644 resource/identityschema/number_attribute_test.go create mode 100644 resource/identityschema/schema.go create mode 100644 resource/identityschema/schema_test.go create mode 100644 resource/identityschema/string_attribute.go create mode 100644 resource/identityschema/string_attribute_test.go diff --git a/internal/fromproto5/getresourceidentityschemas.go b/internal/fromproto5/getresourceidentityschemas.go new file mode 100644 index 00000000..a5ca3b16 --- /dev/null +++ b/internal/fromproto5/getresourceidentityschemas.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetResourceIdentitySchemasRequest returns the *fwserver.GetResourceIdentitySchemasRequest +// equivalent of a *tfprotov5.GetResourceIdentitySchemasRequest. +func GetResourceIdentitySchemasRequest(ctx context.Context, proto5 *tfprotov5.GetResourceIdentitySchemasRequest) *fwserver.GetResourceIdentitySchemasRequest { + if proto5 == nil { + return nil + } + + fw := &fwserver.GetResourceIdentitySchemasRequest{} + + return fw +} diff --git a/internal/fromproto5/getresourceidentityschemas_test.go b/internal/fromproto5/getresourceidentityschemas_test.go new file mode 100644 index 00000000..e3143c24 --- /dev/null +++ b/internal/fromproto5/getresourceidentityschemas_test.go @@ -0,0 +1,44 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto5_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +func TestGetResourceIdentitySchemasRequest(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + input *tfprotov5.GetResourceIdentitySchemasRequest + expected *fwserver.GetResourceIdentitySchemasRequest + }{ + "nil": { + input: nil, + expected: nil, + }, + "empty": { + input: &tfprotov5.GetResourceIdentitySchemasRequest{}, + expected: &fwserver.GetResourceIdentitySchemasRequest{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := fromproto5.GetResourceIdentitySchemasRequest(context.Background(), testCase.input) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/internal/fwserver/server.go b/internal/fwserver/server.go index b6f2bc85..22723f9f 100644 --- a/internal/fwserver/server.go +++ b/internal/fwserver/server.go @@ -689,3 +689,48 @@ func (s *Server) ResourceSchemas(ctx context.Context) (map[string]fwschema.Schem return resourceSchemas, diags } + +// ResourceIdentitySchemas returns a map of Resource Identity Schemas for the +// GetResourceIdentitySchemas RPC without caching since not all schemas are guaranteed to +// be necessary for later provider operations. The schema implementations are +// also validated. +func (s *Server) ResourceIdentitySchemas(ctx context.Context) (map[string]fwschema.Schema, diag.Diagnostics) { + resourceIdentitySchemas := make(map[string]fwschema.Schema) + + resourceFuncs, diags := s.ResourceFuncs(ctx) + + for typeName, resourceFunc := range resourceFuncs { + r := resourceFunc() + + rWithIdentity, ok := r.(resource.ResourceWithIdentity) + if !ok { + // Resource identity support is optional, so we can skip resources that don't implement it. + continue + } + + identitySchemaReq := resource.IdentitySchemaRequest{} + identitySchemaResp := resource.IdentitySchemaResponse{} + + logging.FrameworkTrace(ctx, "Calling provider defined Resource IdentitySchema method", map[string]interface{}{logging.KeyResourceType: typeName}) + rWithIdentity.IdentitySchema(ctx, identitySchemaReq, &identitySchemaResp) + logging.FrameworkTrace(ctx, "Called provider defined Resource IdentitySchema method", map[string]interface{}{logging.KeyResourceType: typeName}) + + diags.Append(identitySchemaResp.Diagnostics...) + + if identitySchemaResp.Diagnostics.HasError() { + continue + } + + validateDiags := identitySchemaResp.IdentitySchema.ValidateImplementation(ctx) + + diags.Append(validateDiags...) + + if validateDiags.HasError() { + continue + } + + resourceIdentitySchemas[typeName] = identitySchemaResp.IdentitySchema + } + + return resourceIdentitySchemas, diags +} diff --git a/internal/fwserver/server_getresourceidentityschemas.go b/internal/fwserver/server_getresourceidentityschemas.go new file mode 100644 index 00000000..511c6bb0 --- /dev/null +++ b/internal/fwserver/server_getresourceidentityschemas.go @@ -0,0 +1,34 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// GetResourceIdentitySchemasRequest is the framework server request for the +// GetResourceIdentitySchemas RPC. +type GetResourceIdentitySchemasRequest struct{} + +// GetResourceIdentitySchemasResponse is the framework server response for the +// GetResourceIdentitySchemas RPC. +type GetResourceIdentitySchemasResponse struct { + IdentitySchemas map[string]fwschema.Schema + Diagnostics diag.Diagnostics +} + +// GetResourceIdentitySchemas implements the framework server GetResourceIdentitySchemas RPC. +func (s *Server) GetResourceIdentitySchemas(ctx context.Context, req *GetResourceIdentitySchemasRequest, resp *GetResourceIdentitySchemasResponse) { + identitySchemas, diags := s.ResourceIdentitySchemas(ctx) + resp.Diagnostics.Append(diags...) + + if resp.Diagnostics.HasError() { + return + } + + resp.IdentitySchemas = identitySchemas +} diff --git a/internal/fwserver/server_getresourceidentityschemas_test.go b/internal/fwserver/server_getresourceidentityschemas_test.go new file mode 100644 index 00000000..c780a7ff --- /dev/null +++ b/internal/fwserver/server_getresourceidentityschemas_test.go @@ -0,0 +1,229 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fwserver_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testprovider" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" +) + +func TestServerGetResourceIdentitySchemas(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + server *fwserver.Server + request *fwserver.GetResourceIdentitySchemasRequest + expectedResponse *fwserver.GetResourceIdentitySchemasResponse + }{ + "empty-provider": { + server: &fwserver.Server{ + Provider: &testprovider.Provider{}, + }, + expectedResponse: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{}, + }, + }, + "resource-no-identity-schemas": { + server: &fwserver.Server{ + Provider: &testprovider.Provider{ + ResourcesMethod: func(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource1" + }, + } + }, + func() resource.Resource { + return &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource2" + }, + } + }, + } + }, + }, + }, + request: &fwserver.GetResourceIdentitySchemasRequest{}, + expectedResponse: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{}, + }, + }, + "resource-identity-schemas": { + server: &fwserver.Server{ + Provider: &testprovider.Provider{ + ResourcesMethod: func(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource1" + }, + } + }, + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource2" + }, + }, + IdentitySchemaMethod: func(ctx context.Context, req resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test2": identityschema.StringAttribute{ + RequiredForImport: true, + }, + }, + } + }, + } + }, + func() resource.Resource { + return &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource3" + }, + } + }, + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource4" + }, + }, + IdentitySchemaMethod: func(ctx context.Context, req resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test4": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + } + }, + } + }, + } + }, + }, + }, + request: &fwserver.GetResourceIdentitySchemasRequest{}, + expectedResponse: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource2": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test2": identityschema.StringAttribute{ + RequiredForImport: true, + }, + }, + }, + "test_resource4": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test4": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + }, + "resource-identity-schemas-invalid-attribute-name": { + server: &fwserver.Server{ + Provider: &testprovider.Provider{ + ResourcesMethod: func(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource1" + }, + } + }, + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource2" + }, + }, + IdentitySchemaMethod: func(ctx context.Context, req resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "$": identityschema.StringAttribute{ + RequiredForImport: true, + }, + }, + } + }, + } + }, + func() resource.Resource { + return &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource3" + }, + } + }, + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource4" + }, + }, + IdentitySchemaMethod: func(ctx context.Context, req resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test4": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + } + }, + } + }, + } + }, + }, + }, + request: &fwserver.GetResourceIdentitySchemasRequest{}, + expectedResponse: &fwserver.GetResourceIdentitySchemasResponse{ + Diagnostics: diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Invalid Attribute/Block Name", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + "\"$\" at schema path \"$\" is an invalid attribute/block name. "+ + "Names must only contain lowercase alphanumeric characters (a-z, 0-9) and underscores (_).", + ), + }, + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + response := &fwserver.GetResourceIdentitySchemasResponse{} + testCase.server.GetResourceIdentitySchemas(context.Background(), testCase.request, response) + + if diff := cmp.Diff(response, testCase.expectedResponse); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/internal/proto5server/server_getresourceidentityschemas.go b/internal/proto5server/server_getresourceidentityschemas.go new file mode 100644 index 00000000..97ecb47e --- /dev/null +++ b/internal/proto5server/server_getresourceidentityschemas.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto5" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetResourceIdentitySchemas satisfies the tfprotov5.ProviderServer interface. +func (s *Server) GetResourceIdentitySchemas(ctx context.Context, proto5Req *tfprotov5.GetResourceIdentitySchemasRequest) (*tfprotov5.GetResourceIdentitySchemasResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwReq := fromproto5.GetResourceIdentitySchemasRequest(ctx, proto5Req) + fwResp := &fwserver.GetResourceIdentitySchemasResponse{} + + s.FrameworkServer.GetResourceIdentitySchemas(ctx, fwReq, fwResp) + + return toproto5.GetResourceIdentitySchemasResponse(ctx, fwResp), nil +} diff --git a/internal/proto5server/server_getresourceidentityschemas_test.go b/internal/proto5server/server_getresourceidentityschemas_test.go new file mode 100644 index 00000000..e054e2e9 --- /dev/null +++ b/internal/proto5server/server_getresourceidentityschemas_test.go @@ -0,0 +1,218 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "bytes" + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testprovider" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-plugin-log/tfsdklogtest" +) + +func TestServerGetResourceIdentitySchemas(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + server *Server + request *tfprotov5.GetResourceIdentitySchemasRequest + expectedError error + expectedResponse *tfprotov5.GetResourceIdentitySchemasResponse + }{ + "resource-identity-schemas": { + server: &Server{ + FrameworkServer: fwserver.Server{ + Provider: &testprovider.Provider{ + ResourcesMethod: func(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource1" + }, + }, + IdentitySchemaMethod: func(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test1": identityschema.StringAttribute{ + RequiredForImport: true, + }, + }, + } + }, + } + }, + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource2" + }, + }, + IdentitySchemaMethod: func(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test2": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + } + }, + } + }, + } + }, + }, + }, + }, + request: &tfprotov5.GetResourceIdentitySchemasRequest{}, + expectedResponse: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource1": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test1", + RequiredForImport: true, + Type: tftypes.String, + }, + }, + }, + "test_resource2": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test2", + RequiredForImport: true, + Type: tftypes.Bool, + }, + }, + }, + }, + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.server.GetResourceIdentitySchemas(context.Background(), new(tfprotov5.GetResourceIdentitySchemasRequest)) + + if diff := cmp.Diff(testCase.expectedError, err); diff != "" { + t.Errorf("unexpected error difference: %s", diff) + } + + if diff := cmp.Diff(testCase.expectedResponse, got); diff != "" { + t.Errorf("unexpected response difference: %s", diff) + } + }) + } +} + +func TestServerGetResourceIdentitySchemas_logging(t *testing.T) { + t.Parallel() + + var output bytes.Buffer + + ctx := tfsdklogtest.RootLogger(context.Background(), &output) + ctx = logging.InitContext(ctx) + + testServer := &Server{ + FrameworkServer: fwserver.Server{ + Provider: &testprovider.Provider{ + ResourcesMethod: func(ctx context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "examplecloud_thing" + }, + }, + IdentitySchemaMethod: func(ctx context.Context, req resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{} + }, + } + }, + } + }, + }, + }, + } + + _, err := testServer.GetResourceIdentitySchemas(ctx, new(tfprotov5.GetResourceIdentitySchemasRequest)) + + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + entries, err := tfsdklogtest.MultilineJSONDecode(&output) + + if err != nil { + t.Fatalf("unable to read multiple line JSON: %s", err) + } + + expectedEntries := []map[string]interface{}{ + { + "@level": "trace", + "@message": "Checking ResourceTypes lock", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Checking ProviderTypeName lock", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Calling provider defined Provider Metadata", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Called provider defined Provider Metadata", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Calling provider defined Provider Resources", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Called provider defined Provider Resources", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Found resource type", + "@module": "sdk.framework", + "tf_resource_type": "examplecloud_thing", + }, + { + "@level": "trace", + "@message": "Calling provider defined Resource IdentitySchema method", + "@module": "sdk.framework", + "tf_resource_type": "examplecloud_thing", + }, + { + "@level": "trace", + "@message": "Called provider defined Resource IdentitySchema method", + "@module": "sdk.framework", + "tf_resource_type": "examplecloud_thing", + }, + } + + if diff := cmp.Diff(entries, expectedEntries); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/internal/proto5server/server_upgraderesourceidentity.go b/internal/proto5server/server_upgraderesourceidentity.go new file mode 100644 index 00000000..bbd9a0a1 --- /dev/null +++ b/internal/proto5server/server_upgraderesourceidentity.go @@ -0,0 +1,15 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto5server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// UpgradeResourceIdentity satisfies the tfprotov5.ProviderServer interface. +func (s *Server) UpgradeResourceIdentity(ctx context.Context, proto5Req *tfprotov5.UpgradeResourceIdentityRequest) (*tfprotov5.UpgradeResourceIdentityResponse, error) { + panic("unimplemented") // TODO: implement +} diff --git a/internal/testing/testprovider/resourcewithidentity.go b/internal/testing/testprovider/resourcewithidentity.go new file mode 100644 index 00000000..514b979d --- /dev/null +++ b/internal/testing/testprovider/resourcewithidentity.go @@ -0,0 +1,30 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package testprovider + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/resource" +) + +var _ resource.Resource = &ResourceWithIdentity{} +var _ resource.ResourceWithIdentity = &ResourceWithIdentity{} + +// Declarative resource.ResourceWithIdentity for unit testing. +type ResourceWithIdentity struct { + *Resource + + // ResourceWithIdentity interface methods + IdentitySchemaMethod func(context.Context, resource.IdentitySchemaRequest, *resource.IdentitySchemaResponse) +} + +// IdentitySchema implements resource.ResourceWithIdentity. +func (p *ResourceWithIdentity) IdentitySchema(ctx context.Context, req resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + if p.IdentitySchemaMethod == nil { + return + } + + p.IdentitySchemaMethod(ctx, req, resp) +} diff --git a/internal/toproto5/getresourceidentityschemas.go b/internal/toproto5/getresourceidentityschemas.go new file mode 100644 index 00000000..4080a171 --- /dev/null +++ b/internal/toproto5/getresourceidentityschemas.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" +) + +// GetResourceIdentitySchemasResponse returns the *tfprotov5.GetResourceIdentitySchemasResponse +// equivalent of a *fwserver.GetResourceIdentitySchemasResponse. +func GetResourceIdentitySchemasResponse(ctx context.Context, fw *fwserver.GetResourceIdentitySchemasResponse) *tfprotov5.GetResourceIdentitySchemasResponse { + if fw == nil { + return nil + } + + protov5 := &tfprotov5.GetResourceIdentitySchemasResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + IdentitySchemas: make(map[string]*tfprotov5.ResourceIdentitySchema, len(fw.IdentitySchemas)), + } + + var err error + + for resourceType, identitySchema := range fw.IdentitySchemas { + protov5.IdentitySchemas[resourceType], err = IdentitySchema(ctx, identitySchema) + + if err != nil { + protov5.Diagnostics = append(protov5.Diagnostics, &tfprotov5.Diagnostic{ + Severity: tfprotov5.DiagnosticSeverityError, + Summary: "Error converting resource identity schema", + Detail: "The identity schema for the resource \"" + resourceType + "\" couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov5 + } + } + + return protov5 +} diff --git a/internal/toproto5/getresourceidentityschemas_test.go b/internal/toproto5/getresourceidentityschemas_test.go new file mode 100644 index 00000000..0dff8745 --- /dev/null +++ b/internal/toproto5/getresourceidentityschemas_test.go @@ -0,0 +1,367 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestGetResourceIdentitySchemasResponse(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + input *fwserver.GetResourceIdentitySchemasResponse + expected *tfprotov5.GetResourceIdentitySchemasResponse + }{ + "nil": { + input: nil, + expected: nil, + }, + "resource-identity-identity-multiple-resources": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource_1": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + }, + "test_resource_2": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource_1": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + RequiredForImport: true, + Name: "test_attribute", + Type: tftypes.Bool, + }, + }, + }, + "test_resource_2": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + RequiredForImport: true, + Name: "test_attribute", + Type: tftypes.Bool, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-optionalforimport": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + OptionalForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + OptionalForImport: true, + Type: tftypes.Bool, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-requiredforimport": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + Type: tftypes.Bool, + RequiredForImport: true, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-bool": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Bool, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-float32": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.Float32Attribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-float64": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.Float64Attribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-int32": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.Int32Attribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-int64": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.Int64Attribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-list-string": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.ListAttribute{ + RequiredForImport: true, + ElementType: types.StringType, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.List{ + ElementType: tftypes.String, + }, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-number": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.NumberAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-string": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.StringAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.String, + }, + }, + }, + }, + }, + }, + "resource-identity-version": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Version: 123, + }, + }, + }, + expected: &tfprotov5.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov5.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{}, + Version: 123, + }, + }, + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := toproto5.GetResourceIdentitySchemasResponse(context.Background(), testCase.input) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/internal/toproto5/identity_schema.go b/internal/toproto5/identity_schema.go new file mode 100644 index 00000000..003dbf15 --- /dev/null +++ b/internal/toproto5/identity_schema.go @@ -0,0 +1,52 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + "sort" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// IdentitySchema returns the *tfprotov5.ResourceIdentitySchema equivalent of a Schema. +func IdentitySchema(ctx context.Context, s fwschema.Schema) (*tfprotov5.ResourceIdentitySchema, error) { + if s == nil { + return nil, nil + } + + result := &tfprotov5.ResourceIdentitySchema{ + Version: s.GetVersion(), + } + + attrs := make([]*tfprotov5.ResourceIdentitySchemaAttribute, 0) + + for name, attr := range s.GetAttributes() { + a, err := IdentitySchemaAttribute(ctx, name, tftypes.NewAttributePath().WithAttributeName(name), attr) + + if err != nil { + return nil, err + } + + attrs = append(attrs, a) + } + + sort.Slice(attrs, func(i, j int) bool { + if attrs[i] == nil { + return true + } + + if attrs[j] == nil { + return false + } + + return attrs[i].Name < attrs[j].Name + }) + + result.IdentityAttributes = attrs + + return result, nil +} diff --git a/internal/toproto5/identity_schema_attribute.go b/internal/toproto5/identity_schema_attribute.go new file mode 100644 index 00000000..01714f7a --- /dev/null +++ b/internal/toproto5/identity_schema_attribute.go @@ -0,0 +1,43 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// IdentitySchemaAttribute returns the *tfprotov5.ResourceIdentitySchemaAttribute equivalent of an +// Attribute. Errors will be tftypes.AttributePathErrors based on `path`. `name` is the name of the attribute. +func IdentitySchemaAttribute(ctx context.Context, name string, path *tftypes.AttributePath, a fwschema.Attribute) (*tfprotov5.ResourceIdentitySchemaAttribute, error) { + if _, ok := a.(fwschema.NestedAttribute); ok { + return nil, path.NewErrorf("identity schemas and protocol version 5 don't support NestedAttribute") + } + + if a.GetType() == nil { + return nil, path.NewErrorf("must have Type set") + } + + if !a.IsRequiredForImport() && !a.IsOptionalForImport() { + return nil, path.NewErrorf("must have RequiredForImport or OptionalForImport set") + } + + identitySchemaAttribute := &tfprotov5.ResourceIdentitySchemaAttribute{ + Name: name, + RequiredForImport: a.IsRequiredForImport(), + OptionalForImport: a.IsOptionalForImport(), + Type: a.GetType().TerraformType(ctx), + + // Unlike other schema attributes, identity attributes only have a single description field which + // is assumed to be markdown. Both a.GetDescription() and a.GetMarkdownDescription() will return + // the same string, so we just chose one here. + Description: a.GetDescription(), + } + + return identitySchemaAttribute, nil +} diff --git a/internal/toproto5/identity_schema_attribute_test.go b/internal/toproto5/identity_schema_attribute_test.go new file mode 100644 index 00000000..28704ba5 --- /dev/null +++ b/internal/toproto5/identity_schema_attribute_test.go @@ -0,0 +1,257 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +func TestIdentitySchemaAttribute(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + attr fwschema.Attribute + path *tftypes.AttributePath + expected *tfprotov5.ResourceIdentitySchemaAttribute + expectedErr string + } + + tests := map[string]testCase{ + "description": { + name: "string", + attr: testschema.Attribute{ + Type: types.StringType, + RequiredForImport: true, + Description: "A string attribute", + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov5.ResourceIdentitySchemaAttribute{ + Name: "string", + Type: tftypes.String, + RequiredForImport: true, + Description: "A string attribute", + }, + }, + "attr-string": { + name: "string", + attr: testschema.Attribute{ + Type: types.StringType, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov5.ResourceIdentitySchemaAttribute{ + Name: "string", + Type: tftypes.String, + RequiredForImport: true, + }, + }, + "attr-bool": { + name: "bool", + attr: testschema.Attribute{ + Type: types.BoolType, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov5.ResourceIdentitySchemaAttribute{ + Name: "bool", + Type: tftypes.Bool, + RequiredForImport: true, + }, + }, + "attr-number": { + name: "number", + attr: testschema.Attribute{ + Type: types.NumberType, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov5.ResourceIdentitySchemaAttribute{ + Name: "number", + Type: tftypes.Number, + RequiredForImport: true, + }, + }, + "attr-list": { + name: "list", + attr: testschema.Attribute{ + Type: types.ListType{ElemType: types.NumberType}, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov5.ResourceIdentitySchemaAttribute{ + Name: "list", + Type: tftypes.List{ElementType: tftypes.Number}, + RequiredForImport: true, + }, + }, + "requiredforimport": { + name: "string", + attr: testschema.Attribute{ + Type: types.StringType, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov5.ResourceIdentitySchemaAttribute{ + Name: "string", + Type: tftypes.String, + RequiredForImport: true, + }, + }, + "optionalforimport": { + name: "string", + attr: testschema.Attribute{ + Type: types.StringType, + OptionalForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov5.ResourceIdentitySchemaAttribute{ + Name: "string", + Type: tftypes.String, + OptionalForImport: true, + }, + }, + "nested-attr-single-error": { + name: "single_nested", + attr: testschema.NestedAttribute{ + NestedObject: testschema.NestedAttributeObject{ + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + Optional: true, + }, + "computed": testschema.Attribute{ + Type: types.NumberType, + Computed: true, + Sensitive: true, + }, + }, + }, + NestingMode: fwschema.NestingModeSingle, + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "identity schemas and protocol version 5 don't support NestedAttribute", + }, + "nested-attr-list-error": { + name: "list_nested", + attr: testschema.NestedAttribute{ + NestedObject: testschema.NestedAttributeObject{ + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + Optional: true, + }, + "computed": testschema.Attribute{ + Type: types.NumberType, + Computed: true, + Sensitive: true, + }, + }, + }, + NestingMode: fwschema.NestingModeList, + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "identity schemas and protocol version 5 don't support NestedAttribute", + }, + "nested-attr-map-error": { + name: "map_nested", + attr: testschema.NestedAttribute{ + NestedObject: testschema.NestedAttributeObject{ + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + Optional: true, + }, + "computed": testschema.Attribute{ + Type: types.NumberType, + Computed: true, + Sensitive: true, + }, + }, + }, + NestingMode: fwschema.NestingModeMap, + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "identity schemas and protocol version 5 don't support NestedAttribute", + }, + "nested-attr-set-error": { + name: "set_nested", + attr: testschema.NestedAttribute{ + NestedObject: testschema.NestedAttributeObject{ + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + Optional: true, + }, + "computed": testschema.Attribute{ + Type: types.NumberType, + Computed: true, + Sensitive: true, + }, + }, + }, + NestingMode: fwschema.NestingModeSet, + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "identity schemas and protocol version 5 don't support NestedAttribute", + }, + "attr-unset": { + name: "whoops", + attr: testschema.Attribute{ + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "must have Type set", + }, + "missing-requiredforimport-and-optionalforimport": { + name: "whoops", + attr: testschema.Attribute{ + Type: types.StringType, + }, + path: tftypes.NewAttributePath(), + expectedErr: "must have RequiredForImport or OptionalForImport set", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := toproto5.IdentitySchemaAttribute(context.Background(), tc.name, tc.path, tc.attr) + if err != nil { + if tc.expectedErr == "" { + t.Errorf("Unexpected error: %s", err) + return + } + if err.Error() != tc.expectedErr { + t.Errorf("Expected error to be %q, got %q", tc.expectedErr, err.Error()) + return + } + // got expected error + return + } + if err == nil && tc.expectedErr != "" { + t.Errorf("Expected error to be %q, got nil", tc.expectedErr) + return + } + if diff := cmp.Diff(got, tc.expected); diff != "" { + t.Errorf("Unexpected diff (+wanted, -got): %s", diff) + return + } + }) + } +} diff --git a/internal/toproto5/identity_schema_test.go b/internal/toproto5/identity_schema_test.go new file mode 100644 index 00000000..8388c4c1 --- /dev/null +++ b/internal/toproto5/identity_schema_test.go @@ -0,0 +1,138 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto5_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto5" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tfprotov5" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +func TestIdentitySchema(t *testing.T) { + t.Parallel() + + type testCase struct { + input fwschema.Schema + expected *tfprotov5.ResourceIdentitySchema + expectedErr string + } + + tests := map[string]testCase{ + "nil": { + input: nil, + expected: nil, + }, + "empty-val": { + input: testschema.Schema{}, + expected: &tfprotov5.ResourceIdentitySchema{ + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{}, + Version: 0, + }, + }, + "basic-attrs": { + input: testschema.Schema{ + Version: 1, + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + RequiredForImport: true, + }, + "number": testschema.Attribute{ + Type: types.NumberType, + OptionalForImport: true, + }, + "bool": testschema.Attribute{ + Type: types.BoolType, + OptionalForImport: true, + }, + }, + }, + expected: &tfprotov5.ResourceIdentitySchema{ + Version: 1, + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "bool", + Type: tftypes.Bool, + OptionalForImport: true, + }, + { + Name: "number", + Type: tftypes.Number, + OptionalForImport: true, + }, + { + Name: "string", + Type: tftypes.String, + RequiredForImport: true, + }, + }, + }, + }, + "complex-attrs": { + input: testschema.Schema{ + Version: 2, + Attributes: map[string]fwschema.Attribute{ + "list_of_string": testschema.Attribute{ + Type: types.ListType{ElemType: types.StringType}, + RequiredForImport: true, + }, + "list_of_bool": testschema.Attribute{ + Type: types.ListType{ElemType: types.BoolType}, + RequiredForImport: true, + }, + }, + }, + expected: &tfprotov5.ResourceIdentitySchema{ + Version: 2, + IdentityAttributes: []*tfprotov5.ResourceIdentitySchemaAttribute{ + { + Name: "list_of_bool", + Type: tftypes.List{ElementType: tftypes.Bool}, + RequiredForImport: true, + }, + { + Name: "list_of_string", + Type: tftypes.List{ElementType: tftypes.String}, + RequiredForImport: true, + }, + }, + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := toproto5.IdentitySchema(context.Background(), tc.input) + if err != nil { + if tc.expectedErr == "" { + t.Errorf("Unexpected error: %s", err) + return + } + if err.Error() != tc.expectedErr { + t.Errorf("Expected error to be %q, got %q", tc.expectedErr, err.Error()) + return + } + // got expected error + return + } + if err == nil && tc.expectedErr != "" { + t.Errorf("Expected error to be %q, got nil", tc.expectedErr) + return + } + if diff := cmp.Diff(got, tc.expected); diff != "" { + t.Errorf("Unexpected diff (+wanted, -got): %s", diff) + return + } + }) + } +} diff --git a/resource/identity_schema.go b/resource/identity_schema.go new file mode 100644 index 00000000..812173d2 --- /dev/null +++ b/resource/identity_schema.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package resource + +import ( + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" +) + +// IdentitySchemaRequest represents a request for the Resource to return its identity schema. +// An instance of this request struct is supplied as an argument to the +// Resource type IdentitySchema method. +type IdentitySchemaRequest struct{} + +// IdentitySchemaResponse represents a response to a SchemaRequest. An instance of this +// response struct is supplied as an argument to the Resource type IdentitySchema +// method. +type IdentitySchemaResponse struct { + // IdentitySchema is the schema of the resource identity. + IdentitySchema identityschema.Schema + + // Diagnostics report errors or warnings related to retrieving the resource + // identity schema. An empty slice indicates success, with no warnings + // or errors generated. + Diagnostics diag.Diagnostics +} diff --git a/resource/identityschema/attribute.go b/resource/identityschema/attribute.go new file mode 100644 index 00000000..06ef9315 --- /dev/null +++ b/resource/identityschema/attribute.go @@ -0,0 +1,33 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// Attribute define a value field inside the Schema. Implementations in this +// package include: +// - BoolAttribute +// - Float32Attribute +// - Float64Attribute +// - Int32Attribute +// - Int64Attribute +// - ListAttribute +// - NumberAttribute +// - StringAttribute +// +// The available attribute types for a resource identity schema are intentionally +// limited. Nested attributes and blocks are not supported in identity schemas, +// as well as ListAttribute definitions can only have primitive element types of: +// - types.BoolType +// - types.Float32Type +// - types.Float64Type +// - types.Int32Type +// - types.Int64Type +// - types.NumberType +// - types.StringType +type Attribute interface { + fwschema.Attribute +} diff --git a/resource/identityschema/bool_attribute.go b/resource/identityschema/bool_attribute.go new file mode 100644 index 00000000..c17ae954 --- /dev/null +++ b/resource/identityschema/bool_attribute.go @@ -0,0 +1,127 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = BoolAttribute{} +) + +// BoolAttribute represents a schema attribute that is a boolean. When +// retrieving the value for this attribute, use types.Bool as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a boolean or directly via the true/false keywords. +// +// example_attribute = true +type BoolAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.BoolType. When retrieving data, the basetypes.BoolValuable + // associated with this custom type must be used in place of types.Bool. + CustomType basetypes.BoolTypable + + // RequiredForImport indicates whether the practitioner must enter a value for + // this attribute when importing a managed resource by this identity. + // RequiredForImport and OptionalForImport cannot both be true. + RequiredForImport bool + + // OptionalForImport indicates whether the practitioner can choose to enter a value + // for this attribute when importing a managed resource by this identity. + // OptionalForImport and RequiredForImport cannot both be true. + OptionalForImport bool + + // Description is used in various tooling, like the language server or the documentation + // generator, to give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It can be written as plain text with no + // special formatting, or formatted as Markdown. + Description string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a BoolAttribute. +func (a BoolAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a BoolAttribute +// and all fields are equal. +func (a BoolAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(BoolAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns an empty string as identity attributes cannot +// surface deprecation messages. +func (a BoolAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain plaintext or Markdown. +func (a BoolAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain Markdown or plaintext. +func (a BoolAttribute) GetMarkdownDescription() string { + return a.Description +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a BoolAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.BoolType +} + +// IsComputed returns false as it's not relevant for identity schemas. +func (a BoolAttribute) IsComputed() bool { + return false +} + +// IsOptional returns false as it's not relevant for identity schemas. +func (a BoolAttribute) IsOptional() bool { + return false +} + +// IsRequired returns false as it's not relevant for identity schemas. +func (a BoolAttribute) IsRequired() bool { + return false +} + +// IsSensitive returns false as it's not relevant for identity schemas. +func (a BoolAttribute) IsSensitive() bool { + return false +} + +// IsWriteOnly returns false as it's not relevant for identity schemas. +func (a BoolAttribute) IsWriteOnly() bool { + return false +} + +// IsRequiredForImport returns the RequiredForImport field value. +func (a BoolAttribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport returns the OptionalForImport field value. +func (a BoolAttribute) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/resource/identityschema/bool_attribute_test.go b/resource/identityschema/bool_attribute_test.go new file mode 100644 index 00000000..057cde79 --- /dev/null +++ b/resource/identityschema/bool_attribute_test.go @@ -0,0 +1,431 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestBoolAttributeApplyTerraform5AttributePathStep(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + step tftypes.AttributePathStep + expected any + expectedError error + }{ + "AttributeName": { + attribute: identityschema.BoolAttribute{}, + step: tftypes.AttributeName("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.BoolType"), + }, + "ElementKeyInt": { + attribute: identityschema.BoolAttribute{}, + step: tftypes.ElementKeyInt(1), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.BoolType"), + }, + "ElementKeyString": { + attribute: identityschema.BoolAttribute{}, + step: tftypes.ElementKeyString("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.BoolType"), + }, + "ElementKeyValue": { + attribute: identityschema.BoolAttribute{}, + step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.BoolType"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.attribute.ApplyTerraform5AttributePathStep(testCase.step) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeGetDeprecationMessage(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected string + }{ + "no-deprecation-message": { + attribute: identityschema.BoolAttribute{}, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDeprecationMessage() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeEqual(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + other fwschema.Attribute + expected bool + }{ + "different-type": { + attribute: identityschema.BoolAttribute{}, + other: testschema.AttributeWithBoolValidators{}, + expected: false, + }, + "equal": { + attribute: identityschema.BoolAttribute{}, + other: identityschema.BoolAttribute{}, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.Equal(testCase.other) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeGetDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected string + }{ + "no-description": { + attribute: identityschema.BoolAttribute{}, + expected: "", + }, + "description": { + attribute: identityschema.BoolAttribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeGetMarkdownDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected string + }{ + "no-markdown-description": { + attribute: identityschema.BoolAttribute{}, + expected: "", + }, + "markdown-description-from-description": { + attribute: identityschema.BoolAttribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetMarkdownDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeGetType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected attr.Type + }{ + "base": { + attribute: identityschema.BoolAttribute{}, + expected: types.BoolType, + }, + "custom-type": { + attribute: identityschema.BoolAttribute{ + CustomType: testtypes.BoolType{}, + }, + expected: testtypes.BoolType{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetType() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsComputed(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected bool + }{ + "not-computed": { + attribute: identityschema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsComputed() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsOptional(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected bool + }{ + "not-optional": { + attribute: identityschema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptional() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsRequired(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected bool + }{ + "not-required": { + attribute: identityschema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequired() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsSensitive(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected bool + }{ + "not-sensitive": { + attribute: identityschema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsSensitive() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsWriteOnly(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected bool + }{ + "not-writeOnly": { + attribute: identityschema.BoolAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsWriteOnly() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: identityschema.BoolAttribute{}, + expected: false, + }, + "requiredForImport": { + attribute: identityschema.BoolAttribute{ + RequiredForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestBoolAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.BoolAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: identityschema.BoolAttribute{}, + expected: false, + }, + "optionalForImport": { + attribute: identityschema.BoolAttribute{ + OptionalForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/identityschema/doc.go b/resource/identityschema/doc.go new file mode 100644 index 00000000..14efe3ec --- /dev/null +++ b/resource/identityschema/doc.go @@ -0,0 +1,11 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +// Package identityschema contains all available schema functionality for managed +// resource identity. +// +// TODO: Verify these type names are what we ended with. +// +// Resource identity schemas define the structure and value types for identity state data. +// Schemas are implemented via the resource.ResourceWithIdentity type IdentitySchema method. +package identityschema diff --git a/resource/identityschema/float32_attribute.go b/resource/identityschema/float32_attribute.go new file mode 100644 index 00000000..ce741d32 --- /dev/null +++ b/resource/identityschema/float32_attribute.go @@ -0,0 +1,130 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = Float32Attribute{} +) + +// Float32Attribute represents a schema attribute that is a 32-bit floating +// point number. When retrieving the value for this attribute, use +// types.Float32 as the value type unless the CustomType field is set. +// +// Use Int32Attribute for 32-bit integer attributes or NumberAttribute for +// 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point value. +// +// example_attribute = 123.45 +type Float32Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Float32Type. When retrieving data, the basetypes.Float32Valuable + // associated with this custom type must be used in place of types.Float32. + CustomType basetypes.Float32Typable + + // RequiredForImport indicates whether the practitioner must enter a value for + // this attribute when importing a managed resource by this identity. + // RequiredForImport and OptionalForImport cannot both be true. + RequiredForImport bool + + // OptionalForImport indicates whether the practitioner can choose to enter a value + // for this attribute when importing a managed resource by this identity. + // OptionalForImport and RequiredForImport cannot both be true. + OptionalForImport bool + + // Description is used in various tooling, like the language server or the documentation + // generator, to give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It can be written as plain text with no + // special formatting, or formatted as Markdown. + Description string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Float32Attribute. +func (a Float32Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Float32Attribute +// and all fields are equal. +func (a Float32Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Float32Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns an empty string as identity attributes cannot +// surface deprecation messages. +func (a Float32Attribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain plaintext or Markdown. +func (a Float32Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain Markdown or plaintext. +func (a Float32Attribute) GetMarkdownDescription() string { + return a.Description +} + +// GetType returns types.Float32Type or the CustomType field value if defined. +func (a Float32Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Float32Type +} + +// IsComputed returns false as it's not relevant for identity schemas. +func (a Float32Attribute) IsComputed() bool { + return false +} + +// IsOptional returns false as it's not relevant for identity schemas. +func (a Float32Attribute) IsOptional() bool { + return false +} + +// IsRequired returns false as it's not relevant for identity schemas. +func (a Float32Attribute) IsRequired() bool { + return false +} + +// IsSensitive returns false as it's not relevant for identity schemas. +func (a Float32Attribute) IsSensitive() bool { + return false +} + +// IsWriteOnly returns false as it's not relevant for identity schemas. +func (a Float32Attribute) IsWriteOnly() bool { + return false +} + +// IsRequiredForImport returns the RequiredForImport field value. +func (a Float32Attribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport returns the OptionalForImport field value. +func (a Float32Attribute) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/resource/identityschema/float32_attribute_test.go b/resource/identityschema/float32_attribute_test.go new file mode 100644 index 00000000..0f906f88 --- /dev/null +++ b/resource/identityschema/float32_attribute_test.go @@ -0,0 +1,431 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestFloat32AttributeApplyTerraform5AttributePathStep(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + step tftypes.AttributePathStep + expected any + expectedError error + }{ + "AttributeName": { + attribute: identityschema.Float32Attribute{}, + step: tftypes.AttributeName("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Float32Type"), + }, + "ElementKeyInt": { + attribute: identityschema.Float32Attribute{}, + step: tftypes.ElementKeyInt(1), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Float32Type"), + }, + "ElementKeyString": { + attribute: identityschema.Float32Attribute{}, + step: tftypes.ElementKeyString("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Float32Type"), + }, + "ElementKeyValue": { + attribute: identityschema.Float32Attribute{}, + step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Float32Type"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.attribute.ApplyTerraform5AttributePathStep(testCase.step) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeGetDeprecationMessage(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected string + }{ + "no-deprecation-message": { + attribute: identityschema.Float32Attribute{}, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDeprecationMessage() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeEqual(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + other fwschema.Attribute + expected bool + }{ + "different-type": { + attribute: identityschema.Float32Attribute{}, + other: testschema.AttributeWithFloat32Validators{}, + expected: false, + }, + "equal": { + attribute: identityschema.Float32Attribute{}, + other: identityschema.Float32Attribute{}, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.Equal(testCase.other) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeGetDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected string + }{ + "no-description": { + attribute: identityschema.Float32Attribute{}, + expected: "", + }, + "description": { + attribute: identityschema.Float32Attribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeGetMarkdownDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected string + }{ + "no-markdown-description": { + attribute: identityschema.Float32Attribute{}, + expected: "", + }, + "markdown-description-from-description": { + attribute: identityschema.Float32Attribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetMarkdownDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeGetType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected attr.Type + }{ + "base": { + attribute: identityschema.Float32Attribute{}, + expected: types.Float32Type, + }, + "custom-type": { + attribute: identityschema.Float32Attribute{ + CustomType: testtypes.Float32Type{}, + }, + expected: testtypes.Float32Type{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetType() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsComputed(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected bool + }{ + "not-computed": { + attribute: identityschema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsComputed() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsOptional(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected bool + }{ + "not-optional": { + attribute: identityschema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptional() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsRequired(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected bool + }{ + "not-required": { + attribute: identityschema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequired() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsSensitive(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected bool + }{ + "not-sensitive": { + attribute: identityschema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsSensitive() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsWriteOnly(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected bool + }{ + "not-writeOnly": { + attribute: identityschema.Float32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsWriteOnly() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: identityschema.Float32Attribute{}, + expected: false, + }, + "requiredForImport": { + attribute: identityschema.Float32Attribute{ + RequiredForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: identityschema.Float32Attribute{}, + expected: false, + }, + "optionalForImport": { + attribute: identityschema.Float32Attribute{ + OptionalForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/identityschema/float64_attribute.go b/resource/identityschema/float64_attribute.go new file mode 100644 index 00000000..a6e33fb3 --- /dev/null +++ b/resource/identityschema/float64_attribute.go @@ -0,0 +1,130 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = Float64Attribute{} +) + +// Float64Attribute represents a schema attribute that is a 64-bit floating +// point number. When retrieving the value for this attribute, use +// types.Float64 as the value type unless the CustomType field is set. +// +// Use Int64Attribute for 64-bit integer attributes or NumberAttribute for +// 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point value. +// +// example_attribute = 123.45 +type Float64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Float64Type. When retrieving data, the basetypes.Float64Valuable + // associated with this custom type must be used in place of types.Float64. + CustomType basetypes.Float64Typable + + // RequiredForImport indicates whether the practitioner must enter a value for + // this attribute when importing a managed resource by this identity. + // RequiredForImport and OptionalForImport cannot both be true. + RequiredForImport bool + + // OptionalForImport indicates whether the practitioner can choose to enter a value + // for this attribute when importing a managed resource by this identity. + // OptionalForImport and RequiredForImport cannot both be true. + OptionalForImport bool + + // Description is used in various tooling, like the language server or the documentation + // generator, to give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It can be written as plain text with no + // special formatting, or formatted as Markdown. + Description string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Float64Attribute. +func (a Float64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Float64Attribute +// and all fields are equal. +func (a Float64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Float64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns an empty string as identity attributes cannot +// surface deprecation messages. +func (a Float64Attribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain plaintext or Markdown. +func (a Float64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain Markdown or plaintext. +func (a Float64Attribute) GetMarkdownDescription() string { + return a.Description +} + +// GetType returns types.Float64Type or the CustomType field value if defined. +func (a Float64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Float64Type +} + +// IsComputed returns false as it's not relevant for identity schemas. +func (a Float64Attribute) IsComputed() bool { + return false +} + +// IsOptional returns false as it's not relevant for identity schemas. +func (a Float64Attribute) IsOptional() bool { + return false +} + +// IsRequired returns false as it's not relevant for identity schemas. +func (a Float64Attribute) IsRequired() bool { + return false +} + +// IsSensitive returns false as it's not relevant for identity schemas. +func (a Float64Attribute) IsSensitive() bool { + return false +} + +// IsWriteOnly returns false as it's not relevant for identity schemas. +func (a Float64Attribute) IsWriteOnly() bool { + return false +} + +// IsRequiredForImport returns the RequiredForImport field value. +func (a Float64Attribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport returns the OptionalForImport field value. +func (a Float64Attribute) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/resource/identityschema/float64_attribute_test.go b/resource/identityschema/float64_attribute_test.go new file mode 100644 index 00000000..e5473e7b --- /dev/null +++ b/resource/identityschema/float64_attribute_test.go @@ -0,0 +1,431 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestFloat64AttributeApplyTerraform5AttributePathStep(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + step tftypes.AttributePathStep + expected any + expectedError error + }{ + "AttributeName": { + attribute: identityschema.Float64Attribute{}, + step: tftypes.AttributeName("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Float64Type"), + }, + "ElementKeyInt": { + attribute: identityschema.Float64Attribute{}, + step: tftypes.ElementKeyInt(1), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Float64Type"), + }, + "ElementKeyString": { + attribute: identityschema.Float64Attribute{}, + step: tftypes.ElementKeyString("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Float64Type"), + }, + "ElementKeyValue": { + attribute: identityschema.Float64Attribute{}, + step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Float64Type"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.attribute.ApplyTerraform5AttributePathStep(testCase.step) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeGetDeprecationMessage(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected string + }{ + "no-deprecation-message": { + attribute: identityschema.Float64Attribute{}, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDeprecationMessage() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeEqual(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + other fwschema.Attribute + expected bool + }{ + "different-type": { + attribute: identityschema.Float64Attribute{}, + other: testschema.AttributeWithFloat64Validators{}, + expected: false, + }, + "equal": { + attribute: identityschema.Float64Attribute{}, + other: identityschema.Float64Attribute{}, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.Equal(testCase.other) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeGetDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected string + }{ + "no-description": { + attribute: identityschema.Float64Attribute{}, + expected: "", + }, + "description": { + attribute: identityschema.Float64Attribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeGetMarkdownDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected string + }{ + "no-markdown-description": { + attribute: identityschema.Float64Attribute{}, + expected: "", + }, + "markdown-description-from-description": { + attribute: identityschema.Float64Attribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetMarkdownDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeGetType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected attr.Type + }{ + "base": { + attribute: identityschema.Float64Attribute{}, + expected: types.Float64Type, + }, + "custom-type": { + attribute: identityschema.Float64Attribute{ + CustomType: testtypes.Float64Type{}, + }, + expected: testtypes.Float64Type{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetType() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsComputed(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected bool + }{ + "not-computed": { + attribute: identityschema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsComputed() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsOptional(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected bool + }{ + "not-optional": { + attribute: identityschema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptional() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsRequired(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected bool + }{ + "not-required": { + attribute: identityschema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequired() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsSensitive(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected bool + }{ + "not-sensitive": { + attribute: identityschema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsSensitive() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsWriteOnly(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected bool + }{ + "not-writeOnly": { + attribute: identityschema.Float64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsWriteOnly() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: identityschema.Float64Attribute{}, + expected: false, + }, + "requiredForImport": { + attribute: identityschema.Float64Attribute{ + RequiredForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestFloat64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Float64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: identityschema.Float64Attribute{}, + expected: false, + }, + "optionalForImport": { + attribute: identityschema.Float64Attribute{ + OptionalForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/identityschema/int32_attribute.go b/resource/identityschema/int32_attribute.go new file mode 100644 index 00000000..a5ef7e81 --- /dev/null +++ b/resource/identityschema/int32_attribute.go @@ -0,0 +1,130 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = Int32Attribute{} +) + +// Int32Attribute represents a schema attribute that is a 32-bit integer. +// When retrieving the value for this attribute, use types.Int32 as the value +// type unless the CustomType field is set. +// +// Use Float32Attribute for 32-bit floating point number attributes or +// NumberAttribute for 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via an integer value. +// +// example_attribute = 123 +type Int32Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Int32Type. When retrieving data, the basetypes.Int32Valuable + // associated with this custom type must be used in place of types.Int32. + CustomType basetypes.Int32Typable + + // RequiredForImport indicates whether the practitioner must enter a value for + // this attribute when importing a managed resource by this identity. + // RequiredForImport and OptionalForImport cannot both be true. + RequiredForImport bool + + // OptionalForImport indicates whether the practitioner can choose to enter a value + // for this attribute when importing a managed resource by this identity. + // OptionalForImport and RequiredForImport cannot both be true. + OptionalForImport bool + + // Description is used in various tooling, like the language server or the documentation + // generator, to give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It can be written as plain text with no + // special formatting, or formatted as Markdown. + Description string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Int32Attribute. +func (a Int32Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Int32Attribute +// and all fields are equal. +func (a Int32Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Int32Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns an empty string as identity attributes cannot +// surface deprecation messages. +func (a Int32Attribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain plaintext or Markdown. +func (a Int32Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain Markdown or plaintext. +func (a Int32Attribute) GetMarkdownDescription() string { + return a.Description +} + +// GetType returns types.Int32Type or the CustomType field value if defined. +func (a Int32Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Int32Type +} + +// IsComputed returns false as it's not relevant for identity schemas. +func (a Int32Attribute) IsComputed() bool { + return false +} + +// IsOptional returns false as it's not relevant for identity schemas. +func (a Int32Attribute) IsOptional() bool { + return false +} + +// IsRequired returns false as it's not relevant for identity schemas. +func (a Int32Attribute) IsRequired() bool { + return false +} + +// IsSensitive returns false as it's not relevant for identity schemas. +func (a Int32Attribute) IsSensitive() bool { + return false +} + +// IsWriteOnly returns false as it's not relevant for identity schemas. +func (a Int32Attribute) IsWriteOnly() bool { + return false +} + +// IsRequiredForImport returns the RequiredForImport field value. +func (a Int32Attribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport returns the OptionalForImport field value. +func (a Int32Attribute) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/resource/identityschema/int32_attribute_test.go b/resource/identityschema/int32_attribute_test.go new file mode 100644 index 00000000..7b68255c --- /dev/null +++ b/resource/identityschema/int32_attribute_test.go @@ -0,0 +1,431 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestInt32AttributeApplyTerraform5AttributePathStep(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + step tftypes.AttributePathStep + expected any + expectedError error + }{ + "AttributeName": { + attribute: identityschema.Int32Attribute{}, + step: tftypes.AttributeName("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Int32Type"), + }, + "ElementKeyInt": { + attribute: identityschema.Int32Attribute{}, + step: tftypes.ElementKeyInt(1), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Int32Type"), + }, + "ElementKeyString": { + attribute: identityschema.Int32Attribute{}, + step: tftypes.ElementKeyString("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Int32Type"), + }, + "ElementKeyValue": { + attribute: identityschema.Int32Attribute{}, + step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Int32Type"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.attribute.ApplyTerraform5AttributePathStep(testCase.step) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeGetDeprecationMessage(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected string + }{ + "no-deprecation-message": { + attribute: identityschema.Int32Attribute{}, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDeprecationMessage() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeEqual(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + other fwschema.Attribute + expected bool + }{ + "different-type": { + attribute: identityschema.Int32Attribute{}, + other: testschema.AttributeWithInt32Validators{}, + expected: false, + }, + "equal": { + attribute: identityschema.Int32Attribute{}, + other: identityschema.Int32Attribute{}, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.Equal(testCase.other) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeGetDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected string + }{ + "no-description": { + attribute: identityschema.Int32Attribute{}, + expected: "", + }, + "description": { + attribute: identityschema.Int32Attribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeGetMarkdownDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected string + }{ + "no-markdown-description": { + attribute: identityschema.Int32Attribute{}, + expected: "", + }, + "markdown-description-from-description": { + attribute: identityschema.Int32Attribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetMarkdownDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeGetType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected attr.Type + }{ + "base": { + attribute: identityschema.Int32Attribute{}, + expected: types.Int32Type, + }, + "custom-type": { + attribute: identityschema.Int32Attribute{ + CustomType: testtypes.Int32Type{}, + }, + expected: testtypes.Int32Type{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetType() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsComputed(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected bool + }{ + "not-computed": { + attribute: identityschema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsComputed() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsOptional(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected bool + }{ + "not-optional": { + attribute: identityschema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptional() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsRequired(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected bool + }{ + "not-required": { + attribute: identityschema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequired() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsSensitive(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected bool + }{ + "not-sensitive": { + attribute: identityschema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsSensitive() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsWriteOnly(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected bool + }{ + "not-writeOnly": { + attribute: identityschema.Int32Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsWriteOnly() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: identityschema.Int32Attribute{}, + expected: false, + }, + "requiredForImport": { + attribute: identityschema.Int32Attribute{ + RequiredForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt32AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int32Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: identityschema.Int32Attribute{}, + expected: false, + }, + "optionalForImport": { + attribute: identityschema.Int32Attribute{ + OptionalForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/identityschema/int64_attribute.go b/resource/identityschema/int64_attribute.go new file mode 100644 index 00000000..332a1d1c --- /dev/null +++ b/resource/identityschema/int64_attribute.go @@ -0,0 +1,130 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = Int64Attribute{} +) + +// Int64Attribute represents a schema attribute that is a 64-bit integer. +// When retrieving the value for this attribute, use types.Int64 as the value +// type unless the CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// NumberAttribute for 512-bit generic number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via an integer value. +// +// example_attribute = 123 +type Int64Attribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.Int64Type. When retrieving data, the basetypes.Int64Valuable + // associated with this custom type must be used in place of types.Int64. + CustomType basetypes.Int64Typable + + // RequiredForImport indicates whether the practitioner must enter a value for + // this attribute when importing a managed resource by this identity. + // RequiredForImport and OptionalForImport cannot both be true. + RequiredForImport bool + + // OptionalForImport indicates whether the practitioner can choose to enter a value + // for this attribute when importing a managed resource by this identity. + // OptionalForImport and RequiredForImport cannot both be true. + OptionalForImport bool + + // Description is used in various tooling, like the language server or the documentation + // generator, to give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It can be written as plain text with no + // special formatting, or formatted as Markdown. + Description string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a Int64Attribute. +func (a Int64Attribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a Int64Attribute +// and all fields are equal. +func (a Int64Attribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(Int64Attribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns an empty string as identity attributes cannot +// surface deprecation messages. +func (a Int64Attribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain plaintext or Markdown. +func (a Int64Attribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain Markdown or plaintext. +func (a Int64Attribute) GetMarkdownDescription() string { + return a.Description +} + +// GetType returns types.Int64Type or the CustomType field value if defined. +func (a Int64Attribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.Int64Type +} + +// IsComputed returns false as it's not relevant for identity schemas. +func (a Int64Attribute) IsComputed() bool { + return false +} + +// IsOptional returns false as it's not relevant for identity schemas. +func (a Int64Attribute) IsOptional() bool { + return false +} + +// IsRequired returns false as it's not relevant for identity schemas. +func (a Int64Attribute) IsRequired() bool { + return false +} + +// IsSensitive returns false as it's not relevant for identity schemas. +func (a Int64Attribute) IsSensitive() bool { + return false +} + +// IsWriteOnly returns false as it's not relevant for identity schemas. +func (a Int64Attribute) IsWriteOnly() bool { + return false +} + +// IsRequiredForImport returns the RequiredForImport field value. +func (a Int64Attribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport returns the OptionalForImport field value. +func (a Int64Attribute) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/resource/identityschema/int64_attribute_test.go b/resource/identityschema/int64_attribute_test.go new file mode 100644 index 00000000..2bba9c50 --- /dev/null +++ b/resource/identityschema/int64_attribute_test.go @@ -0,0 +1,431 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestInt64AttributeApplyTerraform5AttributePathStep(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + step tftypes.AttributePathStep + expected any + expectedError error + }{ + "AttributeName": { + attribute: identityschema.Int64Attribute{}, + step: tftypes.AttributeName("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.Int64Type"), + }, + "ElementKeyInt": { + attribute: identityschema.Int64Attribute{}, + step: tftypes.ElementKeyInt(1), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.Int64Type"), + }, + "ElementKeyString": { + attribute: identityschema.Int64Attribute{}, + step: tftypes.ElementKeyString("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.Int64Type"), + }, + "ElementKeyValue": { + attribute: identityschema.Int64Attribute{}, + step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.Int64Type"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.attribute.ApplyTerraform5AttributePathStep(testCase.step) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeGetDeprecationMessage(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected string + }{ + "no-deprecation-message": { + attribute: identityschema.Int64Attribute{}, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDeprecationMessage() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeEqual(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + other fwschema.Attribute + expected bool + }{ + "different-type": { + attribute: identityschema.Int64Attribute{}, + other: testschema.AttributeWithInt64Validators{}, + expected: false, + }, + "equal": { + attribute: identityschema.Int64Attribute{}, + other: identityschema.Int64Attribute{}, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.Equal(testCase.other) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeGetDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected string + }{ + "no-description": { + attribute: identityschema.Int64Attribute{}, + expected: "", + }, + "description": { + attribute: identityschema.Int64Attribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeGetMarkdownDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected string + }{ + "no-markdown-description": { + attribute: identityschema.Int64Attribute{}, + expected: "", + }, + "markdown-description-from-description": { + attribute: identityschema.Int64Attribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetMarkdownDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeGetType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected attr.Type + }{ + "base": { + attribute: identityschema.Int64Attribute{}, + expected: types.Int64Type, + }, + "custom-type": { + attribute: identityschema.Int64Attribute{ + CustomType: testtypes.Int64Type{}, + }, + expected: testtypes.Int64Type{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetType() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsComputed(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected bool + }{ + "not-computed": { + attribute: identityschema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsComputed() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsOptional(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected bool + }{ + "not-optional": { + attribute: identityschema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptional() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsRequired(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected bool + }{ + "not-required": { + attribute: identityschema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequired() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsSensitive(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected bool + }{ + "not-sensitive": { + attribute: identityschema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsSensitive() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsWriteOnly(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected bool + }{ + "not-writeOnly": { + attribute: identityschema.Int64Attribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsWriteOnly() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected bool + }{ + "not-requiredForImport": { + attribute: identityschema.Int64Attribute{}, + expected: false, + }, + "requiredForImport": { + attribute: identityschema.Int64Attribute{ + RequiredForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestInt64AttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.Int64Attribute + expected bool + }{ + "not-optionalForImport": { + attribute: identityschema.Int64Attribute{}, + expected: false, + }, + "optionalForImport": { + attribute: identityschema.Int64Attribute{ + OptionalForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/identityschema/list_attribute.go b/resource/identityschema/list_attribute.go new file mode 100644 index 00000000..86fe7973 --- /dev/null +++ b/resource/identityschema/list_attribute.go @@ -0,0 +1,173 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = ListAttribute{} + _ fwschema.AttributeWithValidateImplementation = ListAttribute{} +) + +// ListAttribute represents a schema attribute that is a list with a single +// element type. When retrieving the value for this attribute, use types.List +// as the value type unless the CustomType field is set. The ElementType field +// must be set. +// +// In identity schemas, ListAttribute is only permitted to have a primitive ElementType, +// which are: +// - types.BoolType +// - types.Float32Type +// - types.Float64Type +// - types.Int32Type +// - types.Int64Type +// - types.NumberType +// - types.StringType +// +// Terraform configurations configure this attribute using expressions that +// return a list or directly via square brace syntax. +// +// # list of strings +// example_attribute = ["first", "second"] +type ListAttribute struct { + // ElementType is the type for all elements of the list. This field must be + // set. + // + // ElementType must be a primitive, which are: + // - types.BoolType + // - types.Float32Type + // - types.Float64Type + // - types.Int32Type + // - types.Int64Type + // - types.NumberType + // - types.StringType + ElementType attr.Type + + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.ListType. When retrieving data, the basetypes.ListValuable + // associated with this custom type must be used in place of types.List. + CustomType basetypes.ListTypable + + // RequiredForImport indicates whether the practitioner must enter a value for + // this attribute when importing a managed resource by this identity. + // RequiredForImport and OptionalForImport cannot both be true. + RequiredForImport bool + + // OptionalForImport indicates whether the practitioner can choose to enter a value + // for this attribute when importing a managed resource by this identity. + // OptionalForImport and RequiredForImport cannot both be true. + OptionalForImport bool + + // Description is used in various tooling, like the language server or the documentation + // generator, to give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It can be written as plain text with no + // special formatting, or formatted as Markdown. + Description string +} + +// ApplyTerraform5AttributePathStep returns the result of stepping into a list +// index or an error. +func (a ListAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a ListAttribute +// and all fields are equal. +func (a ListAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(ListAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns an empty string as identity attributes cannot +// surface deprecation messages. +func (a ListAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain plaintext or Markdown. +func (a ListAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain Markdown or plaintext. +func (a ListAttribute) GetMarkdownDescription() string { + return a.Description +} + +// GetType returns types.ListType or the CustomType field value if defined. +func (a ListAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.ListType{ + ElemType: a.ElementType, + } +} + +// IsComputed returns false as it's not relevant for identity schemas. +func (a ListAttribute) IsComputed() bool { + return false +} + +// IsOptional returns false as it's not relevant for identity schemas. +func (a ListAttribute) IsOptional() bool { + return false +} + +// IsRequired returns false as it's not relevant for identity schemas. +func (a ListAttribute) IsRequired() bool { + return false +} + +// IsSensitive returns false as it's not relevant for identity schemas. +func (a ListAttribute) IsSensitive() bool { + return false +} + +// IsWriteOnly returns false as it's not relevant for identity schemas. +func (a ListAttribute) IsWriteOnly() bool { + return false +} + +// IsRequiredForImport returns the RequiredForImport field value. +func (a ListAttribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport returns the OptionalForImport field value. +func (a ListAttribute) IsOptionalForImport() bool { + return a.OptionalForImport +} + +// ValidateImplementation contains logic for validating the +// provider-defined implementation of the attribute to prevent unexpected +// errors or panics. This logic runs during the GetResourceIdentitySchemas RPC and +// should never include false positives. +func (a ListAttribute) ValidateImplementation(ctx context.Context, req fwschema.ValidateImplementationRequest, resp *fwschema.ValidateImplementationResponse) { + if a.CustomType == nil && a.ElementType == nil { + resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) + } + + // TODO: Write validation similar to the dynamic type validation/diagnostic for detecting + // non-primitive element types + // if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { + // resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) + // } +} diff --git a/resource/identityschema/list_attribute_test.go b/resource/identityschema/list_attribute_test.go new file mode 100644 index 00000000..48c90f00 --- /dev/null +++ b/resource/identityschema/list_attribute_test.go @@ -0,0 +1,520 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema_test + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestListAttributeApplyTerraform5AttributePathStep(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + step tftypes.AttributePathStep + expected any + expectedError error + }{ + "AttributeName": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + step: tftypes.AttributeName("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply step tftypes.AttributeName to ListType"), + }, + "ElementKeyInt": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + step: tftypes.ElementKeyInt(1), + expected: types.StringType, + expectedError: nil, + }, + "ElementKeyString": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + step: tftypes.ElementKeyString("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply step tftypes.ElementKeyString to ListType"), + }, + "ElementKeyValue": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedError: fmt.Errorf("cannot apply step tftypes.ElementKeyValue to ListType"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.attribute.ApplyTerraform5AttributePathStep(testCase.step) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeGetDeprecationMessage(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected string + }{ + "no-deprecation-message": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDeprecationMessage() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeEqual(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + other fwschema.Attribute + expected bool + }{ + "different-type": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + other: testschema.AttributeWithListValidators{}, + expected: false, + }, + "different-element-type": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + other: identityschema.ListAttribute{ElementType: types.BoolType}, + expected: false, + }, + "equal": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + other: identityschema.ListAttribute{ElementType: types.StringType}, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.Equal(testCase.other) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeGetDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected string + }{ + "no-description": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: "", + }, + "description": { + attribute: identityschema.ListAttribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeGetMarkdownDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected string + }{ + "no-markdown-description": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: "", + }, + "markdown-description-from-description": { + attribute: identityschema.ListAttribute{ + ElementType: types.StringType, + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetMarkdownDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeGetType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected attr.Type + }{ + "base": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: types.ListType{ElemType: types.StringType}, + }, + "custom-type": { + attribute: identityschema.ListAttribute{ + CustomType: testtypes.ListType{ListType: types.ListType{ElemType: types.StringType}}, + }, + expected: testtypes.ListType{ListType: types.ListType{ElemType: types.StringType}}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetType() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsComputed(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected bool + }{ + "not-computed": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsComputed() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsOptional(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected bool + }{ + "not-optional": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptional() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsRequired(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected bool + }{ + "not-required": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequired() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsSensitive(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected bool + }{ + "not-sensitive": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsSensitive() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsWriteOnly(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected bool + }{ + "not-writeOnly": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsWriteOnly() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: false, + }, + "requiredForImport": { + attribute: identityschema.ListAttribute{ + ElementType: types.StringType, + RequiredForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: identityschema.ListAttribute{ElementType: types.StringType}, + expected: false, + }, + "optionalForImport": { + attribute: identityschema.ListAttribute{ + ElementType: types.StringType, + OptionalForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestListAttributeValidateImplementation(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.ListAttribute + request fwschema.ValidateImplementationRequest + expected *fwschema.ValidateImplementationResponse + }{ + "elementtype": { + attribute: identityschema.ListAttribute{ + RequiredForImport: true, + ElementType: types.StringType, + }, + request: fwschema.ValidateImplementationRequest{ + Name: "test", + Path: path.Root("test"), + }, + expected: &fwschema.ValidateImplementationResponse{}, + }, + // TODO: Update this test once the validation logic is in place + // "elementtype-invalid": { + // attribute: identityschema.ListAttribute{ + // RequiredForImport: true, + // ElementType: types.DynamicType, + // }, + // request: fwschema.ValidateImplementationRequest{ + // Name: "test", + // Path: path.Root("test"), + // }, + // expected: &fwschema.ValidateImplementationResponse{ + // Diagnostics: diag.Diagnostics{ + // diag.NewErrorDiagnostic( + // "Invalid Schema Implementation", + // "When validating the schema, an implementation issue was found. "+ + // "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + // "\"test\" is an attribute that contains a collection type with a nested dynamic type.\n\n"+ + // "Dynamic types inside of collections are not currently supported in terraform-plugin-framework. "+ + // "If underlying dynamic values are required, replace the \"test\" attribute definition with DynamicAttribute instead.", + // ), + // }, + // }, + // }, + "elementtype-missing": { + attribute: identityschema.ListAttribute{ + RequiredForImport: true, + }, + request: fwschema.ValidateImplementationRequest{ + Name: "test", + Path: path.Root("test"), + }, + expected: &fwschema.ValidateImplementationResponse{ + Diagnostics: diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Invalid Attribute Implementation", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + "\"test\" is missing the CustomType or ElementType field on a collection Attribute. "+ + "One of these fields is required to prevent other unexpected errors or panics.", + ), + }, + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := &fwschema.ValidateImplementationResponse{} + testCase.attribute.ValidateImplementation(context.Background(), testCase.request, got) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/identityschema/number_attribute.go b/resource/identityschema/number_attribute.go new file mode 100644 index 00000000..d1533477 --- /dev/null +++ b/resource/identityschema/number_attribute.go @@ -0,0 +1,131 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = NumberAttribute{} +) + +// NumberAttribute represents a schema attribute that is a generic number with +// up to 512 bits of floating point or integer precision. When retrieving the +// value for this attribute, use types.Number as the value type unless the +// CustomType field is set. +// +// Use Float64Attribute for 64-bit floating point number attributes or +// Int64Attribute for 64-bit integer number attributes. +// +// Terraform configurations configure this attribute using expressions that +// return a number or directly via a floating point or integer value. +// +// example_attribute = 123 +type NumberAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.NumberType. When retrieving data, the basetypes.NumberValuable + // associated with this custom type must be used in place of types.Number. + CustomType basetypes.NumberTypable + + // RequiredForImport indicates whether the practitioner must enter a value for + // this attribute when importing a managed resource by this identity. + // RequiredForImport and OptionalForImport cannot both be true. + RequiredForImport bool + + // OptionalForImport indicates whether the practitioner can choose to enter a value + // for this attribute when importing a managed resource by this identity. + // OptionalForImport and RequiredForImport cannot both be true. + OptionalForImport bool + + // Description is used in various tooling, like the language server or the documentation + // generator, to give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It can be written as plain text with no + // special formatting, or formatted as Markdown. + Description string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a NumberAttribute. +func (a NumberAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a NumberAttribute +// and all fields are equal. +func (a NumberAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(NumberAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns an empty string as identity attributes cannot +// surface deprecation messages. +func (a NumberAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain plaintext or Markdown. +func (a NumberAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain Markdown or plaintext. +func (a NumberAttribute) GetMarkdownDescription() string { + return a.Description +} + +// GetType returns types.NumberType or the CustomType field value if defined. +func (a NumberAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.NumberType +} + +// IsComputed returns false as it's not relevant for identity schemas. +func (a NumberAttribute) IsComputed() bool { + return false +} + +// IsOptional returns false as it's not relevant for identity schemas. +func (a NumberAttribute) IsOptional() bool { + return false +} + +// IsRequired returns false as it's not relevant for identity schemas. +func (a NumberAttribute) IsRequired() bool { + return false +} + +// IsSensitive returns false as it's not relevant for identity schemas. +func (a NumberAttribute) IsSensitive() bool { + return false +} + +// IsWriteOnly returns false as it's not relevant for identity schemas. +func (a NumberAttribute) IsWriteOnly() bool { + return false +} + +// IsRequiredForImport returns the RequiredForImport field value. +func (a NumberAttribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport returns the OptionalForImport field value. +func (a NumberAttribute) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/resource/identityschema/number_attribute_test.go b/resource/identityschema/number_attribute_test.go new file mode 100644 index 00000000..9597643c --- /dev/null +++ b/resource/identityschema/number_attribute_test.go @@ -0,0 +1,431 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestNumberAttributeApplyTerraform5AttributePathStep(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + step tftypes.AttributePathStep + expected any + expectedError error + }{ + "AttributeName": { + attribute: identityschema.NumberAttribute{}, + step: tftypes.AttributeName("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.NumberType"), + }, + "ElementKeyInt": { + attribute: identityschema.NumberAttribute{}, + step: tftypes.ElementKeyInt(1), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.NumberType"), + }, + "ElementKeyString": { + attribute: identityschema.NumberAttribute{}, + step: tftypes.ElementKeyString("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.NumberType"), + }, + "ElementKeyValue": { + attribute: identityschema.NumberAttribute{}, + step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.NumberType"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.attribute.ApplyTerraform5AttributePathStep(testCase.step) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeGetDeprecationMessage(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected string + }{ + "no-deprecation-message": { + attribute: identityschema.NumberAttribute{}, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDeprecationMessage() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeEqual(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + other fwschema.Attribute + expected bool + }{ + "different-type": { + attribute: identityschema.NumberAttribute{}, + other: testschema.AttributeWithNumberValidators{}, + expected: false, + }, + "equal": { + attribute: identityschema.NumberAttribute{}, + other: identityschema.NumberAttribute{}, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.Equal(testCase.other) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeGetDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected string + }{ + "no-description": { + attribute: identityschema.NumberAttribute{}, + expected: "", + }, + "description": { + attribute: identityschema.NumberAttribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeGetMarkdownDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected string + }{ + "no-markdown-description": { + attribute: identityschema.NumberAttribute{}, + expected: "", + }, + "markdown-description-from-description": { + attribute: identityschema.NumberAttribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetMarkdownDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeGetType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected attr.Type + }{ + "base": { + attribute: identityschema.NumberAttribute{}, + expected: types.NumberType, + }, + "custom-type": { + attribute: identityschema.NumberAttribute{ + CustomType: testtypes.NumberType{}, + }, + expected: testtypes.NumberType{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetType() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsComputed(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected bool + }{ + "not-computed": { + attribute: identityschema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsComputed() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsOptional(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected bool + }{ + "not-optional": { + attribute: identityschema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptional() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsRequired(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected bool + }{ + "not-required": { + attribute: identityschema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequired() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsSensitive(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected bool + }{ + "not-sensitive": { + attribute: identityschema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsSensitive() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsWriteOnly(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected bool + }{ + "not-writeOnly": { + attribute: identityschema.NumberAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsWriteOnly() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: identityschema.NumberAttribute{}, + expected: false, + }, + "requiredForImport": { + attribute: identityschema.NumberAttribute{ + RequiredForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestNumberAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.NumberAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: identityschema.NumberAttribute{}, + expected: false, + }, + "optionalForImport": { + attribute: identityschema.NumberAttribute{ + OptionalForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/identityschema/schema.go b/resource/identityschema/schema.go new file mode 100644 index 00000000..1dfd0983 --- /dev/null +++ b/resource/identityschema/schema.go @@ -0,0 +1,147 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/path" +) + +// Schema must satify the fwschema.Schema interface. +var _ fwschema.Schema = Schema{} + +// TODO: Verify these type names are what we ended with. +// +// Schema defines the structure and value types of resource identity data. This type +// is used as the resource.IdentitySchemaResponse type Schema field, which is +// implemented by the resource.ResourceWithIdentity type IdentitySchema method. +type Schema struct { + // Attributes is the mapping of underlying attribute names to attribute + // definitions. + // + // Names must only contain lowercase letters, numbers, and underscores. + Attributes map[string]Attribute + + // Version indicates the current version of the resource identity schema. Resource + // identity schema versioning enables identity state upgrades in conjunction with the + // [resource.ResourceWithIdentityStateUpgrades] interface. Versioning is only + // required if there is a breaking change involving existing identity state data, + // such as changing an attribute type in a manner that is incompatible with the Terraform type. + // + // Versions are conventionally only incremented by one each release. + Version int64 +} + +// ApplyTerraform5AttributePathStep applies the given AttributePathStep to the +// schema. +func (s Schema) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (any, error) { + return fwschema.SchemaApplyTerraform5AttributePathStep(s, step) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtPath(ctx context.Context, p path.Path) (fwschema.Attribute, diag.Diagnostics) { + return fwschema.SchemaAttributeAtPath(ctx, s, p) +} + +// AttributeAtPath returns the Attribute at the passed path. If the path points +// to an element or attribute of a complex type, rather than to an Attribute, +// it will return an ErrPathInsideAtomicAttribute error. +func (s Schema) AttributeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (fwschema.Attribute, error) { + return fwschema.SchemaAttributeAtTerraformPath(ctx, s, p) +} + +// GetAttributes returns the Attributes field value. +func (s Schema) GetAttributes() map[string]fwschema.Attribute { + return schemaAttributes(s.Attributes) +} + +// GetBlocks returns an empty map as it's not relevant for identity schemas. +func (s Schema) GetBlocks() map[string]fwschema.Block { + return map[string]fwschema.Block{} +} + +// GetDeprecationMessage returns an empty string as identity schemas cannot +// surface deprecation messages. +func (s Schema) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns an empty string as identity schemas cannot +// surface descriptions. +func (s Schema) GetDescription() string { + return "" +} + +// GetMarkdownDescription returns an empty string as identity schemas cannot +// surface descriptions. +func (s Schema) GetMarkdownDescription() string { + return "" +} + +// GetVersion returns the Version field value. +func (s Schema) GetVersion() int64 { + return s.Version +} + +// Type returns the framework type of the schema. +func (s Schema) Type() attr.Type { + return fwschema.SchemaType(s) +} + +// TypeAtPath returns the framework type at the given schema path. +func (s Schema) TypeAtPath(ctx context.Context, p path.Path) (attr.Type, diag.Diagnostics) { + return fwschema.SchemaTypeAtPath(ctx, s, p) +} + +// TypeAtTerraformPath returns the framework type at the given tftypes path. +func (s Schema) TypeAtTerraformPath(ctx context.Context, p *tftypes.AttributePath) (attr.Type, error) { + return fwschema.SchemaTypeAtTerraformPath(ctx, s, p) +} + +// Validate verifies that the schema is not using a reserved field name for a top-level attribute. +// +// Deprecated: Use the ValidateImplementation method instead. +func (s Schema) Validate() diag.Diagnostics { + return s.ValidateImplementation(context.Background()) +} + +// ValidateImplementation contains logic for validating the provider-defined +// implementation of the schema and underlying attributes and blocks to prevent +// unexpected errors or panics. This logic runs during the +// GetResourceIdentitySchemas RPC, or via provider-defined unit testing, and should +// never include false positives. +func (s Schema) ValidateImplementation(ctx context.Context) diag.Diagnostics { + var diags diag.Diagnostics + + for attributeName, attribute := range s.GetAttributes() { + req := fwschema.ValidateImplementationRequest{ + Name: attributeName, + Path: path.Root(attributeName), + } + + diags.Append(fwschema.IsReservedResourceAttributeName(req.Name, req.Path)...) + diags.Append(fwschema.ValidateAttributeImplementation(ctx, attribute, req)...) + } + + return diags +} + +// schemaAttributes is a identity to fwschema type conversion function. +func schemaAttributes(attributes map[string]Attribute) map[string]fwschema.Attribute { + result := make(map[string]fwschema.Attribute, len(attributes)) + + for name, attribute := range attributes { + result[name] = attribute + } + + return result +} diff --git a/resource/identityschema/schema_test.go b/resource/identityschema/schema_test.go new file mode 100644 index 00000000..394cdd42 --- /dev/null +++ b/resource/identityschema/schema_test.go @@ -0,0 +1,915 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema_test + +import ( + "context" + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestSchemaApplyTerraform5AttributePathStep(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + step tftypes.AttributePathStep + expected any + expectedError error + }{ + "AttributeName-attribute": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + step: tftypes.AttributeName("testattr"), + expected: identityschema.StringAttribute{}, + expectedError: nil, + }, + "AttributeName-missing": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + step: tftypes.AttributeName("other"), + expected: nil, + expectedError: fmt.Errorf("could not find attribute or block \"other\" in schema"), + }, + "ElementKeyInt": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + step: tftypes.ElementKeyInt(1), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to schema"), + }, + "ElementKeyString": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + step: tftypes.ElementKeyString("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to schema"), + }, + "ElementKeyValue": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to schema"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.schema.ApplyTerraform5AttributePathStep(testCase.step) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaAttributeAtPath(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + path path.Path + expected fwschema.Attribute + expectedDiags diag.Diagnostics + }{ + "empty-root": { + schema: identityschema.Schema{}, + path: path.Empty(), + expected: nil, + expectedDiags: diag.Diagnostics{ + diag.NewAttributeErrorDiagnostic( + path.Empty(), + "Invalid Schema Path", + "When attempting to get the framework attribute associated with a schema path, an unexpected error was returned. "+ + "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + "Path: \n"+ + "Original Error: got unexpected type identityschema.Schema", + ), + }, + }, + "root": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.StringAttribute{}, + }, + }, + path: path.Empty(), + expected: nil, + expectedDiags: diag.Diagnostics{ + diag.NewAttributeErrorDiagnostic( + path.Empty(), + "Invalid Schema Path", + "When attempting to get the framework attribute associated with a schema path, an unexpected error was returned. "+ + "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + "Path: \n"+ + "Original Error: got unexpected type identityschema.Schema", + ), + }, + }, + "WithAttributeName-attribute": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "other": identityschema.BoolAttribute{}, + "test": identityschema.StringAttribute{}, + }, + }, + path: path.Root("test"), + expected: identityschema.StringAttribute{}, + }, + "WithElementKeyInt": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.StringAttribute{}, + }, + }, + path: path.Empty().AtListIndex(0), + expected: nil, + expectedDiags: diag.Diagnostics{ + diag.NewAttributeErrorDiagnostic( + path.Empty().AtListIndex(0), + "Invalid Schema Path", + "When attempting to get the framework attribute associated with a schema path, an unexpected error was returned. "+ + "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + "Path: [0]\n"+ + "Original Error: ElementKeyInt(0) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyInt to schema", + ), + }, + }, + "WithElementKeyString": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.StringAttribute{}, + }, + }, + path: path.Empty().AtMapKey("test"), + expected: nil, + expectedDiags: diag.Diagnostics{ + diag.NewAttributeErrorDiagnostic( + path.Empty().AtMapKey("test"), + "Invalid Schema Path", + "When attempting to get the framework attribute associated with a schema path, an unexpected error was returned. "+ + "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + "Path: [\"test\"]\n"+ + "Original Error: ElementKeyString(\"test\") still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyString to schema", + ), + }, + }, + "WithElementKeyValue": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.StringAttribute{}, + }, + }, + path: path.Empty().AtSetValue(types.StringValue("test")), + expected: nil, + expectedDiags: diag.Diagnostics{ + diag.NewAttributeErrorDiagnostic( + path.Empty().AtSetValue(types.StringValue("test")), + "Invalid Schema Path", + "When attempting to get the framework attribute associated with a schema path, an unexpected error was returned. "+ + "This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + "Path: [Value(\"test\")]\n"+ + "Original Error: ElementKeyValue(tftypes.String<\"test\">) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyValue to schema", + ), + }, + }, + } + + for name, tc := range testCases { + + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, diags := tc.schema.AttributeAtPath(context.Background(), tc.path) + + if diff := cmp.Diff(diags, tc.expectedDiags); diff != "" { + t.Errorf("Unexpected diagnostics (+wanted, -got): %s", diff) + } + + if diff := cmp.Diff(got, tc.expected); diff != "" { + t.Errorf("Unexpected result (+wanted, -got): %s", diff) + } + }) + } +} + +func TestSchemaAttributeAtTerraformPath(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + path *tftypes.AttributePath + expected fwschema.Attribute + expectedErr string + }{ + "empty-root": { + schema: identityschema.Schema{}, + path: tftypes.NewAttributePath(), + expected: nil, + expectedErr: "got unexpected type identityschema.Schema", + }, + "empty-nil": { + schema: identityschema.Schema{}, + path: nil, + expected: nil, + expectedErr: "got unexpected type identityschema.Schema", + }, + "root": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.StringAttribute{}, + }, + }, + path: tftypes.NewAttributePath(), + expected: nil, + expectedErr: "got unexpected type identityschema.Schema", + }, + "nil": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.StringAttribute{}, + }, + }, + path: nil, + expected: nil, + expectedErr: "got unexpected type identityschema.Schema", + }, + "WithAttributeName-attribute": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "other": identityschema.BoolAttribute{}, + "test": identityschema.StringAttribute{}, + }, + }, + path: tftypes.NewAttributePath().WithAttributeName("test"), + expected: identityschema.StringAttribute{}, + }, + "WithElementKeyInt": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.StringAttribute{}, + }, + }, + path: tftypes.NewAttributePath().WithElementKeyInt(0), + expected: nil, + expectedErr: "ElementKeyInt(0) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyInt to schema", + }, + "WithElementKeyString": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.StringAttribute{}, + }, + }, + path: tftypes.NewAttributePath().WithElementKeyString("test"), + expected: nil, + expectedErr: "ElementKeyString(\"test\") still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyString to schema", + }, + "WithElementKeyValue": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.StringAttribute{}, + }, + }, + path: tftypes.NewAttributePath().WithElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedErr: "ElementKeyValue(tftypes.String<\"test\">) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyValue to schema", + }, + } + + for name, tc := range testCases { + + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := tc.schema.AttributeAtTerraformPath(context.Background(), tc.path) + + if err != nil { + if tc.expectedErr == "" { + t.Errorf("Unexpected error: %s", err) + return + } + if err.Error() != tc.expectedErr { + t.Errorf("Expected error to be %q, got %q", tc.expectedErr, err.Error()) + return + } + // got expected error + return + } + + if err == nil && tc.expectedErr != "" { + t.Errorf("Expected error to be %q, got nil", tc.expectedErr) + return + } + + if diff := cmp.Diff(got, tc.expected); diff != "" { + t.Errorf("Unexpected result (+wanted, -got): %s", diff) + } + }) + } +} + +func TestSchemaGetAttributes(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + expected map[string]fwschema.Attribute + }{ + "no-attributes": { + schema: identityschema.Schema{}, + expected: map[string]fwschema.Attribute{}, + }, + "attributes": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr1": identityschema.StringAttribute{}, + "testattr2": identityschema.StringAttribute{}, + }, + }, + expected: map[string]fwschema.Attribute{ + "testattr1": identityschema.StringAttribute{}, + "testattr2": identityschema.StringAttribute{}, + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.schema.GetAttributes() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaGetBlocks(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + expected map[string]fwschema.Block + }{ + "no-blocks": { + schema: identityschema.Schema{}, + expected: map[string]fwschema.Block{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.schema.GetBlocks() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaGetDeprecationMessage(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + expected string + }{ + "no-deprecation-message": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.schema.GetDeprecationMessage() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaGetDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + expected string + }{ + "no-description": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.schema.GetDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaGetMarkdownDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + expected string + }{ + "no-markdown-description": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.schema.GetMarkdownDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaGetVersion(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + expected int64 + }{ + "no-version": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + expected: 0, + }, + "version": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + Version: 1, + }, + expected: 1, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.schema.GetVersion() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + expected attr.Type + }{ + "base": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "testattr": identityschema.StringAttribute{}, + }, + }, + expected: types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "testattr": types.StringType, + }, + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.schema.Type() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaTypeAtPath(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + path path.Path + expected attr.Type + expectedDiags diag.Diagnostics + }{ + "empty-schema-empty-path": { + schema: identityschema.Schema{}, + path: path.Empty(), + expected: types.ObjectType{}, + }, + "empty-path": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "bool": identityschema.BoolAttribute{}, + "string": identityschema.StringAttribute{}, + }, + }, + path: path.Empty(), + expected: types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "bool": types.BoolType, + "string": types.StringType, + }, + }, + }, + "AttributeName-Attribute": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "bool": identityschema.BoolAttribute{}, + "string": identityschema.StringAttribute{}, + }, + }, + path: path.Root("string"), + expected: types.StringType, + }, + "AttributeName-non-existent": { + schema: identityschema.Schema{}, + path: path.Root("non-existent"), + expectedDiags: diag.Diagnostics{ + diag.NewAttributeErrorDiagnostic( + path.Root("non-existent"), + "Invalid Schema Path", + "When attempting to get the framework type associated with a schema path, an unexpected error was returned. This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + "Path: non-existent\n"+ + "Original Error: AttributeName(\"non-existent\") still remains in the path: could not find attribute or block \"non-existent\" in schema", + ), + }, + }, + "ElementKeyInt": { + schema: identityschema.Schema{}, + path: path.Empty().AtListIndex(0), + expectedDiags: diag.Diagnostics{ + diag.NewAttributeErrorDiagnostic( + path.Empty().AtListIndex(0), + "Invalid Schema Path", + "When attempting to get the framework type associated with a schema path, an unexpected error was returned. This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + "Path: [0]\n"+ + "Original Error: ElementKeyInt(0) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyInt to schema", + ), + }, + }, + "ElementKeyString": { + schema: identityschema.Schema{}, + path: path.Empty().AtMapKey("invalid"), + expectedDiags: diag.Diagnostics{ + diag.NewAttributeErrorDiagnostic( + path.Empty().AtMapKey("invalid"), + "Invalid Schema Path", + "When attempting to get the framework type associated with a schema path, an unexpected error was returned. This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + "Path: [\"invalid\"]\n"+ + "Original Error: ElementKeyString(\"invalid\") still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyString to schema", + ), + }, + }, + "ElementKeyValue": { + schema: identityschema.Schema{}, + path: path.Empty().AtSetValue(types.StringNull()), + expectedDiags: diag.Diagnostics{ + diag.NewAttributeErrorDiagnostic( + path.Empty().AtSetValue(types.StringNull()), + "Invalid Schema Path", + "When attempting to get the framework type associated with a schema path, an unexpected error was returned. This is always an issue with the provider. Please report this to the provider developers.\n\n"+ + "Path: [Value()]\n"+ + "Original Error: ElementKeyValue(tftypes.String) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyValue to schema", + ), + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, diags := testCase.schema.TypeAtPath(context.Background(), testCase.path) + + if diff := cmp.Diff(diags, testCase.expectedDiags); diff != "" { + t.Errorf("unexpected diagnostics difference: %s", diff) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaTypeAtTerraformPath(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + path *tftypes.AttributePath + expected attr.Type + expectedError error + }{ + "empty-schema-nil-path": { + schema: identityschema.Schema{}, + path: nil, + expected: types.ObjectType{}, + }, + "empty-schema-empty-path": { + schema: identityschema.Schema{}, + path: tftypes.NewAttributePath(), + expected: types.ObjectType{}, + }, + "nil-path": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "bool": identityschema.BoolAttribute{}, + "string": identityschema.StringAttribute{}, + }, + }, + path: nil, + expected: types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "bool": types.BoolType, + "string": types.StringType, + }, + }, + }, + "empty-path": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "bool": identityschema.BoolAttribute{}, + "string": identityschema.StringAttribute{}, + }, + }, + path: tftypes.NewAttributePath(), + expected: types.ObjectType{ + AttrTypes: map[string]attr.Type{ + "bool": types.BoolType, + "string": types.StringType, + }, + }, + }, + "AttributeName-Attribute": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "bool": identityschema.BoolAttribute{}, + "string": identityschema.StringAttribute{}, + }, + }, + path: tftypes.NewAttributePath().WithAttributeName("string"), + expected: types.StringType, + }, + "AttributeName-non-existent": { + schema: identityschema.Schema{}, + path: tftypes.NewAttributePath().WithAttributeName("non-existent"), + expectedError: fmt.Errorf("AttributeName(\"non-existent\") still remains in the path: could not find attribute or block \"non-existent\" in schema"), + }, + "ElementKeyInt": { + schema: identityschema.Schema{}, + path: tftypes.NewAttributePath().WithElementKeyInt(0), + expectedError: fmt.Errorf("ElementKeyInt(0) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyInt to schema"), + }, + "ElementKeyString": { + schema: identityschema.Schema{}, + path: tftypes.NewAttributePath().WithElementKeyString("invalid"), + expectedError: fmt.Errorf("ElementKeyString(\"invalid\") still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyString to schema"), + }, + "ElementKeyValue": { + schema: identityschema.Schema{}, + path: tftypes.NewAttributePath().WithElementKeyValue(tftypes.NewValue(tftypes.String, nil)), + expectedError: fmt.Errorf("ElementKeyValue(tftypes.String) still remains in the path: cannot apply AttributePathStep tftypes.ElementKeyValue to schema"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.schema.TypeAtTerraformPath(context.Background(), testCase.path) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestSchemaValidate(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + expectedDiags diag.Diagnostics + }{ + "empty-schema": { + schema: identityschema.Schema{}, + }, + "validate-implementation-error": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "depends_on": identityschema.StringAttribute{}, + }, + }, + expectedDiags: diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Reserved Root Attribute/Block Name", + "When validating the resource or data source schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + "\"depends_on\" is a reserved root attribute/block name. "+ + "This is to prevent practitioners from needing special Terraform configuration syntax.", + ), + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + diags := testCase.schema.Validate() + + if diff := cmp.Diff(diags, testCase.expectedDiags); diff != "" { + t.Errorf("Unexpected diagnostics (+wanted, -got): %s", diff) + } + }) + } +} + +func TestSchemaValidateImplementation(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + schema identityschema.Schema + expectedDiags diag.Diagnostics + }{ + "empty-schema": { + schema: identityschema.Schema{}, + }, + "attribute-using-reserved-field-name": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "depends_on": identityschema.StringAttribute{}, + }, + }, + expectedDiags: diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Reserved Root Attribute/Block Name", + "When validating the resource or data source schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + "\"depends_on\" is a reserved root attribute/block name. "+ + "This is to prevent practitioners from needing special Terraform configuration syntax.", + ), + }, + }, + "attribute-using-invalid-field-name": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "^": identityschema.StringAttribute{}, + }, + }, + expectedDiags: diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Invalid Attribute/Block Name", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + "\"^\" at schema path \"^\" is an invalid attribute/block name. "+ + "Names must only contain lowercase alphanumeric characters (a-z, 0-9) and underscores (_).", + ), + }, + }, + "attribute-with-validate-attribute-implementation-error": { + schema: identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test": identityschema.ListAttribute{ + RequiredForImport: true, + }, + }, + }, + expectedDiags: diag.Diagnostics{ + diag.NewErrorDiagnostic( + "Invalid Attribute Implementation", + "When validating the schema, an implementation issue was found. "+ + "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ + "\"test\" is missing the CustomType or ElementType field on a collection Attribute. "+ + "One of these fields is required to prevent other unexpected errors or panics.", + ), + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + diags := testCase.schema.ValidateImplementation(context.Background()) + + if diff := cmp.Diff(diags, testCase.expectedDiags); diff != "" { + t.Errorf("Unexpected diagnostics (+wanted, -got): %s", diff) + } + }) + } +} diff --git a/resource/identityschema/string_attribute.go b/resource/identityschema/string_attribute.go new file mode 100644 index 00000000..3061b89c --- /dev/null +++ b/resource/identityschema/string_attribute.go @@ -0,0 +1,127 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema + +import ( + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-framework/types/basetypes" +) + +// Ensure the implementation satisfies the desired interfaces. +var ( + _ Attribute = StringAttribute{} +) + +// StringAttribute represents a schema attribute that is a string. When +// retrieving the value for this attribute, use types.String as the value type +// unless the CustomType field is set. +// +// Terraform configurations configure this attribute using expressions that +// return a string or directly via double quote syntax. +// +// example_attribute = "value" +type StringAttribute struct { + // CustomType enables the use of a custom attribute type in place of the + // default basetypes.StringType. When retrieving data, the basetypes.StringValuable + // associated with this custom type must be used in place of types.String. + CustomType basetypes.StringTypable + + // RequiredForImport indicates whether the practitioner must enter a value for + // this attribute when importing a managed resource by this identity. + // RequiredForImport and OptionalForImport cannot both be true. + RequiredForImport bool + + // OptionalForImport indicates whether the practitioner can choose to enter a value + // for this attribute when importing a managed resource by this identity. + // OptionalForImport and RequiredForImport cannot both be true. + OptionalForImport bool + + // Description is used in various tooling, like the language server or the documentation + // generator, to give practitioners more information about what this attribute is, + // what it's for, and how it should be used. It can be written as plain text with no + // special formatting, or formatted as Markdown. + Description string +} + +// ApplyTerraform5AttributePathStep always returns an error as it is not +// possible to step further into a StringAttribute. +func (a StringAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) { + return a.GetType().ApplyTerraform5AttributePathStep(step) +} + +// Equal returns true if the given Attribute is a StringAttribute +// and all fields are equal. +func (a StringAttribute) Equal(o fwschema.Attribute) bool { + if _, ok := o.(StringAttribute); !ok { + return false + } + + return fwschema.AttributesEqual(a, o) +} + +// GetDeprecationMessage returns an empty string as identity attributes cannot +// surface deprecation messages. +func (a StringAttribute) GetDeprecationMessage() string { + return "" +} + +// GetDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain plaintext or Markdown. +func (a StringAttribute) GetDescription() string { + return a.Description +} + +// GetMarkdownDescription returns the Description field value. For identity attributes, +// there is only a single description field that is permitted to contain Markdown or plaintext. +func (a StringAttribute) GetMarkdownDescription() string { + return a.Description +} + +// GetType returns types.StringType or the CustomType field value if defined. +func (a StringAttribute) GetType() attr.Type { + if a.CustomType != nil { + return a.CustomType + } + + return types.StringType +} + +// IsComputed returns false as it's not relevant for identity schemas. +func (a StringAttribute) IsComputed() bool { + return false +} + +// IsOptional returns false as it's not relevant for identity schemas. +func (a StringAttribute) IsOptional() bool { + return false +} + +// IsRequired returns false as it's not relevant for identity schemas. +func (a StringAttribute) IsRequired() bool { + return false +} + +// IsSensitive returns false as it's not relevant for identity schemas. +func (a StringAttribute) IsSensitive() bool { + return false +} + +// IsWriteOnly returns false as it's not relevant for identity schemas. +func (a StringAttribute) IsWriteOnly() bool { + return false +} + +// IsRequiredForImport returns the RequiredForImport field value. +func (a StringAttribute) IsRequiredForImport() bool { + return a.RequiredForImport +} + +// IsOptionalForImport returns the OptionalForImport field value. +func (a StringAttribute) IsOptionalForImport() bool { + return a.OptionalForImport +} diff --git a/resource/identityschema/string_attribute_test.go b/resource/identityschema/string_attribute_test.go new file mode 100644 index 00000000..18f6666e --- /dev/null +++ b/resource/identityschema/string_attribute_test.go @@ -0,0 +1,431 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package identityschema_test + +import ( + "fmt" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/attr" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testtypes" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestStringAttributeApplyTerraform5AttributePathStep(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + step tftypes.AttributePathStep + expected any + expectedError error + }{ + "AttributeName": { + attribute: identityschema.StringAttribute{}, + step: tftypes.AttributeName("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.AttributeName to basetypes.StringType"), + }, + "ElementKeyInt": { + attribute: identityschema.StringAttribute{}, + step: tftypes.ElementKeyInt(1), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyInt to basetypes.StringType"), + }, + "ElementKeyString": { + attribute: identityschema.StringAttribute{}, + step: tftypes.ElementKeyString("test"), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyString to basetypes.StringType"), + }, + "ElementKeyValue": { + attribute: identityschema.StringAttribute{}, + step: tftypes.ElementKeyValue(tftypes.NewValue(tftypes.String, "test")), + expected: nil, + expectedError: fmt.Errorf("cannot apply AttributePathStep tftypes.ElementKeyValue to basetypes.StringType"), + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.attribute.ApplyTerraform5AttributePathStep(testCase.step) + + if err != nil { + if testCase.expectedError == nil { + t.Fatalf("expected no error, got: %s", err) + } + + if !strings.Contains(err.Error(), testCase.expectedError.Error()) { + t.Fatalf("expected error %q, got: %s", testCase.expectedError, err) + } + } + + if err == nil && testCase.expectedError != nil { + t.Fatalf("got no error, expected: %s", testCase.expectedError) + } + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeGetDeprecationMessage(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected string + }{ + "no-deprecation-message": { + attribute: identityschema.StringAttribute{}, + expected: "", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDeprecationMessage() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeEqual(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + other fwschema.Attribute + expected bool + }{ + "different-type": { + attribute: identityschema.StringAttribute{}, + other: testschema.AttributeWithStringValidators{}, + expected: false, + }, + "equal": { + attribute: identityschema.StringAttribute{}, + other: identityschema.StringAttribute{}, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.Equal(testCase.other) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeGetDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected string + }{ + "no-description": { + attribute: identityschema.StringAttribute{}, + expected: "", + }, + "description": { + attribute: identityschema.StringAttribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeGetMarkdownDescription(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected string + }{ + "no-markdown-description": { + attribute: identityschema.StringAttribute{}, + expected: "", + }, + "markdown-description-from-description": { + attribute: identityschema.StringAttribute{ + Description: "test description", + }, + expected: "test description", + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetMarkdownDescription() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeGetType(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected attr.Type + }{ + "base": { + attribute: identityschema.StringAttribute{}, + expected: types.StringType, + }, + "custom-type": { + attribute: identityschema.StringAttribute{ + CustomType: testtypes.StringType{}, + }, + expected: testtypes.StringType{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.GetType() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsComputed(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected bool + }{ + "not-computed": { + attribute: identityschema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsComputed() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsOptional(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected bool + }{ + "not-optional": { + attribute: identityschema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptional() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsRequired(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected bool + }{ + "not-required": { + attribute: identityschema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequired() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsSensitive(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected bool + }{ + "not-sensitive": { + attribute: identityschema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsSensitive() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsWriteOnly(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected bool + }{ + "not-writeOnly": { + attribute: identityschema.StringAttribute{}, + expected: false, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsWriteOnly() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsRequiredForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected bool + }{ + "not-requiredForImport": { + attribute: identityschema.StringAttribute{}, + expected: false, + }, + "requiredForImport": { + attribute: identityschema.StringAttribute{ + RequiredForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsRequiredForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} + +func TestStringAttributeIsOptionalForImport(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + attribute identityschema.StringAttribute + expected bool + }{ + "not-optionalForImport": { + attribute: identityschema.StringAttribute{}, + expected: false, + }, + "optionalForImport": { + attribute: identityschema.StringAttribute{ + OptionalForImport: true, + }, + expected: true, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := testCase.attribute.IsOptionalForImport() + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/resource/resource.go b/resource/resource.go index 7113d4bf..ce2694a2 100644 --- a/resource/resource.go +++ b/resource/resource.go @@ -196,3 +196,13 @@ type ResourceWithValidateConfig interface { // ValidateConfig performs the validation. ValidateConfig(context.Context, ValidateConfigRequest, *ValidateConfigResponse) } + +// ResourceWithIdentity is an interface type that extends Resource to implement managed resource identity. +// +// TODO: Describe identity concept in more detail, reference the upgrade identity interface +type ResourceWithIdentity interface { + Resource + + // IdentitySchema should return the identity schema for this resource. + IdentitySchema(context.Context, IdentitySchemaRequest, *IdentitySchemaResponse) +} From 63dc8256674896f1155d28953ae879c3d851fd39 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Thu, 6 Mar 2025 17:42:14 -0500 Subject: [PATCH 10/14] protov6 + tests --- .../fromproto6/getresourceidentityschemas.go | 23 ++ .../getresourceidentityschemas_test.go | 44 +++ .../server_getresourceidentityschemas.go | 27 ++ .../server_getresourceidentityschemas_test.go | 218 +++++++++++ .../server_upgraderesourceidentity.go | 15 + .../toproto6/getresourceidentityschemas.go | 42 ++ .../getresourceidentityschemas_test.go | 367 ++++++++++++++++++ internal/toproto6/identity_schema.go | 52 +++ .../toproto6/identity_schema_attribute.go | 43 ++ .../identity_schema_attribute_test.go | 257 ++++++++++++ internal/toproto6/identity_schema_test.go | 138 +++++++ 11 files changed, 1226 insertions(+) create mode 100644 internal/fromproto6/getresourceidentityschemas.go create mode 100644 internal/fromproto6/getresourceidentityschemas_test.go create mode 100644 internal/proto6server/server_getresourceidentityschemas.go create mode 100644 internal/proto6server/server_getresourceidentityschemas_test.go create mode 100644 internal/proto6server/server_upgraderesourceidentity.go create mode 100644 internal/toproto6/getresourceidentityschemas.go create mode 100644 internal/toproto6/getresourceidentityschemas_test.go create mode 100644 internal/toproto6/identity_schema.go create mode 100644 internal/toproto6/identity_schema_attribute.go create mode 100644 internal/toproto6/identity_schema_attribute_test.go create mode 100644 internal/toproto6/identity_schema_test.go diff --git a/internal/fromproto6/getresourceidentityschemas.go b/internal/fromproto6/getresourceidentityschemas.go new file mode 100644 index 00000000..448c5b56 --- /dev/null +++ b/internal/fromproto6/getresourceidentityschemas.go @@ -0,0 +1,23 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetResourceIdentitySchemasRequest returns the *fwserver.GetResourceIdentitySchemasRequest +// equivalent of a *tfprotov6.GetResourceIdentitySchemasRequest. +func GetResourceIdentitySchemasRequest(ctx context.Context, proto6 *tfprotov6.GetResourceIdentitySchemasRequest) *fwserver.GetResourceIdentitySchemasRequest { + if proto6 == nil { + return nil + } + + fw := &fwserver.GetResourceIdentitySchemasRequest{} + + return fw +} diff --git a/internal/fromproto6/getresourceidentityschemas_test.go b/internal/fromproto6/getresourceidentityschemas_test.go new file mode 100644 index 00000000..22ab5120 --- /dev/null +++ b/internal/fromproto6/getresourceidentityschemas_test.go @@ -0,0 +1,44 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package fromproto6_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +func TestGetResourceIdentitySchemasRequest(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + input *tfprotov6.GetResourceIdentitySchemasRequest + expected *fwserver.GetResourceIdentitySchemasRequest + }{ + "nil": { + input: nil, + expected: nil, + }, + "empty": { + input: &tfprotov6.GetResourceIdentitySchemasRequest{}, + expected: &fwserver.GetResourceIdentitySchemasRequest{}, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := fromproto6.GetResourceIdentitySchemasRequest(context.Background(), testCase.input) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/internal/proto6server/server_getresourceidentityschemas.go b/internal/proto6server/server_getresourceidentityschemas.go new file mode 100644 index 00000000..5258d024 --- /dev/null +++ b/internal/proto6server/server_getresourceidentityschemas.go @@ -0,0 +1,27 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fromproto6" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetResourceIdentitySchemas satisfies the tfprotov6.ProviderServer interface. +func (s *Server) GetResourceIdentitySchemas(ctx context.Context, proto6Req *tfprotov6.GetResourceIdentitySchemasRequest) (*tfprotov6.GetResourceIdentitySchemasResponse, error) { + ctx = s.registerContext(ctx) + ctx = logging.InitContext(ctx) + + fwReq := fromproto6.GetResourceIdentitySchemasRequest(ctx, proto6Req) + fwResp := &fwserver.GetResourceIdentitySchemasResponse{} + + s.FrameworkServer.GetResourceIdentitySchemas(ctx, fwReq, fwResp) + + return toproto6.GetResourceIdentitySchemasResponse(ctx, fwResp), nil +} diff --git a/internal/proto6server/server_getresourceidentityschemas_test.go b/internal/proto6server/server_getresourceidentityschemas_test.go new file mode 100644 index 00000000..d5d7ddfc --- /dev/null +++ b/internal/proto6server/server_getresourceidentityschemas_test.go @@ -0,0 +1,218 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "bytes" + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/logging" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testprovider" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" + "github.com/hashicorp/terraform-plugin-log/tfsdklogtest" +) + +func TestServerGetResourceIdentitySchemas(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + server *Server + request *tfprotov6.GetResourceIdentitySchemasRequest + expectedError error + expectedResponse *tfprotov6.GetResourceIdentitySchemasResponse + }{ + "resource-identity-schemas": { + server: &Server{ + FrameworkServer: fwserver.Server{ + Provider: &testprovider.Provider{ + ResourcesMethod: func(_ context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource1" + }, + }, + IdentitySchemaMethod: func(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test1": identityschema.StringAttribute{ + RequiredForImport: true, + }, + }, + } + }, + } + }, + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "test_resource2" + }, + }, + IdentitySchemaMethod: func(_ context.Context, _ resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test2": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + } + }, + } + }, + } + }, + }, + }, + }, + request: &tfprotov6.GetResourceIdentitySchemasRequest{}, + expectedResponse: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource1": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test1", + RequiredForImport: true, + Type: tftypes.String, + }, + }, + }, + "test_resource2": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test2", + RequiredForImport: true, + Type: tftypes.Bool, + }, + }, + }, + }, + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := testCase.server.GetResourceIdentitySchemas(context.Background(), new(tfprotov6.GetResourceIdentitySchemasRequest)) + + if diff := cmp.Diff(testCase.expectedError, err); diff != "" { + t.Errorf("unexpected error difference: %s", diff) + } + + if diff := cmp.Diff(testCase.expectedResponse, got); diff != "" { + t.Errorf("unexpected response difference: %s", diff) + } + }) + } +} + +func TestServerGetResourceIdentitySchemas_logging(t *testing.T) { + t.Parallel() + + var output bytes.Buffer + + ctx := tfsdklogtest.RootLogger(context.Background(), &output) + ctx = logging.InitContext(ctx) + + testServer := &Server{ + FrameworkServer: fwserver.Server{ + Provider: &testprovider.Provider{ + ResourcesMethod: func(ctx context.Context) []func() resource.Resource { + return []func() resource.Resource{ + func() resource.Resource { + return &testprovider.ResourceWithIdentity{ + Resource: &testprovider.Resource{ + MetadataMethod: func(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { + resp.TypeName = "examplecloud_thing" + }, + }, + IdentitySchemaMethod: func(ctx context.Context, req resource.IdentitySchemaRequest, resp *resource.IdentitySchemaResponse) { + resp.IdentitySchema = identityschema.Schema{} + }, + } + }, + } + }, + }, + }, + } + + _, err := testServer.GetResourceIdentitySchemas(ctx, new(tfprotov6.GetResourceIdentitySchemasRequest)) + + if err != nil { + t.Fatalf("unexpected error: %s", err) + } + + entries, err := tfsdklogtest.MultilineJSONDecode(&output) + + if err != nil { + t.Fatalf("unable to read multiple line JSON: %s", err) + } + + expectedEntries := []map[string]interface{}{ + { + "@level": "trace", + "@message": "Checking ResourceTypes lock", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Checking ProviderTypeName lock", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Calling provider defined Provider Metadata", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Called provider defined Provider Metadata", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Calling provider defined Provider Resources", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Called provider defined Provider Resources", + "@module": "sdk.framework", + }, + { + "@level": "trace", + "@message": "Found resource type", + "@module": "sdk.framework", + "tf_resource_type": "examplecloud_thing", + }, + { + "@level": "trace", + "@message": "Calling provider defined Resource IdentitySchema method", + "@module": "sdk.framework", + "tf_resource_type": "examplecloud_thing", + }, + { + "@level": "trace", + "@message": "Called provider defined Resource IdentitySchema method", + "@module": "sdk.framework", + "tf_resource_type": "examplecloud_thing", + }, + } + + if diff := cmp.Diff(entries, expectedEntries); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } +} diff --git a/internal/proto6server/server_upgraderesourceidentity.go b/internal/proto6server/server_upgraderesourceidentity.go new file mode 100644 index 00000000..d5f55ab2 --- /dev/null +++ b/internal/proto6server/server_upgraderesourceidentity.go @@ -0,0 +1,15 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package proto6server + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// UpgradeResourceIdentity satisfies the tfprotov6.ProviderServer interface. +func (s *Server) UpgradeResourceIdentity(ctx context.Context, proto6Req *tfprotov6.UpgradeResourceIdentityRequest) (*tfprotov6.UpgradeResourceIdentityResponse, error) { + panic("unimplemented") // TODO: implement +} diff --git a/internal/toproto6/getresourceidentityschemas.go b/internal/toproto6/getresourceidentityschemas.go new file mode 100644 index 00000000..eb5d406e --- /dev/null +++ b/internal/toproto6/getresourceidentityschemas.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// GetResourceIdentitySchemasResponse returns the *tfprotov6.GetResourceIdentitySchemasResponse +// equivalent of a *fwserver.GetResourceIdentitySchemasResponse. +func GetResourceIdentitySchemasResponse(ctx context.Context, fw *fwserver.GetResourceIdentitySchemasResponse) *tfprotov6.GetResourceIdentitySchemasResponse { + if fw == nil { + return nil + } + + protov6 := &tfprotov6.GetResourceIdentitySchemasResponse{ + Diagnostics: Diagnostics(ctx, fw.Diagnostics), + IdentitySchemas: make(map[string]*tfprotov6.ResourceIdentitySchema, len(fw.IdentitySchemas)), + } + + var err error + + for resourceType, identitySchema := range fw.IdentitySchemas { + protov6.IdentitySchemas[resourceType], err = IdentitySchema(ctx, identitySchema) + + if err != nil { + protov6.Diagnostics = append(protov6.Diagnostics, &tfprotov6.Diagnostic{ + Severity: tfprotov6.DiagnosticSeverityError, + Summary: "Error converting resource identity schema", + Detail: "The identity schema for the resource \"" + resourceType + "\" couldn't be converted into a usable type. This is always a problem with the provider. Please report the following to the provider developer:\n\n" + err.Error(), + }) + + return protov6 + } + } + + return protov6 +} diff --git a/internal/toproto6/getresourceidentityschemas_test.go b/internal/toproto6/getresourceidentityschemas_test.go new file mode 100644 index 00000000..86670bdf --- /dev/null +++ b/internal/toproto6/getresourceidentityschemas_test.go @@ -0,0 +1,367 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/fwserver" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-framework/resource/identityschema" + "github.com/hashicorp/terraform-plugin-framework/types" +) + +func TestGetResourceIdentitySchemasResponse(t *testing.T) { + t.Parallel() + + testCases := map[string]struct { + input *fwserver.GetResourceIdentitySchemasResponse + expected *tfprotov6.GetResourceIdentitySchemasResponse + }{ + "nil": { + input: nil, + expected: nil, + }, + "resource-identity-identity-multiple-resources": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource_1": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + }, + "test_resource_2": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource_1": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + RequiredForImport: true, + Name: "test_attribute", + Type: tftypes.Bool, + }, + }, + }, + "test_resource_2": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + RequiredForImport: true, + Name: "test_attribute", + Type: tftypes.Bool, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-optionalforimport": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + OptionalForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + OptionalForImport: true, + Type: tftypes.Bool, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-requiredforimport": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + Type: tftypes.Bool, + RequiredForImport: true, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-bool": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.BoolAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Bool, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-float32": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.Float32Attribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-float64": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.Float64Attribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-int32": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.Int32Attribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-int64": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.Int64Attribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-list-string": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.ListAttribute{ + RequiredForImport: true, + ElementType: types.StringType, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.List{ + ElementType: tftypes.String, + }, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-number": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.NumberAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.Number, + }, + }, + }, + }, + }, + }, + "resource-identity-attribute-type-string": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Attributes: map[string]identityschema.Attribute{ + "test_attribute": identityschema.StringAttribute{ + RequiredForImport: true, + }, + }, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "test_attribute", + RequiredForImport: true, + Type: tftypes.String, + }, + }, + }, + }, + }, + }, + "resource-identity-version": { + input: &fwserver.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]fwschema.Schema{ + "test_resource": identityschema.Schema{ + Version: 123, + }, + }, + }, + expected: &tfprotov6.GetResourceIdentitySchemasResponse{ + IdentitySchemas: map[string]*tfprotov6.ResourceIdentitySchema{ + "test_resource": { + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{}, + Version: 123, + }, + }, + }, + }, + } + + for name, testCase := range testCases { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got := toproto6.GetResourceIdentitySchemasResponse(context.Background(), testCase.input) + + if diff := cmp.Diff(got, testCase.expected); diff != "" { + t.Errorf("unexpected difference: %s", diff) + } + }) + } +} diff --git a/internal/toproto6/identity_schema.go b/internal/toproto6/identity_schema.go new file mode 100644 index 00000000..3c645580 --- /dev/null +++ b/internal/toproto6/identity_schema.go @@ -0,0 +1,52 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + "sort" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +// IdentitySchema returns the *tfprotov6.ResourceIdentitySchema equivalent of a Schema. +func IdentitySchema(ctx context.Context, s fwschema.Schema) (*tfprotov6.ResourceIdentitySchema, error) { + if s == nil { + return nil, nil + } + + result := &tfprotov6.ResourceIdentitySchema{ + Version: s.GetVersion(), + } + + attrs := make([]*tfprotov6.ResourceIdentitySchemaAttribute, 0) + + for name, attr := range s.GetAttributes() { + a, err := IdentitySchemaAttribute(ctx, name, tftypes.NewAttributePath().WithAttributeName(name), attr) + + if err != nil { + return nil, err + } + + attrs = append(attrs, a) + } + + sort.Slice(attrs, func(i, j int) bool { + if attrs[i] == nil { + return true + } + + if attrs[j] == nil { + return false + } + + return attrs[i].Name < attrs[j].Name + }) + + result.IdentityAttributes = attrs + + return result, nil +} diff --git a/internal/toproto6/identity_schema_attribute.go b/internal/toproto6/identity_schema_attribute.go new file mode 100644 index 00000000..5fe815de --- /dev/null +++ b/internal/toproto6/identity_schema_attribute.go @@ -0,0 +1,43 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6 + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" + + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" +) + +// IdentitySchemaAttribute returns the *tfprotov6.ResourceIdentitySchemaAttribute equivalent of an +// Attribute. Errors will be tftypes.AttributePathErrors based on `path`. `name` is the name of the attribute. +func IdentitySchemaAttribute(ctx context.Context, name string, path *tftypes.AttributePath, a fwschema.Attribute) (*tfprotov6.ResourceIdentitySchemaAttribute, error) { + if _, ok := a.(fwschema.NestedAttribute); ok { + return nil, path.NewErrorf("identity schemas don't support NestedAttribute") + } + + if a.GetType() == nil { + return nil, path.NewErrorf("must have Type set") + } + + if !a.IsRequiredForImport() && !a.IsOptionalForImport() { + return nil, path.NewErrorf("must have RequiredForImport or OptionalForImport set") + } + + identitySchemaAttribute := &tfprotov6.ResourceIdentitySchemaAttribute{ + Name: name, + RequiredForImport: a.IsRequiredForImport(), + OptionalForImport: a.IsOptionalForImport(), + Type: a.GetType().TerraformType(ctx), + + // Unlike other schema attributes, identity attributes only have a single description field which + // is assumed to be markdown. Both a.GetDescription() and a.GetMarkdownDescription() will return + // the same string, so we just chose one here. + Description: a.GetDescription(), + } + + return identitySchemaAttribute, nil +} diff --git a/internal/toproto6/identity_schema_attribute_test.go b/internal/toproto6/identity_schema_attribute_test.go new file mode 100644 index 00000000..45fa0d1a --- /dev/null +++ b/internal/toproto6/identity_schema_attribute_test.go @@ -0,0 +1,257 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +func TestIdentitySchemaAttribute(t *testing.T) { + t.Parallel() + + type testCase struct { + name string + attr fwschema.Attribute + path *tftypes.AttributePath + expected *tfprotov6.ResourceIdentitySchemaAttribute + expectedErr string + } + + tests := map[string]testCase{ + "description": { + name: "string", + attr: testschema.Attribute{ + Type: types.StringType, + RequiredForImport: true, + Description: "A string attribute", + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov6.ResourceIdentitySchemaAttribute{ + Name: "string", + Type: tftypes.String, + RequiredForImport: true, + Description: "A string attribute", + }, + }, + "attr-string": { + name: "string", + attr: testschema.Attribute{ + Type: types.StringType, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov6.ResourceIdentitySchemaAttribute{ + Name: "string", + Type: tftypes.String, + RequiredForImport: true, + }, + }, + "attr-bool": { + name: "bool", + attr: testschema.Attribute{ + Type: types.BoolType, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov6.ResourceIdentitySchemaAttribute{ + Name: "bool", + Type: tftypes.Bool, + RequiredForImport: true, + }, + }, + "attr-number": { + name: "number", + attr: testschema.Attribute{ + Type: types.NumberType, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov6.ResourceIdentitySchemaAttribute{ + Name: "number", + Type: tftypes.Number, + RequiredForImport: true, + }, + }, + "attr-list": { + name: "list", + attr: testschema.Attribute{ + Type: types.ListType{ElemType: types.NumberType}, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov6.ResourceIdentitySchemaAttribute{ + Name: "list", + Type: tftypes.List{ElementType: tftypes.Number}, + RequiredForImport: true, + }, + }, + "requiredforimport": { + name: "string", + attr: testschema.Attribute{ + Type: types.StringType, + RequiredForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov6.ResourceIdentitySchemaAttribute{ + Name: "string", + Type: tftypes.String, + RequiredForImport: true, + }, + }, + "optionalforimport": { + name: "string", + attr: testschema.Attribute{ + Type: types.StringType, + OptionalForImport: true, + }, + path: tftypes.NewAttributePath(), + expected: &tfprotov6.ResourceIdentitySchemaAttribute{ + Name: "string", + Type: tftypes.String, + OptionalForImport: true, + }, + }, + "nested-attr-single-error": { + name: "single_nested", + attr: testschema.NestedAttribute{ + NestedObject: testschema.NestedAttributeObject{ + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + Optional: true, + }, + "computed": testschema.Attribute{ + Type: types.NumberType, + Computed: true, + Sensitive: true, + }, + }, + }, + NestingMode: fwschema.NestingModeSingle, + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "identity schemas don't support NestedAttribute", + }, + "nested-attr-list-error": { + name: "list_nested", + attr: testschema.NestedAttribute{ + NestedObject: testschema.NestedAttributeObject{ + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + Optional: true, + }, + "computed": testschema.Attribute{ + Type: types.NumberType, + Computed: true, + Sensitive: true, + }, + }, + }, + NestingMode: fwschema.NestingModeList, + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "identity schemas don't support NestedAttribute", + }, + "nested-attr-map-error": { + name: "map_nested", + attr: testschema.NestedAttribute{ + NestedObject: testschema.NestedAttributeObject{ + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + Optional: true, + }, + "computed": testschema.Attribute{ + Type: types.NumberType, + Computed: true, + Sensitive: true, + }, + }, + }, + NestingMode: fwschema.NestingModeMap, + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "identity schemas don't support NestedAttribute", + }, + "nested-attr-set-error": { + name: "set_nested", + attr: testschema.NestedAttribute{ + NestedObject: testschema.NestedAttributeObject{ + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + Optional: true, + }, + "computed": testschema.Attribute{ + Type: types.NumberType, + Computed: true, + Sensitive: true, + }, + }, + }, + NestingMode: fwschema.NestingModeSet, + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "identity schemas don't support NestedAttribute", + }, + "attr-unset": { + name: "whoops", + attr: testschema.Attribute{ + Optional: true, + }, + path: tftypes.NewAttributePath(), + expectedErr: "must have Type set", + }, + "missing-requiredforimport-and-optionalforimport": { + name: "whoops", + attr: testschema.Attribute{ + Type: types.StringType, + }, + path: tftypes.NewAttributePath(), + expectedErr: "must have RequiredForImport or OptionalForImport set", + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := toproto6.IdentitySchemaAttribute(context.Background(), tc.name, tc.path, tc.attr) + if err != nil { + if tc.expectedErr == "" { + t.Errorf("Unexpected error: %s", err) + return + } + if err.Error() != tc.expectedErr { + t.Errorf("Expected error to be %q, got %q", tc.expectedErr, err.Error()) + return + } + // got expected error + return + } + if err == nil && tc.expectedErr != "" { + t.Errorf("Expected error to be %q, got nil", tc.expectedErr) + return + } + if diff := cmp.Diff(got, tc.expected); diff != "" { + t.Errorf("Unexpected diff (+wanted, -got): %s", diff) + return + } + }) + } +} diff --git a/internal/toproto6/identity_schema_test.go b/internal/toproto6/identity_schema_test.go new file mode 100644 index 00000000..f8ebd172 --- /dev/null +++ b/internal/toproto6/identity_schema_test.go @@ -0,0 +1,138 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package toproto6_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/hashicorp/terraform-plugin-framework/internal/fwschema" + "github.com/hashicorp/terraform-plugin-framework/internal/testing/testschema" + "github.com/hashicorp/terraform-plugin-framework/internal/toproto6" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" + "github.com/hashicorp/terraform-plugin-go/tftypes" +) + +func TestIdentitySchema(t *testing.T) { + t.Parallel() + + type testCase struct { + input fwschema.Schema + expected *tfprotov6.ResourceIdentitySchema + expectedErr string + } + + tests := map[string]testCase{ + "nil": { + input: nil, + expected: nil, + }, + "empty-val": { + input: testschema.Schema{}, + expected: &tfprotov6.ResourceIdentitySchema{ + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{}, + Version: 0, + }, + }, + "basic-attrs": { + input: testschema.Schema{ + Version: 1, + Attributes: map[string]fwschema.Attribute{ + "string": testschema.Attribute{ + Type: types.StringType, + RequiredForImport: true, + }, + "number": testschema.Attribute{ + Type: types.NumberType, + OptionalForImport: true, + }, + "bool": testschema.Attribute{ + Type: types.BoolType, + OptionalForImport: true, + }, + }, + }, + expected: &tfprotov6.ResourceIdentitySchema{ + Version: 1, + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "bool", + Type: tftypes.Bool, + OptionalForImport: true, + }, + { + Name: "number", + Type: tftypes.Number, + OptionalForImport: true, + }, + { + Name: "string", + Type: tftypes.String, + RequiredForImport: true, + }, + }, + }, + }, + "complex-attrs": { + input: testschema.Schema{ + Version: 2, + Attributes: map[string]fwschema.Attribute{ + "list_of_string": testschema.Attribute{ + Type: types.ListType{ElemType: types.StringType}, + RequiredForImport: true, + }, + "list_of_bool": testschema.Attribute{ + Type: types.ListType{ElemType: types.BoolType}, + RequiredForImport: true, + }, + }, + }, + expected: &tfprotov6.ResourceIdentitySchema{ + Version: 2, + IdentityAttributes: []*tfprotov6.ResourceIdentitySchemaAttribute{ + { + Name: "list_of_bool", + Type: tftypes.List{ElementType: tftypes.Bool}, + RequiredForImport: true, + }, + { + Name: "list_of_string", + Type: tftypes.List{ElementType: tftypes.String}, + RequiredForImport: true, + }, + }, + }, + }, + } + + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + t.Parallel() + + got, err := toproto6.IdentitySchema(context.Background(), tc.input) + if err != nil { + if tc.expectedErr == "" { + t.Errorf("Unexpected error: %s", err) + return + } + if err.Error() != tc.expectedErr { + t.Errorf("Expected error to be %q, got %q", tc.expectedErr, err.Error()) + return + } + // got expected error + return + } + if err == nil && tc.expectedErr != "" { + t.Errorf("Expected error to be %q, got nil", tc.expectedErr) + return + } + if diff := cmp.Diff(got, tc.expected); diff != "" { + t.Errorf("Unexpected diff (+wanted, -got): %s", diff) + return + } + }) + } +} From f97d278827b800746c4bd5554092d62741ae822b Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Thu, 6 Mar 2025 17:57:38 -0500 Subject: [PATCH 11/14] fix up package docs + build specific TODO comments --- .../server_upgraderesourceidentity.go | 2 +- .../server_upgraderesourceidentity.go | 2 +- resource/identityschema/doc.go | 2 -- resource/identityschema/list_attribute.go | 6 +---- .../identityschema/list_attribute_test.go | 23 ------------------- resource/identityschema/schema.go | 6 ++--- resource/resource.go | 2 +- 7 files changed, 6 insertions(+), 37 deletions(-) diff --git a/internal/proto5server/server_upgraderesourceidentity.go b/internal/proto5server/server_upgraderesourceidentity.go index bbd9a0a1..f5b1979f 100644 --- a/internal/proto5server/server_upgraderesourceidentity.go +++ b/internal/proto5server/server_upgraderesourceidentity.go @@ -11,5 +11,5 @@ import ( // UpgradeResourceIdentity satisfies the tfprotov5.ProviderServer interface. func (s *Server) UpgradeResourceIdentity(ctx context.Context, proto5Req *tfprotov5.UpgradeResourceIdentityRequest) (*tfprotov5.UpgradeResourceIdentityResponse, error) { - panic("unimplemented") // TODO: implement + panic("unimplemented") // TODO:ResourceIdentity: implement } diff --git a/internal/proto6server/server_upgraderesourceidentity.go b/internal/proto6server/server_upgraderesourceidentity.go index d5f55ab2..042efce8 100644 --- a/internal/proto6server/server_upgraderesourceidentity.go +++ b/internal/proto6server/server_upgraderesourceidentity.go @@ -11,5 +11,5 @@ import ( // UpgradeResourceIdentity satisfies the tfprotov6.ProviderServer interface. func (s *Server) UpgradeResourceIdentity(ctx context.Context, proto6Req *tfprotov6.UpgradeResourceIdentityRequest) (*tfprotov6.UpgradeResourceIdentityResponse, error) { - panic("unimplemented") // TODO: implement + panic("unimplemented") // TODO:ResourceIdentity: implement } diff --git a/resource/identityschema/doc.go b/resource/identityschema/doc.go index 14efe3ec..5e468a5c 100644 --- a/resource/identityschema/doc.go +++ b/resource/identityschema/doc.go @@ -4,8 +4,6 @@ // Package identityschema contains all available schema functionality for managed // resource identity. // -// TODO: Verify these type names are what we ended with. -// // Resource identity schemas define the structure and value types for identity state data. // Schemas are implemented via the resource.ResourceWithIdentity type IdentitySchema method. package identityschema diff --git a/resource/identityschema/list_attribute.go b/resource/identityschema/list_attribute.go index 86fe7973..ef396c24 100644 --- a/resource/identityschema/list_attribute.go +++ b/resource/identityschema/list_attribute.go @@ -165,9 +165,5 @@ func (a ListAttribute) ValidateImplementation(ctx context.Context, req fwschema. resp.Diagnostics.Append(fwschema.AttributeMissingElementTypeDiag(req.Path)) } - // TODO: Write validation similar to the dynamic type validation/diagnostic for detecting - // non-primitive element types - // if a.CustomType == nil && fwtype.ContainsCollectionWithDynamic(a.GetType()) { - // resp.Diagnostics.Append(fwtype.AttributeCollectionWithDynamicTypeDiag(req.Path)) - // } + // TODO:ResourceIdentity: Write validation + tests that ensure the element type only contains primitive elements (bool, string, number) } diff --git a/resource/identityschema/list_attribute_test.go b/resource/identityschema/list_attribute_test.go index 48c90f00..45fc40c1 100644 --- a/resource/identityschema/list_attribute_test.go +++ b/resource/identityschema/list_attribute_test.go @@ -460,29 +460,6 @@ func TestListAttributeValidateImplementation(t *testing.T) { }, expected: &fwschema.ValidateImplementationResponse{}, }, - // TODO: Update this test once the validation logic is in place - // "elementtype-invalid": { - // attribute: identityschema.ListAttribute{ - // RequiredForImport: true, - // ElementType: types.DynamicType, - // }, - // request: fwschema.ValidateImplementationRequest{ - // Name: "test", - // Path: path.Root("test"), - // }, - // expected: &fwschema.ValidateImplementationResponse{ - // Diagnostics: diag.Diagnostics{ - // diag.NewErrorDiagnostic( - // "Invalid Schema Implementation", - // "When validating the schema, an implementation issue was found. "+ - // "This is always an issue with the provider and should be reported to the provider developers.\n\n"+ - // "\"test\" is an attribute that contains a collection type with a nested dynamic type.\n\n"+ - // "Dynamic types inside of collections are not currently supported in terraform-plugin-framework. "+ - // "If underlying dynamic values are required, replace the \"test\" attribute definition with DynamicAttribute instead.", - // ), - // }, - // }, - // }, "elementtype-missing": { attribute: identityschema.ListAttribute{ RequiredForImport: true, diff --git a/resource/identityschema/schema.go b/resource/identityschema/schema.go index 1dfd0983..6d68aff9 100644 --- a/resource/identityschema/schema.go +++ b/resource/identityschema/schema.go @@ -17,10 +17,8 @@ import ( // Schema must satify the fwschema.Schema interface. var _ fwschema.Schema = Schema{} -// TODO: Verify these type names are what we ended with. -// // Schema defines the structure and value types of resource identity data. This type -// is used as the resource.IdentitySchemaResponse type Schema field, which is +// is used as the resource.IdentitySchemaResponse type IdentitySchema field, which is // implemented by the resource.ResourceWithIdentity type IdentitySchema method. type Schema struct { // Attributes is the mapping of underlying attribute names to attribute @@ -31,7 +29,7 @@ type Schema struct { // Version indicates the current version of the resource identity schema. Resource // identity schema versioning enables identity state upgrades in conjunction with the - // [resource.ResourceWithIdentityStateUpgrades] interface. Versioning is only + // [resource.ResourceWithUpgradeIdentity] interface. Versioning is only // required if there is a breaking change involving existing identity state data, // such as changing an attribute type in a manner that is incompatible with the Terraform type. // diff --git a/resource/resource.go b/resource/resource.go index ce2694a2..f9982402 100644 --- a/resource/resource.go +++ b/resource/resource.go @@ -199,7 +199,7 @@ type ResourceWithValidateConfig interface { // ResourceWithIdentity is an interface type that extends Resource to implement managed resource identity. // -// TODO: Describe identity concept in more detail, reference the upgrade identity interface +// TODO:ResourceIdentity: Add more documentation here to describe what identity is used for. type ResourceWithIdentity interface { Resource From 5578a7ddf5f17765f55c0ceae5a7c590c4143191 Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Thu, 6 Mar 2025 18:18:39 -0500 Subject: [PATCH 12/14] spellcheck! --- datasource/schema/bool_attribute.go | 4 ++-- datasource/schema/dynamic_attribute.go | 4 ++-- datasource/schema/float32_attribute.go | 4 ++-- datasource/schema/float64_attribute.go | 4 ++-- datasource/schema/int32_attribute.go | 4 ++-- datasource/schema/int64_attribute.go | 4 ++-- datasource/schema/list_attribute.go | 4 ++-- datasource/schema/list_nested_attribute.go | 4 ++-- datasource/schema/map_attribute.go | 4 ++-- datasource/schema/map_nested_attribute.go | 4 ++-- datasource/schema/number_attribute.go | 4 ++-- datasource/schema/object_attribute.go | 4 ++-- datasource/schema/set_attribute.go | 4 ++-- datasource/schema/set_nested_attribute.go | 4 ++-- datasource/schema/single_nested_attribute.go | 4 ++-- datasource/schema/string_attribute.go | 4 ++-- ephemeral/schema/bool_attribute.go | 4 ++-- ephemeral/schema/dynamic_attribute.go | 4 ++-- ephemeral/schema/float32_attribute.go | 4 ++-- ephemeral/schema/float64_attribute.go | 4 ++-- ephemeral/schema/int32_attribute.go | 4 ++-- ephemeral/schema/int64_attribute.go | 4 ++-- ephemeral/schema/list_attribute.go | 4 ++-- ephemeral/schema/list_nested_attribute.go | 4 ++-- ephemeral/schema/map_attribute.go | 4 ++-- ephemeral/schema/map_nested_attribute.go | 4 ++-- ephemeral/schema/number_attribute.go | 4 ++-- ephemeral/schema/object_attribute.go | 4 ++-- ephemeral/schema/set_attribute.go | 4 ++-- ephemeral/schema/set_nested_attribute.go | 4 ++-- ephemeral/schema/single_nested_attribute.go | 4 ++-- ephemeral/schema/string_attribute.go | 4 ++-- provider/metaschema/bool_attribute.go | 4 ++-- provider/metaschema/float64_attribute.go | 4 ++-- provider/metaschema/int64_attribute.go | 4 ++-- provider/metaschema/list_attribute.go | 4 ++-- provider/metaschema/list_nested_attribute.go | 4 ++-- provider/metaschema/map_attribute.go | 4 ++-- provider/metaschema/map_nested_attribute.go | 4 ++-- provider/metaschema/number_attribute.go | 4 ++-- provider/metaschema/object_attribute.go | 4 ++-- provider/metaschema/set_attribute.go | 4 ++-- provider/metaschema/set_nested_attribute.go | 4 ++-- provider/metaschema/single_nested_attribute.go | 4 ++-- provider/metaschema/string_attribute.go | 4 ++-- provider/schema/bool_attribute.go | 4 ++-- provider/schema/dynamic_attribute.go | 4 ++-- provider/schema/float32_attribute.go | 4 ++-- provider/schema/float64_attribute.go | 4 ++-- provider/schema/int32_attribute.go | 4 ++-- provider/schema/int64_attribute.go | 4 ++-- provider/schema/list_attribute.go | 4 ++-- provider/schema/list_nested_attribute.go | 4 ++-- provider/schema/map_attribute.go | 4 ++-- provider/schema/map_nested_attribute.go | 4 ++-- provider/schema/number_attribute.go | 4 ++-- provider/schema/object_attribute.go | 4 ++-- provider/schema/set_attribute.go | 4 ++-- provider/schema/set_nested_attribute.go | 4 ++-- provider/schema/single_nested_attribute.go | 4 ++-- provider/schema/string_attribute.go | 4 ++-- resource/schema/bool_attribute.go | 4 ++-- resource/schema/dynamic_attribute.go | 4 ++-- resource/schema/float32_attribute.go | 4 ++-- resource/schema/float64_attribute.go | 4 ++-- resource/schema/int32_attribute.go | 4 ++-- resource/schema/int64_attribute.go | 4 ++-- resource/schema/list_attribute.go | 4 ++-- resource/schema/list_nested_attribute.go | 4 ++-- resource/schema/map_attribute.go | 4 ++-- resource/schema/map_nested_attribute.go | 4 ++-- resource/schema/number_attribute.go | 4 ++-- resource/schema/object_attribute.go | 4 ++-- resource/schema/set_attribute.go | 4 ++-- resource/schema/set_nested_attribute.go | 4 ++-- resource/schema/single_nested_attribute.go | 4 ++-- resource/schema/string_attribute.go | 4 ++-- 77 files changed, 154 insertions(+), 154 deletions(-) diff --git a/datasource/schema/bool_attribute.go b/datasource/schema/bool_attribute.go index 55a98257..5830d6c2 100644 --- a/datasource/schema/bool_attribute.go +++ b/datasource/schema/bool_attribute.go @@ -192,13 +192,13 @@ func (a BoolAttribute) IsSensitive() bool { return a.Sensitive } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/dynamic_attribute.go b/datasource/schema/dynamic_attribute.go index 52649038..2d489fe8 100644 --- a/datasource/schema/dynamic_attribute.go +++ b/datasource/schema/dynamic_attribute.go @@ -188,13 +188,13 @@ func (a DynamicAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a DynamicAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a DynamicAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/float32_attribute.go b/datasource/schema/float32_attribute.go index 4ad4203c..c7c09f6c 100644 --- a/datasource/schema/float32_attribute.go +++ b/datasource/schema/float32_attribute.go @@ -195,13 +195,13 @@ func (a Float32Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float32Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float32Attribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/float64_attribute.go b/datasource/schema/float64_attribute.go index 6e965edf..b688653e 100644 --- a/datasource/schema/float64_attribute.go +++ b/datasource/schema/float64_attribute.go @@ -195,13 +195,13 @@ func (a Float64Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/int32_attribute.go b/datasource/schema/int32_attribute.go index 67b355d2..44c2b631 100644 --- a/datasource/schema/int32_attribute.go +++ b/datasource/schema/int32_attribute.go @@ -195,13 +195,13 @@ func (a Int32Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int32Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int32Attribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/int64_attribute.go b/datasource/schema/int64_attribute.go index 535f1f8a..c5dc49dc 100644 --- a/datasource/schema/int64_attribute.go +++ b/datasource/schema/int64_attribute.go @@ -195,13 +195,13 @@ func (a Int64Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/list_attribute.go b/datasource/schema/list_attribute.go index de211ed6..d581d663 100644 --- a/datasource/schema/list_attribute.go +++ b/datasource/schema/list_attribute.go @@ -213,13 +213,13 @@ func (a ListAttribute) ListValidators() []validator.List { return a.Validators } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/list_nested_attribute.go b/datasource/schema/list_nested_attribute.go index 4e844574..f2b88a87 100644 --- a/datasource/schema/list_nested_attribute.go +++ b/datasource/schema/list_nested_attribute.go @@ -236,13 +236,13 @@ func (a ListNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/map_attribute.go b/datasource/schema/map_attribute.go index 8e703088..16413337 100644 --- a/datasource/schema/map_attribute.go +++ b/datasource/schema/map_attribute.go @@ -211,13 +211,13 @@ func (a MapAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/map_nested_attribute.go b/datasource/schema/map_nested_attribute.go index b9a8bb90..30c0c224 100644 --- a/datasource/schema/map_nested_attribute.go +++ b/datasource/schema/map_nested_attribute.go @@ -236,13 +236,13 @@ func (a MapNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/number_attribute.go b/datasource/schema/number_attribute.go index 61e9184e..fc12b09d 100644 --- a/datasource/schema/number_attribute.go +++ b/datasource/schema/number_attribute.go @@ -191,13 +191,13 @@ func (a NumberAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/object_attribute.go b/datasource/schema/object_attribute.go index 98128518..21586932 100644 --- a/datasource/schema/object_attribute.go +++ b/datasource/schema/object_attribute.go @@ -210,13 +210,13 @@ func (a ObjectAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/set_attribute.go b/datasource/schema/set_attribute.go index 714a9602..638c2134 100644 --- a/datasource/schema/set_attribute.go +++ b/datasource/schema/set_attribute.go @@ -206,13 +206,13 @@ func (a SetAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/set_nested_attribute.go b/datasource/schema/set_nested_attribute.go index 30ed7573..4247933f 100644 --- a/datasource/schema/set_nested_attribute.go +++ b/datasource/schema/set_nested_attribute.go @@ -231,13 +231,13 @@ func (a SetNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/single_nested_attribute.go b/datasource/schema/single_nested_attribute.go index 290d2107..838c9e33 100644 --- a/datasource/schema/single_nested_attribute.go +++ b/datasource/schema/single_nested_attribute.go @@ -245,13 +245,13 @@ func (a SingleNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsOptionalForImport() bool { return false diff --git a/datasource/schema/string_attribute.go b/datasource/schema/string_attribute.go index 250fb5ff..9a61de9b 100644 --- a/datasource/schema/string_attribute.go +++ b/datasource/schema/string_attribute.go @@ -187,13 +187,13 @@ func (a StringAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/bool_attribute.go b/ephemeral/schema/bool_attribute.go index 4ff3b43b..f8ebd5ef 100644 --- a/ephemeral/schema/bool_attribute.go +++ b/ephemeral/schema/bool_attribute.go @@ -191,13 +191,13 @@ func (a BoolAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/dynamic_attribute.go b/ephemeral/schema/dynamic_attribute.go index 205c73ea..339775fe 100644 --- a/ephemeral/schema/dynamic_attribute.go +++ b/ephemeral/schema/dynamic_attribute.go @@ -192,13 +192,13 @@ func (a DynamicAttribute) DynamicValidators() []validator.Dynamic { return a.Validators } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a DynamicAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a DynamicAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/float32_attribute.go b/ephemeral/schema/float32_attribute.go index cb5de0fb..733502fe 100644 --- a/ephemeral/schema/float32_attribute.go +++ b/ephemeral/schema/float32_attribute.go @@ -194,13 +194,13 @@ func (a Float32Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float32Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float32Attribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/float64_attribute.go b/ephemeral/schema/float64_attribute.go index a295ace3..9c72720f 100644 --- a/ephemeral/schema/float64_attribute.go +++ b/ephemeral/schema/float64_attribute.go @@ -194,13 +194,13 @@ func (a Float64Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/int32_attribute.go b/ephemeral/schema/int32_attribute.go index 1f948eaf..c493b08c 100644 --- a/ephemeral/schema/int32_attribute.go +++ b/ephemeral/schema/int32_attribute.go @@ -194,13 +194,13 @@ func (a Int32Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int32Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int32Attribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/int64_attribute.go b/ephemeral/schema/int64_attribute.go index 95b96fe2..c356ac65 100644 --- a/ephemeral/schema/int64_attribute.go +++ b/ephemeral/schema/int64_attribute.go @@ -194,13 +194,13 @@ func (a Int64Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/list_attribute.go b/ephemeral/schema/list_attribute.go index 05cc6895..246e77a7 100644 --- a/ephemeral/schema/list_attribute.go +++ b/ephemeral/schema/list_attribute.go @@ -206,13 +206,13 @@ func (a ListAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/list_nested_attribute.go b/ephemeral/schema/list_nested_attribute.go index ea4954da..a70b6835 100644 --- a/ephemeral/schema/list_nested_attribute.go +++ b/ephemeral/schema/list_nested_attribute.go @@ -235,13 +235,13 @@ func (a ListNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/map_attribute.go b/ephemeral/schema/map_attribute.go index 018e83c4..86480e01 100644 --- a/ephemeral/schema/map_attribute.go +++ b/ephemeral/schema/map_attribute.go @@ -210,13 +210,13 @@ func (a MapAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/map_nested_attribute.go b/ephemeral/schema/map_nested_attribute.go index f935c12c..6e8df3dd 100644 --- a/ephemeral/schema/map_nested_attribute.go +++ b/ephemeral/schema/map_nested_attribute.go @@ -235,13 +235,13 @@ func (a MapNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/number_attribute.go b/ephemeral/schema/number_attribute.go index 6b5de920..d56a4ddb 100644 --- a/ephemeral/schema/number_attribute.go +++ b/ephemeral/schema/number_attribute.go @@ -190,13 +190,13 @@ func (a NumberAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/object_attribute.go b/ephemeral/schema/object_attribute.go index 32776907..cab38b7e 100644 --- a/ephemeral/schema/object_attribute.go +++ b/ephemeral/schema/object_attribute.go @@ -208,13 +208,13 @@ func (a ObjectAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/set_attribute.go b/ephemeral/schema/set_attribute.go index a0523502..963253f9 100644 --- a/ephemeral/schema/set_attribute.go +++ b/ephemeral/schema/set_attribute.go @@ -205,13 +205,13 @@ func (a SetAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/set_nested_attribute.go b/ephemeral/schema/set_nested_attribute.go index f5740cd5..0e1dc40a 100644 --- a/ephemeral/schema/set_nested_attribute.go +++ b/ephemeral/schema/set_nested_attribute.go @@ -230,13 +230,13 @@ func (a SetNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/single_nested_attribute.go b/ephemeral/schema/single_nested_attribute.go index 16cc31fc..23bc8cf1 100644 --- a/ephemeral/schema/single_nested_attribute.go +++ b/ephemeral/schema/single_nested_attribute.go @@ -244,13 +244,13 @@ func (a SingleNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsOptionalForImport() bool { return false diff --git a/ephemeral/schema/string_attribute.go b/ephemeral/schema/string_attribute.go index c751c987..ec8f8692 100644 --- a/ephemeral/schema/string_attribute.go +++ b/ephemeral/schema/string_attribute.go @@ -186,13 +186,13 @@ func (a StringAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/bool_attribute.go b/provider/metaschema/bool_attribute.go index 811a94e3..d02fcc80 100644 --- a/provider/metaschema/bool_attribute.go +++ b/provider/metaschema/bool_attribute.go @@ -125,13 +125,13 @@ func (a BoolAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/float64_attribute.go b/provider/metaschema/float64_attribute.go index a4eb9e9d..96c634fb 100644 --- a/provider/metaschema/float64_attribute.go +++ b/provider/metaschema/float64_attribute.go @@ -128,13 +128,13 @@ func (a Float64Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/int64_attribute.go b/provider/metaschema/int64_attribute.go index 25a21493..7490bd7b 100644 --- a/provider/metaschema/int64_attribute.go +++ b/provider/metaschema/int64_attribute.go @@ -128,13 +128,13 @@ func (a Int64Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/list_attribute.go b/provider/metaschema/list_attribute.go index 2149c212..ea663a8a 100644 --- a/provider/metaschema/list_attribute.go +++ b/provider/metaschema/list_attribute.go @@ -141,13 +141,13 @@ func (a ListAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/list_nested_attribute.go b/provider/metaschema/list_nested_attribute.go index bf9b2f94..ccc3293d 100644 --- a/provider/metaschema/list_nested_attribute.go +++ b/provider/metaschema/list_nested_attribute.go @@ -167,13 +167,13 @@ func (a ListNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/map_attribute.go b/provider/metaschema/map_attribute.go index 18a3e986..99d90e76 100644 --- a/provider/metaschema/map_attribute.go +++ b/provider/metaschema/map_attribute.go @@ -144,13 +144,13 @@ func (a MapAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/map_nested_attribute.go b/provider/metaschema/map_nested_attribute.go index 5962d38a..79029c83 100644 --- a/provider/metaschema/map_nested_attribute.go +++ b/provider/metaschema/map_nested_attribute.go @@ -167,13 +167,13 @@ func (a MapNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/number_attribute.go b/provider/metaschema/number_attribute.go index 829c0a50..3e345a7f 100644 --- a/provider/metaschema/number_attribute.go +++ b/provider/metaschema/number_attribute.go @@ -129,13 +129,13 @@ func (a NumberAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/object_attribute.go b/provider/metaschema/object_attribute.go index 091fff81..7c325a23 100644 --- a/provider/metaschema/object_attribute.go +++ b/provider/metaschema/object_attribute.go @@ -143,13 +143,13 @@ func (a ObjectAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/set_attribute.go b/provider/metaschema/set_attribute.go index a4b8365c..5878c6ec 100644 --- a/provider/metaschema/set_attribute.go +++ b/provider/metaschema/set_attribute.go @@ -139,13 +139,13 @@ func (a SetAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/set_nested_attribute.go b/provider/metaschema/set_nested_attribute.go index a137deda..102ede61 100644 --- a/provider/metaschema/set_nested_attribute.go +++ b/provider/metaschema/set_nested_attribute.go @@ -162,13 +162,13 @@ func (a SetNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/single_nested_attribute.go b/provider/metaschema/single_nested_attribute.go index a10d2368..51b7c73b 100644 --- a/provider/metaschema/single_nested_attribute.go +++ b/provider/metaschema/single_nested_attribute.go @@ -182,13 +182,13 @@ func (a SingleNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsOptionalForImport() bool { return false diff --git a/provider/metaschema/string_attribute.go b/provider/metaschema/string_attribute.go index 5efcba28..eb056e2d 100644 --- a/provider/metaschema/string_attribute.go +++ b/provider/metaschema/string_attribute.go @@ -125,13 +125,13 @@ func (a StringAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/bool_attribute.go b/provider/schema/bool_attribute.go index ea1eb8f9..9f4f3713 100644 --- a/provider/schema/bool_attribute.go +++ b/provider/schema/bool_attribute.go @@ -186,13 +186,13 @@ func (a BoolAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/dynamic_attribute.go b/provider/schema/dynamic_attribute.go index 5e5c07ed..86da9aef 100644 --- a/provider/schema/dynamic_attribute.go +++ b/provider/schema/dynamic_attribute.go @@ -183,13 +183,13 @@ func (a DynamicAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a DynamicAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a DynamicAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/float32_attribute.go b/provider/schema/float32_attribute.go index f272539b..bd124a33 100644 --- a/provider/schema/float32_attribute.go +++ b/provider/schema/float32_attribute.go @@ -189,13 +189,13 @@ func (a Float32Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float32Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float32Attribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/float64_attribute.go b/provider/schema/float64_attribute.go index 33615446..d7c32832 100644 --- a/provider/schema/float64_attribute.go +++ b/provider/schema/float64_attribute.go @@ -189,13 +189,13 @@ func (a Float64Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/int32_attribute.go b/provider/schema/int32_attribute.go index 3b97a0f3..1c5bde95 100644 --- a/provider/schema/int32_attribute.go +++ b/provider/schema/int32_attribute.go @@ -189,13 +189,13 @@ func (a Int32Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int32Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int32Attribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/int64_attribute.go b/provider/schema/int64_attribute.go index 1dc1f85e..bf334a6d 100644 --- a/provider/schema/int64_attribute.go +++ b/provider/schema/int64_attribute.go @@ -189,13 +189,13 @@ func (a Int64Attribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/list_attribute.go b/provider/schema/list_attribute.go index e9482597..55f6f233 100644 --- a/provider/schema/list_attribute.go +++ b/provider/schema/list_attribute.go @@ -202,13 +202,13 @@ func (a ListAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/list_nested_attribute.go b/provider/schema/list_nested_attribute.go index 07d6ebd4..e00e940b 100644 --- a/provider/schema/list_nested_attribute.go +++ b/provider/schema/list_nested_attribute.go @@ -230,13 +230,13 @@ func (a ListNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/map_attribute.go b/provider/schema/map_attribute.go index a43108d1..28cc5f5b 100644 --- a/provider/schema/map_attribute.go +++ b/provider/schema/map_attribute.go @@ -205,13 +205,13 @@ func (a MapAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/map_nested_attribute.go b/provider/schema/map_nested_attribute.go index d2ee6ece..5b824649 100644 --- a/provider/schema/map_nested_attribute.go +++ b/provider/schema/map_nested_attribute.go @@ -229,13 +229,13 @@ func (a MapNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/number_attribute.go b/provider/schema/number_attribute.go index d8b467cc..add021b1 100644 --- a/provider/schema/number_attribute.go +++ b/provider/schema/number_attribute.go @@ -185,13 +185,13 @@ func (a NumberAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/object_attribute.go b/provider/schema/object_attribute.go index ddd0e1b2..0cb33f1f 100644 --- a/provider/schema/object_attribute.go +++ b/provider/schema/object_attribute.go @@ -204,13 +204,13 @@ func (a ObjectAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/set_attribute.go b/provider/schema/set_attribute.go index 87ee7363..9d1a8f0c 100644 --- a/provider/schema/set_attribute.go +++ b/provider/schema/set_attribute.go @@ -200,13 +200,13 @@ func (a SetAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/set_nested_attribute.go b/provider/schema/set_nested_attribute.go index b879b40c..f5d788e6 100644 --- a/provider/schema/set_nested_attribute.go +++ b/provider/schema/set_nested_attribute.go @@ -225,13 +225,13 @@ func (a SetNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/single_nested_attribute.go b/provider/schema/single_nested_attribute.go index 65f35310..6c306d16 100644 --- a/provider/schema/single_nested_attribute.go +++ b/provider/schema/single_nested_attribute.go @@ -239,13 +239,13 @@ func (a SingleNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsOptionalForImport() bool { return false diff --git a/provider/schema/string_attribute.go b/provider/schema/string_attribute.go index db6667f0..feb9e803 100644 --- a/provider/schema/string_attribute.go +++ b/provider/schema/string_attribute.go @@ -181,13 +181,13 @@ func (a StringAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/bool_attribute.go b/resource/schema/bool_attribute.go index b3d57ee7..3cdbc0e9 100644 --- a/resource/schema/bool_attribute.go +++ b/resource/schema/bool_attribute.go @@ -244,13 +244,13 @@ func (a BoolAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a BoolAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/dynamic_attribute.go b/resource/schema/dynamic_attribute.go index 72b74637..b7b4f38b 100644 --- a/resource/schema/dynamic_attribute.go +++ b/resource/schema/dynamic_attribute.go @@ -230,13 +230,13 @@ func (a DynamicAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a DynamicAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a DynamicAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/float32_attribute.go b/resource/schema/float32_attribute.go index ed7e5fb9..acd37a15 100644 --- a/resource/schema/float32_attribute.go +++ b/resource/schema/float32_attribute.go @@ -247,13 +247,13 @@ func (a Float32Attribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float32Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float32Attribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/float64_attribute.go b/resource/schema/float64_attribute.go index 947c1695..8db8fb0b 100644 --- a/resource/schema/float64_attribute.go +++ b/resource/schema/float64_attribute.go @@ -247,13 +247,13 @@ func (a Float64Attribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Float64Attribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/int32_attribute.go b/resource/schema/int32_attribute.go index 102be037..5426a574 100644 --- a/resource/schema/int32_attribute.go +++ b/resource/schema/int32_attribute.go @@ -247,13 +247,13 @@ func (a Int32Attribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int32Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int32Attribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/int64_attribute.go b/resource/schema/int64_attribute.go index 3455b7a5..b700f2cc 100644 --- a/resource/schema/int64_attribute.go +++ b/resource/schema/int64_attribute.go @@ -247,13 +247,13 @@ func (a Int64Attribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a Int64Attribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/list_attribute.go b/resource/schema/list_attribute.go index 85dbc9a3..29419ebd 100644 --- a/resource/schema/list_attribute.go +++ b/resource/schema/list_attribute.go @@ -247,13 +247,13 @@ func (a ListAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/list_nested_attribute.go b/resource/schema/list_nested_attribute.go index 74c739e9..76a4e3cd 100644 --- a/resource/schema/list_nested_attribute.go +++ b/resource/schema/list_nested_attribute.go @@ -278,13 +278,13 @@ func (a ListNestedAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ListNestedAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/map_attribute.go b/resource/schema/map_attribute.go index f045a6c8..837b3110 100644 --- a/resource/schema/map_attribute.go +++ b/resource/schema/map_attribute.go @@ -250,13 +250,13 @@ func (a MapAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/map_nested_attribute.go b/resource/schema/map_nested_attribute.go index 717140e6..cdea0f5b 100644 --- a/resource/schema/map_nested_attribute.go +++ b/resource/schema/map_nested_attribute.go @@ -278,13 +278,13 @@ func (a MapNestedAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a MapNestedAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/number_attribute.go b/resource/schema/number_attribute.go index 910b2f5a..a443945e 100644 --- a/resource/schema/number_attribute.go +++ b/resource/schema/number_attribute.go @@ -233,13 +233,13 @@ func (a NumberAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a NumberAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/object_attribute.go b/resource/schema/object_attribute.go index 896b2921..1de48e87 100644 --- a/resource/schema/object_attribute.go +++ b/resource/schema/object_attribute.go @@ -249,13 +249,13 @@ func (a ObjectAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a ObjectAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/set_attribute.go b/resource/schema/set_attribute.go index f33fd3df..2c9f0828 100644 --- a/resource/schema/set_attribute.go +++ b/resource/schema/set_attribute.go @@ -235,13 +235,13 @@ func (a SetAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/set_nested_attribute.go b/resource/schema/set_nested_attribute.go index 0d6eef59..c3b26780 100644 --- a/resource/schema/set_nested_attribute.go +++ b/resource/schema/set_nested_attribute.go @@ -260,13 +260,13 @@ func (a SetNestedAttribute) IsWriteOnly() bool { return false } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SetNestedAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/single_nested_attribute.go b/resource/schema/single_nested_attribute.go index 4ad79ffe..0d4e00e2 100644 --- a/resource/schema/single_nested_attribute.go +++ b/resource/schema/single_nested_attribute.go @@ -286,13 +286,13 @@ func (a SingleNestedAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a SingleNestedAttribute) IsOptionalForImport() bool { return false diff --git a/resource/schema/string_attribute.go b/resource/schema/string_attribute.go index 50aad8a0..12340ee6 100644 --- a/resource/schema/string_attribute.go +++ b/resource/schema/string_attribute.go @@ -229,13 +229,13 @@ func (a StringAttribute) IsWriteOnly() bool { return a.WriteOnly } -// IsRequiredForImport returns false as this behavior is only revelant +// IsRequiredForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsRequiredForImport() bool { return false } -// IsOptionalForImport returns false as this behavior is only revelant +// IsOptionalForImport returns false as this behavior is only relevant // for managed resource identity schema attributes. func (a StringAttribute) IsOptionalForImport() bool { return false From bf3fb10c1b23f46f683522864eeb3c7e4494428b Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Fri, 14 Mar 2025 08:42:36 -0400 Subject: [PATCH 13/14] update go dep --- go.mod | 6 +++--- go.sum | 34 ++++++++++++++++++---------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/go.mod b/go.mod index 584c97cf..fd586aba 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.22.7 require ( github.com/google/go-cmp v0.7.0 - github.com/hashicorp/terraform-plugin-go v0.26.1-0.20250219133416-0561ec7f0caf + github.com/hashicorp/terraform-plugin-go v0.26.1-0.20250314120210-d406d3409aef github.com/hashicorp/terraform-plugin-log v0.9.0 ) @@ -28,7 +28,7 @@ require ( golang.org/x/net v0.34.0 // indirect golang.org/x/sys v0.29.0 // indirect golang.org/x/text v0.21.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect - google.golang.org/grpc v1.70.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/grpc v1.71.0 // indirect google.golang.org/protobuf v1.36.5 // indirect ) diff --git a/go.sum b/go.sum index a285453e..d841220e 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,8 @@ github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0U github.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/terraform-plugin-go v0.26.1-0.20250219133416-0561ec7f0caf h1:qsHBfGoRp15P8vc95eAVMVO6erkMfpLKZ/6A5lLcR1w= -github.com/hashicorp/terraform-plugin-go v0.26.1-0.20250219133416-0561ec7f0caf/go.mod h1:dUu1RU16sOSKn6w4g+xaAnV0S0wHsVBEY/XH8jv1kx4= +github.com/hashicorp/terraform-plugin-go v0.26.1-0.20250314120210-d406d3409aef h1:RtNtj/RAsw/ef2bpeMlCDo+HsREcQVyJ+20AzikH3kw= +github.com/hashicorp/terraform-plugin-go v0.26.1-0.20250314120210-d406d3409aef/go.mod h1:MfDwS/KnIy2QzCwdRtuqIjZ23gpYa9Vm+Z8cFpx8qtU= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= github.com/hashicorp/terraform-registry-address v0.2.4 h1:JXu/zHB2Ymg/TGVCRu10XqNa4Sh2bWcqCNyKWjnCPJA= @@ -54,16 +54,18 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= -go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= -go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= -go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= -go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= -go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= -go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= -go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= -go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= -go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -76,10 +78,10 @@ golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1:hgh8P4EuoxpsuKMXX/To36nOFD7vixReXgn8lPGnt+o= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= -google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= +google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From b4507e80b64b533a6f7cf8c7348cb2af21dac16f Mon Sep 17 00:00:00 2001 From: Austin Valle Date: Tue, 18 Mar 2025 15:55:32 -0400 Subject: [PATCH 14/14] update go sum --- go.sum | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index 87caaf9b..97560026 100644 --- a/go.sum +++ b/go.sum @@ -66,8 +66,8 @@ go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=