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

path: Initial Path Expression Support #396

Merged
merged 5 commits into from
Jun 29, 2022
Merged

path: Initial Path Expression Support #396

merged 5 commits into from
Jun 29, 2022

Conversation

bflad
Copy link
Contributor

@bflad bflad commented Jun 28, 2022

Reference: #81
Reference: hashicorp/terraform-plugin-framework-validators#14
Reference: hashicorp/terraform-plugin-framework-validators#15
Reference: hashicorp/terraform-plugin-framework-validators#16
Reference: hashicorp/terraform-plugin-framework-validators#17
Reference: hashicorp/terraform-plugin-framework-validators#20

This introduces the concept of root and relative attribute path expressions, abstractions on top of an attribute path, which enables provider developers to declare logic which might match zero, one, or more paths.

Paths are directly convertible into path expressions as exact expression steps. The builder-like syntax for exact expression steps matches the syntax for regular path steps, such as AtName() in both cases always represents an exact transversal into the attribute name of an object. Additional expression steps enable matching any list, map, or set element, such as AtAnyListIndex(). It also supports relative attribute path expressions, by supporting a parent expression step AtParent() and starting an expression with MatchRelative() so it can be combined with a prior path expression.

The framework will automatically expose path expressions to attribute plan modifiers and validators, so they can more intuitively support relative paths as inputs to their logic. For example, the terraform-plugin-framework-validators Go module will implement support for terraform-plugin-sdk multiple attribute schema behaviors such as ConflictsWith. It is expected that the downstream implementation can allow provider developers to declare the validator with expressions such as:

tfsdk.Attribute{
	// ... other fields ...

	Validators: []AttributeValidators{
		schemavalidator.ConflictsWith(
			// Example absolute path from root
			path.MatchRoot("root_attribute"),

			// Example relative path from current attribute
			// e.g. another attribute at the same list index of ListNestedAttributes
			path.MatchRelative().AtParent().AtName("another_same_level_attribute"),
		),
	},
}

Then the logic within the validator can take the ValidateAttributeRequest.AttributePathExpression and use the (path.Expression).Merge() method to combine the current attribute expression with any incoming expressions.

To find matching attribute paths based on a path expression within tfsdk.Config, tfsdk.Plan, and tfsdk.State, a PathMatches(path.Expression) method has been added to each type. The resulting paths can then be used to fetch data via existing functionality, such as the GetAttribute() method of each type.

Reference: #81
Reference: hashicorp/terraform-plugin-framework-validators#14
Reference: hashicorp/terraform-plugin-framework-validators#15
Reference: hashicorp/terraform-plugin-framework-validators#16
Reference: hashicorp/terraform-plugin-framework-validators#17
Reference: hashicorp/terraform-plugin-framework-validators#20

This introduces the concept of an attribute path expression, an abstraction on top of an attribute path, which enables provider developers to declare logic which might match zero, one, or more paths.

Paths are directly convertable into path expressions as exact expression steps. The builder-like syntax for exact expression steps matches the syntax for path steps, such as `AtName()` in both cases always represents an exact transversal into the attribute name of an object. Additional expression steps enable matching any list, map, or set element, such as `AtAnyListIndex()`. It also supports relative attribute path expressions, by supporting a parent expression step `AtParent()` or starting an expression with `MatchParent()` which can be combined with a prior path expression.

The framework will automatically expose path expressions to attribute plan modifiers and validators, so they can more intuitively support relative paths as inputs to their logic. For example, the `terraform-plugin-framework-validators` Go module will implement support for `terraform-plugin-sdk` multiple attribute schema behaviors such as `ConflictsWith`. It is expected that the downstream implementation can allow provider developers to declare the validator with expressions such as:

```go
tfsdk.Attribute{
	// ... other fields ...

	Validators: []AttributeValidators{
		schemavalidator.ConflictsWith(
			// Example absolute path from root
			path.MatchRoot("root_attribute"),

			// Example relative path from current attribute
			// e.g. another attribute at the same list index of ListNestedAttributes
			path.MatchParent().AtName("another_same_level_attribute"),
		),
	},
}
```

Then the logic within the validator can take the `ValidateAttributeRequest.AttributePathExpression` and use the `(path.Expression).Append()` method to combine the current attribute expression with any incoming expressions.

While this introduction will expose the expression types and make them available to attribute plan modifiers and validators, there is not yet a simple methodology for getting valid paths within data stored in `tfsdk.Config`, `tfsdk.Plan`, and `tfsdk.State` that match the expression. This will be added after this initial expression API is reviewed and approved.
@bflad bflad added the enhancement New feature or request label Jun 28, 2022
@bflad bflad added this to the v0.10.0 milestone Jun 28, 2022
@bflad bflad requested a review from a team as a code owner June 28, 2022 14:38
Copy link
Contributor

@detro detro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code wise is 👨‍🍳 💋

But I do have a "how do I use this?" question.


// Expression represents an attribute path with expression steps, which can
// represent zero, one, or more actual Paths.
type Expression struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the description, I was expecting an .Append() method here.

I see there is one on the ExpressionSteps, but not on the expression itself.

The reason for me asking, is that I'm trying to imagine how we would take the input for a schemavalidator, append it to the path.Expression of the attribute, and get to the referred-to attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh goodness, you are absolutely right that I omitted that method. It's important to be able to merge expressions, especially in plan modifiers and validators. I'll get that pushed up shortly.

@bflad
Copy link
Contributor Author

bflad commented Jun 29, 2022

@detro I wound up adding the (path.Expression).Merge(path.Expression) path.Expression method and the (tfsdk.Config).PathMatches(path.Expression) path.Paths, (tfsdk.Plan).PathMatches(path.Expression) path.Paths, and (tfsdk.State).PathMatches(path.Expression) path.Paths methods, so this pull request should be more fully functional downstream for testing. Can you please take a fresh look? Thanks so much.

@bflad bflad requested review from detro and bendbennett June 29, 2022 17:21
@bflad bflad merged commit 34bd9b6 into main Jun 29, 2022
@bflad bflad deleted the bflad-pathexp branch June 29, 2022 23:00
bflad added a commit to hashicorp/terraform-docs-common that referenced this pull request Jul 8, 2022
…mework-only features

Reference: hashicorp/terraform-plugin-framework#396
Reference: hashicorp/terraform-plugin-framework#409

These will be included in the upcoming terraform-plugin-framework v0.10.0 release and are features not available in terraform-plugin-sdk/v2.
bflad added a commit to hashicorp/terraform-docs-common that referenced this pull request Jul 21, 2022
…mework-only features (#65)

Reference: hashicorp/terraform-plugin-framework#396
Reference: hashicorp/terraform-plugin-framework#409

These were included in the terraform-plugin-framework v0.10.0 release and are features not available in terraform-plugin-sdk/v2.
@github-actions
Copy link

I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions.
If you have found a problem that seems related to this change, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants