github.com/koding/terraform@v0.6.4-0.20170608090606-5d7e0339779d/builtin/providers/google/resource_compute_router.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 resourceComputeRouter() *schema.Resource {
    15  	return &schema.Resource{
    16  		Create: resourceComputeRouterCreate,
    17  		Read:   resourceComputeRouterRead,
    18  		Delete: resourceComputeRouterDelete,
    19  		Importer: &schema.ResourceImporter{
    20  			State: resourceComputeRouterImportState,
    21  		},
    22  
    23  		Schema: map[string]*schema.Schema{
    24  			"name": &schema.Schema{
    25  				Type:     schema.TypeString,
    26  				Required: true,
    27  				ForceNew: true,
    28  			},
    29  
    30  			"network": &schema.Schema{
    31  				Type:             schema.TypeString,
    32  				Required:         true,
    33  				ForceNew:         true,
    34  				DiffSuppressFunc: linkDiffSuppress,
    35  			},
    36  
    37  			"description": &schema.Schema{
    38  				Type:     schema.TypeString,
    39  				Optional: true,
    40  				ForceNew: true,
    41  			},
    42  
    43  			"project": &schema.Schema{
    44  				Type:     schema.TypeString,
    45  				Optional: true,
    46  				Computed: true,
    47  				ForceNew: true,
    48  			},
    49  
    50  			"region": &schema.Schema{
    51  				Type:     schema.TypeString,
    52  				Optional: true,
    53  				Computed: true,
    54  				ForceNew: true,
    55  			},
    56  
    57  			"bgp": &schema.Schema{
    58  				Type:     schema.TypeList,
    59  				MaxItems: 1,
    60  				Required: true,
    61  				ForceNew: true,
    62  				Elem: &schema.Resource{
    63  					Schema: map[string]*schema.Schema{
    64  
    65  						"asn": &schema.Schema{
    66  							Type:     schema.TypeInt,
    67  							Required: true,
    68  							ForceNew: true,
    69  						},
    70  					},
    71  				},
    72  			},
    73  
    74  			"self_link": &schema.Schema{
    75  				Type:     schema.TypeString,
    76  				Computed: true,
    77  			},
    78  		},
    79  	}
    80  }
    81  
    82  func resourceComputeRouterCreate(d *schema.ResourceData, meta interface{}) error {
    83  
    84  	config := meta.(*Config)
    85  
    86  	region, err := getRegion(d, config)
    87  	if err != nil {
    88  		return err
    89  	}
    90  
    91  	project, err := getProject(d, config)
    92  	if err != nil {
    93  		return err
    94  	}
    95  
    96  	name := d.Get("name").(string)
    97  
    98  	routerLock := getRouterLockName(region, name)
    99  	mutexKV.Lock(routerLock)
   100  	defer mutexKV.Unlock(routerLock)
   101  
   102  	network, err := getNetworkLink(d, config, "network")
   103  	if err != nil {
   104  		return err
   105  	}
   106  	routersService := config.clientCompute.Routers
   107  
   108  	router := &compute.Router{
   109  		Name:    name,
   110  		Network: network,
   111  	}
   112  
   113  	if v, ok := d.GetOk("description"); ok {
   114  		router.Description = v.(string)
   115  	}
   116  
   117  	if _, ok := d.GetOk("bgp"); ok {
   118  		prefix := "bgp.0"
   119  		if v, ok := d.GetOk(prefix + ".asn"); ok {
   120  			asn := v.(int)
   121  			bgp := &compute.RouterBgp{
   122  				Asn: int64(asn),
   123  			}
   124  			router.Bgp = bgp
   125  		}
   126  	}
   127  
   128  	op, err := routersService.Insert(project, region, router).Do()
   129  	if err != nil {
   130  		return fmt.Errorf("Error Inserting Router %s into network %s: %s", name, network, err)
   131  	}
   132  	d.SetId(fmt.Sprintf("%s/%s", region, name))
   133  	err = computeOperationWaitRegion(config, op, project, region, "Inserting Router")
   134  	if err != nil {
   135  		d.SetId("")
   136  		return fmt.Errorf("Error Waiting to Insert Router %s into network %s: %s", name, network, err)
   137  	}
   138  
   139  	return resourceComputeRouterRead(d, meta)
   140  }
   141  
   142  func resourceComputeRouterRead(d *schema.ResourceData, meta interface{}) error {
   143  
   144  	config := meta.(*Config)
   145  
   146  	region, err := getRegion(d, config)
   147  	if err != nil {
   148  		return err
   149  	}
   150  
   151  	project, err := getProject(d, config)
   152  	if err != nil {
   153  		return err
   154  	}
   155  
   156  	name := d.Get("name").(string)
   157  	routersService := config.clientCompute.Routers
   158  	router, err := routersService.Get(project, region, name).Do()
   159  
   160  	if err != nil {
   161  		if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
   162  			log.Printf("[WARN] Removing router %s/%s because it is gone", region, name)
   163  			d.SetId("")
   164  
   165  			return nil
   166  		}
   167  
   168  		return fmt.Errorf("Error Reading Router %s: %s", name, err)
   169  	}
   170  
   171  	d.Set("self_link", router.SelfLink)
   172  	d.Set("network", router.Network)
   173  
   174  	d.Set("name", router.Name)
   175  	d.Set("description", router.Description)
   176  	d.Set("region", region)
   177  	d.Set("project", project)
   178  	d.Set("bgp", flattenAsn(router.Bgp.Asn))
   179  	d.SetId(fmt.Sprintf("%s/%s", region, name))
   180  
   181  	return nil
   182  }
   183  
   184  func resourceComputeRouterDelete(d *schema.ResourceData, meta interface{}) error {
   185  
   186  	config := meta.(*Config)
   187  
   188  	region, err := getRegion(d, config)
   189  	if err != nil {
   190  		return err
   191  	}
   192  
   193  	project, err := getProject(d, config)
   194  	if err != nil {
   195  		return err
   196  	}
   197  
   198  	name := d.Get("name").(string)
   199  
   200  	routerLock := getRouterLockName(region, name)
   201  	mutexKV.Lock(routerLock)
   202  	defer mutexKV.Unlock(routerLock)
   203  
   204  	routersService := config.clientCompute.Routers
   205  
   206  	op, err := routersService.Delete(project, region, name).Do()
   207  	if err != nil {
   208  		return fmt.Errorf("Error Reading Router %s: %s", name, err)
   209  	}
   210  
   211  	err = computeOperationWaitRegion(config, op, project, region, "Deleting Router")
   212  	if err != nil {
   213  		return fmt.Errorf("Error Waiting to Delete Router %s: %s", name, err)
   214  	}
   215  
   216  	d.SetId("")
   217  	return nil
   218  }
   219  
   220  func resourceComputeRouterImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
   221  	parts := strings.Split(d.Id(), "/")
   222  	if len(parts) != 2 {
   223  		return nil, fmt.Errorf("Invalid router specifier. Expecting {region}/{name}")
   224  	}
   225  
   226  	d.Set("region", parts[0])
   227  	d.Set("name", parts[1])
   228  
   229  	return []*schema.ResourceData{d}, nil
   230  }
   231  
   232  func getRouterLink(config *Config, project string, region string, router string) (string, error) {
   233  
   234  	if !strings.HasPrefix(router, "https://www.googleapis.com/compute/") {
   235  		// Router value provided is just the name, lookup the router SelfLink
   236  		routerData, err := config.clientCompute.Routers.Get(
   237  			project, region, router).Do()
   238  		if err != nil {
   239  			return "", fmt.Errorf("Error reading router: %s", err)
   240  		}
   241  		router = routerData.SelfLink
   242  	}
   243  
   244  	return router, nil
   245  
   246  }
   247  
   248  func flattenAsn(asn int64) []map[string]interface{} {
   249  	result := make([]map[string]interface{}, 0, 1)
   250  	r := make(map[string]interface{})
   251  	r["asn"] = asn
   252  	result = append(result, r)
   253  	return result
   254  }