github.com/minamijoyo/terraform@v0.7.8-0.20161029001309-18b3736ba44b/builtin/providers/vcd/resource_vcd_dnat.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 resourceVcdDNAT() *schema.Resource {
    11  	return &schema.Resource{
    12  		Create: resourceVcdDNATCreate,
    13  		Delete: resourceVcdDNATDelete,
    14  		Read:   resourceVcdDNATRead,
    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  			"port": &schema.Schema{
    30  				Type:     schema.TypeInt,
    31  				Required: true,
    32  				ForceNew: true,
    33  			},
    34  
    35  			"internal_ip": &schema.Schema{
    36  				Type:     schema.TypeString,
    37  				Required: true,
    38  				ForceNew: true,
    39  			},
    40  		},
    41  	}
    42  }
    43  
    44  func resourceVcdDNATCreate(d *schema.ResourceData, meta interface{}) error {
    45  	vcdClient := meta.(*VCDClient)
    46  	// Multiple VCD components need to run operations on the Edge Gateway, as
    47  	// the edge gatway will throw back an error if it is already performing an
    48  	// operation we must wait until we can aquire a lock on the client
    49  	vcdClient.Mutex.Lock()
    50  	defer vcdClient.Mutex.Unlock()
    51  	portString := getPortString(d.Get("port").(int))
    52  
    53  	edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
    54  
    55  	if err != nil {
    56  		return fmt.Errorf("Unable to find edge gateway: %#v", err)
    57  	}
    58  
    59  	// Creating a loop to offer further protection from the edge gateway erroring
    60  	// due to being busy eg another person is using another client so wouldn't be
    61  	// constrained by out lock. If the edge gateway reurns with a busy error, wait
    62  	// 3 seconds and then try again. Continue until a non-busy error or success
    63  
    64  	err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError {
    65  		task, err := edgeGateway.AddNATMapping("DNAT", d.Get("external_ip").(string),
    66  			d.Get("internal_ip").(string),
    67  			portString)
    68  		if err != nil {
    69  			return resource.RetryableError(
    70  				fmt.Errorf("Error setting DNAT rules: %#v", err))
    71  		}
    72  
    73  		return resource.RetryableError(task.WaitTaskCompletion())
    74  	})
    75  
    76  	if err != nil {
    77  		return fmt.Errorf("Error completing tasks: %#v", err)
    78  	}
    79  
    80  	d.SetId(d.Get("external_ip").(string) + "_" + portString)
    81  	return nil
    82  }
    83  
    84  func resourceVcdDNATRead(d *schema.ResourceData, meta interface{}) error {
    85  	vcdClient := meta.(*VCDClient)
    86  	e, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
    87  
    88  	if err != nil {
    89  		return fmt.Errorf("Unable to find edge gateway: %#v", err)
    90  	}
    91  
    92  	var found bool
    93  
    94  	for _, r := range e.EdgeGateway.Configuration.EdgeGatewayServiceConfiguration.NatService.NatRule {
    95  		if r.RuleType == "DNAT" &&
    96  			r.GatewayNatRule.OriginalIP == d.Get("external_ip").(string) &&
    97  			r.GatewayNatRule.OriginalPort == getPortString(d.Get("port").(int)) {
    98  			found = true
    99  			d.Set("internal_ip", r.GatewayNatRule.TranslatedIP)
   100  		}
   101  	}
   102  
   103  	if !found {
   104  		d.SetId("")
   105  	}
   106  
   107  	return nil
   108  }
   109  
   110  func resourceVcdDNATDelete(d *schema.ResourceData, meta interface{}) error {
   111  	vcdClient := meta.(*VCDClient)
   112  	// Multiple VCD components need to run operations on the Edge Gateway, as
   113  	// the edge gatway will throw back an error if it is already performing an
   114  	// operation we must wait until we can aquire a lock on the client
   115  	vcdClient.Mutex.Lock()
   116  	defer vcdClient.Mutex.Unlock()
   117  	portString := getPortString(d.Get("port").(int))
   118  
   119  	edgeGateway, err := vcdClient.OrgVdc.FindEdgeGateway(d.Get("edge_gateway").(string))
   120  
   121  	if err != nil {
   122  		return fmt.Errorf("Unable to find edge gateway: %#v", err)
   123  	}
   124  	err = retryCall(vcdClient.MaxRetryTimeout, func() *resource.RetryError {
   125  		task, err := edgeGateway.RemoveNATMapping("DNAT", d.Get("external_ip").(string),
   126  			d.Get("internal_ip").(string),
   127  			portString)
   128  		if err != nil {
   129  			return resource.RetryableError(
   130  				fmt.Errorf("Error setting DNAT rules: %#v", err))
   131  		}
   132  
   133  		return resource.RetryableError(task.WaitTaskCompletion())
   134  	})
   135  	if err != nil {
   136  		return fmt.Errorf("Error completing tasks: %#v", err)
   137  	}
   138  	return nil
   139  }