From ccd31ebd9d9f9a0d0eb1ff7ef40f64aa1ee94038 Mon Sep 17 00:00:00 2001 From: Chris Marget Date: Wed, 30 Oct 2024 14:52:31 -0400 Subject: [PATCH] centralize regexes used in attribute validation --- apstra/blueprint/datacenter_generic_system.go | 5 ++-- apstra/blueprint/datacenter_routing_policy.go | 5 ++-- apstra/blueprint/datacenter_routing_zone.go | 8 +++--- .../blueprint/datacenter_virtual_network.go | 5 ++-- .../device_allocation_system_attributes.go | 4 +-- apstra/freeform/allocation_group.go | 5 ++-- apstra/freeform/link.go | 4 +-- apstra/freeform/resource.go | 4 +-- apstra/freeform/resource_generator.go | 12 +++------ apstra/freeform/resource_group.go | 6 ++--- apstra/freeform/resource_group_generator.go | 7 ++--- apstra/freeform/system.go | 7 +++-- apstra/regexp/regexp.go | 27 +++++++++++++++++++ 13 files changed, 55 insertions(+), 44 deletions(-) create mode 100644 apstra/regexp/regexp.go diff --git a/apstra/blueprint/datacenter_generic_system.go b/apstra/blueprint/datacenter_generic_system.go index 94388b9c..ec0f6621 100644 --- a/apstra/blueprint/datacenter_generic_system.go +++ b/apstra/blueprint/datacenter_generic_system.go @@ -6,13 +6,13 @@ import ( "fmt" "math" "net" - "regexp" "sort" "github.com/Juniper/apstra-go-sdk/apstra" "github.com/Juniper/apstra-go-sdk/apstra/enum" "github.com/Juniper/terraform-provider-apstra/apstra/constants" "github.com/Juniper/terraform-provider-apstra/apstra/design" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-nettypes/cidrtypes" "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" @@ -76,8 +76,7 @@ func (o DatacenterGenericSystem) ResourceAttributes() map[string]resourceSchema. Computed: true, PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()}, Validators: []validator.String{ - stringvalidator.RegexMatches(regexp.MustCompile("^[A-Za-z0-9.-]+$"), - "only alphanumeric characters, '.' and '-' allowed."), + stringvalidator.RegexMatches(apstraregexp.HostNameConstraint, apstraregexp.HostNameConstraintMsg), stringvalidator.LengthBetween(1, 32), }, }, diff --git a/apstra/blueprint/datacenter_routing_policy.go b/apstra/blueprint/datacenter_routing_policy.go index 088fd7a7..c34a6846 100644 --- a/apstra/blueprint/datacenter_routing_policy.go +++ b/apstra/blueprint/datacenter_routing_policy.go @@ -4,11 +4,11 @@ import ( "context" "fmt" "net" - "regexp" "strings" "github.com/Juniper/apstra-go-sdk/apstra" "github.com/Juniper/terraform-provider-apstra/apstra/constants" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/Juniper/terraform-provider-apstra/apstra/utils" apstravalidator "github.com/Juniper/terraform-provider-apstra/apstra/validator" "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" @@ -42,7 +42,6 @@ type DatacenterRoutingPolicy struct { } func (o DatacenterRoutingPolicy) ResourceAttributes() map[string]resourceSchema.Attribute { - nameRE := regexp.MustCompile("^[A-Za-z0-9_-]+$") return map[string]resourceSchema.Attribute{ "id": resourceSchema.StringAttribute{ MarkdownDescription: "Apstra graph node ID.", @@ -54,7 +53,7 @@ func (o DatacenterRoutingPolicy) ResourceAttributes() map[string]resourceSchema. Required: true, Validators: []validator.String{ stringvalidator.LengthBetween(1, 17), - stringvalidator.RegexMatches(nameRE, "only underscore, dash and alphanumeric characters allowed."), + stringvalidator.RegexMatches(apstraregexp.AlphaNumW2HLConstraint, apstraregexp.AlphaNumW2HLConstraintMsg), }, }, "description": resourceSchema.StringAttribute{ diff --git a/apstra/blueprint/datacenter_routing_zone.go b/apstra/blueprint/datacenter_routing_zone.go index ec52a7c8..751c0b4c 100644 --- a/apstra/blueprint/datacenter_routing_zone.go +++ b/apstra/blueprint/datacenter_routing_zone.go @@ -4,12 +4,12 @@ import ( "context" "fmt" "net" - "regexp" "github.com/Juniper/apstra-go-sdk/apstra" "github.com/Juniper/apstra-go-sdk/apstra/enum" "github.com/Juniper/terraform-provider-apstra/apstra/constants" "github.com/Juniper/terraform-provider-apstra/apstra/design" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/Juniper/terraform-provider-apstra/apstra/utils" apstravalidator "github.com/Juniper/terraform-provider-apstra/apstra/validator" "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" @@ -67,8 +67,7 @@ func (o DatacenterRoutingZone) DataSourceAttributes() map[string]dataSourceSchem Optional: true, Validators: []validator.String{ stringvalidator.LengthBetween(1, 17), - stringvalidator.RegexMatches(regexp.MustCompile("^[A-Za-z0-9_-]+$"), - "only underscore, dash and alphanumeric characters allowed."), + stringvalidator.RegexMatches(apstraregexp.AlphaNumW2HLConstraint, apstraregexp.AlphaNumW2HLConstraintMsg), }, }, "vrf_name": dataSourceSchema.StringAttribute{ @@ -208,8 +207,7 @@ func (o DatacenterRoutingZone) ResourceAttributes() map[string]resourceSchema.At MarkdownDescription: "Name displayed in the Apstra web UI.", Required: true, Validators: []validator.String{ - stringvalidator.RegexMatches(regexp.MustCompile("^[A-Za-z0-9_-]+$"), - "only underscore, dash and alphanumeric characters allowed."), + stringvalidator.RegexMatches(apstraregexp.AlphaNumW2HLConstraint, apstraregexp.AlphaNumW2HLConstraintMsg), stringvalidator.LengthBetween(1, 15), }, }, diff --git a/apstra/blueprint/datacenter_virtual_network.go b/apstra/blueprint/datacenter_virtual_network.go index 813bf2b8..fc52797d 100644 --- a/apstra/blueprint/datacenter_virtual_network.go +++ b/apstra/blueprint/datacenter_virtual_network.go @@ -4,14 +4,13 @@ import ( "context" "fmt" "net" - "regexp" "strconv" "github.com/Juniper/apstra-go-sdk/apstra" apiversions "github.com/Juniper/terraform-provider-apstra/apstra/api_versions" "github.com/Juniper/terraform-provider-apstra/apstra/compatibility" "github.com/Juniper/terraform-provider-apstra/apstra/constants" - "github.com/Juniper/terraform-provider-apstra/apstra/design" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/Juniper/terraform-provider-apstra/apstra/utils" apstravalidator "github.com/Juniper/terraform-provider-apstra/apstra/validator" "github.com/hashicorp/terraform-plugin-framework-validators/helpers/validatordiag" @@ -295,7 +294,7 @@ func (o DatacenterVirtualNetwork) ResourceAttributes() map[string]resourceSchema Required: true, Validators: []validator.String{ stringvalidator.LengthBetween(1, 30), - stringvalidator.RegexMatches(regexp.MustCompile(design.AlphaNumericRegexp), "valid characters are: "+design.AlphaNumericChars), + stringvalidator.RegexMatches(apstraregexp.AlphaNumW2HLConstraint, apstraregexp.AlphaNumW2HLConstraintMsg), }, }, "blueprint_id": resourceSchema.StringAttribute{ diff --git a/apstra/blueprint/device_allocation_system_attributes.go b/apstra/blueprint/device_allocation_system_attributes.go index 6d5e28e1..0c3b98d9 100644 --- a/apstra/blueprint/device_allocation_system_attributes.go +++ b/apstra/blueprint/device_allocation_system_attributes.go @@ -14,6 +14,7 @@ import ( "github.com/Juniper/apstra-go-sdk/apstra/enum" "github.com/Juniper/terraform-provider-apstra/apstra/compatibility" "github.com/Juniper/terraform-provider-apstra/apstra/constants" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/go-version" "github.com/hashicorp/terraform-plugin-framework-nettypes/cidrtypes" @@ -63,8 +64,7 @@ func (o DeviceAllocationSystemAttributes) ResourceAttributes() map[string]resour Computed: true, MarkdownDescription: "Hostname of the System node.", Validators: []validator.String{ - stringvalidator.RegexMatches(regexp.MustCompile("^[A-Za-z0-9.-]+$"), - "only alphanumeric characters, '.' and '-' allowed."), + stringvalidator.RegexMatches(apstraregexp.HostNameConstraint, apstraregexp.HostNameConstraintMsg), stringvalidator.LengthBetween(1, 32), }, }, diff --git a/apstra/freeform/allocation_group.go b/apstra/freeform/allocation_group.go index 53db6460..a1052207 100644 --- a/apstra/freeform/allocation_group.go +++ b/apstra/freeform/allocation_group.go @@ -3,11 +3,11 @@ package freeform import ( "context" "fmt" - "regexp" "strings" "github.com/Juniper/apstra-go-sdk/apstra" "github.com/Juniper/apstra-go-sdk/apstra/enum" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" @@ -86,8 +86,7 @@ func (o AllocGroup) ResourceAttributes() map[string]resourceSchema.Attribute { Required: true, PlanModifiers: []planmodifier.String{stringplanmodifier.RequiresReplace()}, Validators: []validator.String{ - stringvalidator.RegexMatches(regexp.MustCompile("^[a-zA-Z0-9.-_]+$"), - "name may consist only of the following characters : a-zA-Z0-9.-_"), + stringvalidator.RegexMatches(apstraregexp.StdNameConstraint, apstraregexp.StdNameConstraintMsg), }, }, "type": resourceSchema.StringAttribute{ diff --git a/apstra/freeform/link.go b/apstra/freeform/link.go index dbb105b3..55be3d71 100644 --- a/apstra/freeform/link.go +++ b/apstra/freeform/link.go @@ -3,9 +3,9 @@ package freeform import ( "context" "fmt" - "regexp" "github.com/Juniper/apstra-go-sdk/apstra" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-validators/mapvalidator" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" @@ -100,7 +100,7 @@ func (o Link) ResourceAttributes() map[string]resourceSchema.Attribute { MarkdownDescription: "Freeform Link name as shown in the Web UI.", Required: true, Validators: []validator.String{ - stringvalidator.RegexMatches(regexp.MustCompile("^[a-zA-Z0-9.-_]+$"), "name may consist only of the following characters : a-zA-Z0-9.-_"), + stringvalidator.RegexMatches(apstraregexp.StdNameConstraint, apstraregexp.StdNameConstraintMsg), }, }, "speed": resourceSchema.StringAttribute{ diff --git a/apstra/freeform/resource.go b/apstra/freeform/resource.go index 7799a85e..88c65459 100644 --- a/apstra/freeform/resource.go +++ b/apstra/freeform/resource.go @@ -3,12 +3,12 @@ package freeform import ( "context" "fmt" - "regexp" "strconv" "strings" "github.com/Juniper/apstra-go-sdk/apstra" "github.com/Juniper/apstra-go-sdk/apstra/enum" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/Juniper/terraform-provider-apstra/apstra/utils" apstravalidator "github.com/Juniper/terraform-provider-apstra/apstra/validator" "github.com/hashicorp/terraform-plugin-framework-nettypes/cidrtypes" @@ -136,7 +136,7 @@ func (o Resource) ResourceAttributes() map[string]resourceSchema.Attribute { MarkdownDescription: "Freeform Resource name as shown in the Web UI.", Required: true, Validators: []validator.String{ - stringvalidator.RegexMatches(regexp.MustCompile("^[a-zA-Z0-9.-_]+$"), "name may consist only of the following characters : a-zA-Z0-9.-_"), + stringvalidator.RegexMatches(apstraregexp.StdNameConstraint, apstraregexp.StdNameConstraintMsg), }, }, "group_id": resourceSchema.StringAttribute{ diff --git a/apstra/freeform/resource_generator.go b/apstra/freeform/resource_generator.go index 4dfdd375..2fcee940 100644 --- a/apstra/freeform/resource_generator.go +++ b/apstra/freeform/resource_generator.go @@ -3,15 +3,14 @@ package freeform import ( "context" "fmt" - "regexp" "strings" + "github.com/Juniper/apstra-go-sdk/apstra" "github.com/Juniper/apstra-go-sdk/apstra/enum" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" + "github.com/Juniper/terraform-provider-apstra/apstra/utils" apstravalidator "github.com/Juniper/terraform-provider-apstra/apstra/validator" "github.com/hashicorp/terraform-plugin-framework-validators/int64validator" - - "github.com/Juniper/apstra-go-sdk/apstra" - "github.com/Juniper/terraform-provider-apstra/apstra/utils" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -110,10 +109,7 @@ func (o ResourceGenerator) ResourceAttributes() map[string]resourceSchema.Attrib MarkdownDescription: "Freeform Resource Generator name as shown in the Web UI.", Required: true, Validators: []validator.String{ - stringvalidator.RegexMatches( - regexp.MustCompile("^[a-zA-Z0-9.-_]+$"), - "name may consist only of the following characters : a-zA-Z0-9.-_", - ), + stringvalidator.RegexMatches(apstraregexp.StdNameConstraint, apstraregexp.StdNameConstraintMsg), }, }, "scope": resourceSchema.StringAttribute{ diff --git a/apstra/freeform/resource_group.go b/apstra/freeform/resource_group.go index ccc4f51b..33f2eda4 100644 --- a/apstra/freeform/resource_group.go +++ b/apstra/freeform/resource_group.go @@ -3,8 +3,8 @@ package freeform import ( "context" "encoding/json" - "regexp" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" @@ -97,9 +97,7 @@ func (o ResourceGroup) ResourceAttributes() map[string]resourceSchema.Attribute MarkdownDescription: "Freeform Resource Group name as shown in the Web UI.", Required: true, Validators: []validator.String{ - stringvalidator.RegexMatches( - regexp.MustCompile("^[a-zA-Z0-9.-_]+$"), - "name may consist only of the following characters : a-zA-Z0-9.-_"), + stringvalidator.RegexMatches(apstraregexp.StdNameConstraint, apstraregexp.StdNameConstraintMsg), }, }, "parent_id": resourceSchema.StringAttribute{ diff --git a/apstra/freeform/resource_group_generator.go b/apstra/freeform/resource_group_generator.go index 25753639..4843dd29 100644 --- a/apstra/freeform/resource_group_generator.go +++ b/apstra/freeform/resource_group_generator.go @@ -2,9 +2,9 @@ package freeform import ( "context" - "regexp" "github.com/Juniper/apstra-go-sdk/apstra" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" dataSourceSchema "github.com/hashicorp/terraform-plugin-framework/datasource/schema" "github.com/hashicorp/terraform-plugin-framework/diag" @@ -84,10 +84,7 @@ func (o GroupGenerator) ResourceAttributes() map[string]resourceSchema.Attribute MarkdownDescription: "Freeform Group Generator name as shown in the Web UI.", Required: true, Validators: []validator.String{ - stringvalidator.RegexMatches( - regexp.MustCompile("^[a-zA-Z0-9.-_]+$"), - "name may consist only of the following characters : a-zA-Z0-9.-_", - ), + stringvalidator.RegexMatches(apstraregexp.StdNameConstraint, apstraregexp.StdNameConstraintMsg), }, }, "scope": resourceSchema.StringAttribute{ diff --git a/apstra/freeform/system.go b/apstra/freeform/system.go index 48ed264a..8dfcef63 100644 --- a/apstra/freeform/system.go +++ b/apstra/freeform/system.go @@ -3,9 +3,9 @@ package freeform import ( "context" "fmt" - "regexp" "github.com/Juniper/apstra-go-sdk/apstra" + apstraregexp "github.com/Juniper/terraform-provider-apstra/apstra/regexp" "github.com/Juniper/terraform-provider-apstra/apstra/utils" apstravalidator "github.com/Juniper/terraform-provider-apstra/apstra/validator" "github.com/hashicorp/terraform-plugin-framework-validators/setvalidator" @@ -87,7 +87,6 @@ func (o System) DataSourceAttributes() map[string]dataSourceSchema.Attribute { } func (o System) ResourceAttributes() map[string]resourceSchema.Attribute { - hostnameRegexp := "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$" return map[string]resourceSchema.Attribute{ "blueprint_id": resourceSchema.StringAttribute{ MarkdownDescription: "Apstra Blueprint ID.", @@ -104,14 +103,14 @@ func (o System) ResourceAttributes() map[string]resourceSchema.Attribute { MarkdownDescription: "Freeform System name as shown in the Web UI.", Required: true, Validators: []validator.String{ - stringvalidator.RegexMatches(regexp.MustCompile("^[a-zA-Z0-9.-_]+$"), "name may consist only of the following characters : a-zA-Z0-9.-_"), + stringvalidator.RegexMatches(apstraregexp.StdNameConstraint, apstraregexp.StdNameConstraintMsg), }, }, "hostname": resourceSchema.StringAttribute{ MarkdownDescription: "Hostname of the Freeform System.", Required: true, Validators: []validator.String{ - stringvalidator.RegexMatches(regexp.MustCompile(hostnameRegexp), "must match regex "+hostnameRegexp), + stringvalidator.RegexMatches(apstraregexp.FreeformHostnameConstraint, apstraregexp.FreeformHostnameConstraintMsg), }, }, "deploy_mode": resourceSchema.StringAttribute{ diff --git a/apstra/regexp/regexp.go b/apstra/regexp/regexp.go new file mode 100644 index 00000000..300f7b1d --- /dev/null +++ b/apstra/regexp/regexp.go @@ -0,0 +1,27 @@ +package apstraregexp + +import "regexp" + +const ( + alphaNumW2HLConstraintReString = "^[" + alphaNumW2HLConstraintChars + "]+$" + alphaNumW2HLConstraintChars = "a-zA-Z0-9_-" + AlphaNumW2HLConstraintMsg = "value must consist only of the following characters: `" + alphaNumW2HLConstraintChars + "`." + + freeformHostnameConstraintReString = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$" + FreeformHostnameConstraintMsg = "value must match regexp: `" + freeformHostnameConstraintReString + "`." + + hostNameConstraintReString = "^[" + hostNameConstraintChars + "]+$" + hostNameConstraintChars = "a-zA-Z0-9.-" + HostNameConstraintMsg = "value must consist only of the following characters: `" + hostNameConstraintChars + "`." + + stdNameConstraintReString = "^[" + stdNameConstraintChars + "]+$" + stdNameConstraintChars = "a-zA-Z0-9._-" + StdNameConstraintMsg = "value must consist only of the following characters: `" + stdNameConstraintChars + "`." +) + +var ( + AlphaNumW2HLConstraint = regexp.MustCompile(alphaNumW2HLConstraintReString) + FreeformHostnameConstraint = regexp.MustCompile(freeformHostnameConstraintReString) + HostNameConstraint = regexp.MustCompile(hostNameConstraintReString) + StdNameConstraint = regexp.MustCompile(stdNameConstraintReString) +)