Skip to content

Commit

Permalink
providers/aws: start filling out
Browse files Browse the repository at this point in the history
  • Loading branch information
mitchellh committed Jun 24, 2014
1 parent 9b4b89c commit c556e2a
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 13 deletions.
46 changes: 46 additions & 0 deletions builtin/providers/aws/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package aws

import (
"strings"
"unicode"

"github.com/mitchellh/goamz/aws"
)

type Config struct {
AccessKey string `mapstructure:"access_key"`
SecretKey string `mapstructure:"secret_key"`
Region string `mapstructure:"region"`
}

// AWSAuth returns a valid aws.Auth object for access to AWS services, or
// an error if the authentication couldn't be resolved.
//
// TODO(mitchellh): Test in some way.
func (c *Config) AWSAuth() (aws.Auth, error) {
auth, err := aws.GetAuth(c.AccessKey, c.SecretKey)
if err == nil {
// Store the accesskey and secret that we got...
c.AccessKey = auth.AccessKey
c.SecretKey = auth.SecretKey
}

return auth, err
}

// AWSRegion returns the configured region.
//
// TODO(mitchellh): Test in some way.
func (c *Config) AWSRegion() (aws.Region, error) {
if c.Region != "" {
return aws.Regions[c.Region], nil
}

md, err := aws.GetMetaData("placement/availability-zone")
if err != nil {
return aws.Region{}, err
}

region := strings.TrimRightFunc(string(md), unicode.IsLetter)
return aws.Regions[region], nil
}
1 change: 0 additions & 1 deletion builtin/providers/aws/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ func diffBuilder_aws_instance() *diff.ResourceBuilder {
"ami",
"availability_zone",
"instance_type",
"region",
},
}
}
31 changes: 31 additions & 0 deletions builtin/providers/aws/refresh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package aws

import (
"github.com/hashicorp/terraform/terraform"
)

// RefreshFunc is a function that performs a refresh of a specific type
// of resource.
type RefreshFunc func(
*ResourceProvider,
*terraform.ResourceState) (*terraform.ResourceState, error)

// refreshMap keeps track of all the resources that this provider
// can refresh.
var refreshMap map[string]RefreshFunc

func init() {
refreshMap = map[string]RefreshFunc{
"aws_instance": refresh_aws_instance,
}
}

func refresh_aws_instance(
p *ResourceProvider,
s *terraform.ResourceState) (*terraform.ResourceState, error) {
if s.ID != "" {
panic("OH MY WOW")
}

return s, nil
}
56 changes: 48 additions & 8 deletions builtin/providers/aws/resource_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,52 @@ package aws

import (
"fmt"
"log"

"github.com/hashicorp/terraform/helper/config"
"github.com/hashicorp/terraform/terraform"
"github.com/mitchellh/goamz/ec2"
)

type ResourceProvider struct {
Config Config

ec2conn *ec2.EC2
}

func (p *ResourceProvider) Validate(c *terraform.ResourceConfig) ([]string, []error) {
errs := c.CheckSet([]string{
"access_key",
"secret_key",
})

return nil, errs
return nil, nil
}

func (p *ResourceProvider) Configure(*terraform.ResourceConfig) error {
func (p *ResourceProvider) Configure(c *terraform.ResourceConfig) error {
if _, err := config.Decode(&p.Config, c.Config); err != nil {
return err
}

// Get the auth and region. This can fail if keys/regions were not
// specified and we're attempting to use the environment.
var errs []error
log.Println("Building AWS auth structure")
auth, err := p.Config.AWSAuth()
if err != nil {
errs = append(errs, err)
}

log.Println("Building AWS region structure")
region, err := p.Config.AWSRegion()
if err != nil {
errs = append(errs, err)
}

if len(errs) == 0 {
log.Println("Initializing EC2 connection")
p.ec2conn = ec2.New(auth, region)
}

if len(errs) > 0 {
return &terraform.MultiError{Errors: errs}
}

return nil
}

Expand Down Expand Up @@ -50,7 +79,18 @@ func (p *ResourceProvider) Diff(

func (p *ResourceProvider) Refresh(
s *terraform.ResourceState) (*terraform.ResourceState, error) {
return s, nil
// If there isn't an ID previously, then the thing didn't exist,
// so there is nothing to refresh.
if s.ID == "" {
return s, nil
}

f, ok := refreshMap[s.Type]
if !ok {
return s, fmt.Errorf("Unknown resource type: %s", s.Type)
}

return f(p, s)
}

func (p *ResourceProvider) Resources() []terraform.ResourceType {
Expand Down
32 changes: 32 additions & 0 deletions builtin/providers/aws/resource_provider_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,43 @@
package aws

import (
"reflect"
"testing"

"github.com/hashicorp/terraform/config"
"github.com/hashicorp/terraform/terraform"
)

func TestResourceProvider_impl(t *testing.T) {
var _ terraform.ResourceProvider = new(ResourceProvider)
}

func TestResourceProvider_Configure(t *testing.T) {
rp := new(ResourceProvider)

raw := map[string]interface{}{
"access_key": "foo",
"secret_key": "bar",
"region": "us-east",
}

rawConfig, err := config.NewRawConfig(raw)
if err != nil {
t.Fatalf("err: %s", err)
}

err = rp.Configure(terraform.NewResourceConfig(rawConfig))
if err != nil {
t.Fatalf("err: %s", err)
}

expected := Config{
AccessKey: "foo",
SecretKey: "bar",
Region: "us-east",
}

if !reflect.DeepEqual(rp.Config, expected) {
t.Fatalf("bad: %#v", rp.Config)
}
}
28 changes: 28 additions & 0 deletions helper/config/decode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package config

import (
"github.com/mitchellh/mapstructure"
)

func Decode(target interface{}, raws ...interface{}) (*mapstructure.Metadata, error) {
var md mapstructure.Metadata
decoderConfig := &mapstructure.DecoderConfig{
Metadata: &md,
Result: target,
WeaklyTypedInput: true,
}

decoder, err := mapstructure.NewDecoder(decoderConfig)
if err != nil {
return nil, err
}

for _, raw := range raws {
err := decoder.Decode(raw)
if err != nil {
return nil, err
}
}

return &md, nil
}
5 changes: 1 addition & 4 deletions terraform/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,10 +340,7 @@ func (t *terraformProvider) init(vars map[string]string) (err error) {
panic(err)
}

rc = &ResourceConfig{
ComputedKeys: t.Config.RawConfig.UnknownKeys(),
Raw: t.Config.RawConfig.Config(),
}
rc = NewResourceConfig(t.Config.RawConfig)
}

err = t.Provider.Configure(rc)
Expand Down

0 comments on commit c556e2a

Please sign in to comment.