mirror of https://github.com/hashicorp/terraform
parent
434d0c9d86
commit
5e9d385f96
@ -0,0 +1,122 @@
|
||||
package cloudstack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/xanzy/go-cloudstack/cloudstack"
|
||||
)
|
||||
|
||||
func resourceCloudStackSSHKeyPair() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceCloudStackSSHKeyPairCreate,
|
||||
Read: resourceCloudStackSSHKeyPairRead,
|
||||
Delete: resourceCloudStackSSHKeyPairDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"public_key": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
},
|
||||
|
||||
"private_key": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
|
||||
"fingerprint": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceCloudStackSSHKeyPairCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
cs := meta.(*cloudstack.CloudStackClient)
|
||||
|
||||
name := d.Get("name").(string)
|
||||
publicKey := d.Get("public_key").(string)
|
||||
|
||||
if publicKey != "" {
|
||||
//register key supplied
|
||||
p := cs.SSH.NewRegisterSSHKeyPairParams(name, publicKey)
|
||||
r, err := cs.SSH.RegisterSSHKeyPair(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("[DEBUG] RegisterSSHKeyPair response: %+v\n", r)
|
||||
log.Printf("[DEBUG] Key pair successfully registered at Cloudstack")
|
||||
d.SetId(name)
|
||||
} else {
|
||||
//no key supplied, must create one and return the private key
|
||||
p := cs.SSH.NewCreateSSHKeyPairParams(name)
|
||||
r, err := cs.SSH.CreateSSHKeyPair(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Printf("[DEBUG] CreateSSHKeyPair response: %+v\n", r)
|
||||
log.Printf("[DEBUG] Key pair successfully generated at Cloudstack")
|
||||
log.Printf("[DEBUG] Private key returned: %s", r.Privatekey)
|
||||
d.Set("private_key", r.Privatekey)
|
||||
d.SetId(name)
|
||||
}
|
||||
|
||||
return resourceCloudStackSSHKeyPairRead(d, meta)
|
||||
}
|
||||
|
||||
func resourceCloudStackSSHKeyPairRead(d *schema.ResourceData, meta interface{}) error {
|
||||
cs := meta.(*cloudstack.CloudStackClient)
|
||||
|
||||
log.Printf("[DEBUG] looking for ssh key %s with name %s", d.Id(), d.Get("name").(string))
|
||||
|
||||
p := cs.SSH.NewListSSHKeyPairsParams()
|
||||
p.SetName(d.Get("name").(string))
|
||||
|
||||
r, err := cs.SSH.ListSSHKeyPairs(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if r.Count == 0 {
|
||||
log.Printf("[DEBUG] Key pair %s does not exist", d.Get("name").(string))
|
||||
d.Set("name", "")
|
||||
return nil
|
||||
}
|
||||
|
||||
//SSHKeyPair name is unique in a cloudstack account so dont need to check for multiple
|
||||
d.Set("name", r.SSHKeyPairs[0].Name)
|
||||
d.Set("fingerprint", r.SSHKeyPairs[0].Fingerprint)
|
||||
log.Printf("[DEBUG] Read ssh key pair %+v\n", d)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCloudStackSSHKeyPairDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
cs := meta.(*cloudstack.CloudStackClient)
|
||||
|
||||
// Create a new parameter struct
|
||||
p := cs.SSH.NewDeleteSSHKeyPairParams(d.Get("name").(string))
|
||||
|
||||
// Remove the SSH Keypair
|
||||
_, err := cs.SSH.DeleteSSHKeyPair(p)
|
||||
if err != nil {
|
||||
// This is a very poor way to be told the UUID does no longer exist :(
|
||||
if strings.Contains(err.Error(), fmt.Sprintf(
|
||||
"A key pair with name '%s' does not exist for account", d.Get("name").(string))) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("Error deleting SSH Keypair: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -0,0 +1,160 @@
|
||||
package cloudstack
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/xanzy/go-cloudstack/cloudstack"
|
||||
)
|
||||
|
||||
func TestAccCloudStackSSHKeyPair_create(t *testing.T) {
|
||||
var sshkey cloudstack.SSHKeyPair
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckCloudStackSSHKeyPairDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccCloudStackSSHKeyPair_create,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckCloudStackSSHKeyPairExists("cloudstack_ssh_keypair.foo", &sshkey),
|
||||
testAccCheckCloudStackSSHKeyPairAttributes(&sshkey),
|
||||
testAccCheckCloudStackSSHKeyPairCreateAttributes("cloudstack_ssh_keypair.foo"),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccCloudStackSSHKeyPair_register(t *testing.T) {
|
||||
var sshkey cloudstack.SSHKeyPair
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckCloudStackSSHKeyPairDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
resource.TestStep{
|
||||
Config: testAccCloudStackSSHKeyPair_register,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckCloudStackSSHKeyPairExists("cloudstack_ssh_keypair.foo", &sshkey),
|
||||
testAccCheckCloudStackSSHKeyPairAttributes(&sshkey),
|
||||
resource.TestCheckResourceAttr(
|
||||
"cloudstack_ssh_keypair.foo",
|
||||
"public_key",
|
||||
CLOUDSTACK_SSH_PUBLIC_KEY),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckCloudStackSSHKeyPairExists(n string, sshkey *cloudstack.SSHKeyPair) 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.Attributes["name"] == "" {
|
||||
return fmt.Errorf("No ssh key name is set")
|
||||
}
|
||||
|
||||
cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
|
||||
p := cs.SSH.NewListSSHKeyPairsParams()
|
||||
p.SetName(rs.Primary.Attributes["name"])
|
||||
list, err := cs.SSH.ListSSHKeyPairs(p)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if list.Count == 1 && list.SSHKeyPairs[0].Name == rs.Primary.Attributes["name"] {
|
||||
//ssh key exists
|
||||
*sshkey = *list.SSHKeyPairs[0]
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("SSH key not found")
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckCloudStackSSHKeyPairAttributes(
|
||||
sshkey *cloudstack.SSHKeyPair) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
|
||||
fingerprintLen := len(sshkey.Fingerprint)
|
||||
if fingerprintLen != 47 {
|
||||
return fmt.Errorf(
|
||||
"SSH key: Attribute private_key expected length 47, got %d",
|
||||
fingerprintLen)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckCloudStackSSHKeyPairCreateAttributes(
|
||||
name string) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
ms := s.RootModule()
|
||||
rs, ok := ms.Resources[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not found: %s", name)
|
||||
}
|
||||
|
||||
is := rs.Primary
|
||||
if is == nil {
|
||||
return fmt.Errorf("No primary instance: %s", name)
|
||||
}
|
||||
|
||||
log.Printf("Private key calculated: %s", is.Attributes["private_key"])
|
||||
if !strings.Contains(is.Attributes["private_key"], "PRIVATE KEY") {
|
||||
return fmt.Errorf(
|
||||
"SSH key: Attribute private_key expected 'PRIVATE KEY' to be present, got %s",
|
||||
is.Attributes["private_key"])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckCloudStackSSHKeyPairDestroy(s *terraform.State) error {
|
||||
cs := testAccProvider.Meta().(*cloudstack.CloudStackClient)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "cloudstack_ssh_keypair" {
|
||||
continue
|
||||
}
|
||||
|
||||
if rs.Primary.Attributes["name"] == "" {
|
||||
return fmt.Errorf("No ssh key name is set")
|
||||
}
|
||||
|
||||
p := cs.SSH.NewDeleteSSHKeyPairParams(rs.Primary.Attributes["name"])
|
||||
_, err := cs.SSH.DeleteSSHKeyPair(p)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf(
|
||||
"Error deleting ssh key (%s): %s",
|
||||
rs.Primary.Attributes["name"], err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var testAccCloudStackSSHKeyPair_create = fmt.Sprintf(`
|
||||
resource "cloudstack_ssh_keypair" "foo" {
|
||||
name = "terraform-testacc"
|
||||
}`)
|
||||
|
||||
var testAccCloudStackSSHKeyPair_register = fmt.Sprintf(`
|
||||
resource "cloudstack_ssh_keypair" "foo" {
|
||||
name = "terraform-testacc"
|
||||
public_key = "%s"
|
||||
}`, CLOUDSTACK_SSH_PUBLIC_KEY)
|
||||
Loading…
Reference in new issue