github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/builtin/providers/vcd/resource_vcd_dnat.go (about)

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