package mailgun import ( "context" "fmt" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" "github.com/mailgun/mailgun-go/v3" "os" "strconv" "testing" "time" ) type fullDomain struct { domainResponse mailgun.DomainResponse domainConnection mailgun.DomainConnection domainTracking mailgun.DomainTracking ipAddress []string credentials []mailgun.Credential } func getFullDomain(mg *mailgun.MailgunImpl, domainName string) (*fullDomain, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) defer cancel() mg = mailgun.NewMailgun(domainName, mg.APIKey()) var domain fullDomain var err error domain.domainResponse, err = mg.GetDomain(ctx, domainName) if err != nil { return nil, fmt.Errorf("Error Getting mailgun domain Details for %s: Error: %s", domainName, err) } domain.domainConnection, err = mg.GetDomainConnection(ctx, domainName) if err != nil { return nil, fmt.Errorf("Error Getting mailgun domain connection Details for %s: Error: %s", domainName, err) } domain.domainTracking, err = mg.GetDomainTracking(ctx, domainName) if err != nil { return nil, fmt.Errorf("Error Getting mailgun domain tracking Details for %s: Error: %s", domainName, err) } ipAddress, err := mg.ListDomainIPS(ctx) if err != nil { return nil, fmt.Errorf("Error Getting mailgun domain ips2 for %s: Error: %s", domainName, err) } ips := make([]string, len(ipAddress)) for i, r := range ipAddress { ips[i] = r.IP } domain.ipAddress = ips domain.credentials, err = ListCredentials(domainName, mg.APIKey()) if err != nil { return nil, fmt.Errorf("Error Getting mailgun credentials for %s: Error: %s", domainName, err) } return &domain, nil } func TestAccMailgunDomain_basic(t *testing.T) { var domain fullDomain resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccDomainCheckDestroy(&domain), Steps: []resource.TestStep{ { Config: interpolateTerraformTemplateDomain(testAccDomainConfig_basic), Check: resource.ComposeTestCheckFunc( testAccDomainCheckExists("mailgun_domain.exemple", &domain), testAccDomainCheckAttributes("mailgun_domain.exemple", &domain), ), }, }, }) } func TestAccMailgunDomain_withUpdate(t *testing.T) { var domain fullDomain resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, CheckDestroy: testAccDomainCheckDestroy(&domain), Steps: []resource.TestStep{ { Config: interpolateTerraformTemplateDomain(testAccDomainConfig_basic), Check: resource.ComposeTestCheckFunc( testAccDomainCheckExists("mailgun_domain.exemple", &domain), testAccDomainCheckAttributes("mailgun_domain.exemple", &domain), ), }, { Config: interpolateTerraformTemplateDomain(testAccDomainConfig_update), Check: resource.ComposeTestCheckFunc( testAccDomainCheckExists("mailgun_domain.exemple", &domain), testAccDomainCheckAttributes("mailgun_domain.exemple", &domain), ), }, }, }) } func testAccDomainCheckExists(rn string, domain *fullDomain) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[rn] if !ok { return fmt.Errorf("resource not found: %s", rn) } if rs.Primary.ID == "" { return fmt.Errorf("domainID not set") } mg := testAccProvider.Meta().(*mailgun.MailgunImpl) domainId := rs.Primary.ID gotDomain, err := getFullDomain(mg, domainId) if err != nil { return fmt.Errorf("error getting domain: %s", err) } *domain = *gotDomain return nil } } func testAccDomainCheckAttributes(rn string, domain *fullDomain) resource.TestCheckFunc { return func(s *terraform.State) error { attrs := s.RootModule().Resources[rn].Primary.Attributes check := func(key, stateValue, domainValue string) error { if domainValue != stateValue { return fmt.Errorf("different values for %s in state (%s) and in mailgun (%s)", key, stateValue, domainValue) } return nil } for key, value := range attrs { var err error switch key { case "name": err = check(key, value, domain.domainResponse.Domain.Name) case "smtp_password": err = check(key, value, domain.domainResponse.Domain.SMTPPassword) case "smtp_login": err = check(key, value, domain.domainResponse.Domain.SMTPLogin) case "wildcard": err = check(key, value, strconv.FormatBool(domain.domainResponse.Domain.Wildcard)) case "state": err = check(key, value, domain.domainResponse.Domain.State) case "open_tracking_settings_active": err = check(key, value, strconv.FormatBool(domain.domainTracking.Open.Active)) case "click_tracking_settings_active": err = check(key, value, strconv.FormatBool(domain.domainTracking.Click.Active)) case "unsubscribe_tracking_settings_active": err = check(key, value, strconv.FormatBool(domain.domainTracking.Unsubscribe.Active)) case "unsubscribe_tracking_settings_html_footer": err = check(key, value, domain.domainTracking.Unsubscribe.HTMLFooter) case "unsubscribe_tracking_settings_text_footer": err = check(key, value, domain.domainTracking.Unsubscribe.TextFooter) case "skip_verification": err = check(key, value, strconv.FormatBool(domain.domainConnection.SkipVerification)) case "require_tls": err = check(key, value, strconv.FormatBool(domain.domainConnection.RequireTLS)) } if err != nil { return err } } return nil } } func testAccDomainCheckDestroy(domain *fullDomain) resource.TestCheckFunc { return func(s *terraform.State) error { mg := testAccProvider.Meta().(*mailgun.MailgunImpl) ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) defer cancel() _, err := mg.GetDomain(ctx, domain.domainResponse.Domain.Name) if err == nil { return fmt.Errorf("domain still exists") } return nil } } func interpolateTerraformTemplateDomain(template string) string { domainName := "" if v := os.Getenv("MAILGUN_DOMAIN"); v != "" { domainName = v } return fmt.Sprintf(template, domainName) } const testAccDomainConfig_basic = ` resource "mailgun_domain" "exemple" { name="%s" wildcard=true credentials{ login="aaaaaaa" password="adfshfjqdskjhgfksdgfkqgfk" } } ` const testAccDomainConfig_update = ` resource "mailgun_domain" "exemple" { name="%s" credentials{ login="aaaaaaa" password="adfshfjqdskjhgfksdgfkqgfk" } } `