Merge pull request #4676 from betawaffle/packet-failure-handling
Handle external state changes for Packet resources gracefully.
This commit is contained in:
commit
6bc93ba6e7
|
@ -13,7 +13,7 @@ type Config struct {
|
||||||
AuthToken string
|
AuthToken string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client() returns a new client for accessing packet.
|
// Client() returns a new client for accessing Packet's API.
|
||||||
func (c *Config) Client() *packngo.Client {
|
func (c *Config) Client() *packngo.Client {
|
||||||
return packngo.NewClient(consumerToken, c.AuthToken, cleanhttp.DefaultClient())
|
return packngo.NewClient(consumerToken, c.AuthToken, cleanhttp.DefaultClient())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package packet
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/packethost/packngo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func friendlyError(err error) error {
|
||||||
|
if e, ok := err.(*packngo.ErrorResponse); ok {
|
||||||
|
return &ErrorResponse{
|
||||||
|
StatusCode: e.Response.StatusCode,
|
||||||
|
Errors: Errors(e.Errors),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func isForbidden(err error) bool {
|
||||||
|
if r, ok := err.(*ErrorResponse); ok {
|
||||||
|
return r.StatusCode == http.StatusForbidden
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNotFound(err error) bool {
|
||||||
|
if r, ok := err.(*ErrorResponse); ok {
|
||||||
|
return r.StatusCode == http.StatusNotFound
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
type Errors []string
|
||||||
|
|
||||||
|
func (e Errors) Error() string {
|
||||||
|
return strings.Join(e, "; ")
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorResponse struct {
|
||||||
|
StatusCode int
|
||||||
|
Errors
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Provider returns a schema.Provider for Packet.
|
// Provider returns a schema.Provider for managing Packet infrastructure.
|
||||||
func Provider() terraform.ResourceProvider {
|
func Provider() terraform.ResourceProvider {
|
||||||
return &schema.Provider{
|
return &schema.Provider{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
|
@ -31,6 +31,5 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||||
config := Config{
|
config := Config{
|
||||||
AuthToken: d.Get("auth_token").(string),
|
AuthToken: d.Get("auth_token").(string),
|
||||||
}
|
}
|
||||||
|
|
||||||
return config.Client(), nil
|
return config.Client(), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package packet
|
package packet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
|
@ -146,22 +146,23 @@ func resourcePacketDeviceCreate(d *schema.ResourceData, meta interface{}) error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] Device create configuration: %#v", createRequest)
|
|
||||||
|
|
||||||
newDevice, _, err := client.Devices.Create(createRequest)
|
newDevice, _, err := client.Devices.Create(createRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error creating device: %s", err)
|
return friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the device id
|
|
||||||
d.SetId(newDevice.ID)
|
d.SetId(newDevice.ID)
|
||||||
|
|
||||||
log.Printf("[INFO] Device ID: %s", d.Id())
|
// Wait for the device so we can get the networking attributes that show up after a while.
|
||||||
|
_, err = waitForDeviceAttribute(d, "active", []string{"queued", "provisioning"}, "state", meta)
|
||||||
_, err = WaitForDeviceAttribute(d, "active", []string{"queued", "provisioning"}, "state", meta)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf(
|
if isForbidden(err) {
|
||||||
"Error waiting for device (%s) to become ready: %s", d.Id(), err)
|
// If the device doesn't get to the active state, we can't recover it from here.
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return errors.New("provisioning time limit exceeded; the Packet team will investigate")
|
||||||
|
}
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return resourcePacketDeviceRead(d, meta)
|
return resourcePacketDeviceRead(d, meta)
|
||||||
|
@ -170,10 +171,17 @@ func resourcePacketDeviceCreate(d *schema.ResourceData, meta interface{}) error
|
||||||
func resourcePacketDeviceRead(d *schema.ResourceData, meta interface{}) error {
|
func resourcePacketDeviceRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*packngo.Client)
|
client := meta.(*packngo.Client)
|
||||||
|
|
||||||
// Retrieve the device properties for updating the state
|
|
||||||
device, _, err := client.Devices.Get(d.Id())
|
device, _, err := client.Devices.Get(d.Id())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error retrieving device: %s", err)
|
err = friendlyError(err)
|
||||||
|
|
||||||
|
// If the device somehow already destroyed, mark as succesfully gone.
|
||||||
|
if isNotFound(err) {
|
||||||
|
d.SetId("")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Set("name", device.Hostname)
|
d.Set("name", device.Hostname)
|
||||||
|
@ -186,35 +194,36 @@ func resourcePacketDeviceRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
d.Set("created", device.Created)
|
d.Set("created", device.Created)
|
||||||
d.Set("updated", device.Updated)
|
d.Set("updated", device.Updated)
|
||||||
|
|
||||||
tags := make([]string, 0)
|
tags := make([]string, 0, len(device.Tags))
|
||||||
for _, tag := range device.Tags {
|
for _, tag := range device.Tags {
|
||||||
tags = append(tags, tag)
|
tags = append(tags, tag)
|
||||||
}
|
}
|
||||||
d.Set("tags", tags)
|
d.Set("tags", tags)
|
||||||
|
|
||||||
provisionerAddress := ""
|
var (
|
||||||
|
host string
|
||||||
networks := make([]map[string]interface{}, 0, 1)
|
networks = make([]map[string]interface{}, 0, 1)
|
||||||
|
)
|
||||||
for _, ip := range device.Network {
|
for _, ip := range device.Network {
|
||||||
network := make(map[string]interface{})
|
network := map[string]interface{}{
|
||||||
network["address"] = ip.Address
|
"address": ip.Address,
|
||||||
network["gateway"] = ip.Gateway
|
"gateway": ip.Gateway,
|
||||||
network["family"] = ip.Family
|
"family": ip.Family,
|
||||||
network["cidr"] = ip.Cidr
|
"cidr": ip.Cidr,
|
||||||
network["public"] = ip.Public
|
"public": ip.Public,
|
||||||
|
}
|
||||||
networks = append(networks, network)
|
networks = append(networks, network)
|
||||||
|
|
||||||
if ip.Family == 4 && ip.Public == true {
|
if ip.Family == 4 && ip.Public == true {
|
||||||
provisionerAddress = ip.Address
|
host = ip.Address
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.Set("network", networks)
|
d.Set("network", networks)
|
||||||
|
|
||||||
log.Printf("[DEBUG] Provisioner Address set to %v", provisionerAddress)
|
if host != "" {
|
||||||
|
|
||||||
if provisionerAddress != "" {
|
|
||||||
d.SetConnInfo(map[string]string{
|
d.SetConnInfo(map[string]string{
|
||||||
"type": "ssh",
|
"type": "ssh",
|
||||||
"host": provisionerAddress,
|
"host": host,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,19 +233,15 @@ func resourcePacketDeviceRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
func resourcePacketDeviceUpdate(d *schema.ResourceData, meta interface{}) error {
|
func resourcePacketDeviceUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*packngo.Client)
|
client := meta.(*packngo.Client)
|
||||||
|
|
||||||
if d.HasChange("locked") && d.Get("locked").(bool) {
|
if d.HasChange("locked") {
|
||||||
_, err := client.Devices.Lock(d.Id())
|
var action func(string) (*packngo.Response, error)
|
||||||
|
if d.Get("locked").(bool) {
|
||||||
if err != nil {
|
action = client.Devices.Lock
|
||||||
return fmt.Errorf(
|
} else {
|
||||||
"Error locking device (%s): %s", d.Id(), err)
|
action = client.Devices.Unlock
|
||||||
}
|
}
|
||||||
} else if d.HasChange("locked") {
|
if _, err := action(d.Id()); err != nil {
|
||||||
_, err := client.Devices.Unlock(d.Id())
|
return friendlyError(err)
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf(
|
|
||||||
"Error unlocking device (%s): %s", d.Id(), err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,22 +251,14 @@ func resourcePacketDeviceUpdate(d *schema.ResourceData, meta interface{}) error
|
||||||
func resourcePacketDeviceDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourcePacketDeviceDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*packngo.Client)
|
client := meta.(*packngo.Client)
|
||||||
|
|
||||||
log.Printf("[INFO] Deleting device: %s", d.Id())
|
|
||||||
if _, err := client.Devices.Delete(d.Id()); err != nil {
|
if _, err := client.Devices.Delete(d.Id()); err != nil {
|
||||||
return fmt.Errorf("Error deleting device: %s", err)
|
return friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func WaitForDeviceAttribute(
|
func waitForDeviceAttribute(d *schema.ResourceData, target string, pending []string, attribute string, meta interface{}) (interface{}, error) {
|
||||||
d *schema.ResourceData, target string, pending []string, attribute string, meta interface{}) (interface{}, error) {
|
|
||||||
// Wait for the device so we can get the networking attributes
|
|
||||||
// that show up after a while
|
|
||||||
log.Printf(
|
|
||||||
"[INFO] Waiting for device (%s) to have %s of %s",
|
|
||||||
d.Id(), attribute, target)
|
|
||||||
|
|
||||||
stateConf := &resource.StateChangeConf{
|
stateConf := &resource.StateChangeConf{
|
||||||
Pending: pending,
|
Pending: pending,
|
||||||
Target: target,
|
Target: target,
|
||||||
|
@ -270,27 +267,22 @@ func WaitForDeviceAttribute(
|
||||||
Delay: 10 * time.Second,
|
Delay: 10 * time.Second,
|
||||||
MinTimeout: 3 * time.Second,
|
MinTimeout: 3 * time.Second,
|
||||||
}
|
}
|
||||||
|
|
||||||
return stateConf.WaitForState()
|
return stateConf.WaitForState()
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDeviceStateRefreshFunc(
|
func newDeviceStateRefreshFunc(d *schema.ResourceData, attribute string, meta interface{}) resource.StateRefreshFunc {
|
||||||
d *schema.ResourceData, attribute string, meta interface{}) resource.StateRefreshFunc {
|
|
||||||
client := meta.(*packngo.Client)
|
client := meta.(*packngo.Client)
|
||||||
|
|
||||||
return func() (interface{}, string, error) {
|
return func() (interface{}, string, error) {
|
||||||
err := resourcePacketDeviceRead(d, meta)
|
if err := resourcePacketDeviceRead(d, meta); err != nil {
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
return nil, "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we can access our attribute
|
|
||||||
if attr, ok := d.GetOk(attribute); ok {
|
if attr, ok := d.GetOk(attribute); ok {
|
||||||
// Retrieve the device properties
|
|
||||||
device, _, err := client.Devices.Get(d.Id())
|
device, _, err := client.Devices.Get(d.Id())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, "", fmt.Errorf("Error retrieving device: %s", err)
|
return nil, "", friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &device, attr.(string), nil
|
return &device, attr.(string), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,19 +290,14 @@ func newDeviceStateRefreshFunc(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Powers on the device and waits for it to be active
|
// powerOnAndWait Powers on the device 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.(*packngo.Client)
|
client := meta.(*packngo.Client)
|
||||||
_, err := client.Devices.PowerOn(d.Id())
|
_, err := client.Devices.PowerOn(d.Id())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for power on
|
_, err = waitForDeviceAttribute(d, "active", []string{"off"}, "state", client)
|
||||||
_, err = WaitForDeviceAttribute(d, "active", []string{"off"}, "state", client)
|
return err
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
package packet
|
package packet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/packethost/packngo"
|
"github.com/packethost/packngo"
|
||||||
)
|
)
|
||||||
|
@ -53,14 +49,12 @@ func resourcePacketProjectCreate(d *schema.ResourceData, meta interface{}) error
|
||||||
PaymentMethod: d.Get("payment_method").(string),
|
PaymentMethod: d.Get("payment_method").(string),
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] Project create configuration: %#v", createRequest)
|
|
||||||
project, _, err := client.Projects.Create(createRequest)
|
project, _, err := client.Projects.Create(createRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error creating Project: %s", err)
|
return friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(project.ID)
|
d.SetId(project.ID)
|
||||||
log.Printf("[INFO] Project created: %s", project.ID)
|
|
||||||
|
|
||||||
return resourcePacketProjectRead(d, meta)
|
return resourcePacketProjectRead(d, meta)
|
||||||
}
|
}
|
||||||
|
@ -70,14 +64,16 @@ func resourcePacketProjectRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
|
||||||
key, _, err := client.Projects.Get(d.Id())
|
key, _, err := client.Projects.Get(d.Id())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If the project somehow already destroyed, mark as
|
err = friendlyError(err)
|
||||||
// succesfully gone
|
|
||||||
if strings.Contains(err.Error(), "404") {
|
// If the project somehow already destroyed, mark as succesfully gone.
|
||||||
|
if isNotFound(err) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("Error retrieving Project: %s", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Set("id", key.ID)
|
d.Set("id", key.ID)
|
||||||
|
@ -100,10 +96,9 @@ func resourcePacketProjectUpdate(d *schema.ResourceData, meta interface{}) error
|
||||||
updateRequest.PaymentMethod = attr.(string)
|
updateRequest.PaymentMethod = attr.(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] Project update: %#v", d.Get("id"))
|
|
||||||
_, _, err := client.Projects.Update(updateRequest)
|
_, _, err := client.Projects.Update(updateRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to update Project: %s", err)
|
return friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resourcePacketProjectRead(d, meta)
|
return resourcePacketProjectRead(d, meta)
|
||||||
|
@ -112,10 +107,9 @@ func resourcePacketProjectUpdate(d *schema.ResourceData, meta interface{}) error
|
||||||
func resourcePacketProjectDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourcePacketProjectDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*packngo.Client)
|
client := meta.(*packngo.Client)
|
||||||
|
|
||||||
log.Printf("[INFO] Deleting Project: %s", d.Id())
|
|
||||||
_, err := client.Projects.Delete(d.Id())
|
_, err := client.Projects.Delete(d.Id())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error deleting SSH key: %s", err)
|
return friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
|
|
|
@ -37,11 +37,8 @@ func testAccCheckPacketProjectDestroy(s *terraform.State) error {
|
||||||
if rs.Type != "packet_project" {
|
if rs.Type != "packet_project" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if _, _, err := client.Projects.Get(rs.Primary.ID); err == nil {
|
||||||
_, _, err := client.Projects.Get(rs.Primary.ID)
|
return fmt.Errorf("Project cstill exists")
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
fmt.Errorf("Project cstill exists")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,11 +47,9 @@ func testAccCheckPacketProjectDestroy(s *terraform.State) error {
|
||||||
|
|
||||||
func testAccCheckPacketProjectAttributes(project *packngo.Project) resource.TestCheckFunc {
|
func testAccCheckPacketProjectAttributes(project *packngo.Project) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if project.Name != "foobar" {
|
if project.Name != "foobar" {
|
||||||
return fmt.Errorf("Bad name: %s", project.Name)
|
return fmt.Errorf("Bad name: %s", project.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,11 +57,9 @@ func testAccCheckPacketProjectAttributes(project *packngo.Project) resource.Test
|
||||||
func testAccCheckPacketProjectExists(n string, project *packngo.Project) resource.TestCheckFunc {
|
func testAccCheckPacketProjectExists(n string, project *packngo.Project) 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 {
|
||||||
return fmt.Errorf("Not found: %s", n)
|
return fmt.Errorf("Not found: %s", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
if rs.Primary.ID == "" {
|
||||||
return fmt.Errorf("No Record ID is set")
|
return fmt.Errorf("No Record ID is set")
|
||||||
}
|
}
|
||||||
|
@ -74,11 +67,9 @@ func testAccCheckPacketProjectExists(n string, project *packngo.Project) resourc
|
||||||
client := testAccProvider.Meta().(*packngo.Client)
|
client := testAccProvider.Meta().(*packngo.Client)
|
||||||
|
|
||||||
foundProject, _, err := client.Projects.Get(rs.Primary.ID)
|
foundProject, _, err := client.Projects.Get(rs.Primary.ID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if foundProject.ID != rs.Primary.ID {
|
if foundProject.ID != rs.Primary.ID {
|
||||||
return fmt.Errorf("Record not found: %v - %v", rs.Primary.ID, foundProject)
|
return fmt.Errorf("Record not found: %v - %v", rs.Primary.ID, foundProject)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
package packet
|
package packet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/packethost/packngo"
|
"github.com/packethost/packngo"
|
||||||
)
|
)
|
||||||
|
@ -59,14 +55,12 @@ func resourcePacketSSHKeyCreate(d *schema.ResourceData, meta interface{}) error
|
||||||
Key: d.Get("public_key").(string),
|
Key: d.Get("public_key").(string),
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] SSH Key create configuration: %#v", createRequest)
|
|
||||||
key, _, err := client.SSHKeys.Create(createRequest)
|
key, _, err := client.SSHKeys.Create(createRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error creating SSH Key: %s", err)
|
return friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(key.ID)
|
d.SetId(key.ID)
|
||||||
log.Printf("[INFO] SSH Key: %s", key.ID)
|
|
||||||
|
|
||||||
return resourcePacketSSHKeyRead(d, meta)
|
return resourcePacketSSHKeyRead(d, meta)
|
||||||
}
|
}
|
||||||
|
@ -76,14 +70,16 @@ func resourcePacketSSHKeyRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
|
||||||
key, _, err := client.SSHKeys.Get(d.Id())
|
key, _, err := client.SSHKeys.Get(d.Id())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
err = friendlyError(err)
|
||||||
|
|
||||||
// If the key is somehow already destroyed, mark as
|
// If the key is somehow already destroyed, mark as
|
||||||
// succesfully gone
|
// succesfully gone
|
||||||
if strings.Contains(err.Error(), "404") {
|
if isNotFound(err) {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("Error retrieving SSH key: %s", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Set("id", key.ID)
|
d.Set("id", key.ID)
|
||||||
|
@ -105,10 +101,9 @@ func resourcePacketSSHKeyUpdate(d *schema.ResourceData, meta interface{}) error
|
||||||
Key: d.Get("public_key").(string),
|
Key: d.Get("public_key").(string),
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] SSH key update: %#v", d.Get("id"))
|
|
||||||
_, _, err := client.SSHKeys.Update(updateRequest)
|
_, _, err := client.SSHKeys.Update(updateRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to update SSH key: %s", err)
|
return friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resourcePacketSSHKeyRead(d, meta)
|
return resourcePacketSSHKeyRead(d, meta)
|
||||||
|
@ -117,10 +112,9 @@ func resourcePacketSSHKeyUpdate(d *schema.ResourceData, meta interface{}) error
|
||||||
func resourcePacketSSHKeyDelete(d *schema.ResourceData, meta interface{}) error {
|
func resourcePacketSSHKeyDelete(d *schema.ResourceData, meta interface{}) error {
|
||||||
client := meta.(*packngo.Client)
|
client := meta.(*packngo.Client)
|
||||||
|
|
||||||
log.Printf("[INFO] Deleting SSH key: %s", d.Id())
|
|
||||||
_, err := client.SSHKeys.Delete(d.Id())
|
_, err := client.SSHKeys.Delete(d.Id())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error deleting SSH key: %s", err)
|
return friendlyError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
|
|
|
@ -40,11 +40,8 @@ func testAccCheckPacketSSHKeyDestroy(s *terraform.State) error {
|
||||||
if rs.Type != "packet_ssh_key" {
|
if rs.Type != "packet_ssh_key" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if _, _, err := client.SSHKeys.Get(rs.Primary.ID); err == nil {
|
||||||
_, _, err := client.SSHKeys.Get(rs.Primary.ID)
|
return fmt.Errorf("SSH key still exists")
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
fmt.Errorf("SSH key still exists")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,11 +50,9 @@ func testAccCheckPacketSSHKeyDestroy(s *terraform.State) error {
|
||||||
|
|
||||||
func testAccCheckPacketSSHKeyAttributes(key *packngo.SSHKey) resource.TestCheckFunc {
|
func testAccCheckPacketSSHKeyAttributes(key *packngo.SSHKey) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
if key.Label != "foobar" {
|
if key.Label != "foobar" {
|
||||||
return fmt.Errorf("Bad name: %s", key.Label)
|
return fmt.Errorf("Bad name: %s", key.Label)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,11 +60,9 @@ func testAccCheckPacketSSHKeyAttributes(key *packngo.SSHKey) resource.TestCheckF
|
||||||
func testAccCheckPacketSSHKeyExists(n string, key *packngo.SSHKey) resource.TestCheckFunc {
|
func testAccCheckPacketSSHKeyExists(n string, key *packngo.SSHKey) 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 {
|
||||||
return fmt.Errorf("Not found: %s", n)
|
return fmt.Errorf("Not found: %s", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if rs.Primary.ID == "" {
|
if rs.Primary.ID == "" {
|
||||||
return fmt.Errorf("No Record ID is set")
|
return fmt.Errorf("No Record ID is set")
|
||||||
}
|
}
|
||||||
|
@ -77,11 +70,9 @@ func testAccCheckPacketSSHKeyExists(n string, key *packngo.SSHKey) resource.Test
|
||||||
client := testAccProvider.Meta().(*packngo.Client)
|
client := testAccProvider.Meta().(*packngo.Client)
|
||||||
|
|
||||||
foundKey, _, err := client.SSHKeys.Get(rs.Primary.ID)
|
foundKey, _, err := client.SSHKeys.Get(rs.Primary.ID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if foundKey.ID != rs.Primary.ID {
|
if foundKey.ID != rs.Primary.ID {
|
||||||
return fmt.Errorf("SSh Key not found: %v - %v", rs.Primary.ID, foundKey)
|
return fmt.Errorf("SSh Key not found: %v - %v", rs.Primary.ID, foundKey)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue