github.com/leeprovoost/terraform@v0.6.10-0.20160119085442-96f3f76118e7/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 }