terraform/builtin/providers/google/resource_compute_router_int...

270 lines
6.8 KiB
Go
Raw Normal View History

2017-01-27 15:32:42 +01:00
package google
import (
"fmt"
"log"
"strings"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
)
func resourceComputeRouterInterface() *schema.Resource {
return &schema.Resource{
Create: resourceComputeRouterInterfaceCreate,
Read: resourceComputeRouterInterfaceRead,
Delete: resourceComputeRouterInterfaceDelete,
Importer: &schema.ResourceImporter{
State: resourceComputeRouterInterfaceImportState,
},
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"router": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"vpn_tunnel": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: linkDiffSuppress,
2017-01-27 15:32:42 +01:00
},
"ip_range": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"project": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
2017-01-27 15:32:42 +01:00
ForceNew: true,
},
"region": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
},
}
}
func resourceComputeRouterInterfaceCreate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
region, err := getRegion(d, config)
if err != nil {
return err
}
project, err := getProject(d, config)
if err != nil {
return err
}
routerName := d.Get("router").(string)
ifaceName := d.Get("name").(string)
routerLock := getRouterLockName(region, routerName)
mutexKV.Lock(routerLock)
defer mutexKV.Unlock(routerLock)
2017-01-27 15:32:42 +01:00
routersService := config.clientCompute.Routers
2017-01-27 15:32:42 +01:00
router, err := routersService.Get(project, region, routerName).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
log.Printf("[WARN] Removing router interface %s because its router %s/%s is gone", ifaceName, region, routerName)
2017-01-27 15:32:42 +01:00
d.SetId("")
return nil
}
return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err)
}
ifaces := router.Interfaces
2017-01-27 15:32:42 +01:00
for _, iface := range ifaces {
if iface.Name == ifaceName {
d.SetId("")
return fmt.Errorf("Router %s has interface %s already", routerName, ifaceName)
2017-01-27 15:32:42 +01:00
}
}
vpnTunnel, err := getVpnTunnelLink(config, project, region, d.Get("vpn_tunnel").(string))
if err != nil {
return err
}
2017-01-27 15:32:42 +01:00
iface := &compute.RouterInterface{Name: ifaceName,
LinkedVpnTunnel: vpnTunnel}
2017-01-27 15:32:42 +01:00
if v, ok := d.GetOk("ip_range"); ok {
iface.IpRange = v.(string)
}
2017-01-27 15:32:42 +01:00
log.Printf("[INFO] Adding interface %s", ifaceName)
ifaces = append(ifaces, iface)
patchRouter := &compute.Router{
Interfaces: ifaces,
}
2017-01-27 15:32:42 +01:00
log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, ifaces)
op, err := routersService.Patch(project, region, router.Name, patchRouter).Do()
if err != nil {
return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err)
}
d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName))
err = computeOperationWaitRegion(config, op, project, region, "Patching router")
if err != nil {
d.SetId("")
return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err)
2017-01-27 15:32:42 +01:00
}
return resourceComputeRouterInterfaceRead(d, meta)
}
func resourceComputeRouterInterfaceRead(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
region, err := getRegion(d, config)
if err != nil {
return err
}
project, err := getProject(d, config)
if err != nil {
return err
}
routerName := d.Get("router").(string)
ifaceName := d.Get("name").(string)
routersService := config.clientCompute.Routers
2017-01-27 15:32:42 +01:00
router, err := routersService.Get(project, region, routerName).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
log.Printf("[WARN] Removing router interface %s because its router %s/%s is gone", ifaceName, region, routerName)
2017-01-27 15:32:42 +01:00
d.SetId("")
return nil
}
return fmt.Errorf("Error Reading router %s/%s: %s", region, routerName, err)
}
for _, iface := range router.Interfaces {
2017-01-27 15:32:42 +01:00
if iface.Name == ifaceName {
d.SetId(fmt.Sprintf("%s/%s/%s", region, routerName, ifaceName))
d.Set("vpn_tunnel", iface.LinkedVpnTunnel)
2017-01-27 15:32:42 +01:00
d.Set("ip_range", iface.IpRange)
d.Set("region", region)
d.Set("project", project)
return nil
2017-01-27 15:32:42 +01:00
}
}
log.Printf("[WARN] Removing router interface %s/%s/%s because it is gone", region, routerName, ifaceName)
d.SetId("")
2017-01-27 15:32:42 +01:00
return nil
}
func resourceComputeRouterInterfaceDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
region, err := getRegion(d, config)
if err != nil {
return err
}
project, err := getProject(d, config)
if err != nil {
return err
}
routerName := d.Get("router").(string)
ifaceName := d.Get("name").(string)
routerLock := getRouterLockName(region, routerName)
mutexKV.Lock(routerLock)
defer mutexKV.Unlock(routerLock)
2017-01-27 15:32:42 +01:00
routersService := config.clientCompute.Routers
2017-01-27 15:32:42 +01:00
router, err := routersService.Get(project, region, routerName).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
log.Printf("[WARN] Removing router interface %s because its router %s/%s is gone", ifaceName, region, routerName)
2017-01-27 15:32:42 +01:00
return nil
}
return fmt.Errorf("Error Reading Router %s: %s", routerName, err)
}
var ifaceFound bool
2017-01-27 15:32:42 +01:00
newIfaces := make([]*compute.RouterInterface, 0, len(router.Interfaces))
for _, iface := range router.Interfaces {
2017-01-27 15:32:42 +01:00
if iface.Name == ifaceName {
ifaceFound = true
continue
} else {
newIfaces = append(newIfaces, iface)
}
}
if !ifaceFound {
log.Printf("[DEBUG] Router %s/%s had no interface %s already", region, routerName, ifaceName)
d.SetId("")
return nil
}
2017-01-27 15:32:42 +01:00
log.Printf(
"[INFO] Removing interface %s from router %s/%s", ifaceName, region, routerName)
patchRouter := &compute.Router{
Interfaces: newIfaces,
}
2017-01-27 15:32:42 +01:00
log.Printf("[DEBUG] Updating router %s/%s with interfaces: %+v", region, routerName, newIfaces)
op, err := routersService.Patch(project, region, router.Name, patchRouter).Do()
if err != nil {
return fmt.Errorf("Error patching router %s/%s: %s", region, routerName, err)
}
2017-01-27 15:32:42 +01:00
err = computeOperationWaitRegion(config, op, project, region, "Patching router")
if err != nil {
return fmt.Errorf("Error waiting to patch router %s/%s: %s", region, routerName, err)
2017-01-27 15:32:42 +01:00
}
d.SetId("")
2017-01-27 15:32:42 +01:00
return nil
}
func resourceComputeRouterInterfaceImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
parts := strings.Split(d.Id(), "/")
if len(parts) != 3 {
return nil, fmt.Errorf("Invalid router interface specifier. Expecting {region}/{router}/{interface}")
2017-01-27 15:32:42 +01:00
}
d.Set("region", parts[0])
d.Set("router", parts[1])
d.Set("name", parts[2])
return []*schema.ResourceData{d}, nil
}