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

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