providers/google: google_compute_address

This commit is contained in:
Mitchell Hashimoto 2014-08-25 12:55:08 -07:00
parent 80e2023e6b
commit 376d1d6083
5 changed files with 198 additions and 5 deletions

View File

@ -19,6 +19,8 @@ const clientScopes string = "https://www.googleapis.com/auth/compute"
type Config struct {
AccountFile string
ClientSecretsFile string
Project string
Region string
clientCompute *compute.Service
}
@ -34,6 +36,12 @@ func (c *Config) loadAndValidate() error {
if c.ClientSecretsFile == "" {
c.ClientSecretsFile = os.Getenv("GOOGLE_CLIENT_FILE")
}
if c.Project == "" {
c.Project = os.Getenv("GOOGLE_PROJECT")
}
if c.Region == "" {
c.Region = os.Getenv("GOOGLE_REGION")
}
if err := loadJSON(&account, c.AccountFile); err != nil {
return fmt.Errorf(

64
operation.go Normal file
View File

@ -0,0 +1,64 @@
package google
import (
"fmt"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/hashicorp/terraform/helper/resource"
)
// OperationWaitType is an enum specifying what type of operation
// we're waiting on.
type OperationWaitType byte
const (
OperationWaitInvalid OperationWaitType = iota
OperationWaitGlobal
OperationWaitRegion
OperationWaitZone
)
type OperationWaiter struct {
Service *compute.Service
Op *compute.Operation
Project string
Region string
Zone string
Type OperationWaitType
}
func (w *OperationWaiter) RefreshFunc() resource.StateRefreshFunc {
return func() (interface{}, string, error) {
var op *compute.Operation
var err error
switch w.Type {
case OperationWaitGlobal:
op, err = w.Service.GlobalOperations.Get(
w.Project, w.Op.Name).Do()
case OperationWaitRegion:
op, err = w.Service.RegionOperations.Get(
w.Project, w.Region, w.Op.Name).Do()
case OperationWaitZone:
op, err = w.Service.ZoneOperations.Get(
w.Project, w.Zone, w.Op.Name).Do()
default:
return nil, "bad-type", fmt.Errorf(
"Invalid wait type: %#v", w.Type)
}
if err != nil {
return nil, "", err
}
return op, op.Status, nil
}
}
func (w *OperationWaiter) Conf() *resource.StateChangeConf {
return &resource.StateChangeConf{
Pending: []string{"PENDING", "RUNNING"},
Target: "DONE",
Refresh: w.RefreshFunc(),
}
}

View File

@ -17,9 +17,20 @@ func Provider() *schema.Provider {
Type: schema.TypeString,
Required: true,
},
"project": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"region": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
},
ResourcesMap: map[string]*schema.Resource{
"google_compute_address": resourceComputeAddress(),
"google_compute_instance": resourceComputeInstance(),
},
@ -31,11 +42,13 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
config := Config{
AccountFile: d.Get("account_file").(string),
ClientSecretsFile: d.Get("client_secrets_file").(string),
Project: d.Get("project").(string),
Region: d.Get("region").(string),
}
if err := config.loadAndValidate(); err != nil {
return nil, err
}
return nil, nil
return &config, nil
}

107
resource_compute_address.go Normal file
View File

@ -0,0 +1,107 @@
package google
import (
"fmt"
"log"
"time"
"code.google.com/p/google-api-go-client/compute/v1"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceComputeAddress() *schema.Resource {
return &schema.Resource{
Create: resourceComputeAddressCreate,
Read: resourceComputeAddressRead,
Delete: resourceComputeAddressDelete,
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"address": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceComputeAddressCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
// Build the address parameter
addr := &compute.Address{Name: d.Get("name").(string)}
log.Printf("[DEBUG] Address insert request: %#v", addr)
op, err := config.clientCompute.Addresses.Insert(
config.Project, config.Region, addr).Do()
if err != nil {
return fmt.Errorf("Error creating address: %s", err)
}
// It probably maybe worked, so store the ID now
d.SetId(addr.Name)
// Wait for the operation to complete
w := &OperationWaiter{
Service: config.clientCompute,
Op: op,
Project: config.Project,
Region: config.Region,
Type: OperationWaitRegion,
}
state := w.Conf()
state.Timeout = 2 * time.Minute
state.MinTimeout = 1 * time.Second
if _, err := state.WaitForState(); err != nil {
return fmt.Errorf("Error waiting for address to create: %s", err)
}
return resourceComputeAddressRead(d, meta)
}
func resourceComputeAddressRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
addr, err := config.clientCompute.Addresses.Get(
config.Project, config.Region, d.Id()).Do()
if err != nil {
return fmt.Errorf("Error reading address: %s", err)
}
d.Set("address", addr.Address)
return nil
}
func resourceComputeAddressDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
// Delete the address
op, err := config.clientCompute.Addresses.Delete(
config.Project, config.Region, d.Id()).Do()
if err != nil {
return fmt.Errorf("Error deleting address: %s", err)
}
// Wait for the operation to complete
w := &OperationWaiter{
Service: config.clientCompute,
Op: op,
Project: config.Project,
Region: config.Region,
Type: OperationWaitRegion,
}
state := w.Conf()
state.Timeout = 2 * time.Minute
state.MinTimeout = 1 * time.Second
if _, err := state.WaitForState(); err != nil {
return fmt.Errorf("Error waiting for address to delete: %s", err)
}
d.SetId("")
return nil
}

View File

@ -6,14 +6,14 @@ import (
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccComputeInstance_basic(t *testing.T) {
func TestAccComputeAddress_basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
//CheckDestroy: testAccCheckHerokuAppDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeInstance_basic,
Config: testAccComputeAddress_basic,
/*
Check: resource.ComposeTestCheckFunc(
testAccCheckHerokuAppExists("heroku_app.foobar", &app),
@ -156,6 +156,7 @@ func testAccCheckHerokuAppExists(n string, app *heroku.App) resource.TestCheckFu
}
*/
const testAccComputeInstance_basic = `
resource "google_compute_instance" "foobar" {
const testAccComputeAddress_basic = `
resource "google_compute_address" "foobar" {
name = "terraform-test"
}`