github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/vcd/resource_vcd_snat.go (about)

     1  package vcd
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/hashicorp/terraform/helper/resource"
     7  	"github.com/hashicorp/terraform/helper/schema"
     8  )
     9  
    10  func resourceVcdSNAT() *schema.Resource {
    11  	return &schema.Resource{
    12  		Create: resourceVcdSNATCreate,
    13  		Delete: resourceVcdSNATDelete,
    14  		Read:   resourceVcdSNATRead,
    15  
    16  		Schema: map[string]*schema.Schema{
    17  			"edge_gateway": &schema.Schema{
    18  				Type:     schema.TypeString,
    19  				Required: true,
    20  				ForceNew: true,
    21  			},
    22  
    23  			"external_ip": &schema.Schema{
    24  				Type:     schema.TypeString,
    25  				Required: true,
    26  				ForceNew: true,
    27  			},
    28  
    29  			"internal_ip": &schema.Schema{
    30  				Type:     schema.TypeString,
    31  				Required: true,
    32  				ForceNew: true,
    33  			},
    34  		},
    35  	}
    36  }
    37  
    38  func resourceVcdSNATCreate(d *schema.ResourceData, meta interface{}) error {
    39  	vcdClient := meta.(*VCDClient)
    40  	// Multiple VCD components need to run operations on the Edge Gateway, as
    41  	// the edge gatway will throw back an error if it is already performing an
    42  	// operation we must wait until we can aquire a lock on the client
    43  	vcdClient.Mutex.Lock()
    44  	defer vcdClient.Mutex.Unlock()
    45  
    46  	// Creating a loop to offer further protection from the edge gateway erroring
    47  	// due to being busy eg another person is using another client so wouldn't be
    48  	// constrained by out lock. If the edge gateway reurns with a busy error, wait
    49  	// 3 seconds and then try again. Continue until a non-busy error or success
    50  	edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
    51  	if err != nil {
    52  		return fmt.Errorf("Unable to find edge gateway: %#v", err)
    53  	}
    54  
    55  	err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError {
    56  		task, err := edgeGateway.AddNATMapping("SNAT", d.Get("internal_ip").(string),
    57  			d.Get("external_ip").(string),
    58  			"any")
    59  		if err != nil {
    60  			return resource.RetryableError(fmt.Errorf("Error setting SNAT rules: %#v", err))
    61  		}
    62  		return resource.RetryableError(task.WaitTaskCompletion())
    63  	})
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	d.SetId(d.Get("internal_ip").(string))
    69  	return nil
    70  }
    71  
    72  func resourceVcdSNATRead(d *schema.ResourceData, meta interface{}) error {
    73  	vcdClient := meta.(*VCDClient)
    74  	e, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
    75  
    76  	if err != nil {
    77  		return fmt.Errorf("Unable to find edge gateway: %#v", err)
    78  	}
    79  
    80  	var found bool
    81  
    82  	for _, r := range e.EdgeGateway.Configuration.EdgeGatewayServiceConfiguration.NatService.NatRule {
    83  		if r.RuleType == "SNAT" &&
    84  			r.GatewayNatRule.OriginalIP == d.Id() {
    85  			found = true
    86  			d.Set("external_ip", r.GatewayNatRule.TranslatedIP)
    87  		}
    88  	}
    89  
    90  	if !found {
    91  		d.SetId("")
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  func resourceVcdSNATDelete(d *schema.ResourceData, meta interface{}) error {
    98  	vcdClient := meta.(*VCDClient)
    99  	// Multiple VCD components need to run operations on the Edge Gateway, as
   100  	// the edge gatway will throw back an error if it is already performing an
   101  	// operation we must wait until we can aquire a lock on the client
   102  	vcdClient.Mutex.Lock()
   103  	defer vcdClient.Mutex.Unlock()
   104  
   105  	edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
   106  	if err != nil {
   107  		return fmt.Errorf("Unable to find edge gateway: %#v", err)
   108  	}
   109  
   110  	err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError {
   111  		task, err := edgeGateway.RemoveNATMapping("SNAT", d.Get("internal_ip").(string),
   112  			d.Get("external_ip").(string),
   113  			"")
   114  		if err != nil {
   115  			return resource.RetryableError(fmt.Errorf("Error setting SNAT rules: %#v", err))
   116  		}
   117  		return resource.RetryableError(task.WaitTaskCompletion())
   118  	})
   119  	if err != nil {
   120  		return err
   121  	}
   122  
   123  	return nil
   124  }