github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/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 }