fix: exclude zero address as for inadmissable cases (#650)

* fix: exclude zero address as for inadmissable cases

* fix: review finding
This commit is contained in:
Rüdiger Schmitz 2025-01-27 12:17:34 +01:00 committed by GitHub
parent 0912ca0246
commit 2ec95dc20f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 61 additions and 9 deletions

View file

@ -200,7 +200,7 @@ func (r *networkResource) Schema(_ context.Context, _ resource.SchemaRequest, re
Optional: true, Optional: true,
Computed: true, Computed: true,
Validators: []validator.String{ Validators: []validator.String{
validate.IP(), validate.IP(false),
}, },
}, },
"ipv4_nameservers": schema.ListAttribute{ "ipv4_nameservers": schema.ListAttribute{
@ -252,7 +252,7 @@ func (r *networkResource) Schema(_ context.Context, _ resource.SchemaRequest, re
Optional: true, Optional: true,
Computed: true, Computed: true,
Validators: []validator.String{ Validators: []validator.String{
validate.IP(), validate.IP(false),
}, },
}, },
"ipv6_nameservers": schema.ListAttribute{ "ipv6_nameservers": schema.ListAttribute{

View file

@ -161,7 +161,7 @@ func (r *networkAreaRouteResource) Schema(_ context.Context, _ resource.SchemaRe
stringplanmodifier.RequiresReplace(), stringplanmodifier.RequiresReplace(),
}, },
Validators: []validator.String{ Validators: []validator.String{
validate.IP(), validate.IP(false),
}, },
}, },
"prefix": schema.StringAttribute{ "prefix": schema.StringAttribute{

View file

@ -200,7 +200,7 @@ func (r *networkInterfaceResource) Schema(_ context.Context, _ resource.SchemaRe
Optional: true, Optional: true,
Computed: true, Computed: true,
Validators: []validator.String{ Validators: []validator.String{
validate.IP(), validate.IP(false),
}, },
PlanModifiers: []planmodifier.String{ PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(), stringplanmodifier.RequiresReplace(),

View file

@ -147,7 +147,7 @@ func (r *publicIpResource) Schema(_ context.Context, _ resource.SchemaRequest, r
stringplanmodifier.UseStateForUnknown(), stringplanmodifier.UseStateForUnknown(),
}, },
Validators: []validator.String{ Validators: []validator.String{
validate.IP(), validate.IP(false),
}, },
}, },
"network_interface_id": schema.StringAttribute{ "network_interface_id": schema.StringAttribute{

View file

@ -155,7 +155,7 @@ func (r *publicIpAssociateResource) Schema(_ context.Context, _ resource.SchemaR
stringplanmodifier.UseStateForUnknown(), stringplanmodifier.UseStateForUnknown(),
}, },
Validators: []validator.String{ Validators: []validator.String{
validate.IP(), validate.IP(false),
}, },
}, },
"network_interface_id": schema.StringAttribute{ "network_interface_id": schema.StringAttribute{

View file

@ -67,13 +67,17 @@ func UUID() *Validator {
} }
} }
func IP() *Validator { // IP returns a validator that checks, if the given string is a valid IP address.
// The allowZeroAddress parameter defines, if 0.0.0.0, resp. [::] should be considered valid.
func IP(allowZeroAddress bool) *Validator {
description := "value must be an IP address" description := "value must be an IP address"
return &Validator{ return &Validator{
description: description, description: description,
validate: func(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) { validate: func(_ context.Context, req validator.StringRequest, resp *validator.StringResponse) {
if net.ParseIP(req.ConfigValue.ValueString()) == nil { ip := net.ParseIP(req.ConfigValue.ValueString())
invalidZeroAddress := !allowZeroAddress && (net.IPv4zero.Equal(ip) || net.IPv6zero.Equal(ip))
if ip == nil || invalidZeroAddress {
resp.Diagnostics.Append(validatordiag.InvalidAttributeValueDiagnostic( resp.Diagnostics.Append(validatordiag.InvalidAttributeValueDiagnostic(
req.Path, req.Path,
description, description,

View file

@ -58,39 +58,87 @@ func TestUUID(t *testing.T) {
func TestIP(t *testing.T) { func TestIP(t *testing.T) {
tests := []struct { tests := []struct {
description string description string
invalidZero bool
input string input string
isValid bool isValid bool
}{ }{
{ {
"ok IP4", "ok IP4",
false,
"111.222.111.222", "111.222.111.222",
true, true,
}, },
{ {
"ok IP6", "ok IP6",
false,
"2001:0db8:85a3:08d3::0370:7344", "2001:0db8:85a3:08d3::0370:7344",
true, true,
}, },
{ {
"too short", "too short",
false,
"0.1.2", "0.1.2",
false, false,
}, },
{ {
"Empty", "Empty",
false,
"", "",
false, false,
}, },
{ {
"Not an IP", "Not an IP",
false,
"for-sure-not-an-IP", "for-sure-not-an-IP",
false, false,
}, },
{
"valid ipv4 zero",
true,
"0.0.0.0",
true,
},
{
"invalid ipv4 zero",
false,
"0.0.0.0",
false,
},
{
"valid ipv6 zero",
true,
"::",
true,
},
{
"valid ipv6 zero short notation",
true,
"::0",
true,
},
{
"valid ipv6 zero long notation",
true,
"0000:0000:0000:0000:0000:0000:0000:0000",
true,
},
{
"invalid ipv6 zero short notation",
false,
"::",
false,
},
{
"invalid ipv6 zero long notation",
false,
"0000:0000:0000:0000:0000:0000:0000:0000",
false,
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.description, func(t *testing.T) { t.Run(tt.description, func(t *testing.T) {
r := validator.StringResponse{} r := validator.StringResponse{}
IP().ValidateString(context.Background(), validator.StringRequest{ IP(tt.invalidZero).ValidateString(context.Background(), validator.StringRequest{
ConfigValue: types.StringValue(tt.input), ConfigValue: types.StringValue(tt.input),
}, &r) }, &r)