github.com/erriapo/terraform@v0.6.12-0.20160203182612-0340ea72354f/builtin/providers/vcd/resource_vcd_snat.go (about)

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