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

Introducing schemavalidator package #32

Merged
merged 20 commits into from
Jul 12, 2022
Merged

Introducing schemavalidator package #32

merged 20 commits into from
Jul 12, 2022

Conversation

detro
Copy link
Contributor

@detro detro commented May 31, 2022

Closes #14
Closes #15
Closes #16
Closes #17

NOTE: This PR depends on changes in terraform-plugin-framework that will land in v0.10.0. To allow tests to pass, I have temporarily set the go.mod to pull main branch: to do the v0.4.0 release, we will have to wait on FW to ship, then we will update go.mod, and then cut it.

@detro detro requested a review from a team as a code owner May 31, 2022 17:38
@detro detro added this to the v0.2.0 milestone May 31, 2022
Copy link
Contributor

@bendbennett bendbennett left a comment

Choose a reason for hiding this comment

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

Nice!

combovalidator/at_least_one_of.go Outdated Show resolved Hide resolved
combovalidator/exactly_one_of_test.go Outdated Show resolved Hide resolved
go.mod Outdated Show resolved Hide resolved
helpers/attributepath/to_string.go Outdated Show resolved Hide resolved
@ewbankkit
Copy link
Contributor

Drive-by comment:
Have you considered moving helpers below an internal directory so that the functions aren't available in the public API?

@bflad
Copy link
Contributor

bflad commented Jun 1, 2022

I'm not personally sure why they're being moved under helpers/ yet (I haven't asked), but I can say that external validators may wish to implement these as well-defined diagnostics. In the future, we may be able to also leverage them for potential use cases such as a generic Not() validator.

@detro
Copy link
Contributor Author

detro commented Jun 6, 2022

@ewbankkit @bflad about the move under helpers/ I did touch briefly upon it in the previous (now closed) PR and verbally: the essence being, the role of those functions isn't central to validation (the focus of this package) - they have more of a supporting role in the play. The name helpers/ is just an alternative to utilities/ or other well known terms that should allow the developer to understand what's in the package, without a lot of explanation.

About the new validators, I was reading the doc that @bflad put down for native AttributePath in FW, and I was thinking that the name schemavalidator might be better than combovalidator: what do you think?

@detro detro modified the milestones: v0.2.0, v0.3.0 Jun 7, 2022
@bflad
Copy link
Contributor

bflad commented Jun 7, 2022

I may or may not have visceral reactions due to helper/ in terraform-plugin-sdk. 😂 As you mention, it's probably better to put it under there. We're not breaking a cardinal Go convention about avoiding ambiguous package names if its just a prefix.

The schemavalidator package name is a great idea! I'm on board with that naming.

I've mentioned out of band from GitHub that it might be good to wait to merge and release these until hashicorp/terraform-plugin-framework#81 is sorted upstream, just so we don't immediately have to introduce that breaking change here. 👍 I also think you and @bendbennett have been working pretty closely on these, so please reach out if any of my feedback from #29 doesn't make sense.

@detro detro force-pushed the detro/combovalidator branch from 587307a to 8153099 Compare June 20, 2022 09:30
@detro detro changed the title Introducing combovalidator package Introducing schemavalidator package Jun 20, 2022
@detro detro force-pushed the detro/combovalidator branch from 9c8dd47 to e5e117e Compare June 20, 2022 13:01
@bflad bflad added the enhancement New feature or request label Jun 22, 2022
@bflad
Copy link
Contributor

bflad commented Jun 22, 2022

FYI, moving this to v0.4.0 so we can release v0.3.0 with additional validators not dependent on hashicorp/terraform-plugin-framework#81, upgrade the framework dependency when its released, then focus immediately on these.

@bflad bflad modified the milestones: v0.3.0, v0.4.0 Jun 22, 2022
@detro detro force-pushed the detro/combovalidator branch 2 times, most recently from a89d000 to 60886e2 Compare June 27, 2022 17:18
@detro detro force-pushed the detro/combovalidator branch from 60886e2 to e3b6a99 Compare July 6, 2022 13:36
Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

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

Overall it's shaping up really good -- I think we should discuss the semantics of unknown values some more though before committing to these as written.

.changelog/42.txt Outdated Show resolved Hide resolved
schemavalidator/doc.go Outdated Show resolved Hide resolved
schemavalidator/at_least_one_of.go Outdated Show resolved Hide resolved
schemavalidator/at_least_one_of.go Outdated Show resolved Hide resolved
helpers/pathutils/merge.go Outdated Show resolved Hide resolved
schemavalidator/conflicts_with.go Outdated Show resolved Hide resolved
schemavalidator/conflicts_with.go Outdated Show resolved Hide resolved
schemavalidator/conflicts_with_test.go Outdated Show resolved Hide resolved
schemavalidator/required_with.go Outdated Show resolved Hide resolved
schemavalidator/required_with.go Outdated Show resolved Hide resolved
Ivan De Marino and others added 4 commits July 7, 2022 11:54
Co-authored-by: Brian Flad <bflad417@gmail.com>
Co-authored-by: Brian Flad <bflad417@gmail.com>
Co-authored-by: Brian Flad <bflad417@gmail.com>
bflad added a commit to hashicorp/terraform-plugin-framework that referenced this pull request Jul 7, 2022
bflad added a commit to hashicorp/terraform-plugin-framework that referenced this pull request Jul 7, 2022
Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

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

Just some additional drive-by notes about the latest code. Happy to have the unknown values discussion anytime.

I also wonder if we should still consider creating DataSourceConfigValidator/ProviderConfigValidator/ResourceConfigValidator implementations of these to suit provider developer styles as noted in the original issues because sometimes basing multiple attribute validation on a particular attribute can be confusing or duplicative (both in code and returned diagnostics), e.g.

"attr1": tfsdk.Attribute{
  Validators: []tfsdk.AttributeValidator{
    schemavalidator.ConflictsWith(path.MatchRoot("attr2")),
  },
}
"attr2": tfsdk.Attribute{
  Validators: []tfsdk.AttributeValidator{
    schemavalidator.ConflictsWith(path.MatchRoot("attr1")),
  },
}

Would return two similar error diagnostics (one for each attribute validator) versus something like:

func (r exampleResource) ConfigValidators(ctx context.Context) []tfsdk.ResourceConfigValidator {
  return []tfsdk.ResourceConfigValidator{
    configvalidator.ConflictingAttributes(
      path.MatchRoot("attr1"),
      path.MatchRoot("attr2"),
    ),
  }
}

Those *ConfigValidator implementations don't need to be part of this PR, but I worry about closing the original issues without at least creating followup ones to support the other declaration style. Refer also to hashicorp/terraform-plugin-sdk#286. I also need to ensure there is an issue in terraform-plugin-framework that allows a single configuration validator to work across all three of DataSource/Provider/Resource; I'm pretty sure the Validate() method of each is conflicting at the moment, which was an oversight in the original implementation.

schemavalidator/at_least_one_of.go Show resolved Hide resolved
schemavalidator/conflicts_with.go Show resolved Hide resolved
schemavalidator/conflicts_with.go Outdated Show resolved Hide resolved
return fmt.Sprintf("Ensure that if an attribute is set, also these are set: %q", av.pathExpressions)
}

func (av requiredWithAttributeValidator) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, res *tfsdk.ValidateAttributeResponse) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe if the current attribute with the validator is null, the rest of the logic can be skipped.

Suggested change
func (av requiredWithAttributeValidator) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, res *tfsdk.ValidateAttributeResponse) {
func (av requiredWithAttributeValidator) Validate(ctx context.Context, req tfsdk.ValidateAttributeRequest, res *tfsdk.ValidateAttributeResponse) {
if req.AttributeConfig.IsNull() {
return
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

About this one I'm a bit perplexed.

The issue is, if this is "requiredWith", we need to establish if it's NULL whilst the other it's required to be with are NOT NULL.

It should instead fail when the attribute is NULL, but the one its required to be required with aren't.

return
}

if !req.AttributeConfig.IsNull() && mpVal.IsNull() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Paired with the above check if the current attribute with the validator is null:

Suggested change
if !req.AttributeConfig.IsNull() && mpVal.IsNull() {
if mpVal.IsNull() {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

See above, why I'm perplexed with this one.

@detro
Copy link
Contributor Author

detro commented Jul 8, 2022

In regards to having also the DataSourceConfigValidator / ProviderConfigValidator / ResourceConfigValidator, I think that is a fair and probably necessary thing.

One thing that working on those validators showed me, is that while they fulfil the need and match the SDK featureset, the resource/data-source/provider level ones, for schema validation, are WAY better suited.

So I'm going to do create an additional issue to track the work to add those kinds of validators, so we don't lose track of this need, but we can still close the existing issues I was targeting here.

Copy link
Contributor

@bflad bflad left a comment

Choose a reason for hiding this comment

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

Approving the changes outside my own

@detro detro merged commit 81783a7 into main Jul 12, 2022
@detro detro deleted the detro/combovalidator branch July 12, 2022 15:50
@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 Aug 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.