6 "github.com/hashicorp/terraform/helper/schema"
7 "github.com/mailgun/mailgun-go"
12 func resourceMailgunDomain() *schema.Resource {
13 return &schema.Resource{
18 Importer: &schema.ResourceImporter{
19 State: schema.ImportStatePassthrough,
22 Schema: map[string]*schema.Schema{
23 "name": &schema.Schema{
24 Type: schema.TypeString,
29 "spam_action": &schema.Schema{
30 Type: schema.TypeString,
36 "smtp_password": &schema.Schema{
37 Type: schema.TypeString,
42 "smtp_login": &schema.Schema{
43 Type: schema.TypeString,
47 "wildcard": &schema.Schema{
48 Type: schema.TypeBool,
54 "created_at": &schema.Schema{
55 Type: schema.TypeString,
60 "state": &schema.Schema{
61 Type: schema.TypeString,
65 "force_dkim_authority": &schema.Schema{
66 Type: schema.TypeBool,
71 "dkim_key_size": &schema.Schema{
78 "ips": &schema.Schema{
79 Type: schema.TypeList,
83 Elem: &schema.Schema{Type: schema.TypeString},
86 "credentials": &schema.Schema{
87 Type: schema.TypeList,
89 Elem: &schema.Resource{
90 Schema: map[string]*schema.Schema{
91 "created_at": &schema.Schema{
92 Type: schema.TypeString,
95 "login": &schema.Schema{
96 Type: schema.TypeString,
99 "password": &schema.Schema{
100 Type: schema.TypeString,
107 "open_tracking_settings_active": &schema.Schema{
108 Type: schema.TypeBool,
113 "click_tracking_settings_active": &schema.Schema{
114 Type: schema.TypeBool,
119 "unsubscribe_tracking_settings_active": &schema.Schema{
120 Type: schema.TypeBool,
124 "unsubscribe_tracking_settings_html_footer": &schema.Schema{
125 Type: schema.TypeString,
129 "unsubscribe_tracking_settings_text_footer": &schema.Schema{
130 Type: schema.TypeString,
135 "require_tls": &schema.Schema{
136 Type: schema.TypeBool,
141 "skip_verification": &schema.Schema{
142 Type: schema.TypeBool,
147 "receiving_records": &schema.Schema{
148 Type: schema.TypeList,
150 Elem: &schema.Resource{
151 Schema: map[string]*schema.Schema{
152 "name": &schema.Schema{
153 Type: schema.TypeString,
156 "priority": &schema.Schema{
157 Type: schema.TypeString,
160 "record_type": &schema.Schema{
161 Type: schema.TypeString,
164 "valid": &schema.Schema{
165 Type: schema.TypeString,
168 "value": &schema.Schema{
169 Type: schema.TypeString,
176 "sending_records": &schema.Schema{
177 Type: schema.TypeList,
179 Elem: &schema.Resource{
180 Schema: map[string]*schema.Schema{
181 "name": &schema.Schema{
182 Type: schema.TypeString,
185 "priority": &schema.Schema{
186 Type: schema.TypeString,
189 "record_type": &schema.Schema{
190 Type: schema.TypeString,
193 "valid": &schema.Schema{
194 Type: schema.TypeString,
197 "value": &schema.Schema{
198 Type: schema.TypeString,
208 func CreateDomain(d *schema.ResourceData, meta interface{}) error {
209 mg := meta.(*mailgun.MailgunImpl)
210 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
213 log.Printf("[DEBUG] creating mailgun domain: %s", d.Id())
215 creationResponse, err := mg.CreateDomain(ctx, d.Get("name").(string), &mailgun.CreateDomainOptions{
216 Password: d.Get("smtp_password").(string),
217 SpamAction: mailgun.SpamAction(d.Get("spam_action").(string)),
218 Wildcard: d.Get("wildcard").(bool),
219 ForceDKIMAuthority: d.Get("force_dkim_authority").(bool),
220 DKIMKeySize: d.Get("dkim_key_size").(int),
221 IPS: d.Get("ips").([]string),
225 return fmt.Errorf("Error creating mailgun domain: %s", err.Error())
228 mg = mailgun.NewMailgun(creationResponse.Domain.Name, mg.APIKey())
230 for _, i := range d.Get("credentials").([]interface{}) {
231 credential := i.(map[string]interface{})
232 err = mg.CreateCredential(ctx, credential["login"].(string), credential["password"].(string))
234 return fmt.Errorf("Error creating mailgun credential: %s", err.Error())
238 err = mg.UpdateUnsubscribeTracking(ctx, creationResponse.Domain.Name, boolToString(d.Get("unsubscribe_tracking_settings_active").(bool)), d.Get("unsubscribe_tracking_settings_html_footer").(string), d.Get("unsubscribe_tracking_settings_text_footer").(string))
240 return fmt.Errorf("Error updating mailgun unsubscribe tracking settings: %s", err.Error())
243 err = mg.UpdateOpenTracking(ctx, creationResponse.Domain.Name, boolToString(d.Get("open_tracking_settings_active").(bool)))
245 return fmt.Errorf("Error updating mailgun open tracking settings: %s", err.Error())
248 err = mg.UpdateClickTracking(ctx, creationResponse.Domain.Name, boolToString(d.Get("click_tracking_settings_active").(bool)))
250 return fmt.Errorf("Error updating mailgun click tracking settings: %s", err.Error())
253 err = mg.UpdateDomainConnection(ctx, creationResponse.Domain.Name, mailgun.DomainConnection{RequireTLS: d.Get("require_tls").(bool), SkipVerification: d.Get("skip_verification").(bool)})
255 return fmt.Errorf("Error updating mailgun connexion settings: %s", err.Error())
258 d.SetId(creationResponse.Domain.Name)
260 return ReadDomain(d, meta)
263 func UpdateDomain(d *schema.ResourceData, meta interface{}) error {
264 mg := meta.(*mailgun.MailgunImpl)
265 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
267 domainName := d.Get("name").(string)
268 mg = mailgun.NewMailgun(domainName, mg.APIKey())
270 log.Printf("[DEBUG] updating mailgun domain: %s", d.Id())
272 if d.HasChange("unsubscribe_tracking_settings_active") || d.HasChange("unsubscribe_tracking_settings_html_footer") || d.HasChange("unsubscribe_tracking_settings_text_footer") {
273 err := mg.UpdateUnsubscribeTracking(ctx, domainName, boolToString(d.Get("unsubscribe_tracking_settings_active").(bool)), d.Get("unsubscribe_tracking_settings_html_footer").(string), d.Get("unsubscribe_tracking_settings_text_footer").(string))
275 return fmt.Errorf("Error updating mailgun unsubscribe tracking settings: %s", err.Error())
278 if d.HasChange("open_tracking_settings_active") {
279 err := mg.UpdateOpenTracking(ctx, domainName, boolToString(d.Get("open_tracking_settings_active").(bool)))
281 return fmt.Errorf("Error updating mailgun open tracking settings: %s", err.Error())
285 if d.HasChange("click_tracking_settings_active") {
286 err := mg.UpdateClickTracking(ctx, domainName, boolToString(d.Get("click_tracking_settings_active").(bool)))
288 return fmt.Errorf("Error updating mailgun click tracking settings: %s", err.Error())
292 if d.HasChange("require_tls") || d.HasChange("skip_verification") {
293 err := mg.UpdateDomainConnection(ctx, domainName, mailgun.DomainConnection{RequireTLS: d.Get("require_tls").(bool), SkipVerification: d.Get("skip_verification").(bool)})
295 return fmt.Errorf("Error updating mailgun connexion settings: %s", err.Error())
299 if d.HasChange("credentials") {
300 old, new := d.GetChange("credentials")
301 for _, i := range old.([]interface{}) {
302 oldCredential := i.(map[string]interface{})
304 for _, j := range new.([]interface{}) {
305 newCredential := j.(map[string]interface{})
306 if oldCredential["login"] == newCredential["login"] {
308 if oldCredential["password"] != newCredential["password"] {
309 err := mg.ChangeCredentialPassword(ctx, oldCredential["login"].(string), newCredential["password"].(string))
311 return fmt.Errorf("Error updating mailgun credential password: %s", err.Error())
318 err := mg.DeleteCredential(ctx, oldCredential["login"].(string))
320 return fmt.Errorf("Error deleting mailgun credential : %s", err.Error())
325 for _, i := range new.([]interface{}) {
326 newCredential := i.(map[string]interface{})
328 for _, j := range old.([]interface{}) {
329 oldCredential := j.(map[string]interface{})
330 if oldCredential["login"] == newCredential["login"] {
336 err := mg.CreateCredential(ctx, newCredential["login"].(string), newCredential["password"].(string))
338 return fmt.Errorf("Error creating mailgun credential : %s", err.Error())
344 return ReadDomain(d, meta)
347 func DeleteDomain(d *schema.ResourceData, meta interface{}) error {
348 mg := meta.(*mailgun.MailgunImpl)
349 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
352 log.Printf("[DEBUG] Deleting mailgun domain: %s", d.Id())
354 err := mg.DeleteDomain(ctx, d.Get("name").(string))
359 func ReadDomain(d *schema.ResourceData, meta interface{}) error {
360 mg := meta.(*mailgun.MailgunImpl)
361 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
363 domainName := d.Get("name").(string)
364 mg = mailgun.NewMailgun(domainName, mg.APIKey())
366 domainResponse, err := mg.GetDomain(ctx, domainName)
368 return fmt.Errorf("Error Getting mailgun domain Details for %s: Error: %s", d.Id(), err)
371 d.Set("created_at", domainResponse.Domain.CreatedAt)
372 d.Set("smtd_login", domainResponse.Domain.SMTPLogin)
373 d.Set("name", domainResponse.Domain.Name)
374 d.Set("smtd_password", domainResponse.Domain.SMTPPassword)
375 d.Set("wildcard", domainResponse.Domain.Wildcard)
376 d.Set("spam_action", domainResponse.Domain.SpamAction)
377 d.Set("state", domainResponse.Domain.State)
379 simpleReceivingRecords := make([]map[string]interface{}, len(domainResponse.ReceivingDNSRecords))
380 for i, r := range domainResponse.ReceivingDNSRecords {
381 simpleReceivingRecords[i] = make(map[string]interface{})
382 simpleReceivingRecords[i]["priority"] = r.Priority
383 simpleReceivingRecords[i]["name"] = r.Name
384 simpleReceivingRecords[i]["valid"] = r.Valid
385 simpleReceivingRecords[i]["value"] = r.Value
386 simpleReceivingRecords[i]["record_type"] = r.RecordType
388 d.Set("receiving_records", simpleReceivingRecords)
390 simpleSendingRecords := make([]map[string]interface{}, len(domainResponse.SendingDNSRecords))
391 for i, r := range domainResponse.SendingDNSRecords {
392 simpleSendingRecords[i] = make(map[string]interface{})
393 simpleSendingRecords[i]["name"] = r.Name
394 simpleSendingRecords[i]["priority"] = r.Priority
395 simpleSendingRecords[i]["valid"] = r.Valid
396 simpleSendingRecords[i]["value"] = r.Value
397 simpleSendingRecords[i]["record_type"] = r.RecordType
399 d.Set("sending_records", simpleSendingRecords)
401 domainConnection, err := mg.GetDomainConnection(ctx, domainName)
403 return fmt.Errorf("Error Getting mailgun domain connection Details for %s: Error: %s", d.Id(), err)
405 d.Set("require_tls", domainConnection.RequireTLS)
406 d.Set("skip_verification", domainConnection.SkipVerification)
408 domainTracking, err := mg.GetDomainTracking(ctx, domainName)
410 return fmt.Errorf("Error Getting mailgun domain tracking Details for %s: Error: %s", d.Id(), err)
413 d.Set("open_tracking_settings_active", domainTracking.Open.Active)
415 d.Set("click_tracking_settings_active", domainTracking.Click.Active)
416 d.Set("unsubscribe_tracking_settings_active", domainTracking.Unsubscribe.Active)
417 d.Set("unsubscribe_tracking_settings_html_footer", domainTracking.Unsubscribe.HTMLFooter)
418 d.Set("unsubscribe_tracking_settings_text_footer", domainTracking.Unsubscribe.TextFooter)
420 ipAddress, err := mg.ListDomainIPS(ctx)
422 return fmt.Errorf("Error Getting mailgun domain ips for %s: Error: %s", d.Id(), err)
424 ips := make([]string, len(ipAddress))
425 for i, r := range ipAddress {
431 credentialsResponse, err := ListCredentials(domainName, mg.APIKey())
433 return fmt.Errorf("Error Getting mailgun credentials for %s: Error: %s", d.Id(), err)
436 credentials := make([]map[string]interface{}, len(credentialsResponse))
437 for i, r := range credentialsResponse {
438 credentials[i] = make(map[string]interface{})
439 credentials[i]["created_at"] = r.CreatedAt
440 credentials[i]["login"] = r.Login
441 credentials[i]["password"] = r.Password
443 d.Set("credentials", credentials)
450 func boolToString(b bool) string {
457 func ListCredentials(domain, apiKey string) ([]mailgun.Credential, error) {
458 mg := mailgun.NewMailgun(domain, apiKey)
459 it := mg.ListCredentials(nil)
461 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
464 var page, result []mailgun.Credential
465 for it.Next(ctx, &page) {
466 result = append(result, page...)