-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1074 from plalloni/do-ssh-keys
Add DigitalOcean SSH Key resource
- Loading branch information
Showing
3 changed files
with
214 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
builtin/providers/digitalocean/resource_digitalocean_ssh_key.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package digitalocean | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"strings" | ||
|
||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/pearkes/digitalocean" | ||
) | ||
|
||
func resourceDigitalOceanSSHKey() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceDigitalOceanSSHKeyCreate, | ||
Read: resourceDigitalOceanSSHKeyRead, | ||
Update: resourceDigitalOceanSSHKeyUpdate, | ||
Delete: resourceDigitalOceanSSHKeyDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"id": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
|
||
"name": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
|
||
"public_key": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"fingerprint": &schema.Schema{ | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceDigitalOceanSSHKeyCreate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*digitalocean.Client) | ||
|
||
// Build up our creation options | ||
opts := &digitalocean.CreateSSHKey{ | ||
Name: d.Get("name").(string), | ||
PublicKey: d.Get("public_key").(string), | ||
} | ||
|
||
log.Printf("[DEBUG] SSH Key create configuration: %#v", opts) | ||
id, err := client.CreateSSHKey(opts) | ||
if err != nil { | ||
return fmt.Errorf("Error creating SSH Key: %s", err) | ||
} | ||
|
||
d.SetId(id) | ||
log.Printf("[INFO] SSH Key: %s", id) | ||
|
||
return resourceDigitalOceanSSHKeyRead(d, meta) | ||
} | ||
|
||
func resourceDigitalOceanSSHKeyRead(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*digitalocean.Client) | ||
|
||
key, err := client.RetrieveSSHKey(d.Id()) | ||
if err != nil { | ||
// If the key is somehow already destroyed, mark as | ||
// succesfully gone | ||
if strings.Contains(err.Error(), "404 Not Found") { | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
return fmt.Errorf("Error retrieving SSH key: %s", err) | ||
} | ||
|
||
d.Set("name", key.Name) | ||
d.Set("fingerprint", key.Fingerprint) | ||
|
||
return nil | ||
} | ||
|
||
func resourceDigitalOceanSSHKeyUpdate(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*digitalocean.Client) | ||
|
||
var newName string | ||
if v, ok := d.GetOk("name"); ok { | ||
newName = v.(string) | ||
} | ||
|
||
log.Printf("[DEBUG] SSH key update name: %#v", newName) | ||
err := client.RenameSSHKey(d.Id(), newName) | ||
if err != nil { | ||
return fmt.Errorf("Failed to update SSH key: %s", err) | ||
} | ||
|
||
return resourceDigitalOceanSSHKeyRead(d, meta) | ||
} | ||
|
||
func resourceDigitalOceanSSHKeyDelete(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*digitalocean.Client) | ||
|
||
log.Printf("[INFO] Deleting SSH key: %s", d.Id()) | ||
err := client.DestroySSHKey(d.Id()) | ||
if err != nil { | ||
return fmt.Errorf("Error deleting SSH key: %s", err) | ||
} | ||
|
||
d.SetId("") | ||
return nil | ||
} |
99 changes: 99 additions & 0 deletions
99
builtin/providers/digitalocean/resource_digitalocean_ssh_key_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
package digitalocean | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/terraform" | ||
"github.com/pearkes/digitalocean" | ||
) | ||
|
||
func TestAccDigitalOceanSSHKey_Basic(t *testing.T) { | ||
var key digitalocean.SSHKey | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { testAccPreCheck(t) }, | ||
Providers: testAccProviders, | ||
CheckDestroy: testAccCheckDigitalOceanSSHKeyDestroy, | ||
Steps: []resource.TestStep{ | ||
resource.TestStep{ | ||
Config: testAccCheckDigitalOceanSSHKeyConfig_basic, | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckDigitalOceanSSHKeyExists("digitalocean_ssh_key.foobar", &key), | ||
testAccCheckDigitalOceanSSHKeyAttributes(&key), | ||
resource.TestCheckResourceAttr( | ||
"digitalocean_ssh_key.foobar", "name", "foobar"), | ||
resource.TestCheckResourceAttr( | ||
"digitalocean_ssh_key.foobar", "public_key", "abcdef"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckDigitalOceanSSHKeyDestroy(s *terraform.State) error { | ||
client := testAccProvider.Meta().(*digitalocean.Client) | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "digitalocean_ssh_key" { | ||
continue | ||
} | ||
|
||
// Try to find the key | ||
_, err := client.RetrieveSSHKey(rs.Primary.ID) | ||
|
||
if err == nil { | ||
fmt.Errorf("SSH key still exists") | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func testAccCheckDigitalOceanSSHKeyAttributes(key *digitalocean.SSHKey) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
|
||
if key.Name != "foobar" { | ||
return fmt.Errorf("Bad name: %s", key.Name) | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccCheckDigitalOceanSSHKeyExists(n string, key *digitalocean.SSHKey) 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 Record ID is set") | ||
} | ||
|
||
client := testAccProvider.Meta().(*digitalocean.Client) | ||
|
||
foundKey, err := client.RetrieveSSHKey(rs.Primary.ID) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
if foundKey.Name != rs.Primary.ID { | ||
return fmt.Errorf("Record not found") | ||
} | ||
|
||
*key = foundKey | ||
|
||
return nil | ||
} | ||
} | ||
|
||
const testAccCheckDigitalOceanSSHKeyConfig_basic = ` | ||
resource "digitalocean_ssh_key" "foobar" { | ||
name = "foobar" | ||
public_key = "abcdef" | ||
}` |