]> git.immae.eu Git - github/fretlink/terraform-provider-mailgun.git/blame - mailgun/resource_mailgun_domain.go
add test for importation and fix importation for domain
[github/fretlink/terraform-provider-mailgun.git] / mailgun / resource_mailgun_domain.go
CommitLineData
4457c936
AG
1package mailgun
2
3import (
4 "context"
5 "fmt"
6 "github.com/hashicorp/terraform/helper/schema"
7c735cfa 7 "github.com/mailgun/mailgun-go/v3"
4457c936
AG
8 "log"
9 "time"
10)
11
12func resourceMailgunDomain() *schema.Resource {
13 return &schema.Resource{
14 Create: CreateDomain,
15 Update: UpdateDomain,
16 Delete: DeleteDomain,
17 Read: ReadDomain,
18 Importer: &schema.ResourceImporter{
19 State: schema.ImportStatePassthrough,
20 },
21
22 Schema: map[string]*schema.Schema{
23 "name": &schema.Schema{
24 Type: schema.TypeString,
25 Required: true,
26 ForceNew: true,
27 },
28
29 "spam_action": &schema.Schema{
30 Type: schema.TypeString,
31 Default: "disabled",
32 ForceNew: true,
33 Optional: true,
34 },
35
36 "smtp_password": &schema.Schema{
37 Type: schema.TypeString,
38 ForceNew: true,
39 Optional: true,
40 },
41
42 "smtp_login": &schema.Schema{
43 Type: schema.TypeString,
44 Computed: true,
45 },
46
47 "wildcard": &schema.Schema{
48 Type: schema.TypeBool,
49 Default: false,
50 ForceNew: true,
51 Optional: true,
52 },
53
54 "created_at": &schema.Schema{
55 Type: schema.TypeString,
56 Computed: true,
57 ForceNew: true,
58 },
59
60 "state": &schema.Schema{
61 Type: schema.TypeString,
62 Computed: true,
63 },
64
65 "force_dkim_authority": &schema.Schema{
66 Type: schema.TypeBool,
67 Default: false,
68 Optional: true,
69 },
70
71 "dkim_key_size": &schema.Schema{
72 Type: schema.TypeInt,
73 Default: 1024,
74 ForceNew: true,
75 Optional: true,
76 },
77
78 "ips": &schema.Schema{
79 Type: schema.TypeList,
80 Computed: true,
81 ForceNew: true,
82 Optional: true,
83 Elem: &schema.Schema{Type: schema.TypeString},
84 },
85
86 "credentials": &schema.Schema{
87 Type: schema.TypeList,
88 Optional: true,
89 Elem: &schema.Resource{
90 Schema: map[string]*schema.Schema{
91 "created_at": &schema.Schema{
92 Type: schema.TypeString,
93 Computed: true,
94 },
95 "login": &schema.Schema{
96 Type: schema.TypeString,
97 Required: true,
98 },
99 "password": &schema.Schema{
100 Type: schema.TypeString,
101 Required: true,
102 },
103 },
104 },
105 },
106
107 "open_tracking_settings_active": &schema.Schema{
108 Type: schema.TypeBool,
109 Optional: true,
40587421 110 Default: false,
4457c936
AG
111 },
112
113 "click_tracking_settings_active": &schema.Schema{
114 Type: schema.TypeBool,
115 Optional: true,
40587421 116 Default: false,
4457c936
AG
117 },
118
119 "unsubscribe_tracking_settings_active": &schema.Schema{
120 Type: schema.TypeBool,
121 Optional: true,
40587421 122 Default: false,
4457c936
AG
123 },
124 "unsubscribe_tracking_settings_html_footer": &schema.Schema{
125 Type: schema.TypeString,
126 Optional: true,
40587421 127 Default: "\n<br>\n<p><a href=\"%unsubscribe_url%\">unsubscribe</a></p>\n",
4457c936
AG
128 },
129 "unsubscribe_tracking_settings_text_footer": &schema.Schema{
130 Type: schema.TypeString,
131 Optional: true,
40587421 132 Default: "\n\nTo unsubscribe click: <%unsubscribe_url%>\n\n",
4457c936
AG
133 },
134
135 "require_tls": &schema.Schema{
136 Type: schema.TypeBool,
137 Default: false,
138 Optional: true,
139 },
140
141 "skip_verification": &schema.Schema{
142 Type: schema.TypeBool,
143 Default: false,
144 Optional: true,
145 },
146
147 "receiving_records": &schema.Schema{
148 Type: schema.TypeList,
149 Computed: true,
150 Elem: &schema.Resource{
151 Schema: map[string]*schema.Schema{
152 "name": &schema.Schema{
153 Type: schema.TypeString,
154 Computed: true,
155 },
156 "priority": &schema.Schema{
157 Type: schema.TypeString,
158 Computed: true,
159 },
160 "record_type": &schema.Schema{
161 Type: schema.TypeString,
162 Computed: true,
163 },
164 "valid": &schema.Schema{
165 Type: schema.TypeString,
166 Computed: true,
167 },
168 "value": &schema.Schema{
169 Type: schema.TypeString,
170 Computed: true,
171 },
172 },
173 },
174 },
175
176 "sending_records": &schema.Schema{
177 Type: schema.TypeList,
178 Computed: true,
179 Elem: &schema.Resource{
180 Schema: map[string]*schema.Schema{
181 "name": &schema.Schema{
182 Type: schema.TypeString,
183 Computed: true,
184 },
185 "priority": &schema.Schema{
186 Type: schema.TypeString,
187 Computed: true,
188 },
189 "record_type": &schema.Schema{
190 Type: schema.TypeString,
191 Computed: true,
192 },
193 "valid": &schema.Schema{
194 Type: schema.TypeString,
195 Computed: true,
196 },
197 "value": &schema.Schema{
198 Type: schema.TypeString,
199 Computed: true,
200 },
201 },
202 },
203 },
204 },
205 }
206}
207
61f3e553
AG
208func interfaceToStringTab(i interface{}) []string {
209 aInterface := i.([]interface{})
210 aString := make([]string, len(aInterface))
211 for i, v := range aInterface {
212 aString[i] = v.(string)
213 }
214 return aString
215}
4457c936
AG
216func CreateDomain(d *schema.ResourceData, meta interface{}) error {
217 mg := meta.(*mailgun.MailgunImpl)
218 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
219 defer cancel()
220
221 log.Printf("[DEBUG] creating mailgun domain: %s", d.Id())
222
223 creationResponse, err := mg.CreateDomain(ctx, d.Get("name").(string), &mailgun.CreateDomainOptions{
224 Password: d.Get("smtp_password").(string),
225 SpamAction: mailgun.SpamAction(d.Get("spam_action").(string)),
226 Wildcard: d.Get("wildcard").(bool),
227 ForceDKIMAuthority: d.Get("force_dkim_authority").(bool),
228 DKIMKeySize: d.Get("dkim_key_size").(int),
61f3e553 229 IPS: interfaceToStringTab(d.Get("ips")),
4457c936
AG
230 })
231
232 if err != nil {
233 return fmt.Errorf("Error creating mailgun domain: %s", err.Error())
234 }
235
236 mg = mailgun.NewMailgun(creationResponse.Domain.Name, mg.APIKey())
237
238 for _, i := range d.Get("credentials").([]interface{}) {
239 credential := i.(map[string]interface{})
240 err = mg.CreateCredential(ctx, credential["login"].(string), credential["password"].(string))
241 if err != nil {
242 return fmt.Errorf("Error creating mailgun credential: %s", err.Error())
243 }
244 }
245
246 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))
247 if err != nil {
248 return fmt.Errorf("Error updating mailgun unsubscribe tracking settings: %s", err.Error())
249 }
250
251 err = mg.UpdateOpenTracking(ctx, creationResponse.Domain.Name, boolToString(d.Get("open_tracking_settings_active").(bool)))
252 if err != nil {
253 return fmt.Errorf("Error updating mailgun open tracking settings: %s", err.Error())
254 }
255
256 err = mg.UpdateClickTracking(ctx, creationResponse.Domain.Name, boolToString(d.Get("click_tracking_settings_active").(bool)))
257 if err != nil {
258 return fmt.Errorf("Error updating mailgun click tracking settings: %s", err.Error())
259 }
260
261 err = mg.UpdateDomainConnection(ctx, creationResponse.Domain.Name, mailgun.DomainConnection{RequireTLS: d.Get("require_tls").(bool), SkipVerification: d.Get("skip_verification").(bool)})
262 if err != nil {
263 return fmt.Errorf("Error updating mailgun connexion settings: %s", err.Error())
264 }
265
266 d.SetId(creationResponse.Domain.Name)
267
268 return ReadDomain(d, meta)
269}
270
271func UpdateDomain(d *schema.ResourceData, meta interface{}) error {
272 mg := meta.(*mailgun.MailgunImpl)
273 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
274 defer cancel()
275 domainName := d.Get("name").(string)
276 mg = mailgun.NewMailgun(domainName, mg.APIKey())
277
278 log.Printf("[DEBUG] updating mailgun domain: %s", d.Id())
279
280 if d.HasChange("unsubscribe_tracking_settings_active") || d.HasChange("unsubscribe_tracking_settings_html_footer") || d.HasChange("unsubscribe_tracking_settings_text_footer") {
281 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))
282 if err != nil {
283 return fmt.Errorf("Error updating mailgun unsubscribe tracking settings: %s", err.Error())
284 }
285 }
286 if d.HasChange("open_tracking_settings_active") {
287 err := mg.UpdateOpenTracking(ctx, domainName, boolToString(d.Get("open_tracking_settings_active").(bool)))
288 if err != nil {
289 return fmt.Errorf("Error updating mailgun open tracking settings: %s", err.Error())
290 }
291 }
292
293 if d.HasChange("click_tracking_settings_active") {
294 err := mg.UpdateClickTracking(ctx, domainName, boolToString(d.Get("click_tracking_settings_active").(bool)))
295 if err != nil {
296 return fmt.Errorf("Error updating mailgun click tracking settings: %s", err.Error())
297 }
298 }
299
300 if d.HasChange("require_tls") || d.HasChange("skip_verification") {
301 err := mg.UpdateDomainConnection(ctx, domainName, mailgun.DomainConnection{RequireTLS: d.Get("require_tls").(bool), SkipVerification: d.Get("skip_verification").(bool)})
302 if err != nil {
303 return fmt.Errorf("Error updating mailgun connexion settings: %s", err.Error())
304 }
305 }
306
307 if d.HasChange("credentials") {
308 old, new := d.GetChange("credentials")
309 for _, i := range old.([]interface{}) {
310 oldCredential := i.(map[string]interface{})
311 found := false
312 for _, j := range new.([]interface{}) {
313 newCredential := j.(map[string]interface{})
314 if oldCredential["login"] == newCredential["login"] {
315 found = true
316 if oldCredential["password"] != newCredential["password"] {
317 err := mg.ChangeCredentialPassword(ctx, oldCredential["login"].(string), newCredential["password"].(string))
318 if err != nil {
319 return fmt.Errorf("Error updating mailgun credential password: %s", err.Error())
320 }
321 }
322 break
323 }
324 }
325 if !found {
326 err := mg.DeleteCredential(ctx, oldCredential["login"].(string))
327 if err != nil {
328 return fmt.Errorf("Error deleting mailgun credential : %s", err.Error())
329 }
330 }
331 }
332
333 for _, i := range new.([]interface{}) {
334 newCredential := i.(map[string]interface{})
335 found := false
336 for _, j := range old.([]interface{}) {
337 oldCredential := j.(map[string]interface{})
338 if oldCredential["login"] == newCredential["login"] {
339 found = true
340 break
341 }
342 }
343 if !found {
344 err := mg.CreateCredential(ctx, newCredential["login"].(string), newCredential["password"].(string))
345 if err != nil {
346 return fmt.Errorf("Error creating mailgun credential : %s", err.Error())
347 }
348 }
349 }
350 }
351
352 return ReadDomain(d, meta)
353}
354
355func DeleteDomain(d *schema.ResourceData, meta interface{}) error {
356 mg := meta.(*mailgun.MailgunImpl)
357 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
358 defer cancel()
359
360 log.Printf("[DEBUG] Deleting mailgun domain: %s", d.Id())
361
362 err := mg.DeleteDomain(ctx, d.Get("name").(string))
363
364 return err
365}
366
367func ReadDomain(d *schema.ResourceData, meta interface{}) error {
368 mg := meta.(*mailgun.MailgunImpl)
369 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
370 defer cancel()
70ac6365 371 domainName := d.Id()
5c1feb2c 372 mg = mailgun.NewMailgun(domainName, mg.APIKey())
4457c936
AG
373
374 domainResponse, err := mg.GetDomain(ctx, domainName)
375 if err != nil {
376 return fmt.Errorf("Error Getting mailgun domain Details for %s: Error: %s", d.Id(), err)
377 }
70ac6365
AG
378 if _, ok := d.GetOk("dkim_key_size"); !ok {
379 d.Set("dkim_key_size", 1024)
380 }
381
382 if _, ok := d.GetOk("force_dkim_authority"); !ok {
383 d.Set("force_dkim_authority", false)
384 }
4457c936
AG
385
386 d.Set("created_at", domainResponse.Domain.CreatedAt)
387 d.Set("smtd_login", domainResponse.Domain.SMTPLogin)
388 d.Set("name", domainResponse.Domain.Name)
389 d.Set("smtd_password", domainResponse.Domain.SMTPPassword)
390 d.Set("wildcard", domainResponse.Domain.Wildcard)
391 d.Set("spam_action", domainResponse.Domain.SpamAction)
392 d.Set("state", domainResponse.Domain.State)
393
394 simpleReceivingRecords := make([]map[string]interface{}, len(domainResponse.ReceivingDNSRecords))
395 for i, r := range domainResponse.ReceivingDNSRecords {
396 simpleReceivingRecords[i] = make(map[string]interface{})
397 simpleReceivingRecords[i]["priority"] = r.Priority
398 simpleReceivingRecords[i]["name"] = r.Name
399 simpleReceivingRecords[i]["valid"] = r.Valid
400 simpleReceivingRecords[i]["value"] = r.Value
401 simpleReceivingRecords[i]["record_type"] = r.RecordType
402 }
403 d.Set("receiving_records", simpleReceivingRecords)
404
405 simpleSendingRecords := make([]map[string]interface{}, len(domainResponse.SendingDNSRecords))
406 for i, r := range domainResponse.SendingDNSRecords {
407 simpleSendingRecords[i] = make(map[string]interface{})
408 simpleSendingRecords[i]["name"] = r.Name
409 simpleSendingRecords[i]["priority"] = r.Priority
410 simpleSendingRecords[i]["valid"] = r.Valid
411 simpleSendingRecords[i]["value"] = r.Value
412 simpleSendingRecords[i]["record_type"] = r.RecordType
413 }
414 d.Set("sending_records", simpleSendingRecords)
415
416 domainConnection, err := mg.GetDomainConnection(ctx, domainName)
417 if err != nil {
418 return fmt.Errorf("Error Getting mailgun domain connection Details for %s: Error: %s", d.Id(), err)
419 }
420 d.Set("require_tls", domainConnection.RequireTLS)
421 d.Set("skip_verification", domainConnection.SkipVerification)
422
423 domainTracking, err := mg.GetDomainTracking(ctx, domainName)
424 if err != nil {
425 return fmt.Errorf("Error Getting mailgun domain tracking Details for %s: Error: %s", d.Id(), err)
426 }
427
428 d.Set("open_tracking_settings_active", domainTracking.Open.Active)
429
430 d.Set("click_tracking_settings_active", domainTracking.Click.Active)
431 d.Set("unsubscribe_tracking_settings_active", domainTracking.Unsubscribe.Active)
432 d.Set("unsubscribe_tracking_settings_html_footer", domainTracking.Unsubscribe.HTMLFooter)
433 d.Set("unsubscribe_tracking_settings_text_footer", domainTracking.Unsubscribe.TextFooter)
434
3d14d0f6 435 time.Sleep(25 * time.Second)
40587421 436
4457c936 437 ipAddress, err := mg.ListDomainIPS(ctx)
40587421 438
4457c936 439 if err != nil {
40587421 440 return fmt.Errorf("Error Getting mailgun domain ips1 for %s: Error: %s", d.Id(), err)
4457c936
AG
441 }
442 ips := make([]string, len(ipAddress))
443 for i, r := range ipAddress {
444 ips[i] = r.IP
445
446 }
447 d.Set("ips", ips)
448
449 credentialsResponse, err := ListCredentials(domainName, mg.APIKey())
5c1feb2c
AG
450 if err != nil {
451 return fmt.Errorf("Error Getting mailgun credentials for %s: Error: %s", d.Id(), err)
452 }
61f3e553 453
4457c936
AG
454 credentials := make([]map[string]interface{}, len(credentialsResponse))
455 for i, r := range credentialsResponse {
456 credentials[i] = make(map[string]interface{})
457 credentials[i]["created_at"] = r.CreatedAt
458 credentials[i]["login"] = r.Login
459 credentials[i]["password"] = r.Password
460 }
461 d.Set("credentials", credentials)
462
463 d.SetId(domainName)
464
465 return nil
466}
467
468func boolToString(b bool) string {
469 if b {
470 return "true"
471 }
472 return "false"
473}
474
475func ListCredentials(domain, apiKey string) ([]mailgun.Credential, error) {
476 mg := mailgun.NewMailgun(domain, apiKey)
477 it := mg.ListCredentials(nil)
478
479 ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
480 defer cancel()
481
482 var page, result []mailgun.Credential
483 for it.Next(ctx, &page) {
484 result = append(result, page...)
485 }
486
487 if it.Err() != nil {
488 return nil, it.Err()
489 }
490 return result, nil
491}