fix: validates the record conent based on record type (#267)
* fix: validates the record conent based on record type Signed-off-by: Jorge Turrado <jorge.turrado@scrm.lidl> * fix typo Signed-off-by: Jorge Turrado <jorge.turrado@scrm.lidl> * apply feedback Signed-off-by: Jorge Turrado <jorge.turrado@scrm.lidl> * apply feedback Signed-off-by: Jorge Turrado <jorge.turrado@scrm.lidl> --------- Signed-off-by: Jorge Turrado <jorge.turrado@scrm.lidl>
This commit is contained in:
parent
a88688ce93
commit
32d176ee86
3 changed files with 196 additions and 1 deletions
|
|
@ -158,7 +158,7 @@ func (r *recordSetResource) Schema(_ context.Context, _ resource.SchemaRequest,
|
||||||
Validators: []validator.List{
|
Validators: []validator.List{
|
||||||
listvalidator.SizeAtLeast(1),
|
listvalidator.SizeAtLeast(1),
|
||||||
listvalidator.UniqueValues(),
|
listvalidator.UniqueValues(),
|
||||||
listvalidator.ValueStringsAre(validate.IP()),
|
listvalidator.ValueStringsAre(validate.RecordSet()),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"ttl": schema.Int64Attribute{
|
"ttl": schema.Int64Attribute{
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ import (
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
"github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
|
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -73,6 +75,45 @@ func IP() *Validator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func RecordSet() *Validator {
|
||||||
|
const typePath = "type"
|
||||||
|
return &Validator{
|
||||||
|
description: "value must be a valid record set",
|
||||||
|
validate: func(ctx context.Context, req validator.StringRequest, resp *validator.StringResponse) {
|
||||||
|
recordType := basetypes.StringValue{}
|
||||||
|
req.Config.GetAttribute(ctx, path.Root(typePath), &recordType)
|
||||||
|
switch recordType.ValueString() {
|
||||||
|
case "A":
|
||||||
|
ip := net.ParseIP(req.ConfigValue.ValueString())
|
||||||
|
if ip == nil || ip.To4() == nil {
|
||||||
|
resp.Diagnostics.Append(validatordiag.InvalidAttributeValueDiagnostic(
|
||||||
|
req.Path,
|
||||||
|
"value must be an IPv4 address",
|
||||||
|
req.ConfigValue.ValueString(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
case "AAAA":
|
||||||
|
ip := net.ParseIP(req.ConfigValue.ValueString())
|
||||||
|
if ip == nil || ip.To4() != nil || ip.To16() == nil {
|
||||||
|
resp.Diagnostics.Append(validatordiag.InvalidAttributeValueDiagnostic(
|
||||||
|
req.Path,
|
||||||
|
"value must be an IPv6 address",
|
||||||
|
req.ConfigValue.ValueString(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
case "CNAME":
|
||||||
|
case "NS":
|
||||||
|
case "MX":
|
||||||
|
case "TXT":
|
||||||
|
case "ALIAS":
|
||||||
|
case "DNAME":
|
||||||
|
case "CAA":
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func NoSeparator() *Validator {
|
func NoSeparator() *Validator {
|
||||||
description := fmt.Sprintf("value must not contain identifier separator '%s'", core.Separator)
|
description := fmt.Sprintf("value must not contain identifier separator '%s'", core.Separator)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,11 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-go/tftypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUUID(t *testing.T) {
|
func TestUUID(t *testing.T) {
|
||||||
|
|
@ -101,6 +104,157 @@ func TestIP(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRecordSet(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
description string
|
||||||
|
record string
|
||||||
|
recordType string
|
||||||
|
isValid bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"A record ok IP4",
|
||||||
|
"111.222.111.222",
|
||||||
|
"A",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A record fail IP6",
|
||||||
|
"2001:0db8:85a3:08d3::0370:7344",
|
||||||
|
"A",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A record too short",
|
||||||
|
"0.1.2",
|
||||||
|
"A",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A record Empty",
|
||||||
|
"",
|
||||||
|
"A",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"A record Not an IP",
|
||||||
|
"for-sure-not-an-IP",
|
||||||
|
"A",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AAAA record fail IP4",
|
||||||
|
"111.222.111.222",
|
||||||
|
"AAAA",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AAAA record ok IP6",
|
||||||
|
"2001:0db8:85a3:08d3::0370:7344",
|
||||||
|
"AAAA",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AAAA record too short",
|
||||||
|
"0.1.2",
|
||||||
|
"AAAA",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AAAA record Empty",
|
||||||
|
"",
|
||||||
|
"AAAA",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"AAAA record Not an IP",
|
||||||
|
"for-sure-not-an-IP",
|
||||||
|
"AAAA",
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"CNAME record",
|
||||||
|
"some-record",
|
||||||
|
"CNAME",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"NS record",
|
||||||
|
"some-record",
|
||||||
|
"NS",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"MX record",
|
||||||
|
"some-record",
|
||||||
|
"MX",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"TXT record",
|
||||||
|
"some-record",
|
||||||
|
"TXT",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ALIAS record",
|
||||||
|
"some-record",
|
||||||
|
"ALIAS",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DNAME record",
|
||||||
|
"some-record",
|
||||||
|
"DNAME",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"CAA record",
|
||||||
|
"some-record",
|
||||||
|
"CAA",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"random record",
|
||||||
|
"some-record",
|
||||||
|
"random",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.description, func(t *testing.T) {
|
||||||
|
r := validator.StringResponse{}
|
||||||
|
scheme := tftypes.Object{
|
||||||
|
AttributeTypes: map[string]tftypes.Type{
|
||||||
|
"type": tftypes.String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
value := map[string]tftypes.Value{
|
||||||
|
"type": tftypes.NewValue(tftypes.String, tt.recordType),
|
||||||
|
}
|
||||||
|
record := tftypes.NewValue(scheme, value)
|
||||||
|
|
||||||
|
RecordSet().ValidateString(context.Background(), validator.StringRequest{
|
||||||
|
Config: tfsdk.Config{
|
||||||
|
Schema: schema.Schema{
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"type": schema.StringAttribute{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Raw: record,
|
||||||
|
},
|
||||||
|
ConfigValue: types.StringValue(tt.record),
|
||||||
|
}, &r)
|
||||||
|
|
||||||
|
if !tt.isValid && !r.Diagnostics.HasError() {
|
||||||
|
t.Fatalf("Should have failed")
|
||||||
|
}
|
||||||
|
if tt.isValid && r.Diagnostics.HasError() {
|
||||||
|
t.Fatalf("Should not have failed: %v", r.Diagnostics.Errors())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNoSeparator(t *testing.T) {
|
func TestNoSeparator(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
description string
|
description string
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue