Skip to content

Commit

Permalink
Refactoring the PostgreSQL Virtual Network Rule (#1882)
Browse files Browse the repository at this point in the history
  • Loading branch information
tombuildsstuff authored Sep 6, 2018
1 parent ed19944 commit d1a7b19
Show file tree
Hide file tree
Showing 5 changed files with 302 additions and 327 deletions.
43 changes: 43 additions & 0 deletions azurerm/helpers/validate/virtual_network_rule_name.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package validate

import (
"fmt"
"regexp"
)

func VirtualNetworkRuleName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

// Cannot be empty
if len(value) == 0 {
errors = append(errors, fmt.Errorf(
"%q cannot be an empty string: %q", k, value))
}

// Cannot be more than 128 characters
if len(value) > 128 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 128 characters: %q", k, value))
}

// Must only contain alphanumeric characters or hyphens
if !regexp.MustCompile(`^[A-Za-z0-9-]*$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q can only contain alphanumeric characters and hyphens: %q",
k, value))
}

// Cannot end in a hyphen
if regexp.MustCompile(`-$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot end with a hyphen: %q", k, value))
}

// Cannot start with a number or hyphen
if regexp.MustCompile(`^[0-9-]`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot start with a number or hyphen: %q", k, value))
}

return
}
126 changes: 126 additions & 0 deletions azurerm/helpers/validate/virtual_network_rule_name_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package validate

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/acctest"
)

func TestVirtualNetworkRule_invalidNameValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
// Must only contain alphanumeric characters or hyphens (4 cases)
{
Value: "test!Rule",
ErrCount: 1,
},
{
Value: "test_Rule",
ErrCount: 1,
},
{
Value: "test:Rule",
ErrCount: 1,
},
{
Value: "test'Rule",
ErrCount: 1,
},
// Cannot be more than 128 characters (1 case - ensure starts with a letter)
{
Value: fmt.Sprintf("v%s", acctest.RandString(128)),
ErrCount: 1,
},
// Cannot be empty (1 case)
{
Value: "",
ErrCount: 1,
},
// Cannot end in a hyphen (1 case)
{
Value: "testRule-",
ErrCount: 1,
},
// Cannot start with a number or hyphen (2 cases)
{
Value: "7testRule",
ErrCount: 1,
},
{
Value: "-testRule",
ErrCount: 1,
},
}

for _, tc := range cases {
_, errors := VirtualNetworkRuleName(tc.Value, "azurerm_postgresql_virtual_network_rule")

if len(errors) != tc.ErrCount {
t.Fatalf("Bad: Expected the Azure RM PostgreSQL Virtual Network Rule Name to trigger a validation error.")
}
}
}

func TestResourceAzureRMPostgreSQLVirtualNetworkRule_validNameValidation(t *testing.T) {
cases := []struct {
Value string
ErrCount int
}{
// Test all lowercase
{
Value: "thisisarule",
ErrCount: 0,
},
// Test all uppercase
{
Value: "THISISARULE",
ErrCount: 0,
},
// Test alternating cases
{
Value: "tHiSiSaRuLe",
ErrCount: 0,
},
// Test hyphens
{
Value: "this-is-a-rule",
ErrCount: 0,
},
// Test multiple hyphens in a row
{
Value: "this----1s----a----ru1e",
ErrCount: 0,
},
// Test numbers (except for first character)
{
Value: "v1108501298509850810258091285091820-5",
ErrCount: 0,
},
// Test a lot of hyphens and numbers
{
Value: "x-5-4-1-2-5-2-6-1-5-2-5-1-2-5-6-2-2",
ErrCount: 0,
},
// Test exactly 128 characters
{
Value: fmt.Sprintf("v%s", acctest.RandString(127)),
ErrCount: 0,
},
// Test short, 1-letter name
{
Value: "V",
ErrCount: 0,
},
}

for _, tc := range cases {
_, errors := VirtualNetworkRuleName(tc.Value, "azurerm_postgresql_virtual_network_rule")

if len(errors) != tc.ErrCount {
t.Fatalf("Bad: Expected the Virtual Network Rule Name pass name validation successfully but triggered a validation error.")
}
}
}
62 changes: 4 additions & 58 deletions azurerm/resource_arm_postgresql_virtual_network_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"fmt"
"log"
"regexp"
"strings"
"time"

Expand All @@ -14,6 +13,7 @@ import (
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

Expand All @@ -32,7 +32,7 @@ func resourceArmPostgreSQLVirtualNetworkRule() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validatePostgreSQLVirtualNetworkRuleName,
ValidateFunc: validate.VirtualNetworkRuleName,
},

"resource_group_name": resourceGroupNameSchema(),
Expand Down Expand Up @@ -111,7 +111,7 @@ func resourceArmPostgreSQLVirtualNetworkRuleCreateUpdate(d *schema.ResourceData,
return fmt.Errorf("Error creating PostgreSQL Virtual Network Rule %q (PostgreSQL Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err)
}

//Wait for the provisioning state to become ready
// Wait for the provisioning state to become ready
log.Printf("[DEBUG] Waiting for PostgreSQL Virtual Network Rule %q (PostgreSQL Server: %q, Resource Group: %q) to become ready: %+v", name, serverName, resourceGroup, err)
stateConf := &resource.StateChangeConf{
Pending: []string{"Initializing", "InProgress", "Unknown", "ResponseNotFound"},
Expand Down Expand Up @@ -199,66 +199,12 @@ func resourceArmPostgreSQLVirtualNetworkRuleDelete(d *schema.ResourceData, meta
return nil
}

return fmt.Errorf("Error deleting PostgreSQL Virtual Network Rule %q (PostgreSQL Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err)
return fmt.Errorf("Error waiting for deletion of PostgreSQL Virtual Network Rule %q (PostgreSQL Server: %q, Resource Group: %q): %+v", name, serverName, resourceGroup, err)
}

return nil
}

/*
This function checks the format of the PostgreSQL Virtual Network Rule Name to make sure that
it does not contain any potentially invalid values.
*/
func validatePostgreSQLVirtualNetworkRuleName(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

// Cannot be empty
if len(value) == 0 {
errors = append(errors, fmt.Errorf(
"%q cannot be an empty string: %q", k, value))
}

// Cannot be more than 128 characters
if len(value) > 128 {
errors = append(errors, fmt.Errorf(
"%q cannot be longer than 128 characters: %q", k, value))
}

// Must only contain alphanumeric characters or hyphens
if !regexp.MustCompile(`^[A-Za-z0-9-]*$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q can only contain alphanumeric characters and hyphens: %q",
k, value))
}

// Cannot end in a hyphen
if regexp.MustCompile(`-$`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot end with a hyphen: %q", k, value))
}

// Cannot start with a number or hyphen
if regexp.MustCompile(`^[0-9-]`).MatchString(value) {
errors = append(errors, fmt.Errorf(
"%q cannot start with a number or hyphen: %q", k, value))
}

// There are multiple returns in the case that there is more than one invalid
// case applied to the name.
return
}

/*
This function refreshes and checks the state of the PostgreSQL Virtual Network Rule.
Response will contain a VirtualNetworkRuleProperties struct with a State property. The state property contain one of the following states (except ResponseNotFound).
* Deleting
* Initializing
* InProgress
* Unknown
* Ready
* ResponseNotFound (Custom state in case of 404)
*/
func postgreSQLVirtualNetworkStateStatusCodeRefreshFunc(ctx context.Context, client postgresql.VirtualNetworkRulesClient, resourceGroup string, serverName string, name string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
resp, err := client.Get(ctx, resourceGroup, serverName, name)
Expand Down
Loading

0 comments on commit d1a7b19

Please sign in to comment.