provider/rabbitmq: Initial Commit of RabbitMQ Provider

Contains provider configuration, a rabbitmq_vhost resource, and
acceptance test.
This commit is contained in:
Joe Topjian 2016-07-19 04:38:00 +00:00
parent e37dbefd90
commit c2469c95f4
7 changed files with 375 additions and 0 deletions

View File

@ -0,0 +1,32 @@
package rabbitmq
import (
"testing"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccVhost_importBasic(t *testing.T) {
resourceName := "rabbitmq_vhost.test"
var vhost string
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccVhostCheckDestroy(vhost),
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccVhostConfig_basic,
Check: testAccVhostCheck(
resourceName, &vhost,
),
},
resource.TestStep{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,117 @@
package rabbitmq
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net/http"
"github.com/michaelklishin/rabbit-hole"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)
func Provider() terraform.ResourceProvider {
return &schema.Provider{
Schema: map[string]*schema.Schema{
"endpoint": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("RABBITMQ_ENDPOINT", nil),
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if value == "" {
errors = append(errors, fmt.Errorf("Endpoint must not be an empty string"))
}
return
},
},
"username": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("RABBITMQ_USERNAME", nil),
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if value == "" {
errors = append(errors, fmt.Errorf("Username must not be an empty string"))
}
return
},
},
"password": &schema.Schema{
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("RABBITMQ_PASSWORD", nil),
ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)
if value == "" {
errors = append(errors, fmt.Errorf("Password must not be an empty string"))
}
return
},
},
"insecure": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("RABBITMQ_INSECURE", nil),
},
"cacert_file": &schema.Schema{
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("RABBITMQ_CACERT", ""),
},
},
ResourcesMap: map[string]*schema.Resource{
"rabbitmq_vhost": resourceVhost(),
},
ConfigureFunc: providerConfigure,
}
}
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
var username = d.Get("username").(string)
var password = d.Get("password").(string)
var endpoint = d.Get("endpoint").(string)
var insecure = d.Get("insecure").(bool)
var cacertFile = d.Get("cacert_file").(string)
// Configure TLS/SSL:
// Ignore self-signed cert warnings
// Specify a custom CA / intermediary cert
// Specify a certificate and key
tlsConfig := &tls.Config{}
if cacertFile != "" {
caCert, err := ioutil.ReadFile(cacertFile)
if err != nil {
return nil, err
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig.RootCAs = caCertPool
}
if insecure {
tlsConfig.InsecureSkipVerify = true
}
// Connect to RabbitMQ management interface
transport := &http.Transport{TLSClientConfig: tlsConfig}
rmqc, err := rabbithole.NewTLSClient(endpoint, username, password, transport)
if err != nil {
return nil, err
}
return rmqc, nil
}

View File

@ -0,0 +1,46 @@
package rabbitmq
import (
"os"
"testing"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform"
)
// To run these acceptance tests, you will need access to a RabbitMQ server
// with the management plugin enabled.
//
// Set the RABBITMQ_ENDPOINT, RABBITMQ_USERNAME, and RABBITMQ_PASSWORD
// environment variables before running the tests.
//
// You can run the tests like this:
// make testacc TEST=./builtin/providers/rabbitmq
var testAccProviders map[string]terraform.ResourceProvider
var testAccProvider *schema.Provider
func init() {
testAccProvider = Provider().(*schema.Provider)
testAccProviders = map[string]terraform.ResourceProvider{
"rabbitmq": testAccProvider,
}
}
func TestProvider(t *testing.T) {
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
t.Fatalf("err: %s", err)
}
}
func TestProvider_impl(t *testing.T) {
var _ terraform.ResourceProvider = Provider()
}
func testAccPreCheck(t *testing.T) {
for _, name := range []string{"RABBITMQ_ENDPOINT", "RABBITMQ_USERNAME", "RABBITMQ_PASSWORD"} {
if v := os.Getenv(name); v == "" {
t.Fatal("RABBITMQ_ENDPOINT, RABBITMQ_USERNAME and RABBITMQ_PASSWORD must be set for acceptance tests")
}
}
}

View File

@ -0,0 +1,85 @@
package rabbitmq
import (
"fmt"
"log"
"github.com/michaelklishin/rabbit-hole"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceVhost() *schema.Resource {
return &schema.Resource{
Create: CreateVhost,
Read: ReadVhost,
Delete: DeleteVhost,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
},
}
}
func CreateVhost(d *schema.ResourceData, meta interface{}) error {
rmqc := meta.(*rabbithole.Client)
vhost := d.Get("name").(string)
log.Printf("[DEBUG] RabbitMQ: Attempting to create vhost %s", vhost)
resp, err := rmqc.PutVhost(vhost, rabbithole.VhostSettings{})
log.Printf("[DEBUG] RabbitMQ: vhost creation response: %#v", resp)
if err != nil {
return err
}
d.SetId(vhost)
return ReadVhost(d, meta)
}
func ReadVhost(d *schema.ResourceData, meta interface{}) error {
rmqc := meta.(*rabbithole.Client)
vhost, err := rmqc.GetVhost(d.Id())
if err != nil {
return checkDeleted(d, err)
}
log.Printf("[DEBUG] RabbitMQ: Vhost retrieved: %#v", vhost)
d.Set("name", vhost.Name)
return nil
}
func DeleteVhost(d *schema.ResourceData, meta interface{}) error {
rmqc := meta.(*rabbithole.Client)
log.Printf("[DEBUG] RabbitMQ: Attempting to delete vhost %s", d.Id())
resp, err := rmqc.DeleteVhost(d.Id())
log.Printf("[DEBUG] RabbitMQ: vhost deletion response: %#v", resp)
if err != nil {
return err
}
if resp.StatusCode == 404 {
// the vhost was automatically deleted
return nil
}
if resp.StatusCode >= 400 {
return fmt.Errorf("Error deleting RabbitMQ user: %s", resp.Status)
}
return nil
}

View File

@ -0,0 +1,79 @@
package rabbitmq
import (
"fmt"
"testing"
"github.com/michaelklishin/rabbit-hole"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccVhost(t *testing.T) {
var vhost string
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccVhostCheckDestroy(vhost),
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccVhostConfig_basic,
Check: testAccVhostCheck(
"rabbitmq_vhost.test", &vhost,
),
},
},
})
}
func testAccVhostCheck(rn string, name *string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[rn]
if !ok {
return fmt.Errorf("resource not found: %s", rn)
}
if rs.Primary.ID == "" {
return fmt.Errorf("vhost id not set")
}
rmqc := testAccProvider.Meta().(*rabbithole.Client)
vhosts, err := rmqc.ListVhosts()
if err != nil {
return fmt.Errorf("Error retrieving vhosts: %s", err)
}
for _, vhost := range vhosts {
if vhost.Name == rs.Primary.ID {
*name = rs.Primary.ID
return nil
}
}
return fmt.Errorf("Unable to find vhost %s", rn)
}
}
func testAccVhostCheckDestroy(name string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rmqc := testAccProvider.Meta().(*rabbithole.Client)
vhosts, err := rmqc.ListVhosts()
if err != nil {
return fmt.Errorf("Error retrieving vhosts: %s", err)
}
for _, vhost := range vhosts {
if vhost.Name == name {
return fmt.Errorf("vhost still exists: %s", vhost)
}
}
return nil
}
}
const testAccVhostConfig_basic = `
resource "rabbitmq_vhost" "test" {
name = "test"
}`

View File

@ -0,0 +1,14 @@
package rabbitmq
import (
"github.com/hashicorp/terraform/helper/schema"
)
func checkDeleted(d *schema.ResourceData, err error) error {
if err.Error() == "not found" {
d.SetId("")
return nil
}
return err
}

View File

@ -38,6 +38,7 @@ import (
packetprovider "github.com/hashicorp/terraform/builtin/providers/packet"
postgresqlprovider "github.com/hashicorp/terraform/builtin/providers/postgresql"
powerdnsprovider "github.com/hashicorp/terraform/builtin/providers/powerdns"
rabbitmqprovider "github.com/hashicorp/terraform/builtin/providers/rabbitmq"
randomprovider "github.com/hashicorp/terraform/builtin/providers/random"
rundeckprovider "github.com/hashicorp/terraform/builtin/providers/rundeck"
scalewayprovider "github.com/hashicorp/terraform/builtin/providers/scaleway"
@ -93,6 +94,7 @@ var InternalProviders = map[string]plugin.ProviderFunc{
"packet": packetprovider.Provider,
"postgresql": postgresqlprovider.Provider,
"powerdns": powerdnsprovider.Provider,
"rabbitmq": rabbitmqprovider.Provider,
"random": randomprovider.Provider,
"rundeck": rundeckprovider.Provider,
"scaleway": scalewayprovider.Provider,