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

Db/fix predicate validation bug #547

Merged
merged 4 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .changes/unreleased/Bugfix-20241212-155300.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind: Bugfix
body: fix incorrect validation error on predicate values set by for_each values
time: 2024-12-12T15:53:00.747508-06:00
6 changes: 6 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,12 @@ tasks:
cmds:
- task: debug:do-debug-plan

debug-validate:
desc: After debug-start and debug-attach, run "terraform validate" with 'TF_REATTACH_PROVIDERS'
aliases: ["dbg-validate"]
cmds:
- task: debug:do-debug-validate

debug-test:
desc: After debug-start and debug-attach, run "terraform test" with 'TF_REATTACH_PROVIDERS'
aliases: ["dbg-test"]
Expand Down
2 changes: 1 addition & 1 deletion opslevel/resource_opslevel_check_alert_source_usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (r *CheckAlertSourceUsageResource) ValidateConfig(ctx context.Context, req
predicateModel, diags := PredicateObjectToModel(ctx, alertNamePredicate)
resp.Diagnostics.Append(diags...)
if err := predicateModel.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root("alert_name_predicate"), "Invalid Attribute Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root("alert_name_predicate"), "Invalid Attribute Configuration", err.Error())
}
}

Expand Down
32 changes: 26 additions & 6 deletions opslevel/resource_opslevel_check_package_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,28 +156,48 @@ func (r *CheckPackageVersionResource) ValidateConfig(ctx context.Context, req re

if configModel.PackageConstraint.ValueString() == string(opslevel.PackageConstraintEnumMatchesVersion) {
if configModel.MissingPackageResult.IsNull() && !configModel.MissingPackageResult.IsUnknown() {
resp.Diagnostics.AddError("missing_package_result", "missing_package_result is required when package_constraint is 'matches_version'")
resp.Diagnostics.AddAttributeWarning(
path.Root("missing_package_result"),
"Invalid Configuration",
"missing_package_result is required when package_constraint is 'matches_version'",
)
}
if configModel.VersionConstraintPredicate.IsNull() && !configModel.VersionConstraintPredicate.IsUnknown() {
resp.Diagnostics.AddError("version_constraint_predicate", "version_constraint_predicate is required when package_constraint is 'matches_version'")
resp.Diagnostics.AddAttributeWarning(
path.Root("version_constraint_predicate"),
"Invalid Configuration",
"version_constraint_predicate is required when package_constraint is 'matches_version'",
)
}
if !configModel.VersionConstraintPredicate.IsNull() {
predicateModel, diags := PredicateObjectToModel(ctx, configModel.VersionConstraintPredicate)
resp.Diagnostics.Append(diags...)
if !slices.Contains(packageVersionPossiblePredicateTypes, opslevel.PredicateTypeEnum(predicateModel.Type.ValueString())) {
resp.Diagnostics.AddError("version_constraint_predicate", fmt.Sprintf("version_constraint_predicate must be one of %v", packageVersionPossiblePredicateTypes))
resp.Diagnostics.AddAttributeWarning(
path.Root("version_constraint_predicate"),
"Invalid Configuration",
fmt.Sprintf("version_constraint_predicate must be one of %v", packageVersionPossiblePredicateTypes),
)
} else {
if err := predicateModel.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root("version_constraint_predicate"), "Invalid Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root("version_constraint_predicate"), "Invalid Configuration", err.Error())
}
}
}
} else {
if !configModel.MissingPackageResult.IsUnknown() && !configModel.MissingPackageResult.IsNull() {
resp.Diagnostics.AddError("missing_package_result", "missing_package_result is only valid when package_constraint is 'matches_version'")
resp.Diagnostics.AddAttributeWarning(
path.Root("missing_package_result"),
"Invalid Configuration",
"missing_package_result is only valid when package_constraint is 'matches_version'",
)
}
if !configModel.VersionConstraintPredicate.IsUnknown() && !configModel.VersionConstraintPredicate.IsNull() {
resp.Diagnostics.AddError("version_constraint_predicate", "version_constraint_predicate is only valid when package_constraint is 'matches_version'")
resp.Diagnostics.AddAttributeWarning(
path.Root("version_constraint_predicate"),
"Invalid Configuration",
"version_constraint_predicate is only valid when package_constraint is 'matches_version'",
)
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion opslevel/resource_opslevel_check_repository_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ func (r *CheckRepositoryFileResource) ValidateConfig(ctx context.Context, req re
predicateModel, diags := PredicateObjectToModel(ctx, fileContentsPredicate)
resp.Diagnostics.Append(diags...)
if err := predicateModel.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root("file_contents_predicate"), "Invalid Attribute Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root("file_contents_predicate"), "Invalid Attribute Configuration", err.Error())
}
}

Expand Down
8 changes: 6 additions & 2 deletions opslevel/resource_opslevel_check_repository_grep.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,14 @@ func (r *CheckRepositoryGrepResource) ValidateConfig(ctx context.Context, req re
resp.Diagnostics.Append(diags...)

if configModel.DirectorySearch.ValueBool() && !slices.Contains([]string{"exists", "does_not_exist"}, predicateModel.Type.ValueString()) {
resp.Diagnostics.AddError("Config Error", "When 'directory_search' is true, file_contents_predicate type must be 'exists' or 'does_not_exist'")
resp.Diagnostics.AddAttributeWarning(
path.Root("directory_search"),
"Invalid Attribute Configuration",
"When 'directory_search' is true, 'file_contents_predicate' type must be 'exists' or 'does_not_exist'",
)
}
if err := predicateModel.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root("file_contents_predicate"), "Invalid Attribute Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root("file_contents_predicate"), "Invalid Attribute Configuration", err.Error())
}
}

Expand Down
4 changes: 2 additions & 2 deletions opslevel/resource_opslevel_check_repository_search.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,10 @@ func (r *CheckRepositorySearchResource) ValidateConfig(ctx context.Context, req
predicateModel, diags := PredicateObjectToModel(ctx, fileContentsPredicate)
resp.Diagnostics.Append(diags...)
if predicateModel.Type.ValueString() == "exists" || predicateModel.Type.ValueString() == "does_not_exist" {
resp.Diagnostics.AddError("Config Error", "file_contents_predicate type must not be 'exists' or 'does_not_exist'")
resp.Diagnostics.AddAttributeWarning(path.Root("file_contents_predicate"), "Invalid Attribute Configuration", "type must not be 'exists' or 'does_not_exist'")
}
if err := predicateModel.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root("file_contents_predicate"), "Invalid Attribute Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root("file_contents_predicate"), "Invalid Attribute Configuration", err.Error())
}
}

Expand Down
2 changes: 1 addition & 1 deletion opslevel/resource_opslevel_check_service_ownership.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (r *CheckServiceOwnershipResource) ValidateConfig(ctx context.Context, req
predicateModel, diags := PredicateObjectToModel(ctx, tagPredicate)
resp.Diagnostics.Append(diags...)
if err := predicateModel.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root("tag_predicate"), "Invalid Attribute Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root("tag_predicate"), "Invalid Attribute Configuration", err.Error())
}
}

Expand Down
2 changes: 1 addition & 1 deletion opslevel/resource_opslevel_check_service_property.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func (r *CheckServicePropertyResource) ValidateConfig(ctx context.Context, req r
predicateModel, diags := PredicateObjectToModel(ctx, predicate)
resp.Diagnostics.Append(diags...)
if err := predicateModel.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root("predicate"), "Invalid Attribute Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root("predicate"), "Invalid Attribute Configuration", err.Error())
}
}

Expand Down
2 changes: 1 addition & 1 deletion opslevel/resource_opslevel_check_tag_defined.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func (r *CheckTagDefinedResource) ValidateConfig(ctx context.Context, req resour
predicateModel, diags := PredicateObjectToModel(ctx, tagPredicate)
resp.Diagnostics.Append(diags...)
if err := predicateModel.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root("tag_predicate"), "Invalid Attribute Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root("tag_predicate"), "Invalid Attribute Configuration", err.Error())
}
}

Expand Down
2 changes: 1 addition & 1 deletion opslevel/resource_opslevel_check_tool_usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func (r *CheckToolUsageResource) ValidateConfig(ctx context.Context, req resourc
predicateModel, diags := PredicateObjectToModel(ctx, predicate)
resp.Diagnostics.Append(diags...)
if err := predicateModel.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root(predicateSchemaName), "Invalid Attribute Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root(predicateSchemaName), "Invalid Attribute Configuration", err.Error())
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion opslevel/resource_opslevel_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ func (r *FilterResource) ValidateConfig(ctx context.Context, req resource.Valida

for _, filterPredicate := range predicateModels {
if err := filterPredicate.Validate(); err != nil {
resp.Diagnostics.AddAttributeError(path.Root("predicate"), "Invalid Attribute Configuration", err.Error())
resp.Diagnostics.AddAttributeWarning(path.Root("predicate"), "Invalid Attribute Configuration", err.Error())
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion opslevel/terraform_type_conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func PredicateObjectToModel(ctx context.Context, predicateObj basetypes.ObjectVa

objOptions := basetypes.ObjectAsOptions{UnhandledNullAsEmpty: true, UnhandledUnknownAsEmpty: true}
diags := predicateObj.As(ctx, &predicateModel, objOptions)
if predicateModel.Value.ValueString() == "" {
if !predicateModel.Value.IsUnknown() && predicateModel.Value.ValueString() == "" {
predicateModel.Value = types.StringNull()
}
return predicateModel, diags
Expand Down
Loading