Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CSGI-2017 ] Update pagerduty_user_contact_method address validation logic #792

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 42 additions & 13 deletions pagerduty/resource_pagerduty_user_contact_method.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,7 @@ func resourcePagerDutyUserContactMethod() *schema.Resource {
Importer: &schema.ResourceImporter{
State: resourcePagerDutyUserContactMethodImport,
},
CustomizeDiff: func(context context.Context, diff *schema.ResourceDiff, i interface{}) error {
a := diff.Get("address").(string)
t := diff.Get("type").(string)
if t == "sms_contact_method" || t == "phone_contact_method" {
if strings.HasPrefix(a, "0") {
return fmt.Errorf("phone numbers starting with a 0 are not supported was %q", a)
}
if _, err := strconv.Atoi(a); err != nil {
return fmt.Errorf("phone number %q is not valid as it contains non-digit characters: %w", a, err)
}
}
return nil
},
CustomizeDiff: customizeDiffResourceUserContactMethod,
Schema: map[string]*schema.Schema{
"user_id": {
Type: schema.TypeString,
Expand Down Expand Up @@ -88,6 +76,47 @@ func resourcePagerDutyUserContactMethod() *schema.Resource {
}
}

func customizeDiffResourceUserContactMethod(context context.Context, diff *schema.ResourceDiff, i interface{}) error {
a := diff.Get("address").(string)
t := diff.Get("type").(string)
c := diff.Get("country_code").(int)

if t == "sms_contact_method" || t == "phone_contact_method" {
// Validation logic based on https://support.pagerduty.com/docs/user-profile#phone-number-formatting
maxLength := 40
if len(a) > maxLength {
return fmt.Errorf("phone numbers may not exceed 40 characters")
}
for _, char := range a {
isAllowedChar := char == ',' || char == '*' || char == '#'
if _, err := strconv.ParseInt(string(char), 10, 64); err != nil && !isAllowedChar {
return fmt.Errorf("phone numbers may only include digits from 0-9 and the symbols: comma (,), asterisk (*), and pound (#)")
}
}

isMexicoNumber := c == 52
if t == "sms_contact_method" && isMexicoNumber && strings.HasPrefix(a, "1") {
return fmt.Errorf("Mexico-based SMS numbers should be free of area code prefixes, so please remove the leading 1 in the number %q", a)
}

isTrunkPrefixNotSupported := map[int]string{
33: "0", // France (33-0)
40: "0", // Romania (40-0)
44: "0", // UK (44-0)
45: "0", // Denmark (45-0)
49: "0", // Germany (49-0)
61: "0", // Australia (61-0)
66: "0", // Thailand (66-0)
91: "0", // India (91-0)
1: "1", // North America (1-1)
}
if prefix, ok := isTrunkPrefixNotSupported[c]; ok && strings.HasPrefix(a, prefix) {
return fmt.Errorf("Trunk prefixes are not supported for following countries and regions: France, Romania, UK, Denmark, Germany, Australia, Thailand, India and North America, so must be formatted for international use without the leading %s", prefix)
}
}
return nil
}

func buildUserContactMethodStruct(d *schema.ResourceData) *pagerduty.ContactMethod {
contactMethod := &pagerduty.ContactMethod{
Type: d.Get("type").(string),
Expand Down
55 changes: 55 additions & 0 deletions pagerduty/resource_pagerduty_user_contact_method_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,40 @@ func TestAccPagerDutyUserContactMethodPhone_Basic(t *testing.T) {
})
}

func TestAccPagerDutyUserContactMethodPhone_FormatValidation(t *testing.T) {
username := fmt.Sprintf("tf-%s", acctest.RandString(5))
email := fmt.Sprintf("%[email protected]", username)
tooLongNumber := "4153013250415301325041530132504153013250,415301325041530132504,530132504153013250"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyUserContactMethodDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckPagerDutyUserContactMethodPhoneFormatValidationConfig(username, email, "phone_contact_method", "1", tooLongNumber),
PlanOnly: true,
ExpectError: regexp.MustCompile("phone numbers may not exceed 40 characters"),
},
{
Config: testAccCheckPagerDutyUserContactMethodPhoneFormatValidationConfig(username, email, "phone_contact_method", "1", "+4153013250"),
PlanOnly: true,
ExpectError: regexp.MustCompile("phone numbers may only include digits from 0-9 and the symbols"),
},
{
Config: testAccCheckPagerDutyUserContactMethodPhoneFormatValidationConfig(username, email, "phone_contact_method", "44", "01332412251"),
PlanOnly: true,
ExpectError: regexp.MustCompile("Trunk prefixes are not supported for following countries and regions: France, Romania, UK, Denmark, Germany, Australia, Thailand, India and North America, so must be formatted for international use without the leading 0"),
},
{
Config: testAccCheckPagerDutyUserContactMethodPhoneFormatValidationConfig(username, email, "sms_contact_method", "52", "15558889999"),
PlanOnly: true,
ExpectError: regexp.MustCompile("Mexico-based SMS numbers should be free of area code prefixes, so please remove the leading 1 in the number"),
},
},
})
}

func TestAccPagerDutyUserContactMethodPhone_EnforceUpdateIfAlreadyExist(t *testing.T) {
username := fmt.Sprintf("tf-%s", acctest.RandString(5))
email := fmt.Sprintf("%[email protected]", username)
Expand Down Expand Up @@ -281,6 +315,27 @@ resource "pagerduty_user_contact_method" "foo" {
`, username, email, phone)
}

func testAccCheckPagerDutyUserContactMethodPhoneFormatValidationConfig(username, email, method_type, countryCode, phone string) string {
return fmt.Sprintf(`
resource "pagerduty_user" "foo" {
name = "%[1]v"
email = "%[2]v"
color = "red"
role = "user"
job_title = "bar"
description = "bar"
}

resource "pagerduty_user_contact_method" "foo" {
user_id = pagerduty_user.foo.id
type = "%[3]s"
country_code = "+%[4]s"
address = "%[5]s"
label = "%[1]v"
}
`, username, email, method_type, countryCode, phone)
}

func testAccCheckPagerDutyUserContactMethodSMSConfig(username, email string) string {
return fmt.Sprintf(`
resource "pagerduty_user" "foo" {
Expand Down
Loading