use official Go client for DigitalOcean provider
This commit is contained in:
parent
6bd40a7bf4
commit
0bcf557198
|
@ -3,7 +3,8 @@ package digitalocean
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/pearkes/digitalocean"
|
"github.com/digitalocean/godo"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
@ -11,14 +12,14 @@ type Config struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client() returns a new client for accessing digital ocean.
|
// Client() returns a new client for accessing digital ocean.
|
||||||
func (c *Config) Client() (*digitalocean.Client, error) {
|
func (c *Config) Client() (*godo.Client, error) {
|
||||||
client, err := digitalocean.NewClient(c.Token)
|
tokenSrc := oauth2.StaticTokenSource(&oauth2.Token{
|
||||||
|
AccessToken: c.Token,
|
||||||
|
})
|
||||||
|
|
||||||
log.Printf("[INFO] DigitalOcean Client configured for URL: %s", client.URL)
|
client := godo.NewClient(oauth2.NewClient(oauth2.NoContext, tokenSrc))
|
||||||
|
|
||||||
if err != nil {
|
log.Printf("[INFO] DigitalOcean Client configured for URL: %s", client.BaseURL.String())
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/digitalocean/godo"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/pearkes/digitalocean"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func resourceDigitalOceanDomain() *schema.Resource {
|
func resourceDigitalOceanDomain() *schema.Resource {
|
||||||
|
@ -32,30 +32,31 @@ func resourceDigitalOceanDomain() *schema.Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanDomainCreate(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanDomainCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
// Build up our creation options
|
// Build up our creation options
|
||||||
opts := &digitalocean.CreateDomain{
|
|
||||||
|
opts := &godo.DomainCreateRequest{
|
||||||
Name: d.Get("name").(string),
|
Name: d.Get("name").(string),
|
||||||
IPAddress: d.Get("ip_address").(string),
|
IPAddress: d.Get("ip_address").(string),
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] Domain create configuration: %#v", opts)
|
log.Printf("[DEBUG] Domain create configuration: %#v", opts)
|
||||||
name, err := client.CreateDomain(opts)
|
domain, _, err := client.Domains.Create(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error creating Domain: %s", err)
|
return fmt.Errorf("Error creating Domain: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(name)
|
d.SetId(domain.Name)
|
||||||
log.Printf("[INFO] Domain Name: %s", name)
|
log.Printf("[INFO] Domain Name: %s", domain.Name)
|
||||||
|
|
||||||
return resourceDigitalOceanDomainRead(d, meta)
|
return resourceDigitalOceanDomainRead(d, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanDomainRead(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanDomainRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
domain, err := client.RetrieveDomain(d.Id())
|
domain, _, err := client.Domains.Get(d.Id())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If the domain is somehow already destroyed, mark as
|
// If the domain is somehow already destroyed, mark as
|
||||||
// successfully gone
|
// successfully gone
|
||||||
|
@ -73,10 +74,10 @@ func resourceDigitalOceanDomainRead(d *schema.ResourceData, meta interface{}) er
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanDomainDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanDomainDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
log.Printf("[INFO] Deleting Domain: %s", d.Id())
|
log.Printf("[INFO] Deleting Domain: %s", d.Id())
|
||||||
err := client.DestroyDomain(d.Id())
|
_, err := client.Domains.Delete(d.Id())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error deleting Domain: %s", err)
|
return fmt.Errorf("Error deleting Domain: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/digitalocean/godo"
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/pearkes/digitalocean"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccDigitalOceanDomain_Basic(t *testing.T) {
|
func TestAccDigitalOceanDomain_Basic(t *testing.T) {
|
||||||
var domain digitalocean.Domain
|
var domain godo.Domain
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -33,7 +33,7 @@ func TestAccDigitalOceanDomain_Basic(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanDomainDestroy(s *terraform.State) error {
|
func testAccCheckDigitalOceanDomainDestroy(s *terraform.State) error {
|
||||||
client := testAccProvider.Meta().(*digitalocean.Client)
|
client := testAccProvider.Meta().(*godo.Client)
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
for _, rs := range s.RootModule().Resources {
|
||||||
if rs.Type != "digitalocean_domain" {
|
if rs.Type != "digitalocean_domain" {
|
||||||
|
@ -41,17 +41,17 @@ func testAccCheckDigitalOceanDomainDestroy(s *terraform.State) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find the domain
|
// Try to find the domain
|
||||||
_, err := client.RetrieveDomain(rs.Primary.ID)
|
_, _, err := client.Domains.Get(rs.Primary.ID)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Errorf("Domain still exists")
|
return fmt.Errorf("Domain still exists")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanDomainAttributes(domain *digitalocean.Domain) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanDomainAttributes(domain *godo.Domain) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if domain.Name != "foobar-test-terraform.com" {
|
if domain.Name != "foobar-test-terraform.com" {
|
||||||
|
@ -62,7 +62,7 @@ func testAccCheckDigitalOceanDomainAttributes(domain *digitalocean.Domain) resou
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanDomainExists(n string, domain *digitalocean.Domain) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanDomainExists(n string, domain *godo.Domain) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
rs, ok := s.RootModule().Resources[n]
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
|
||||||
|
@ -74,9 +74,9 @@ func testAccCheckDigitalOceanDomainExists(n string, domain *digitalocean.Domain)
|
||||||
return fmt.Errorf("No Record ID is set")
|
return fmt.Errorf("No Record ID is set")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*digitalocean.Client)
|
client := testAccProvider.Meta().(*godo.Client)
|
||||||
|
|
||||||
foundDomain, err := client.RetrieveDomain(rs.Primary.ID)
|
foundDomain, _, err := client.Domains.Get(rs.Primary.ID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -86,7 +86,7 @@ func testAccCheckDigitalOceanDomainExists(n string, domain *digitalocean.Domain)
|
||||||
return fmt.Errorf("Record not found")
|
return fmt.Errorf("Record not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
*domain = foundDomain
|
*domain = *foundDomain
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,13 @@ package digitalocean
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/digitalocean/godo"
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/pearkes/digitalocean"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func resourceDigitalOceanDroplet() *schema.Resource {
|
func resourceDigitalOceanDroplet() *schema.Resource {
|
||||||
|
@ -101,11 +102,13 @@ func resourceDigitalOceanDroplet() *schema.Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanDropletCreate(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanDropletCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
// Build up our creation options
|
// Build up our creation options
|
||||||
opts := &digitalocean.CreateDroplet{
|
opts := &godo.DropletCreateRequest{
|
||||||
Image: d.Get("image").(string),
|
Image: godo.DropletCreateImage{
|
||||||
|
Slug: d.Get("image").(string),
|
||||||
|
},
|
||||||
Name: d.Get("name").(string),
|
Name: d.Get("name").(string),
|
||||||
Region: d.Get("region").(string),
|
Region: d.Get("region").(string),
|
||||||
Size: d.Get("size").(string),
|
Size: d.Get("size").(string),
|
||||||
|
@ -116,7 +119,7 @@ func resourceDigitalOceanDropletCreate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
if attr, ok := d.GetOk("ipv6"); ok {
|
if attr, ok := d.GetOk("ipv6"); ok {
|
||||||
opts.IPV6 = attr.(bool)
|
opts.IPv6 = attr.(bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
if attr, ok := d.GetOk("private_networking"); ok {
|
if attr, ok := d.GetOk("private_networking"); ok {
|
||||||
|
@ -128,25 +131,32 @@ func resourceDigitalOceanDropletCreate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get configured ssh_keys
|
// Get configured ssh_keys
|
||||||
ssh_keys := d.Get("ssh_keys.#").(int)
|
sshKeys := d.Get("ssh_keys.#").(int)
|
||||||
if ssh_keys > 0 {
|
if sshKeys > 0 {
|
||||||
opts.SSHKeys = make([]string, 0, ssh_keys)
|
opts.SSHKeys = make([]godo.DropletCreateSSHKey, 0, sshKeys)
|
||||||
for i := 0; i < ssh_keys; i++ {
|
for i := 0; i < sshKeys; i++ {
|
||||||
key := fmt.Sprintf("ssh_keys.%d", i)
|
key := fmt.Sprintf("ssh_keys.%d", i)
|
||||||
opts.SSHKeys = append(opts.SSHKeys, d.Get(key).(string))
|
id, err := strconv.Atoi(d.Get(key).(string))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
opts.SSHKeys = append(opts.SSHKeys, godo.DropletCreateSSHKey{
|
||||||
|
ID: id,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] Droplet create configuration: %#v", opts)
|
log.Printf("[DEBUG] Droplet create configuration: %#v", opts)
|
||||||
|
|
||||||
id, err := client.CreateDroplet(opts)
|
droplet, _, err := client.Droplets.Create(opts)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error creating droplet: %s", err)
|
return fmt.Errorf("Error creating droplet: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the droplets id
|
// Assign the droplets id
|
||||||
d.SetId(id)
|
d.SetId(strconv.Itoa(droplet.ID))
|
||||||
|
|
||||||
log.Printf("[INFO] Droplet ID: %s", d.Id())
|
log.Printf("[INFO] Droplet ID: %s", d.Id())
|
||||||
|
|
||||||
|
@ -160,10 +170,15 @@ func resourceDigitalOceanDropletCreate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanDropletRead(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanDropletRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid droplet id: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve the droplet properties for updating the state
|
// Retrieve the droplet properties for updating the state
|
||||||
droplet, err := client.RetrieveDroplet(d.Id())
|
droplet, _, err := client.Droplets.Get(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// check if the droplet no longer exists.
|
// check if the droplet no longer exists.
|
||||||
if err.Error() == "Error retrieving droplet: API Error: 404 Not Found" {
|
if err.Error() == "Error retrieving droplet: API Error: 404 Not Found" {
|
||||||
|
@ -174,48 +189,70 @@ func resourceDigitalOceanDropletRead(d *schema.ResourceData, meta interface{}) e
|
||||||
return fmt.Errorf("Error retrieving droplet: %s", err)
|
return fmt.Errorf("Error retrieving droplet: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if droplet.ImageSlug() != "" {
|
if droplet.Image.Slug != "" {
|
||||||
d.Set("image", droplet.ImageSlug())
|
d.Set("image", droplet.Image.Slug)
|
||||||
} else {
|
} else {
|
||||||
d.Set("image", droplet.ImageId())
|
d.Set("image", droplet.Image.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Set("name", droplet.Name)
|
d.Set("name", droplet.Name)
|
||||||
d.Set("region", droplet.RegionSlug())
|
d.Set("region", droplet.Region.Slug)
|
||||||
d.Set("size", droplet.SizeSlug)
|
d.Set("size", droplet.Size.Slug)
|
||||||
d.Set("status", droplet.Status)
|
d.Set("status", droplet.Status)
|
||||||
d.Set("locked", droplet.IsLocked())
|
d.Set("locked", strconv.FormatBool(droplet.Locked))
|
||||||
|
|
||||||
if droplet.IPV6Address("public") != "" {
|
if publicIPv6 := findIPv6AddrByType(droplet, "public"); publicIPv6 != "" {
|
||||||
d.Set("ipv6", true)
|
d.Set("ipv6", true)
|
||||||
d.Set("ipv6_address", droplet.IPV6Address("public"))
|
d.Set("ipv6_address", publicIPv6)
|
||||||
d.Set("ipv6_address_private", droplet.IPV6Address("private"))
|
d.Set("ipv6_address_private", findIPv6AddrByType(droplet, "private"))
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Set("ipv4_address", droplet.IPV4Address("public"))
|
d.Set("ipv4_address", findIPv4AddrByType(droplet, "public"))
|
||||||
|
|
||||||
if droplet.NetworkingType() == "private" {
|
if privateIPv4 := findIPv4AddrByType(droplet, "private"); privateIPv4 != "" {
|
||||||
d.Set("private_networking", true)
|
d.Set("private_networking", true)
|
||||||
d.Set("ipv4_address_private", droplet.IPV4Address("private"))
|
d.Set("ipv4_address_private", privateIPv4)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the connection info
|
// Initialize the connection info
|
||||||
d.SetConnInfo(map[string]string{
|
d.SetConnInfo(map[string]string{
|
||||||
"type": "ssh",
|
"type": "ssh",
|
||||||
"host": droplet.IPV4Address("public"),
|
"host": findIPv4AddrByType(droplet, "public"),
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findIPv6AddrByType(d *godo.Droplet, addrType string) string {
|
||||||
|
for _, addr := range d.Networks.V6 {
|
||||||
|
if addr.Type == addrType {
|
||||||
|
return addr.IPAddress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func findIPv4AddrByType(d *godo.Droplet, addrType string) string {
|
||||||
|
for _, addr := range d.Networks.V4 {
|
||||||
|
if addr.Type == addrType {
|
||||||
|
return addr.IPAddress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid droplet id: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if d.HasChange("size") {
|
if d.HasChange("size") {
|
||||||
oldSize, newSize := d.GetChange("size")
|
oldSize, newSize := d.GetChange("size")
|
||||||
|
|
||||||
err := client.PowerOff(d.Id())
|
_, _, err = client.DropletActions.PowerOff(id)
|
||||||
|
|
||||||
if err != nil && !strings.Contains(err.Error(), "Droplet is already powered off") {
|
if err != nil && !strings.Contains(err.Error(), "Droplet is already powered off") {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
"Error powering off droplet (%s): %s", d.Id(), err)
|
"Error powering off droplet (%s): %s", d.Id(), err)
|
||||||
|
@ -229,7 +266,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resize the droplet
|
// Resize the droplet
|
||||||
err = client.Resize(d.Id(), newSize.(string))
|
_, _, err = client.DropletActions.Resize(id, newSize.(string), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
newErr := powerOnAndWait(d, meta)
|
newErr := powerOnAndWait(d, meta)
|
||||||
if newErr != nil {
|
if newErr != nil {
|
||||||
|
@ -254,7 +291,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{})
|
||||||
"Error waiting for resize droplet (%s) to finish: %s", d.Id(), err)
|
"Error waiting for resize droplet (%s) to finish: %s", d.Id(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = client.PowerOn(d.Id())
|
_, _, err = client.DropletActions.PowerOn(id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
|
@ -272,7 +309,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{})
|
||||||
oldName, newName := d.GetChange("name")
|
oldName, newName := d.GetChange("name")
|
||||||
|
|
||||||
// Rename the droplet
|
// Rename the droplet
|
||||||
err := client.Rename(d.Id(), newName.(string))
|
_, _, err = client.DropletActions.Rename(id, newName.(string))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
|
@ -292,7 +329,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{})
|
||||||
// As there is no way to disable private networking,
|
// As there is no way to disable private networking,
|
||||||
// we only check if it needs to be enabled
|
// we only check if it needs to be enabled
|
||||||
if d.HasChange("private_networking") && d.Get("private_networking").(bool) {
|
if d.HasChange("private_networking") && d.Get("private_networking").(bool) {
|
||||||
err := client.EnablePrivateNetworking(d.Id())
|
_, _, err = client.DropletActions.EnablePrivateNetworking(id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
|
@ -309,7 +346,7 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{})
|
||||||
|
|
||||||
// As there is no way to disable IPv6, we only check if it needs to be enabled
|
// As there is no way to disable IPv6, we only check if it needs to be enabled
|
||||||
if d.HasChange("ipv6") && d.Get("ipv6").(bool) {
|
if d.HasChange("ipv6") && d.Get("ipv6").(bool) {
|
||||||
err := client.EnableIPV6s(d.Id())
|
_, _, err = client.DropletActions.EnableIPv6(id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(
|
return fmt.Errorf(
|
||||||
|
@ -330,9 +367,14 @@ func resourceDigitalOceanDropletUpdate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanDropletDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanDropletDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
_, err := WaitForDropletAttribute(
|
id, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid droplet id: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = WaitForDropletAttribute(
|
||||||
d, "false", []string{"", "true"}, "locked", meta)
|
d, "false", []string{"", "true"}, "locked", meta)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -343,7 +385,7 @@ func resourceDigitalOceanDropletDelete(d *schema.ResourceData, meta interface{})
|
||||||
log.Printf("[INFO] Deleting droplet: %s", d.Id())
|
log.Printf("[INFO] Deleting droplet: %s", d.Id())
|
||||||
|
|
||||||
// Destroy the droplet
|
// Destroy the droplet
|
||||||
err = client.DestroyDroplet(d.Id())
|
_, err = client.Droplets.Delete(id)
|
||||||
|
|
||||||
// Handle remotely destroyed droplets
|
// Handle remotely destroyed droplets
|
||||||
if err != nil && strings.Contains(err.Error(), "404 Not Found") {
|
if err != nil && strings.Contains(err.Error(), "404 Not Found") {
|
||||||
|
@ -386,9 +428,14 @@ func WaitForDropletAttribute(
|
||||||
// cleaner and more efficient
|
// cleaner and more efficient
|
||||||
func newDropletStateRefreshFunc(
|
func newDropletStateRefreshFunc(
|
||||||
d *schema.ResourceData, attribute string, meta interface{}) resource.StateRefreshFunc {
|
d *schema.ResourceData, attribute string, meta interface{}) resource.StateRefreshFunc {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
return func() (interface{}, string, error) {
|
return func() (interface{}, string, error) {
|
||||||
err := resourceDigitalOceanDropletRead(d, meta)
|
id, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = resourceDigitalOceanDropletRead(d, meta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
@ -404,7 +451,7 @@ func newDropletStateRefreshFunc(
|
||||||
// See if we can access our attribute
|
// See if we can access our attribute
|
||||||
if attr, ok := d.GetOk(attribute); ok {
|
if attr, ok := d.GetOk(attribute); ok {
|
||||||
// Retrieve the droplet properties
|
// Retrieve the droplet properties
|
||||||
droplet, err := client.RetrieveDroplet(d.Id())
|
droplet, _, err := client.Droplets.Get(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("Error retrieving droplet: %s", err)
|
return nil, "", fmt.Errorf("Error retrieving droplet: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -418,8 +465,13 @@ func newDropletStateRefreshFunc(
|
||||||
|
|
||||||
// Powers on the droplet and waits for it to be active
|
// Powers on the droplet and waits for it to be active
|
||||||
func powerOnAndWait(d *schema.ResourceData, meta interface{}) error {
|
func powerOnAndWait(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
id, err := strconv.Atoi(d.Id())
|
||||||
err := client.PowerOn(d.Id())
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid droplet id: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := meta.(*godo.Client)
|
||||||
|
_, _, err = client.DropletActions.PowerOn(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,16 +2,17 @@ package digitalocean
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/digitalocean/godo"
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/pearkes/digitalocean"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccDigitalOceanDroplet_Basic(t *testing.T) {
|
func TestAccDigitalOceanDroplet_Basic(t *testing.T) {
|
||||||
var droplet digitalocean.Droplet
|
var droplet godo.Droplet
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -40,7 +41,7 @@ func TestAccDigitalOceanDroplet_Basic(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccDigitalOceanDroplet_Update(t *testing.T) {
|
func TestAccDigitalOceanDroplet_Update(t *testing.T) {
|
||||||
var droplet digitalocean.Droplet
|
var droplet godo.Droplet
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -71,7 +72,7 @@ func TestAccDigitalOceanDroplet_Update(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccDigitalOceanDroplet_PrivateNetworkingIpv6(t *testing.T) {
|
func TestAccDigitalOceanDroplet_PrivateNetworkingIpv6(t *testing.T) {
|
||||||
var droplet digitalocean.Droplet
|
var droplet godo.Droplet
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -94,15 +95,20 @@ func TestAccDigitalOceanDroplet_PrivateNetworkingIpv6(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error {
|
func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error {
|
||||||
client := testAccProvider.Meta().(*digitalocean.Client)
|
client := testAccProvider.Meta().(*godo.Client)
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
for _, rs := range s.RootModule().Resources {
|
||||||
if rs.Type != "digitalocean_droplet" {
|
if rs.Type != "digitalocean_droplet" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(rs.Primary.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find the Droplet
|
// Try to find the Droplet
|
||||||
_, err := client.RetrieveDroplet(rs.Primary.ID)
|
_, _, err = client.Droplets.Get(id)
|
||||||
|
|
||||||
// Wait
|
// Wait
|
||||||
|
|
||||||
|
@ -116,19 +122,19 @@ func testAccCheckDigitalOceanDropletDestroy(s *terraform.State) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanDropletAttributes(droplet *digitalocean.Droplet) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanDropletAttributes(droplet *godo.Droplet) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if droplet.ImageSlug() != "centos-5-8-x32" {
|
if droplet.Image.Slug != "centos-5-8-x32" {
|
||||||
return fmt.Errorf("Bad image_slug: %s", droplet.ImageSlug())
|
return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
if droplet.SizeSlug != "512mb" {
|
if droplet.Size.Slug != "512mb" {
|
||||||
return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug)
|
return fmt.Errorf("Bad size_slug: %s", droplet.Size.Slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
if droplet.RegionSlug() != "nyc3" {
|
if droplet.Region.Slug != "nyc3" {
|
||||||
return fmt.Errorf("Bad region_slug: %s", droplet.RegionSlug())
|
return fmt.Errorf("Bad region_slug: %s", droplet.Region.Slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
if droplet.Name != "foo" {
|
if droplet.Name != "foo" {
|
||||||
|
@ -138,10 +144,10 @@ func testAccCheckDigitalOceanDropletAttributes(droplet *digitalocean.Droplet) re
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanDropletRenamedAndResized(droplet *digitalocean.Droplet) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanDropletRenamedAndResized(droplet *godo.Droplet) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if droplet.SizeSlug != "1gb" {
|
if droplet.Size.Slug != "1gb" {
|
||||||
return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug)
|
return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,50 +159,46 @@ func testAccCheckDigitalOceanDropletRenamedAndResized(droplet *digitalocean.Drop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(droplet *digitalocean.Droplet) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanDropletAttributes_PrivateNetworkingIpv6(droplet *godo.Droplet) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if droplet.ImageSlug() != "centos-5-8-x32" {
|
if droplet.Image.Slug != "centos-5-8-x32" {
|
||||||
return fmt.Errorf("Bad image_slug: %s", droplet.ImageSlug())
|
return fmt.Errorf("Bad image_slug: %s", droplet.Image.Slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
if droplet.SizeSlug != "1gb" {
|
if droplet.Size.Slug != "1gb" {
|
||||||
return fmt.Errorf("Bad size_slug: %s", droplet.SizeSlug)
|
return fmt.Errorf("Bad size_slug: %s", droplet.Size.Slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
if droplet.RegionSlug() != "sgp1" {
|
if droplet.Region.Slug != "sgp1" {
|
||||||
return fmt.Errorf("Bad region_slug: %s", droplet.RegionSlug())
|
return fmt.Errorf("Bad region_slug: %s", droplet.Region.Slug)
|
||||||
}
|
}
|
||||||
|
|
||||||
if droplet.Name != "baz" {
|
if droplet.Name != "baz" {
|
||||||
return fmt.Errorf("Bad name: %s", droplet.Name)
|
return fmt.Errorf("Bad name: %s", droplet.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if droplet.IPV4Address("private") == "" {
|
if findIPv4AddrByType(droplet, "private") == "" {
|
||||||
return fmt.Errorf("No ipv4 private: %s", droplet.IPV4Address("private"))
|
return fmt.Errorf("No ipv4 private: %s", findIPv4AddrByType(droplet, "private"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// if droplet.IPV6Address("private") == "" {
|
// if droplet.IPV6Address("private") == "" {
|
||||||
// return fmt.Errorf("No ipv6 private: %s", droplet.IPV6Address("private"))
|
// return fmt.Errorf("No ipv6 private: %s", droplet.IPV6Address("private"))
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if droplet.NetworkingType() != "private" {
|
if findIPv4AddrByType(droplet, "public") == "" {
|
||||||
return fmt.Errorf("Bad networking type: %s", droplet.NetworkingType())
|
return fmt.Errorf("No ipv4 public: %s", findIPv4AddrByType(droplet, "public"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if droplet.IPV4Address("public") == "" {
|
if findIPv6AddrByType(droplet, "public") == "" {
|
||||||
return fmt.Errorf("No ipv4 public: %s", droplet.IPV4Address("public"))
|
return fmt.Errorf("No ipv6 public: %s", findIPv6AddrByType(droplet, "public"))
|
||||||
}
|
|
||||||
|
|
||||||
if droplet.IPV6Address("public") == "" {
|
|
||||||
return fmt.Errorf("No ipv6 public: %s", droplet.IPV6Address("public"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanDropletExists(n string, droplet *digitalocean.Droplet) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanDropletExists(n string, droplet *godo.Droplet) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
rs, ok := s.RootModule().Resources[n]
|
rs, ok := s.RootModule().Resources[n]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -207,19 +209,25 @@ func testAccCheckDigitalOceanDropletExists(n string, droplet *digitalocean.Dropl
|
||||||
return fmt.Errorf("No Droplet ID is set")
|
return fmt.Errorf("No Droplet ID is set")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*digitalocean.Client)
|
client := testAccProvider.Meta().(*godo.Client)
|
||||||
|
|
||||||
retrieveDroplet, err := client.RetrieveDroplet(rs.Primary.ID)
|
id, err := strconv.Atoi(rs.Primary.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find the Droplet
|
||||||
|
retrieveDroplet, _, err := client.Droplets.Get(id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if retrieveDroplet.StringId() != rs.Primary.ID {
|
if strconv.Itoa(retrieveDroplet.ID) != rs.Primary.ID {
|
||||||
return fmt.Errorf("Droplet not found")
|
return fmt.Errorf("Droplet not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
*droplet = retrieveDroplet
|
*droplet = *retrieveDroplet
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -230,7 +238,7 @@ func testAccCheckDigitalOceanDropletExists(n string, droplet *digitalocean.Dropl
|
||||||
// other test already
|
// other test already
|
||||||
//
|
//
|
||||||
//func Test_new_droplet_state_refresh_func(t *testing.T) {
|
//func Test_new_droplet_state_refresh_func(t *testing.T) {
|
||||||
// droplet := digitalocean.Droplet{
|
// droplet := godo.Droplet{
|
||||||
// Name: "foobar",
|
// Name: "foobar",
|
||||||
// }
|
// }
|
||||||
// resourceMap, _ := resource_digitalocean_droplet_update_state(
|
// resourceMap, _ := resource_digitalocean_droplet_update_state(
|
||||||
|
|
|
@ -3,10 +3,11 @@ package digitalocean
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/digitalocean/godo"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/pearkes/digitalocean"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func resourceDigitalOceanRecord() *schema.Resource {
|
func resourceDigitalOceanRecord() *schema.Resource {
|
||||||
|
@ -66,34 +67,55 @@ func resourceDigitalOceanRecord() *schema.Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanRecordCreate(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanRecordCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
newRecord := digitalocean.CreateRecord{
|
newRecord := godo.DomainRecordEditRequest{
|
||||||
Type: d.Get("type").(string),
|
Type: d.Get("type").(string),
|
||||||
Name: d.Get("name").(string),
|
Name: d.Get("name").(string),
|
||||||
Data: d.Get("value").(string),
|
Data: d.Get("value").(string),
|
||||||
Priority: d.Get("priority").(string),
|
}
|
||||||
Port: d.Get("port").(string),
|
|
||||||
Weight: d.Get("weight").(string),
|
var err error
|
||||||
|
if priority := d.Get("priority").(string); priority != "" {
|
||||||
|
newRecord.Priority, err = strconv.Atoi(priority)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Failed to parse priority as an integer: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if port := d.Get("port").(string); port != "" {
|
||||||
|
newRecord.Port, err = strconv.Atoi(port)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Failed to parse port as an integer: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if weight := d.Get("weight").(string); weight != "" {
|
||||||
|
newRecord.Weight, err = strconv.Atoi(weight)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Failed to parse weight as an integer: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] record create configuration: %#v", newRecord)
|
log.Printf("[DEBUG] record create configuration: %#v", newRecord)
|
||||||
recId, err := client.CreateRecord(d.Get("domain").(string), &newRecord)
|
rec, _, err := client.Domains.CreateRecord(d.Get("domain").(string), &newRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create record: %s", err)
|
return fmt.Errorf("Failed to create record: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(recId)
|
d.SetId(strconv.Itoa(rec.ID))
|
||||||
log.Printf("[INFO] Record ID: %s", d.Id())
|
log.Printf("[INFO] Record ID: %s", d.Id())
|
||||||
|
|
||||||
return resourceDigitalOceanRecordRead(d, meta)
|
return resourceDigitalOceanRecordRead(d, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanRecordRead(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanRecordRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
domain := d.Get("domain").(string)
|
domain := d.Get("domain").(string)
|
||||||
|
id, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid record ID: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
rec, err := client.RetrieveRecord(domain, d.Id())
|
rec, _, err := client.Domains.Record(domain, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If the record is somehow already destroyed, mark as
|
// If the record is somehow already destroyed, mark as
|
||||||
// successfully gone
|
// successfully gone
|
||||||
|
@ -120,23 +142,29 @@ func resourceDigitalOceanRecordRead(d *schema.ResourceData, meta interface{}) er
|
||||||
d.Set("name", rec.Name)
|
d.Set("name", rec.Name)
|
||||||
d.Set("type", rec.Type)
|
d.Set("type", rec.Type)
|
||||||
d.Set("value", rec.Data)
|
d.Set("value", rec.Data)
|
||||||
d.Set("weight", rec.StringWeight())
|
d.Set("weight", strconv.Itoa(rec.Weight))
|
||||||
d.Set("priority", rec.StringPriority())
|
d.Set("priority", strconv.Itoa(rec.Priority))
|
||||||
d.Set("port", rec.StringPort())
|
d.Set("port", strconv.Itoa(rec.Port))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanRecordUpdate(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanRecordUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
var updateRecord digitalocean.UpdateRecord
|
domain := d.Get("domain").(string)
|
||||||
if v, ok := d.GetOk("name"); ok {
|
id, err := strconv.Atoi(d.Id())
|
||||||
updateRecord.Name = v.(string)
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid record ID: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] record update configuration: %#v", updateRecord)
|
var editRecord godo.DomainRecordEditRequest
|
||||||
err := client.UpdateRecord(d.Get("domain").(string), d.Id(), &updateRecord)
|
if v, ok := d.GetOk("name"); ok {
|
||||||
|
editRecord.Name = v.(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[DEBUG] record update configuration: %#v", editRecord)
|
||||||
|
_, _, err = client.Domains.EditRecord(domain, id, &editRecord)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to update record: %s", err)
|
return fmt.Errorf("Failed to update record: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -145,11 +173,17 @@ func resourceDigitalOceanRecordUpdate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanRecordDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanRecordDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
log.Printf(
|
domain := d.Get("domain").(string)
|
||||||
"[INFO] Deleting record: %s, %s", d.Get("domain").(string), d.Id())
|
id, err := strconv.Atoi(d.Id())
|
||||||
err := client.DestroyRecord(d.Get("domain").(string), d.Id())
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid record ID: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[INFO] Deleting record: %s, %d", domain, id)
|
||||||
|
|
||||||
|
_, err = client.Domains.DeleteRecord(domain, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If the record is somehow already destroyed, mark as
|
// If the record is somehow already destroyed, mark as
|
||||||
// successfully gone
|
// successfully gone
|
||||||
|
|
|
@ -2,15 +2,16 @@ package digitalocean
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/digitalocean/godo"
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/pearkes/digitalocean"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccDigitalOceanRecord_Basic(t *testing.T) {
|
func TestAccDigitalOceanRecord_Basic(t *testing.T) {
|
||||||
var record digitalocean.Record
|
var record godo.DomainRecord
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -35,7 +36,7 @@ func TestAccDigitalOceanRecord_Basic(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccDigitalOceanRecord_Updated(t *testing.T) {
|
func TestAccDigitalOceanRecord_Updated(t *testing.T) {
|
||||||
var record digitalocean.Record
|
var record godo.DomainRecord
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -77,7 +78,7 @@ func TestAccDigitalOceanRecord_Updated(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccDigitalOceanRecord_HostnameValue(t *testing.T) {
|
func TestAccDigitalOceanRecord_HostnameValue(t *testing.T) {
|
||||||
var record digitalocean.Record
|
var record godo.DomainRecord
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -104,7 +105,7 @@ func TestAccDigitalOceanRecord_HostnameValue(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccDigitalOceanRecord_RelativeHostnameValue(t *testing.T) {
|
func TestAccDigitalOceanRecord_RelativeHostnameValue(t *testing.T) {
|
||||||
var record digitalocean.Record
|
var record godo.DomainRecord
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -131,7 +132,7 @@ func TestAccDigitalOceanRecord_RelativeHostnameValue(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAccDigitalOceanRecord_ExternalHostnameValue(t *testing.T) {
|
func TestAccDigitalOceanRecord_ExternalHostnameValue(t *testing.T) {
|
||||||
var record digitalocean.Record
|
var record godo.DomainRecord
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -158,14 +159,19 @@ func TestAccDigitalOceanRecord_ExternalHostnameValue(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanRecordDestroy(s *terraform.State) error {
|
func testAccCheckDigitalOceanRecordDestroy(s *terraform.State) error {
|
||||||
client := testAccProvider.Meta().(*digitalocean.Client)
|
client := testAccProvider.Meta().(*godo.Client)
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
for _, rs := range s.RootModule().Resources {
|
||||||
if rs.Type != "digitalocean_record" {
|
if rs.Type != "digitalocean_record" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
domain := rs.Primary.Attributes["domain"]
|
||||||
|
id, err := strconv.Atoi(rs.Primary.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
_, err := client.RetrieveRecord(rs.Primary.Attributes["domain"], rs.Primary.ID)
|
_, _, err = client.Domains.Record(domain, id)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return fmt.Errorf("Record still exists")
|
return fmt.Errorf("Record still exists")
|
||||||
|
@ -175,7 +181,7 @@ func testAccCheckDigitalOceanRecordDestroy(s *terraform.State) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanRecordAttributes(record *digitalocean.Record) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanRecordAttributes(record *godo.DomainRecord) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if record.Data != "192.168.0.10" {
|
if record.Data != "192.168.0.10" {
|
||||||
|
@ -186,7 +192,7 @@ func testAccCheckDigitalOceanRecordAttributes(record *digitalocean.Record) resou
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanRecordAttributesUpdated(record *digitalocean.Record) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanRecordAttributesUpdated(record *godo.DomainRecord) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if record.Data != "192.168.0.11" {
|
if record.Data != "192.168.0.11" {
|
||||||
|
@ -197,7 +203,7 @@ func testAccCheckDigitalOceanRecordAttributesUpdated(record *digitalocean.Record
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanRecordExists(n string, record *digitalocean.Record) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanRecordExists(n string, record *godo.DomainRecord) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
rs, ok := s.RootModule().Resources[n]
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
|
||||||
|
@ -209,25 +215,31 @@ func testAccCheckDigitalOceanRecordExists(n string, record *digitalocean.Record)
|
||||||
return fmt.Errorf("No Record ID is set")
|
return fmt.Errorf("No Record ID is set")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*digitalocean.Client)
|
client := testAccProvider.Meta().(*godo.Client)
|
||||||
|
|
||||||
foundRecord, err := client.RetrieveRecord(rs.Primary.Attributes["domain"], rs.Primary.ID)
|
domain := rs.Primary.Attributes["domain"]
|
||||||
|
id, err := strconv.Atoi(rs.Primary.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
foundRecord, _, err := client.Domains.Record(domain, id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if foundRecord.StringId() != rs.Primary.ID {
|
if strconv.Itoa(foundRecord.ID) != rs.Primary.ID {
|
||||||
return fmt.Errorf("Record not found")
|
return fmt.Errorf("Record not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
*record = foundRecord
|
*record = *foundRecord
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanRecordAttributesHostname(data string, record *digitalocean.Record) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanRecordAttributesHostname(data string, record *godo.DomainRecord) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if record.Data != data {
|
if record.Data != data {
|
||||||
|
|
|
@ -3,10 +3,11 @@ package digitalocean
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/digitalocean/godo"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/pearkes/digitalocean"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func resourceDigitalOceanSSHKey() *schema.Resource {
|
func resourceDigitalOceanSSHKey() *schema.Resource {
|
||||||
|
@ -42,30 +43,35 @@ func resourceDigitalOceanSSHKey() *schema.Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanSSHKeyCreate(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanSSHKeyCreate(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
// Build up our creation options
|
// Build up our creation options
|
||||||
opts := &digitalocean.CreateSSHKey{
|
opts := &godo.KeyCreateRequest{
|
||||||
Name: d.Get("name").(string),
|
Name: d.Get("name").(string),
|
||||||
PublicKey: d.Get("public_key").(string),
|
PublicKey: d.Get("public_key").(string),
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] SSH Key create configuration: %#v", opts)
|
log.Printf("[DEBUG] SSH Key create configuration: %#v", opts)
|
||||||
id, err := client.CreateSSHKey(opts)
|
key, _, err := client.Keys.Create(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error creating SSH Key: %s", err)
|
return fmt.Errorf("Error creating SSH Key: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(id)
|
d.SetId(strconv.Itoa(key.ID))
|
||||||
log.Printf("[INFO] SSH Key: %s", id)
|
log.Printf("[INFO] SSH Key: %d", key.ID)
|
||||||
|
|
||||||
return resourceDigitalOceanSSHKeyRead(d, meta)
|
return resourceDigitalOceanSSHKeyRead(d, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanSSHKeyRead(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanSSHKeyRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
key, err := client.RetrieveSSHKey(d.Id())
|
id, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid SSH key id: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
key, _, err := client.Keys.GetByID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If the key is somehow already destroyed, mark as
|
// If the key is somehow already destroyed, mark as
|
||||||
// successfully gone
|
// successfully gone
|
||||||
|
@ -84,7 +90,12 @@ func resourceDigitalOceanSSHKeyRead(d *schema.ResourceData, meta interface{}) er
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanSSHKeyUpdate(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanSSHKeyUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(d.Id())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid SSH key id: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
var newName string
|
var newName string
|
||||||
if v, ok := d.GetOk("name"); ok {
|
if v, ok := d.GetOk("name"); ok {
|
||||||
|
@ -92,7 +103,10 @@ func resourceDigitalOceanSSHKeyUpdate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] SSH key update name: %#v", newName)
|
log.Printf("[DEBUG] SSH key update name: %#v", newName)
|
||||||
err := client.RenameSSHKey(d.Id(), newName)
|
opts := &godo.KeyUpdateRequest{
|
||||||
|
Name: newName,
|
||||||
|
}
|
||||||
|
_, _, err = client.Keys.UpdateByID(id, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to update SSH key: %s", err)
|
return fmt.Errorf("Failed to update SSH key: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -101,10 +115,15 @@ func resourceDigitalOceanSSHKeyUpdate(d *schema.ResourceData, meta interface{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceDigitalOceanSSHKeyDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourceDigitalOceanSSHKeyDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*digitalocean.Client)
|
client := meta.(*godo.Client)
|
||||||
|
|
||||||
log.Printf("[INFO] Deleting SSH key: %s", d.Id())
|
id, err := strconv.Atoi(d.Id())
|
||||||
err := client.DestroySSHKey(d.Id())
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid SSH key id: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[INFO] Deleting SSH key: %d", id)
|
||||||
|
_, err = client.Keys.DeleteByID(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error deleting SSH key: %s", err)
|
return fmt.Errorf("Error deleting SSH key: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,13 +6,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/digitalocean/godo"
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/pearkes/digitalocean"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccDigitalOceanSSHKey_Basic(t *testing.T) {
|
func TestAccDigitalOceanSSHKey_Basic(t *testing.T) {
|
||||||
var key digitalocean.SSHKey
|
var key godo.Key
|
||||||
|
|
||||||
resource.Test(t, resource.TestCase{
|
resource.Test(t, resource.TestCase{
|
||||||
PreCheck: func() { testAccPreCheck(t) },
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
@ -35,15 +35,20 @@ func TestAccDigitalOceanSSHKey_Basic(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanSSHKeyDestroy(s *terraform.State) error {
|
func testAccCheckDigitalOceanSSHKeyDestroy(s *terraform.State) error {
|
||||||
client := testAccProvider.Meta().(*digitalocean.Client)
|
client := testAccProvider.Meta().(*godo.Client)
|
||||||
|
|
||||||
for _, rs := range s.RootModule().Resources {
|
for _, rs := range s.RootModule().Resources {
|
||||||
if rs.Type != "digitalocean_ssh_key" {
|
if rs.Type != "digitalocean_ssh_key" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(rs.Primary.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find the key
|
// Try to find the key
|
||||||
_, err := client.RetrieveSSHKey(rs.Primary.ID)
|
_, _, err = client.Keys.GetByID(id)
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Errorf("SSH key still exists")
|
fmt.Errorf("SSH key still exists")
|
||||||
|
@ -53,7 +58,7 @@ func testAccCheckDigitalOceanSSHKeyDestroy(s *terraform.State) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanSSHKeyAttributes(key *digitalocean.SSHKey) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanSSHKeyAttributes(key *godo.Key) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if key.Name != "foobar" {
|
if key.Name != "foobar" {
|
||||||
|
@ -64,7 +69,7 @@ func testAccCheckDigitalOceanSSHKeyAttributes(key *digitalocean.SSHKey) resource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testAccCheckDigitalOceanSSHKeyExists(n string, key *digitalocean.SSHKey) resource.TestCheckFunc {
|
func testAccCheckDigitalOceanSSHKeyExists(n string, key *godo.Key) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
rs, ok := s.RootModule().Resources[n]
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
|
||||||
|
@ -76,19 +81,25 @@ func testAccCheckDigitalOceanSSHKeyExists(n string, key *digitalocean.SSHKey) re
|
||||||
return fmt.Errorf("No Record ID is set")
|
return fmt.Errorf("No Record ID is set")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := testAccProvider.Meta().(*digitalocean.Client)
|
client := testAccProvider.Meta().(*godo.Client)
|
||||||
|
|
||||||
foundKey, err := client.RetrieveSSHKey(rs.Primary.ID)
|
id, err := strconv.Atoi(rs.Primary.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find the key
|
||||||
|
foundKey, _, err := client.Keys.GetByID(id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if strconv.Itoa(int(foundKey.Id)) != rs.Primary.ID {
|
if strconv.Itoa(foundKey.ID) != rs.Primary.ID {
|
||||||
return fmt.Errorf("Record not found")
|
return fmt.Errorf("Record not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
*key = foundKey
|
*key = *foundKey
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue