Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all: Add dynamic type, attribute, and function support #931

Merged
merged 127 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
2fa3a2f
initial implementation of dynamic type and value
austinvalle Feb 5, 2024
f57c74e
fix doc string
austinvalle Feb 6, 2024
f87240c
add dynamic defaults
austinvalle Feb 6, 2024
4f3d9ec
add plan modifier for dynamic
austinvalle Feb 6, 2024
61fb4bd
add dynamic attribute, validator, and plan modifiers
austinvalle Feb 6, 2024
a1273bd
add provider and data source attributes and tests
austinvalle Feb 6, 2024
418b4a2
update comment
austinvalle Feb 6, 2024
2fb0289
add resource schema attribute test
austinvalle Feb 6, 2024
8611ed1
add provider metaschema
austinvalle Feb 6, 2024
fb7b246
add hook into attribute validation
austinvalle Feb 6, 2024
09b2486
add hook into plan modification for resources
austinvalle Feb 7, 2024
808d0ee
add hook into dynamic default logic
austinvalle Feb 7, 2024
cd9c2a7
add hooks for dynamic semantic equality
austinvalle Feb 7, 2024
f551d07
add function param and return definitions
austinvalle Feb 7, 2024
5f47981
add function tests
austinvalle Feb 7, 2024
1f1f08a
modify ToTerraformValue to always return DPT
austinvalle Feb 8, 2024
3cde7dc
switch back
austinvalle Feb 8, 2024
1790da5
make reflection update
austinvalle Feb 8, 2024
13801db
update dep
austinvalle Feb 8, 2024
8ddad0c
use safe equal
austinvalle Feb 8, 2024
bdbc729
return attr.Type
austinvalle Feb 9, 2024
d315c6f
add todos and docs based on findings
austinvalle Feb 9, 2024
5327d45
random doc cleanup
austinvalle Feb 13, 2024
7f3e688
doc fix
austinvalle Feb 14, 2024
7362241
fix for data path
austinvalle Feb 15, 2024
d3cc973
switch to tuples and add reflection support
austinvalle Feb 16, 2024
ce83542
update docs
austinvalle Feb 16, 2024
7790feb
add names to variadic param names
austinvalle Feb 16, 2024
c8649a5
update doc note
austinvalle Feb 16, 2024
c99abc5
update docs
austinvalle Feb 16, 2024
160c1f3
update docs
austinvalle Feb 16, 2024
caa6358
add doc note
austinvalle Feb 16, 2024
4ca51e3
add changelog
austinvalle Feb 16, 2024
da9bba4
Merge branch 'av/variadic-tuple' into av/dynamic-support
austinvalle Feb 16, 2024
4fa517f
delete metaschema and fix broken tests
austinvalle Feb 16, 2024
0fd4b91
updated some docs
austinvalle Feb 16, 2024
13be0fc
switch changelog to breaking change
austinvalle Feb 16, 2024
8c5175a
update to tuple index
austinvalle Feb 16, 2024
80c2c2b
update comment wording
austinvalle Feb 16, 2024
2fb35e7
update doc
austinvalle Feb 16, 2024
6dfc032
add new maintainer note
austinvalle Feb 20, 2024
787ba03
Merge branch 'main' into av/variadic-tuple
austinvalle Feb 20, 2024
43aecc9
remove top part of comment
austinvalle Feb 20, 2024
0483510
Merge branch 'av/variadic-tuple' into av/dynamic-support
austinvalle Feb 20, 2024
2e22ad3
add logic to look at value type for dynamic schemas
austinvalle Feb 20, 2024
cbd28b0
add data value tests
austinvalle Feb 20, 2024
183dfe1
add dynamic get at path tests
austinvalle Feb 20, 2024
90def00
add dynamic get tests
austinvalle Feb 20, 2024
5b0e574
add path exist tests
austinvalle Feb 20, 2024
4fd3450
add get provider schema tests
austinvalle Feb 20, 2024
e1aed33
add comment to weird obj fix
austinvalle Feb 20, 2024
106ad02
make changes to support reflection (get)
austinvalle Feb 21, 2024
a036ba4
function: Switch the representation of variadic arguments to `types.T…
austinvalle Feb 21, 2024
fdd6f5e
Merge branch 'main' into av/dynamic-support
austinvalle Feb 21, 2024
201f5b5
add dynamic interface
austinvalle Feb 22, 2024
6e8773f
reflection test
austinvalle Feb 22, 2024
a5efa31
add list type update
austinvalle Feb 22, 2024
3105335
add list value updates
austinvalle Feb 22, 2024
5ca60ce
small refactoring
austinvalle Feb 26, 2024
bb2289d
quick check
austinvalle Feb 26, 2024
0e6c520
revert list type and value
austinvalle Feb 26, 2024
a032257
add detailed comments about the lack of dynamic element type support
austinvalle Feb 26, 2024
5f6cee2
add some object tests for good measure
austinvalle Feb 27, 2024
673df94
add tuple tests
austinvalle Feb 27, 2024
a01f387
add validation logic for list attribute only
austinvalle Feb 27, 2024
658bf56
Merge branch 'main' into av/dynamic-support
austinvalle Feb 27, 2024
63089ab
add block and attribute validation for list
austinvalle Feb 27, 2024
e5b6126
function: Replace usage of diagnostics with function errors during ex…
bendbennett Feb 28, 2024
404d2d9
Update changelog
hc-github-team-tf-provider-devex Feb 28, 2024
ce94913
diag: remove incorrect code (#935)
jxsl13 Feb 28, 2024
27ecdb1
update plugin-go dependency, fix errors and switch equal method
austinvalle Feb 29, 2024
a2a95d2
Merge branch 'main' into av/dynamic-support
austinvalle Feb 29, 2024
ebf452e
function: Add validation for parameter name conflicts and update defa…
austinvalle Feb 29, 2024
c4e9883
resource/schema: Ensure invalid attribute default value errors are ra…
bflad Mar 1, 2024
2282a46
Update provider functions testing docs to help users avoid nil pointe…
SarahFrench Mar 1, 2024
f1c8a97
Reinstate go toolchain and add changelog for Go version bump to 1.21 …
bendbennett Mar 1, 2024
22b4218
Squashed commit of the following:
austinvalle Mar 1, 2024
fac14ea
merge
austinvalle Mar 1, 2024
9993a3b
fix dynamic param
austinvalle Mar 1, 2024
f4e04e4
incorrect merge conflict fix :)
austinvalle Mar 1, 2024
df5b2a2
update comments from feedback
austinvalle Mar 1, 2024
587b6c0
refactor validation logic
austinvalle Mar 1, 2024
6914f08
license headers
austinvalle Mar 1, 2024
a29c433
implement remaining resource and datasource validation
austinvalle Mar 1, 2024
baa150c
implement provider schema validation
austinvalle Mar 1, 2024
de5da55
update error msg and add object validator
austinvalle Mar 2, 2024
d75c10d
add validation to object attributes
austinvalle Mar 2, 2024
cb9d838
update existing attributes to use new bool return
austinvalle Mar 5, 2024
5d7b596
add validation to function parameters and definitions
austinvalle Mar 6, 2024
0f4c70b
refactor to only have one exported function
austinvalle Mar 6, 2024
07e9a67
add tuple tests for completeness
austinvalle Mar 6, 2024
7130b4c
create new fwtype package
austinvalle Mar 11, 2024
6f4097f
add parameter name to validate implementation definition
austinvalle Mar 11, 2024
781ce57
various PR fixes
austinvalle Mar 11, 2024
f1c0b84
add more docs
austinvalle Mar 11, 2024
b21263d
fix docs from default param change
austinvalle Mar 11, 2024
c8a0d4b
Merge branch 'main' into av/dynamic-support
austinvalle Mar 11, 2024
815a150
update comment
austinvalle Mar 11, 2024
cf1d851
add more to reflection case + update comment
austinvalle Mar 11, 2024
6e77881
comment wording
austinvalle Mar 11, 2024
a517b3b
remove todos and add package docs
austinvalle Mar 11, 2024
406e467
add changelogs
austinvalle Mar 11, 2024
3a41acf
Merge branch 'main' into av/dynamic-support
austinvalle Mar 12, 2024
90c4253
Fix the use-case where dynamic value type is known, but the value its…
austinvalle Mar 15, 2024
ecde104
Merge branch 'main' into av/dynamic-support
austinvalle Mar 15, 2024
29ff8d0
check for dynamic underlying value for null/unknown detection
austinvalle Mar 18, 2024
c920b8a
removed the unneccessary interface and removed half-implemented refle…
austinvalle Mar 18, 2024
c4f8382
Merge branch 'main' into av/dynamic-support
austinvalle Mar 18, 2024
e0f7bc8
doc formatting
austinvalle Mar 18, 2024
8e718d4
update static default naming
austinvalle Mar 18, 2024
c7fddc1
add happy path tests for datasource + provider validate implementations
austinvalle Mar 18, 2024
37001a5
update definition validation messaging with variadic
austinvalle Mar 18, 2024
e4b62ae
add doc explicitly saying that dynamic types aren't supported
austinvalle Mar 18, 2024
21b7186
add docs mentioning required dynamic type to functions
austinvalle Mar 18, 2024
6bb2360
prevent nil panics in `types.Dynamic` implementation w/ tests
austinvalle Mar 18, 2024
81afd88
proposal for `NewDynamicValue`
austinvalle Mar 18, 2024
94d27c3
add recommendations in doc string
austinvalle Mar 18, 2024
b341f56
update block msg
austinvalle Mar 18, 2024
0774ad3
update all doc strings and error messages to make recommendations
austinvalle Mar 18, 2024
977db88
move the function validate interfaces to internal package
austinvalle Mar 18, 2024
b13ab37
add maintainer note about parameter name
austinvalle Mar 18, 2024
8a1f4d4
prevent attribute paths from stepping into dynamic types + new tests
austinvalle Mar 20, 2024
9c25457
add helper methods for checking underlying value unknown/null
austinvalle Mar 20, 2024
d5212c3
Merge branch 'main' into av/dynamic-support
austinvalle Mar 20, 2024
fceb149
add tests and comments about edge case with empty values
austinvalle Mar 20, 2024
8e11b2b
move maintainer note
austinvalle Mar 20, 2024
4173c54
Add dynamic type support documentation and considerations
austinvalle Mar 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240311-175905.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'types/basetypes: Added `DynamicType` and `DynamicValue` implementations for
dynamic value handling'
time: 2024-03-11T17:59:05.67474-04:00
custom:
Issue: "147"
7 changes: 7 additions & 0 deletions .changes/unreleased/FEATURES-20240311-180136.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
kind: FEATURES
body: 'types/basetypes: Added interfaces `basetypes.DynamicTypable`, `basetypes.DynamicValuable`,
and `basetypes.DynamicValuableWithSemanticEquals` for dynamic custom type and value
implementations'
time: 2024-03-11T18:01:36.888566-04:00
custom:
Issue: "147"
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240311-180351.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'resource/schema: Added `DynamicAttribute` implementation for dynamic value
handling'
time: 2024-03-11T18:03:51.559347-04:00
custom:
Issue: "147"
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240311-180418.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'datasource/schema: Added `DynamicAttribute` implementation for dynamic value
handling'
time: 2024-03-11T18:04:18.042171-04:00
custom:
Issue: "147"
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240311-180430.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'provider/schema: Added `DynamicAttribute` implementation for dynamic value
handling'
time: 2024-03-11T18:04:30.200616-04:00
custom:
Issue: "147"
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20240311-180515.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: 'function: Added `DynamicParameter` and `DynamicReturn` for dynamic value handling`'
time: 2024-03-11T18:05:15.196275-04:00
custom:
Issue: "147"
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240311-180859.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'resource/schema/dynamicdefault: New package with `StaticValue` implementation
for dynamic schema-based default values'
time: 2024-03-11T18:08:59.479664-04:00
custom:
Issue: "147"
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240311-181044.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'resource/schema/dynamicplanmodifier: New package with built-in implementations
for dynamic value plan modification.'
time: 2024-03-11T18:10:44.015502-04:00
custom:
Issue: "147"
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240311-181151.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'resource/schema/defaults: New `Dynamic` interface for dynamic schema-based
default implementations'
time: 2024-03-11T18:11:51.403326-04:00
custom:
Issue: "147"
6 changes: 6 additions & 0 deletions .changes/unreleased/FEATURES-20240311-181242.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: FEATURES
body: 'resource/schema/planmodifier: New `Dynamic` interface for dynamic value plan
modification implementations'
time: 2024-03-11T18:12:42.945376-04:00
custom:
Issue: "147"
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20240311-181424.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: 'schema/validator: New `Dynamic` interface for dynamic value schema validation'
time: 2024-03-11T18:14:24.809064-04:00
custom:
Issue: "147"
6 changes: 6 additions & 0 deletions attr/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ const (
// NullValueString should be returned by Value.String() implementations
// when Value.IsNull() returns true.
NullValueString = "<null>"

// UnsetValueString should be returned by Value.String() implementations
// when Value does not contain sufficient information to display to users.
//
// This is primarily used for invalid Dynamic Value implementations.
UnsetValueString = "<unset>"
)

// Value defines an interface for describing data associated with an attribute.
Expand Down
188 changes: 188 additions & 0 deletions datasource/schema/dynamic_attribute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package schema

import (
"github.com/hashicorp/terraform-plugin-framework/attr"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)

// Ensure the implementation satisifies the desired interfaces.
var (
_ Attribute = DynamicAttribute{}
_ fwxschema.AttributeWithDynamicValidators = DynamicAttribute{}
)

// DynamicAttribute represents a schema attribute that is a dynamic, rather
// than a single static type. Static types are always preferable over dynamic
// types in Terraform as practitioners will receive less helpful configuration
// assistance from validation error diagnostics and editor integrations. When
// retrieving the value for this attribute, use types.Dynamic as the value type
// unless the CustomType field is set.
//
// The concrete value type for a dynamic is determined at runtime in this order:
// 1. By Terraform, if defined in the configuration (if Required or Optional).
// 2. By the provider (if Computed).
//
// Once the concrete value type has been determined, it must remain consistent between
austinvalle marked this conversation as resolved.
Show resolved Hide resolved
// plan and apply or Terraform will return an error.
type DynamicAttribute struct {
// CustomType enables the use of a custom attribute type in place of the
// default basetypes.DynamicType. When retrieving data, the basetypes.DynamicValuable
// associated with this custom type must be used in place of types.Dynamic.
CustomType basetypes.DynamicTypable

// Required indicates whether the practitioner must enter a value for
// this attribute or not. Required and Optional cannot both be true,
// and Required and Computed cannot both be true.
Required bool

// Optional indicates whether the practitioner can choose to enter a value
// for this attribute or not. Optional and Required cannot both be true.
Optional bool

// Computed indicates whether the provider may return its own value for
// this Attribute or not. Required and Computed cannot both be true. If
// Required and Optional are both false, Computed must be true, and the
// attribute will be considered "read only" for the practitioner, with
// only the provider able to set its value.
Computed bool

// Sensitive indicates whether the value of this attribute should be
// considered sensitive data. Setting it to true will obscure the value
// in CLI output. Sensitive does not impact how values are stored, and
// practitioners are encouraged to store their state as if the entire
// file is sensitive.
Sensitive bool

// Description is used in various tooling, like the language server, to
// give practitioners more information about what this attribute is,
// what it's for, and how it should be used. It should be written as
// plain text, with no special formatting.
Description string

// MarkdownDescription is used in various tooling, like the
// documentation generator, to give practitioners more information
// about what this attribute is, what it's for, and how it should be
// used. It should be formatted using Markdown.
MarkdownDescription string

// DeprecationMessage defines warning diagnostic details to display when
// practitioner configurations use this Attribute. The warning diagnostic
// summary is automatically set to "Attribute Deprecated" along with
// configuration source file and line information.
//
// Set this field to a practitioner actionable message such as:
//
// - "Configure other_attribute instead. This attribute will be removed
// in the next major version of the provider."
// - "Remove this attribute's configuration as it no longer is used and
// the attribute will be removed in the next major version of the
// provider."
//
// In Terraform 1.2.7 and later, this warning diagnostic is displayed any
// time a practitioner attempts to configure a value for this attribute and
// certain scenarios where this attribute is referenced.
//
// In Terraform 1.2.6 and earlier, this warning diagnostic is only
// displayed when the Attribute is Required or Optional, and if the
// practitioner configuration sets the value to a known or unknown value
// (which may eventually be null). It has no effect when the Attribute is
// Computed-only (read-only; not Required or Optional).
//
// Across any Terraform version, there are no warnings raised for
// practitioner configuration values set directly to null, as there is no
// way for the framework to differentiate between an unset and null
// configuration due to how Terraform sends configuration information
// across the protocol.
//
// Additional information about deprecation enhancements for read-only
// attributes can be found in:
//
// - https://github.com/hashicorp/terraform/issues/7569
//
DeprecationMessage string

// Validators define value validation functionality for the attribute. All
// elements of the slice of AttributeValidator are run, regardless of any
// previous error diagnostics.
//
// Many common use case validators can be found in the
// github.com/hashicorp/terraform-plugin-framework-validators Go module.
//
// If the Type field points to a custom type that implements the
// xattr.TypeWithValidate interface, the validators defined in this field
// are run in addition to the validation defined by the type.
Validators []validator.Dynamic
}

// ApplyTerraform5AttributePathStep always returns an error as it is not
// possible to step further into a DynamicAttribute.
func (a DynamicAttribute) ApplyTerraform5AttributePathStep(step tftypes.AttributePathStep) (interface{}, error) {
return a.GetType().ApplyTerraform5AttributePathStep(step)
}

// Equal returns true if the given Attribute is a DynamicAttribute
// and all fields are equal.
func (a DynamicAttribute) Equal(o fwschema.Attribute) bool {
if _, ok := o.(DynamicAttribute); !ok {
return false
}

return fwschema.AttributesEqual(a, o)
}

// GetDeprecationMessage returns the DeprecationMessage field value.
func (a DynamicAttribute) GetDeprecationMessage() string {
return a.DeprecationMessage
}

// GetDescription returns the Description field value.
func (a DynamicAttribute) GetDescription() string {
return a.Description
}

// GetMarkdownDescription returns the MarkdownDescription field value.
func (a DynamicAttribute) GetMarkdownDescription() string {
return a.MarkdownDescription
}

// GetType returns types.DynamicType or the CustomType field value if defined.
func (a DynamicAttribute) GetType() attr.Type {
if a.CustomType != nil {
return a.CustomType
}

return types.DynamicType
}

// IsComputed returns the Computed field value.
func (a DynamicAttribute) IsComputed() bool {
return a.Computed
}

// IsOptional returns the Optional field value.
func (a DynamicAttribute) IsOptional() bool {
return a.Optional
}

// IsRequired returns the Required field value.
func (a DynamicAttribute) IsRequired() bool {
return a.Required
}

// IsSensitive returns the Sensitive field value.
func (a DynamicAttribute) IsSensitive() bool {
return a.Sensitive
}

// DynamicValidators returns the Validators field value.
func (a DynamicAttribute) DynamicValidators() []validator.Dynamic {
return a.Validators
}
Loading
Loading