From a9f39faec65b538e9b426291318b936f925e5f9e Mon Sep 17 00:00:00 2001 From: Gavin Bunney Date: Tue, 8 Oct 2019 15:38:15 -0700 Subject: [PATCH] Added `resource_admin_mail_server` resource --- README.md | 26 ++++ bitbucket/provider.go | 5 +- bitbucket/resource_admin_mail_server.go | 152 +++++++++++++++++++ bitbucket/resource_admin_mail_server_test.go | 64 ++++++++ bitbucket/resource_project_test.go | 6 +- 5 files changed, 247 insertions(+), 6 deletions(-) create mode 100644 bitbucket/resource_admin_mail_server.go create mode 100644 bitbucket/resource_admin_mail_server_test.go diff --git a/README.md b/README.md index 5d1928f..4c1701c 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,32 @@ Additional to the above, the following attributes are emitted: $ terraform import bitbucketserver_repository.test TEST/test-01 ``` +### Set Mail Server Configuration + +```hcl +resource "bitbucketserver_admin_mail_server" "mail" { + hostname = "mail.example.com" + port = 465 + protocol = "SMTPS" + sender_address = "bitbucket@example.com" +} +``` + +* `hostname` - Required. Hostname of the mail server. +* `port` - Required. Port number of the mail server. Typically port 25 or 587 for SMTP and 465 for SMTPS. +* `sender_address` - Required. Email address for notification emails. +* `protocol` - Optional. SMTP or SMTPS supported. Default `SMTP` +* `use_start_tls` - Optional. Use SSL/TLS if available. Default `true` +* `require_start_tls` - Optional. Require SSL to be used. Default `false` +* `username` - Optional. User to connect with. +* `password` - Optional. User to connect with. + +#### Import Mail Configuration + +```bash +$ terraform import bitbucketserver_admin_mail_server.mail mail.example.com +``` + --- ## Development Guide diff --git a/bitbucket/provider.go b/bitbucket/provider.go index 21706e3..f7f219e 100644 --- a/bitbucket/provider.go +++ b/bitbucket/provider.go @@ -29,8 +29,9 @@ func Provider() terraform.ResourceProvider { }, ConfigureFunc: providerConfigure, ResourcesMap: map[string]*schema.Resource{ - "bitbucketserver_project": resourceProject(), - "bitbucketserver_repository": resourceRepository(), + "bitbucketserver_admin_mail_server": resourceAdminMailServer(), + "bitbucketserver_project": resourceProject(), + "bitbucketserver_repository": resourceRepository(), }, } } diff --git a/bitbucket/resource_admin_mail_server.go b/bitbucket/resource_admin_mail_server.go new file mode 100644 index 0000000..fb3750a --- /dev/null +++ b/bitbucket/resource_admin_mail_server.go @@ -0,0 +1,152 @@ +package bitbucket + +import ( + "bytes" + "encoding/json" + "github.com/hashicorp/terraform/helper/schema" + "io/ioutil" +) + +type MailConfiguration struct { + Hostname string `json:"hostname,omitempty"` + Port int `json:"port,omitempty"` + Protocol string `json:"protocol,omitempty"` + UseStartTLS bool `json:"use-start-tls,omitempty"` + RequireStartTLS bool `json:"require-start-tls,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + SenderAddress string `json:"sender-address,omitempty"` +} + +func resourceAdminMailServer() *schema.Resource { + return &schema.Resource{ + Create: resourceAdminMailServerCreate, + Update: resourceAdminMailServerUpdate, + Read: resourceAdminMailServerRead, + Delete: resourceAdminMailServerDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "hostname": { + Type: schema.TypeString, + Required: true, + }, + "port": { + Type: schema.TypeInt, + Optional: true, + Default: 25, + }, + "protocol": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "use_start_tls": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + "require_start_tls": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "username": { + Type: schema.TypeString, + Optional: true, + }, + "password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "sender_address": { + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func newMailConfigurationFromResource(d *schema.ResourceData) *MailConfiguration { + mailConfiguration := &MailConfiguration{ + Hostname: d.Get("hostname").(string), + Port: d.Get("port").(int), + Protocol: d.Get("protocol").(string), + UseStartTLS: d.Get("use_start_tls").(bool), + RequireStartTLS: d.Get("require_start_tls").(bool), + Username: d.Get("username").(string), + Password: d.Get("password").(string), + SenderAddress: d.Get("sender_address").(string), + } + + return mailConfiguration +} + +func resourceAdminMailServerUpdate(d *schema.ResourceData, m interface{}) error { + client := m.(*BitbucketClient) + mailConfiguration := newMailConfigurationFromResource(d) + + bytedata, err := json.Marshal(mailConfiguration) + + if err != nil { + return err + } + + _, err = client.Put("/rest/api/1.0/admin/mail-server", bytes.NewBuffer(bytedata)) + if err != nil { + return err + } + + d.SetId(mailConfiguration.Hostname) + + return resourceAdminMailServerRead(d, m) +} + +func resourceAdminMailServerCreate(d *schema.ResourceData, m interface{}) error { + return resourceAdminMailServerUpdate(d, m) +} + +func resourceAdminMailServerRead(d *schema.ResourceData, m interface{}) error { + + client := m.(*BitbucketClient) + req, err := client.Get("/rest/api/1.0/admin/mail-server") + + if err != nil { + return err + } + + if req.StatusCode == 200 { + + var mailConfiguration MailConfiguration + + body, readerr := ioutil.ReadAll(req.Body) + if readerr != nil { + return readerr + } + + decodeerr := json.Unmarshal(body, &mailConfiguration) + if decodeerr != nil { + return decodeerr + } + + d.Set("hostname", mailConfiguration.Hostname) + d.Set("port", mailConfiguration.Port) + d.Set("protocol", mailConfiguration.Protocol) + d.Set("use_start_tls", mailConfiguration.UseStartTLS) + d.Set("require_start_tls", mailConfiguration.RequireStartTLS) + d.Set("username", mailConfiguration.Username) + d.Set("password", mailConfiguration.Password) + d.Set("sender_address", mailConfiguration.SenderAddress) + } + + return nil +} + +func resourceAdminMailServerDelete(d *schema.ResourceData, m interface{}) error { + client := m.(*BitbucketClient) + _, err := client.Delete("/rest/api/1.0/admin/mail-server") + return err +} diff --git a/bitbucket/resource_admin_mail_server_test.go b/bitbucket/resource_admin_mail_server_test.go new file mode 100644 index 0000000..75cc8d0 --- /dev/null +++ b/bitbucket/resource_admin_mail_server_test.go @@ -0,0 +1,64 @@ +package bitbucket + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccBitbucketAdminMailServer(t *testing.T) { + testAccBitbucketAdminMailServerConfig := ` + resource "bitbucketserver_admin_mail_server" "test" { + hostname = "mail.example.com" + port = 465 + protocol = "SMTP" + use_start_tls = true + require_start_tls = true + sender_address = "test@example.com" + } + ` + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckBitbucketAdminMailServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBitbucketAdminMailServerConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckBitbucketAdminMailServerExists("bitbucketserver_admin_mail_server.test"), + ), + }, + }, + }) +} + +func testAccCheckBitbucketAdminMailServerDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*BitbucketClient) + _, ok := s.RootModule().Resources["bitbucketserver_admin_mail_server.test"] + if !ok { + return fmt.Errorf("not found %s", "bitbucketserver_admin_mail_server.test") + } + + response, _ := client.Get("/rest/api/1.0/admin/main-server") + if response.StatusCode != 404 { + return fmt.Errorf("mail-server configuration still exists") + } + + return nil +} + +func testAccCheckBitbucketAdminMailServerExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("not found %s", n) + } + if rs.Primary.ID == "" { + return fmt.Errorf("no project ID is set") + } + return nil + } +} diff --git a/bitbucket/resource_project_test.go b/bitbucket/resource_project_test.go index 7d5e639..3bf5cbc 100644 --- a/bitbucket/resource_project_test.go +++ b/bitbucket/resource_project_test.go @@ -11,8 +11,6 @@ import ( ) func TestAccBitbucketProject(t *testing.T) { - var repo Repository - testAccBitbucketProjectConfig := fmt.Sprintf(` resource "bitbucketserver_project" "test" { key = "TEST%v" @@ -28,7 +26,7 @@ func TestAccBitbucketProject(t *testing.T) { { Config: testAccBitbucketProjectConfig, Check: resource.ComposeTestCheckFunc( - testAccCheckBitbucketProjectExists("bitbucketserver_project.test", &repo), + testAccCheckBitbucketProjectExists("bitbucketserver_project.test"), ), }, }, @@ -51,7 +49,7 @@ func testAccCheckBitbucketProjectDestroy(s *terraform.State) error { return nil } -func testAccCheckBitbucketProjectExists(n string, repository *Repository) resource.TestCheckFunc { +func testAccCheckBitbucketProjectExists(n string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok {