Skip to content

Commit

Permalink
provider,resource_smtp_credential: Support configuring SMTP credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
issyl0 committed Aug 13, 2021
1 parent cfc9b8e commit acde169
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 3 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ A very nascent Terraform provider for configuring [ImprovMX](https://improvmx.co
- Delete an email forward.
- Import an email forward.
- Update an email forward (ImprovMX allows updating an email forward to send to more than one address, ie `alice@example.com,bob@example.com`).
- Create, update and delete a domain's SMTP credentials.

## Usage

```hcl
terraform {
required_providers {
improvmx = {
source = "issyl0/improvmx"
source = "issyl0/improvmx"
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions docs/resources/improvmx_smtp_credential.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# `improvmx_smtp_credential` Resource

A resource to create ImprovMX domain SMTP credentials.

## Example Usage

```hcl
resource "improvmx_email_forward" "example" {
domain = "example.com"
username = "example"
password = var.password
}
```

## Argument Reference

* `domain` - (Required) Name of the domain.
* `username` - (Required) Username of the SMTP sender.
* `password` - (Required) Password for the SMTP sending account.
8 changes: 6 additions & 2 deletions improvmx/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ type Meta struct {

func Provider() *schema.Provider {
p := &schema.Provider{
Schema: map[string]*schema.Schema{"token": {Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("IMPROVMX_API_TOKEN", nil), Description: "The API token for API operations."}},
ResourcesMap: map[string]*schema.Resource{"improvmx_domain": resourceDomain(), "improvmx_email_forward": resourceEmailForward()},
Schema: map[string]*schema.Schema{"token": {Type: schema.TypeString, Required: true, DefaultFunc: schema.EnvDefaultFunc("IMPROVMX_API_TOKEN", nil), Description: "The API token for API operations."}},
ResourcesMap: map[string]*schema.Resource{
"improvmx_domain": resourceDomain(),
"improvmx_email_forward": resourceEmailForward(),
"improvmx_smtp_credential": resourceSMTPCredential(),
},
DataSourcesMap: map[string]*schema.Resource{},
ProviderMetaSchema: map[string]*schema.Schema{},
}
Expand Down
120 changes: 120 additions & 0 deletions improvmx/resource_smtp_credential.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package improvmx

import (
"fmt"
"log"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func resourceSMTPCredential() *schema.Resource {
return &schema.Resource{
Create: resourceSMTPCredentialCreate,
Read: resourceSMTPCredentialRead,
Update: resourceSMTPCredentialUpdate,
Delete: resourceSMTPCredentialDelete,

Schema: map[string]*schema.Schema{
"domain": {
Type: schema.TypeString,
Required: true,
},
"username": {
Type: schema.TypeString,
Required: true,
},
"password": {
Type: schema.TypeString,
Required: true,
Sensitive: true,
},
},
}
}

func resourceSMTPCredentialCreate(d *schema.ResourceData, meta interface{}) error {
m := meta.(*Meta)

for {
resp := m.Client.CreateSMTPCredential(d.Get("domain").(string), d.Get("username").(string), d.Get("password").(string))

log.Printf("[DEBUG] Got status code %v from ImprovMX API on Create for SMTP %s@%s, success: %v, errors: %v.", resp.Code, d.Get("username").(string), d.Get("domain").(string), resp.Success, resp.Errors)

if resp.Code == 429 {
log.Printf("[DEBUG] Sleeping for 10 seconds to allow rate limit to recover.")
time.Sleep(10 * time.Second)
}

if resp.Code == 404 {
log.Printf("[DEBUG] Couldn't find the resource in ImprovMX. Aborting")
return fmt.Errorf("HTTP response code %d, error text: %s", resp.Code, resp.Errors.Domain)
}

if resp.Success {
return resourceSMTPCredentialRead(d, meta)
}
}
}

func resourceSMTPCredentialRead(d *schema.ResourceData, meta interface{}) error {
m := meta.(*Meta)
m.Mutex.Lock()
defer m.Mutex.Unlock()

for {
resp := m.Client.GetSMTPCredential(d.Get("domain").(string))

log.Printf("[DEBUG] Got status code %v from ImprovMX API on Read for SMTP domain %s, success: %v, errors: %v.", resp.Code, d.Get("domain").(string), resp.Success, resp.Errors)

if resp.Code == 429 {
log.Printf("[DEBUG] Sleeping for 10 seconds to allow rate limit to recover.")
time.Sleep(10 * time.Second)
}

if resp.Code == 404 {
log.Printf("[DEBUG] Couldn't find the resource in ImprovMX. Aborting")
return fmt.Errorf("HTTP response code %d, error text: %s", resp.Code, resp.Errors.Domain)
}

if resp.Success {
d.SetId(d.Get("domain").(string))
d.Set("domain", d.Get("domain").(string))
return nil
}
}
}

func resourceSMTPCredentialUpdate(d *schema.ResourceData, meta interface{}) error {
m := meta.(*Meta)

for {
resp := m.Client.UpdateSMTPCredential(d.Get("domain").(string), d.Get("username").(string), d.Get("password").(string))

log.Printf("[DEBUG] Got status code %v from ImprovMX API on Update for SMTP domain %s@%s, success: %v, errors: %v.", resp.Code, d.Get("username").(string), d.Get("domain").(string), resp.Success, resp.Errors)

if resp.Code == 429 {
log.Printf("[DEBUG] Sleeping for 10 seconds to allow rate limit to recover.")
time.Sleep(10 * time.Second)
}

if resp.Code == 404 {
log.Printf("[DEBUG] Couldn't find the resource in ImprovMX. Aborting")
return fmt.Errorf("HTTP response code %d, error text: %s", resp.Code, resp.Errors.Domain)
}

if resp.Success {
return resourceSMTPCredentialRead(d, meta)
}
}
}

func resourceSMTPCredentialDelete(d *schema.ResourceData, meta interface{}) error {
m := meta.(*Meta)
m.Mutex.Lock()
defer m.Mutex.Unlock()

m.Client.DeleteSMTPCredential(d.Get("domain").(string), d.Get("username").(string))

return nil
}

0 comments on commit acde169

Please sign in to comment.