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