Skip to content

Commit 17b2313

Browse files
author
Pier-Luc Caron-St-Pierre
committed
Migration fromi TypeWithValidate to ValidateableAttribute
1 parent 4214933 commit 17b2313

File tree

4 files changed

+153
-112
lines changed

4 files changed

+153
-112
lines changed

internal/provider/customtypes/packer_fingerprint.go

Lines changed: 52 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@ import (
1111
"github.com/hashicorp/terraform-plugin-framework/attr"
1212
"github.com/hashicorp/terraform-plugin-framework/attr/xattr"
1313
"github.com/hashicorp/terraform-plugin-framework/diag"
14-
"github.com/hashicorp/terraform-plugin-framework/path"
14+
"github.com/hashicorp/terraform-plugin-framework/function"
1515
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
1616
"github.com/hashicorp/terraform-plugin-go/tftypes"
1717
)
1818

19-
// PackerFingerprintType is a custom type for HCP Packer Fingerprints
19+
var (
20+
_ basetypes.StringTypable = &PackerFingerprintType{}
21+
)
22+
2023
type PackerFingerprintType struct {
2124
basetypes.StringType
2225
}
2326

24-
var _ basetypes.StringTypable = &PackerFingerprintType{}
25-
var _ xattr.TypeWithValidate = PackerFingerprintType{}
26-
2727
func (t PackerFingerprintType) String() string {
2828
return "PackerFingerprintType"
2929
}
@@ -66,13 +66,12 @@ func (t PackerFingerprintType) ValueFromTerraform(ctx context.Context, in tftype
6666
return fingerprintValue, nil
6767
}
6868

69-
func NewPackerFingerprintValue(value string) PackerFingerprintValue {
70-
return PackerFingerprintValue{
71-
StringValue: basetypes.NewStringValue(value),
72-
}
73-
}
69+
var (
70+
_ basetypes.StringValuable = &PackerFingerprintValue{}
71+
_ xattr.ValidateableAttribute = &PackerFingerprintValue{}
72+
_ function.ValidateableParameter = &PackerFingerprintValue{}
73+
)
7474

75-
// PackerFingerprintValue is a custom value used to validate that a string is an HCP Packer Fingerprint
7675
type PackerFingerprintValue struct {
7776
basetypes.StringValue
7877
}
@@ -92,38 +91,62 @@ func (v PackerFingerprintValue) Equal(o attr.Value) bool {
9291
return v.StringValue.Equal(other.StringValue)
9392
}
9493

95-
// Validate checks that the value is a valid PackerFingerprint, if it is known and not null.
96-
func (t PackerFingerprintType) Validate(ctx context.Context, value tftypes.Value, valuePath path.Path) diag.Diagnostics {
97-
if value.IsNull() || !value.IsKnown() {
98-
return nil
94+
func (v PackerFingerprintValue) ValidateAttribute(ctx context.Context, req xattr.ValidateAttributeRequest, resp *xattr.ValidateAttributeResponse) {
95+
if v.IsUnknown() || v.IsNull() {
96+
return
9997
}
10098

101-
var diags diag.Diagnostics
102-
var valueString string
103-
104-
if err := value.As(&valueString); err != nil {
105-
diags.Append(newInvalidTerraformValueError(valuePath, err))
106-
return diags
107-
}
99+
valueString := v.String()
108100

109101
if len(valueString) < 1 || len(valueString) > 40 {
110-
diags.AddAttributeError(
111-
valuePath,
112-
"invalid format for an HCP Packer Fingerprint",
113-
"must be between 1 and 40 characters long, inclusive",
102+
resp.Diagnostics.Append(
103+
diag.NewAttributeErrorDiagnostic(
104+
req.Path,
105+
"invalid format for an HCP Packer Fingerprint",
106+
"must be between 1 and 40 characters long, inclusive",
107+
),
114108
)
115109
}
116110

117111
if !regexp.MustCompile(`^[a-zA-Z0-9_\-\.\"]+$`).MatchString(valueString) {
118-
diags.AddAttributeError(
119-
valuePath,
112+
diag.NewAttributeErrorDiagnostic(
113+
req.Path,
120114
"invalid format for an HCP Packer Fingerprint",
121115
// TODO: The regex also allows double quotes, and does not check the first or last characters.
122116
// This is because the v1 HCP Packer API allowed quotes. Once that API is deprecated,
123117
// and there are no more offending versions, we can add the strict validation.
124118
"must contain only alphanumeric characters, underscores, dashes, and periods",
125119
)
126120
}
121+
}
122+
123+
func (v PackerFingerprintValue) ValidateParameter(ctx context.Context, req function.ValidateParameterRequest, resp *function.ValidateParameterResponse) {
124+
if v.IsUnknown() || v.IsNull() {
125+
return
126+
}
127+
128+
valueString := v.String()
129+
130+
if len(valueString) < 1 || len(valueString) > 40 {
131+
resp.Error = function.NewArgumentFuncError(
132+
req.Position,
133+
"HCP Packer Fingerprint must be between 1 and 40 characters long, inclusive",
134+
)
135+
}
136+
137+
if !regexp.MustCompile(`^[a-zA-Z0-9_\-\.\"]+$`).MatchString(valueString) {
138+
resp.Error = function.NewArgumentFuncError(
139+
req.Position,
140+
// TODO: The regex also allows double quotes, and does not check the first or last characters.
141+
// This is because the v1 HCP Packer API allowed quotes. Once that API is deprecated,
142+
// and there are no more offending versions, we can add the strict validation.
143+
"HCP Packer Fingerprint must contain only alphanumeric characters, underscores, dashes, and periods",
144+
)
145+
}
146+
}
127147

128-
return diags
148+
func NewPackerFingerprintValue(value string) PackerFingerprintValue {
149+
return PackerFingerprintValue{
150+
StringValue: basetypes.NewStringValue(value),
151+
}
129152
}

internal/provider/customtypes/slug.go

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@ import (
1010
"github.com/hashicorp/terraform-plugin-framework/attr"
1111
"github.com/hashicorp/terraform-plugin-framework/attr/xattr"
1212
"github.com/hashicorp/terraform-plugin-framework/diag"
13-
"github.com/hashicorp/terraform-plugin-framework/path"
13+
"github.com/hashicorp/terraform-plugin-framework/function"
1414
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
1515
"github.com/hashicorp/terraform-plugin-go/tftypes"
1616
"github.com/hashicorp/terraform-provider-hcp/internal/input"
1717
)
1818

19-
// SlugType is a custom type for Slugs
19+
var (
20+
_ basetypes.StringTypable = &SlugType{}
21+
)
22+
2023
type SlugType struct {
2124
basetypes.StringType
2225
}
2326

24-
var _ basetypes.StringTypable = &SlugType{}
25-
var _ xattr.TypeWithValidate = SlugType{}
26-
2727
func (t SlugType) String() string {
2828
return "SlugType"
2929
}
@@ -66,19 +66,16 @@ func (t SlugType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (att
6666
return slugValue, nil
6767
}
6868

69-
func NewSlugValue(value string) SlugValue {
70-
return SlugValue{
71-
StringValue: basetypes.NewStringValue(value),
72-
}
73-
}
69+
var (
70+
_ basetypes.StringValuable = &SlugValue{}
71+
_ xattr.ValidateableAttribute = &SlugValue{}
72+
_ function.ValidateableParameter = &SlugValue{}
73+
)
7474

75-
// SlugValue is a custom value used to validate that a string is a Slug
7675
type SlugValue struct {
7776
basetypes.StringValue
7877
}
7978

80-
var _ basetypes.StringValuable = SlugValue{}
81-
8279
func (v SlugValue) Type(context.Context) attr.Type {
8380
return SlugType{}
8481
}
@@ -92,28 +89,37 @@ func (v SlugValue) Equal(o attr.Value) bool {
9289
return v.StringValue.Equal(other.StringValue)
9390
}
9491

95-
// Validate checks that the value is a valid Slug, if it is known and not null.
96-
func (t SlugType) Validate(ctx context.Context, value tftypes.Value, valuePath path.Path) diag.Diagnostics {
97-
if value.IsNull() || !value.IsKnown() {
98-
return nil
92+
func (v SlugValue) ValidateAttribute(ctx context.Context, req xattr.ValidateAttributeRequest, resp *xattr.ValidateAttributeResponse) {
93+
if v.IsNull() || v.IsUnknown() {
94+
return
9995
}
10096

101-
var diags diag.Diagnostics
102-
var valueString string
97+
if !input.IsSlug(v.ValueString()) {
98+
resp.Diagnostics.Append(
99+
diag.NewAttributeErrorDiagnostic(
100+
req.Path,
101+
"expected a valid Slug",
102+
"slugs must be of length 3-36 and contain only alphanumeric characters and hyphens",
103+
),
104+
)
105+
}
106+
}
103107

104-
if err := value.As(&valueString); err != nil {
105-
diags.Append(newInvalidTerraformValueError(valuePath, err))
106-
return diags
108+
func (v SlugValue) ValidateParameter(ctx context.Context, req function.ValidateParameterRequest, resp *function.ValidateParameterResponse) {
109+
if v.IsUnknown() || v.IsNull() {
110+
return
107111
}
108112

109-
if !input.IsSlug(valueString) {
110-
diags.AddAttributeError(
111-
valuePath,
112-
"expected a valid Slug",
113+
if !input.IsSlug(v.ValueString()) {
114+
resp.Error = function.NewArgumentFuncError(
115+
req.Position,
113116
"slugs must be of length 3-36 and contain only alphanumeric characters and hyphens",
114117
)
115-
return diags
116118
}
119+
}
117120

118-
return diags
121+
func NewSlugValue(value string) SlugValue {
122+
return SlugValue{
123+
StringValue: basetypes.NewStringValue(value),
124+
}
119125
}

internal/provider/customtypes/ulid.go

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@ import (
1111
"github.com/hashicorp/terraform-plugin-framework/attr"
1212
"github.com/hashicorp/terraform-plugin-framework/attr/xattr"
1313
"github.com/hashicorp/terraform-plugin-framework/diag"
14-
"github.com/hashicorp/terraform-plugin-framework/path"
14+
"github.com/hashicorp/terraform-plugin-framework/function"
1515
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
1616
"github.com/hashicorp/terraform-plugin-go/tftypes"
1717
"github.com/oklog/ulid"
1818
)
1919

20-
// ULIDType is a custom type for ULIDs
20+
var (
21+
_ basetypes.StringTypable = &ULIDType{}
22+
)
23+
2124
type ULIDType struct {
2225
basetypes.StringType
2326
}
2427

25-
var _ basetypes.StringTypable = &ULIDType{}
26-
var _ xattr.TypeWithValidate = ULIDType{}
27-
2828
func (t ULIDType) String() string {
2929
return "ULIDType"
3030
}
@@ -67,19 +67,16 @@ func (t ULIDType) ValueFromTerraform(ctx context.Context, in tftypes.Value) (att
6767
return ulidValue, nil
6868
}
6969

70-
func NewULIDValue(value string) ULIDValue {
71-
return ULIDValue{
72-
StringValue: basetypes.NewStringValue(value),
73-
}
74-
}
70+
var (
71+
_ basetypes.StringValuableWithSemanticEquals = &ULIDValue{}
72+
_ xattr.ValidateableAttribute = &ULIDValue{}
73+
_ function.ValidateableParameter = &ULIDValue{}
74+
)
7575

76-
// ULIDValue is a custom value used to validate that a string is a ULID
7776
type ULIDValue struct {
7877
basetypes.StringValue
7978
}
8079

81-
var _ basetypes.StringValuableWithSemanticEquals = ULIDValue{}
82-
8380
func (v ULIDValue) Type(context.Context) attr.Type {
8481
return ULIDType{}
8582
}
@@ -118,28 +115,38 @@ func (v ULIDValue) StringSemanticEquals(ctx context.Context, newValuable basetyp
118115
return reflect.DeepEqual(oldULID, newULID), diags
119116
}
120117

121-
// Validate checks that the value is a valid ULID, if it is known and not null.
122-
func (t ULIDType) Validate(ctx context.Context, value tftypes.Value, valuePath path.Path) diag.Diagnostics {
123-
if value.IsNull() || !value.IsKnown() {
124-
return nil
118+
func (v ULIDValue) ValidateAttribute(ctx context.Context, req xattr.ValidateAttributeRequest, resp *xattr.ValidateAttributeResponse) {
119+
if v.IsNull() || v.IsUnknown() {
120+
return
125121
}
126122

127-
var diags diag.Diagnostics
128-
var valueString string
123+
if _, err := ulid.Parse(v.ValueString()); err != nil {
124+
resp.Diagnostics.Append(
125+
diag.NewAttributeErrorDiagnostic(
126+
req.Path,
127+
"expected a valid ULID",
128+
err.Error(),
129+
),
130+
)
131+
}
132+
133+
}
129134

130-
if err := value.As(&valueString); err != nil {
131-
diags.Append(newInvalidTerraformValueError(valuePath, err))
132-
return diags
135+
func (v ULIDValue) ValidateParameter(ctx context.Context, req function.ValidateParameterRequest, resp *function.ValidateParameterResponse) {
136+
if v.IsUnknown() || v.IsNull() {
137+
return
133138
}
134139

135-
if _, err := ulid.Parse(valueString); err != nil {
136-
diags.AddAttributeError(
137-
valuePath,
138-
"expected a valid ULID",
140+
if _, err := ulid.Parse(v.ValueString()); err != nil {
141+
resp.Error = function.NewArgumentFuncError(
142+
req.Position,
139143
err.Error(),
140144
)
141-
return diags
142145
}
146+
}
143147

144-
return diags
148+
func NewULIDValue(value string) ULIDValue {
149+
return ULIDValue{
150+
StringValue: basetypes.NewStringValue(value),
151+
}
145152
}

0 commit comments

Comments
 (0)