github.com/acm1/terraform@v0.6.2-0.20150729164239-1f314444f45c/builtin/providers/aws/resource_vpn_connection_route.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  
     8  	"github.com/aws/aws-sdk-go/aws"
     9  	"github.com/aws/aws-sdk-go/aws/awserr"
    10  	"github.com/aws/aws-sdk-go/service/ec2"
    11  
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  )
    14  
    15  func resourceAwsVpnConnectionRoute() *schema.Resource {
    16  	return &schema.Resource{
    17  		// You can't update a route. You can just delete one and make
    18  		// a new one.
    19  		Create: resourceAwsVpnConnectionRouteCreate,
    20  		Update: resourceAwsVpnConnectionRouteCreate,
    21  
    22  		Read:   resourceAwsVpnConnectionRouteRead,
    23  		Delete: resourceAwsVpnConnectionRouteDelete,
    24  
    25  		Schema: map[string]*schema.Schema{
    26  			"destination_cidr_block": &schema.Schema{
    27  				Type:     schema.TypeString,
    28  				Required: true,
    29  				ForceNew: true,
    30  			},
    31  
    32  			"vpn_connection_id": &schema.Schema{
    33  				Type:     schema.TypeString,
    34  				Required: true,
    35  				ForceNew: true,
    36  			},
    37  		},
    38  	}
    39  }
    40  
    41  func resourceAwsVpnConnectionRouteCreate(d *schema.ResourceData, meta interface{}) error {
    42  	conn := meta.(*AWSClient).ec2conn
    43  
    44  	createOpts := &ec2.CreateVPNConnectionRouteInput{
    45  		DestinationCIDRBlock: aws.String(d.Get("destination_cidr_block").(string)),
    46  		VPNConnectionID:      aws.String(d.Get("vpn_connection_id").(string)),
    47  	}
    48  
    49  	// Create the route.
    50  	log.Printf("[DEBUG] Creating VPN connection route")
    51  	_, err := conn.CreateVPNConnectionRoute(createOpts)
    52  	if err != nil {
    53  		return fmt.Errorf("Error creating VPN connection route: %s", err)
    54  	}
    55  
    56  	// Store the ID by the only two data we have available to us.
    57  	d.SetId(fmt.Sprintf("%s:%s", *createOpts.DestinationCIDRBlock, *createOpts.VPNConnectionID))
    58  
    59  	return resourceAwsVpnConnectionRouteRead(d, meta)
    60  }
    61  
    62  func resourceAwsVpnConnectionRouteRead(d *schema.ResourceData, meta interface{}) error {
    63  	conn := meta.(*AWSClient).ec2conn
    64  
    65  	cidrBlock, vpnConnectionId := resourceAwsVpnConnectionRouteParseId(d.Id())
    66  
    67  	routeFilters := []*ec2.Filter{
    68  		&ec2.Filter{
    69  			Name:   aws.String("route.destination-cidr-block"),
    70  			Values: []*string{aws.String(cidrBlock)},
    71  		},
    72  		&ec2.Filter{
    73  			Name:   aws.String("vpn-connection-id"),
    74  			Values: []*string{aws.String(vpnConnectionId)},
    75  		},
    76  	}
    77  
    78  	// Technically, we know everything there is to know about the route
    79  	// from its ID, but we still want to catch cases where it changes
    80  	// outside of terraform and results in a stale state file. Hence,
    81  	// conduct a read.
    82  	resp, err := conn.DescribeVPNConnections(&ec2.DescribeVPNConnectionsInput{
    83  		Filters: routeFilters,
    84  	})
    85  	if err != nil {
    86  		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidVpnConnectionID.NotFound" {
    87  			d.SetId("")
    88  			return nil
    89  		} else {
    90  			log.Printf("[ERROR] Error finding VPN connection route: %s", err)
    91  			return err
    92  		}
    93  	}
    94  	if resp == nil || len(resp.VPNConnections) == 0 {
    95  		// This is kind of a weird edge case. I'd rather return an error
    96  		// instead of just blindly setting the ID to ""... since I don't know
    97  		// what might cause this.
    98  		return fmt.Errorf("No VPN connections returned")
    99  	}
   100  
   101  	vpnConnection := resp.VPNConnections[0]
   102  
   103  	var found bool
   104  	for _, r := range vpnConnection.Routes {
   105  		if *r.DestinationCIDRBlock == cidrBlock {
   106  			d.Set("destination_cidr_block", *r.DestinationCIDRBlock)
   107  			d.Set("vpn_connection_id", *vpnConnection.VPNConnectionID)
   108  			found = true
   109  		}
   110  	}
   111  	if !found {
   112  		// Something other than terraform eliminated the route.
   113  		d.SetId("")
   114  	}
   115  
   116  	return nil
   117  }
   118  
   119  func resourceAwsVpnConnectionRouteDelete(d *schema.ResourceData, meta interface{}) error {
   120  	conn := meta.(*AWSClient).ec2conn
   121  
   122  	_, err := conn.DeleteVPNConnectionRoute(&ec2.DeleteVPNConnectionRouteInput{
   123  		DestinationCIDRBlock: aws.String(d.Get("destination_cidr_block").(string)),
   124  		VPNConnectionID:      aws.String(d.Get("vpn_connection_id").(string)),
   125  	})
   126  	if err != nil {
   127  		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidVpnConnectionID.NotFound" {
   128  			d.SetId("")
   129  			return nil
   130  		} else {
   131  			log.Printf("[ERROR] Error deleting VPN connection route: %s", err)
   132  			return err
   133  		}
   134  	}
   135  
   136  	return nil
   137  }
   138  
   139  func resourceAwsVpnConnectionRouteParseId(id string) (string, string) {
   140  	parts := strings.SplitN(id, ":", 2)
   141  	return parts[0], parts[1]
   142  }