terraform-provider-scaffolding icon indicating copy to clipboard operation
terraform-provider-scaffolding copied to clipboard

feat: add example of usage of ValidateDiagFunc

Open mavogel opened this issue 3 years ago • 3 comments

Details

An example of

  • how to use this function instead of the old ValidateFunc
  • and how to test it

would be helpful.

Currently, I cannot get it running:

"host_path": {
  Type:             schema.TypeString,
  Optional:         true,
  ForceNew:         true,
  ValidateDiagFunc: validateDockerContainerPath,
},

and the implementation:

func validateDockerContainerPath() schema.SchemaValidateDiagFunc {
	return func(v interface{}, path cty.Path) diag.Diagnostics {
		value := v.(string)
		var diags diag.Diagnostics
		if !regexp.MustCompile(`^[a-zA-Z]:\\|^/`).MatchString(value) {
			diags = append(diags, diag.Errorf("%q must be an absolute path", value)...)
		}

		return diags
	}
}

I get the error

cannot use validateDockerContainerPath (value of type func() schema.SchemaValidateDiagFunc) as schema.SchemaValidateDiagFunc value in struct literal

Versions

  • terraform: v0.14.3
  • github.com/hashicorp/terraform-plugin-sdk/v2 v2.4.0

Links

  • is related to https://github.com/hashicorp/terraform-plugin-sdk/issues/534

mavogel avatar Dec 29 '20 10:12 mavogel

Hi @mavogel ! Been through the same problem but got it running eventually.

The function ( for testing purposes )

func TestMyValidatorDiag(i interface{}, p cty.Path) diag.Diagnostics {
	return diag.Diagnostics{
		diag.Diagnostic{
			Severity: diag.Error,
			Summary:  "Item not in required array",
			Detail:   "Country code is wrong!",
		},
	}
}

Then within resource schema

			"geo_codes": {
				Type:     schema.TypeList,
				Required: true,
				ForceNew: false,
				Elem: &schema.Schema{
					Type:             schema.TypeString,
					ValidateDiagFunc: TestMyValidatorDiag,
				},
			},

And finally running terraform plan ( expecting to properly fail :) )

❯ terraform plan                         

Error: Item not in required array

  on terraform.tf line 44, in resource "res_geo" "terraform_test":
  44:   geo_codes = ["XX", "PL"]

Country code is wrong!


Error: Item not in required array

  on terraform.tf line 44, in resource "res_geo" "terraform_test":
  44:   geo_codes = ["XX", "PL"]

Country code is wrong!

Just make sure your imports are correct!

import (
	"context"
	"sort"

	"github.com/hashicorp/go-cty/cty"

	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

This should work! Please let me know if you cannot get it to run - we can try to sort it out further!

RafPe avatar Feb 11 '21 11:02 RafPe

TY @RafPe it was the wrong import that caused trouble. github.com/hashicorp/go-cty/cty is the right one.

I also added a unit test and filed a PR #58

// validators.go
func validateStringIsABC(v interface{}, p cty.Path) diag.Diagnostics {
	value := v.(string)
	var diags diag.Diagnostics
	if value != "abc" {
		diag := diag.Diagnostic{
			Severity: diag.Error,
			Summary:  "wrong value",
			Detail:   fmt.Sprintf("%q is not abc", value),
		}
		diags = append(diags, diag)
	}
	return diags
}

// validators_test.go
func TestValidateStringShouldBeABC(t *testing.T) {
	v := "abc"
	if diags := validateStringIsABC(v, *new(cty.Path)); len(diags) != 0 {
		t.Fatalf("%q should be abc", v)
	}

	v = "not-abc"
	if diags := validateStringIsABC(v, *new(cty.Path)); len(diags) == 0 {
		t.Fatalf("%q should NOT be abc", v)
	}
}

mavogel avatar Mar 11 '21 21:03 mavogel

Hi @mavogel 👋 Thank you for raising this.

Having appropriate documentation on ValidateDiagFunc would be great, although it feels like this would be better suited where the existing validation documentation lives, rather than adding code to the scaffolding repository here. The scaffolding code is not intended to be fully exhaustive of all SDK functionality since attempting to do so may introduce confusion for newer provider developers. We intend more advanced usage, such as writing custom validation functions, to be discoverable via the Terraform documentation.

Would you be interested in introducing this documentation on the website instead? The source code can be found at: https://github.com/hashicorp/terraform-website/blob/master/content/plugin/sdkv2/schemas/schema-behaviors.mdx

Thanks!

bflad avatar Dec 21 '21 16:12 bflad