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 }