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  }