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

Int64 Amount Validation (AtLeastSumOf, AtMostSumOf, EqualToSumOf) #20

Closed
1 task done
bendbennett opened this issue May 23, 2022 · 1 comment · Fixed by #29
Closed
1 task done

Int64 Amount Validation (AtLeastSumOf, AtMostSumOf, EqualToSumOf) #20

bendbennett opened this issue May 23, 2022 · 1 comment · Fixed by #29
Assignees
Labels
enhancement New feature or request type/int64 types.Int64 validators type/multi Multiple attribute validators
Milestone

Comments

@bendbennett
Copy link
Contributor

bendbennett commented May 23, 2022

Terraform CLI and Framework Versions

Any Terraform CLI version; terraform-plugin-framework v0.8.0

Use Cases or Problem Statement

Provider developers should be able to generically validate types.Int64 values for their amount/size. For example:

  • Whether a known value is equal or more than the sum of one or more attributes, but not constrained
  • Whether a known value is equal or less than the sum of one or more attributes, but not constrained
  • Whether a known value is exactly equal to the sum of one or more attributes, but not constrained

Proposal

Inside a int64validator package, create one new unexported types that satisfy the tfsdk.AttributeValidator interface:

var _ atLeastSumOfValidator = tfsdk.AttributeValidator

type atLeastSumOfValidator struct {
	attributesToSum []*tftypes.AttributePath
}

func (v atLeastSumOfValidator) Description(ctx context.Context) string {/*...*/}
func (v atLeastSumOfValidator) MarkdownDescription(ctx context.Context) string {/*...*/}
func (v atLeastSumOfValidator) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, resp *tfsdk.ValidateAttributeResponse) {/*...*/}

Then, create exported functions that return these:

func AtLeastSumOf(attributesToSum []*tftypes.AttributePath) AttributeValidator {/*...*/}

This would allow provider developers to declare attributes such as:

tfsdk.Attribute{
  // ... other fields ...
  Type: types.Int64,
  Validators: tfsdk.AttributeValidators{
    int64validator.AtLeastSumOf(
	tftypes.NewAttributePath().WithAttributeName("attrib_one"), 
	tftypes.NewAttributePath().WithAttributeName("attrib_two")),
  },
},

Additional Information

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct
@bendbennett bendbennett added enhancement New feature or request type/int64 types.Int64 validators labels May 23, 2022
@bflad bflad added the type/multi Multiple attribute validators label May 25, 2022
bendbennett added a commit that referenced this issue May 30, 2022
…ribute(s) are null or unknown for int64 atLeastSumOf (#20)
@bendbennett bendbennett changed the title Int64 Amount Validation (AtLeastSumOf) Int64 Amount Validation (AtLeastSumOf, AtMostSumOf, EqualToSumOf) May 30, 2022
@bflad bflad added this to the v0.4.0 milestone Jun 22, 2022
bflad added a commit to hashicorp/terraform-plugin-framework that referenced this issue 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 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 added a commit to hashicorp/terraform-plugin-framework that referenced this issue Jun 29, 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:

```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.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.
bendbennett added a commit that referenced this issue Jul 6, 2022
bendbennett added a commit that referenced this issue Jul 13, 2022
bendbennett added a commit that referenced this issue Jul 13, 2022
@detro detro closed this as completed in #29 Jul 20, 2022
detro pushed a commit that referenced this issue Jul 20, 2022
* Adding atLeastSumOf, atMostSumOf and equalToSumOf int64 validators (#20)

* Switching to using path expressions

* Do not validate if any attributes are unknown (#20)

* Updating dependencies, including terraform-plugin-framework@0.10.0

* PR review: making use of the new `path.Expression` `.MergeExpressions` method

* Preparing CHANGELOG entry

* Rely on 'tfsdk.ValueAs' to do type validation

Co-authored-by: Ivan De Marino <ivan.demarino@hashicorp.com>
Co-authored-by: Brian Flad <bflad417@gmail.com>
@github-actions
Copy link

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, 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 Aug 20, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request type/int64 types.Int64 validators type/multi Multiple attribute validators
Projects
None yet
2 participants