github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/google/resource_compute_router_interface.go (about) 1 package google 2 3 import ( 4 "fmt" 5 "log" 6 7 "strings" 8 9 "github.com/hashicorp/terraform/helper/schema" 10 "google.golang.org/api/compute/v1" 11 "google.golang.org/api/googleapi" 12 ) 13 14 func resourceComputeRouterInterface() *schema.Resource { 15 return &schema.Resource{ 16 Create: resourceComputeRouterInterfaceCreate, 17 Read: resourceComputeRouterInterfaceRead, 18 Delete: resourceComputeRouterInterfaceDelete, 19 Importer: &schema.ResourceImporter{ 20 State: resourceComputeRouterInterfaceImportState, 21 }, 22 23 Schema: map[string]*schema.Schema{ 24 "name": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: true, 28 }, 29 "router": &schema.Schema{ 30 Type: schema.TypeString, 31 Required: true, 32 ForceNew: true, 33 }, 34 "vpn_tunnel": &schema.Schema{ 35 Type: schema.TypeString, 36 Required: true, 37 ForceNew: true, 38 DiffSuppressFunc: linkDiffSuppress, 39 }, 40 41 "ip_range": &schema.Schema{ 42 Type: schema.TypeString, 43 Optional: true, 44 ForceNew: true, 45 }, 46 "project": &schema.Schema{ 47 Type: schema.TypeString, 48 Optional: true, 49 Computed: true, 50 ForceNew: true, 51 }, 52 53 "region": &schema.Schema{ 54 Type: schema.TypeString, 55 Optional: true, 56 Computed: true, 57 ForceNew: true, 58 }, 59 }, 60 } 61 } 62 63 func resourceComputeRouterInterfaceCreate(d *schema.ResourceData, meta interface{}) error { 64 65 config := meta.(*Config) 66 67 region, err := getRegion(d, config) 68 if err != nil { 69 return err 70 } 71 72 project, err := getProject(d, config) 73 if err != nil { 74 return err 75 } 76 77 routerName := d.Get("router").(string) 78 ifaceName := d.Get("name").(string) 79 80 routerLock := getRouterLockName(region, routerName) 81 mutexKV.Lock(routerLock) 82 defer mutexKV.Unlock(routerLock) 83 84 routersService := config.clientCompute.Routers 85 router, err := routersService.Get(project, region, routerName).Do() 86 if err != nil { 87 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 88 log.Printf("[WARN] Removing router interface %s because its router %s/%s is gone", ifaceName, region, routerName) 89 d.SetId("") 90 91 return nil 92 } 93 94 return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) 95 } 96 97 ifaces := router.Interfaces 98 for _, iface := range ifaces { 99 if iface.Name == ifaceName { 100 d.SetId("") 101 return fmt.Errorf("Router %s has interface %s already", routerName, ifaceName) 102 } 103 } 104 105 vpnTunnel, err := getVpnTunnelLink(config, project, region, d.Get("vpn_tunnel").(string)) 106 if err != nil { 107 return err 108 } 109 110 iface := &compute.RouterInterface{Name: ifaceName, 111 LinkedVpnTunnel: vpnTunnel} 112 113 if v, ok := d.GetOk("ip_range"); ok { 114 iface.IpRange = v.(string) 115 } 116 117 log.Printf("[INFO] Adding interface %s", ifaceName) 118 ifaces = append(ifaces, iface) 119 patchRouter := &compute.Router{ 120 Interfaces: ifaces, 121 } 122 123 log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, ifaces) 124 op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() 125 if err != nil { 126 return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) 127 } 128 d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName)) 129 err = computeOperationWaitRegion(config, op, project, region, "Patching router") 130 if err != nil { 131 d.SetId("") 132 return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) 133 } 134 135 return resourceComputeRouterInterfaceRead(d, meta) 136 } 137 138 func resourceComputeRouterInterfaceRead(d *schema.ResourceData, meta interface{}) error { 139 140 config := meta.(*Config) 141 142 region, err := getRegion(d, config) 143 if err != nil { 144 return err 145 } 146 147 project, err := getProject(d, config) 148 if err != nil { 149 return err 150 } 151 152 routerName := d.Get("router").(string) 153 ifaceName := d.Get("name").(string) 154 155 routersService := config.clientCompute.Routers 156 router, err := routersService.Get(project, region, routerName).Do() 157 if err != nil { 158 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 159 log.Printf("[WARN] Removing router interface %s because its router %s/%s is gone", ifaceName, region, routerName) 160 d.SetId("") 161 162 return nil 163 } 164 165 return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err) 166 } 167 168 for _, iface := range router.Interfaces { 169 170 if iface.Name == ifaceName { 171 d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName)) 172 d.Set("vpn_tunnel", iface.LinkedVpnTunnel) 173 d.Set("ip_range", iface.IpRange) 174 d.Set("region", region) 175 d.Set("project", project) 176 return nil 177 } 178 } 179 180 log.Printf("[WARN] Removing router interface %s/%s/%s because it is gone", region, routerName, ifaceName) 181 d.SetId("") 182 return nil 183 } 184 185 func resourceComputeRouterInterfaceDelete(d *schema.ResourceData, meta interface{}) error { 186 187 config := meta.(*Config) 188 189 region, err := getRegion(d, config) 190 if err != nil { 191 return err 192 } 193 194 project, err := getProject(d, config) 195 if err != nil { 196 return err 197 } 198 199 routerName := d.Get("router").(string) 200 ifaceName := d.Get("name").(string) 201 202 routerLock := getRouterLockName(region, routerName) 203 mutexKV.Lock(routerLock) 204 defer mutexKV.Unlock(routerLock) 205 206 routersService := config.clientCompute.Routers 207 router, err := routersService.Get(project, region, routerName).Do() 208 if err != nil { 209 if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 { 210 log.Printf("[WARN] Removing router interface %s because its router %s/%s is gone", ifaceName, region, routerName) 211 212 return nil 213 } 214 215 return fmt.Errorf("Error Reading Router %s: %s", routerName, err) 216 } 217 218 var ifaceFound bool 219 220 newIfaces := make([]*compute.RouterInterface, 0, len(router.Interfaces)) 221 for _, iface := range router.Interfaces { 222 223 if iface.Name == ifaceName { 224 ifaceFound = true 225 continue 226 } else { 227 newIfaces = append(newIfaces, iface) 228 } 229 } 230 231 if !ifaceFound { 232 log.Printf("[DEBUG] Router %s/%s had no interface %s already", region, routerName, ifaceName) 233 d.SetId("") 234 return nil 235 } 236 237 log.Printf( 238 "[INFO] Removing interface %s from router %s/%s", ifaceName, region, routerName) 239 patchRouter := &compute.Router{ 240 Interfaces: newIfaces, 241 } 242 243 log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, newIfaces) 244 op, err := routersService.Patch(project, region, router.Name, patchRouter).Do() 245 if err != nil { 246 return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err) 247 } 248 249 err = computeOperationWaitRegion(config, op, project, region, "Patching router") 250 if err != nil { 251 return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err) 252 } 253 254 d.SetId("") 255 return nil 256 } 257 258 func resourceComputeRouterInterfaceImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { 259 parts := strings.Split(d.Id(), "/") 260 if len(parts) != 3 { 261 return nil, fmt.Errorf("Invalid router interface specifier. Expecting {region}/{router}/{interface}") 262 } 263 264 d.Set("region", parts[0]) 265 d.Set("router", parts[1]) 266 d.Set("name", parts[2]) 267 268 return []*schema.ResourceData{d}, nil 269 }