Autogenerate router resource. Also adds update support and a few new fields. (#1723)

This commit is contained in:
The Magician 2018-07-12 12:51:11 -07:00 committed by Dana Hoffman
parent 39b17f0e3b
commit 499690f3b3
7 changed files with 671 additions and 305 deletions

View File

@ -27,6 +27,7 @@ var GeneratedComputeResourcesMap = map[string]*schema.Resource{
"google_compute_https_health_check": resourceComputeHttpsHealthCheck(),
"google_compute_region_autoscaler": resourceComputeRegionAutoscaler(),
"google_compute_route": resourceComputeRoute(),
"google_compute_router": resourceComputeRouter(),
"google_compute_ssl_policy": resourceComputeSslPolicy(),
"google_compute_subnetwork": resourceComputeSubnetwork(),
"google_compute_target_http_proxy": resourceComputeTargetHttpProxy(),

View File

@ -1,77 +1,125 @@
// ----------------------------------------------------------------------------
//
// *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
//
// ----------------------------------------------------------------------------
//
// This file is automatically generated by Magic Modules and manual
// changes will be clobbered when the file is regenerated.
//
// Please read more about how to change this file in
// .github/CONTRIBUTING.md.
//
// ----------------------------------------------------------------------------
package google
import (
"fmt"
"log"
"strings"
"reflect"
"strconv"
"time"
"github.com/hashicorp/terraform/helper/schema"
"google.golang.org/api/compute/v1"
"google.golang.org/api/googleapi"
"github.com/hashicorp/terraform/helper/validation"
compute "google.golang.org/api/compute/v1"
)
func resourceComputeRouter() *schema.Resource {
return &schema.Resource{
Create: resourceComputeRouterCreate,
Read: resourceComputeRouterRead,
Update: resourceComputeRouterUpdate,
Delete: resourceComputeRouterDelete,
Importer: &schema.ResourceImporter{
State: resourceComputeRouterImportState,
State: resourceComputeRouterImport,
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(240 * time.Second),
Update: schema.DefaultTimeout(240 * time.Second),
Delete: schema.DefaultTimeout(240 * time.Second),
},
Schema: map[string]*schema.Schema{
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateGCPName,
},
"network": &schema.Schema{
"network": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
},
"description": &schema.Schema{
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"project": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"region": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"bgp": &schema.Schema{
"bgp": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Required: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"asn": &schema.Schema{
"asn": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
},
"advertise_mode": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"DEFAULT", "CUSTOM", ""}, false),
Default: "DEFAULT",
},
"advertised_groups": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"advertised_ip_ranges": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"range": {
Type: schema.TypeString,
Optional: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
},
},
},
"self_link": &schema.Schema{
"region": {
Type: schema.TypeString,
Computed: true,
Optional: true,
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
},
"creation_timestamp": {
Type: schema.TypeString,
Computed: true,
},
"project": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"self_link": {
Type: schema.TypeString,
Computed: true,
},
@ -80,176 +128,444 @@ func resourceComputeRouter() *schema.Resource {
}
func resourceComputeRouterCreate(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
}
name := d.Get("name").(string)
obj := make(map[string]interface{})
nameProp, err := expandComputeRouterName(d.Get("name"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(nameProp)) && (ok || !reflect.DeepEqual(v, nameProp)) {
obj["name"] = nameProp
}
descriptionProp, err := expandComputeRouterDescription(d.Get("description"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(descriptionProp)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
obj["description"] = descriptionProp
}
networkProp, err := expandComputeRouterNetwork(d.Get("network"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("network"); !isEmptyValue(reflect.ValueOf(networkProp)) && (ok || !reflect.DeepEqual(v, networkProp)) {
obj["network"] = networkProp
}
bgpProp, err := expandComputeRouterBgp(d.Get("bgp"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("bgp"); !isEmptyValue(reflect.ValueOf(bgpProp)) && (ok || !reflect.DeepEqual(v, bgpProp)) {
obj["bgp"] = bgpProp
}
regionProp, err := expandComputeRouterRegion(d.Get("region"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("region"); !isEmptyValue(reflect.ValueOf(regionProp)) && (ok || !reflect.DeepEqual(v, regionProp)) {
obj["region"] = regionProp
}
routerLock := getRouterLockName(region, name)
mutexKV.Lock(routerLock)
defer mutexKV.Unlock(routerLock)
lockName, err := replaceVars(d, config, "router/{{region}}/{{name}}")
if err != nil {
return err
}
mutexKV.Lock(lockName)
defer mutexKV.Unlock(lockName)
network, err := ParseNetworkFieldValue(d.Get("network").(string), d, config)
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/routers")
if err != nil {
return err
}
routersService := config.clientCompute.Routers
router := &compute.Router{
Name: name,
Network: network.RelativeLink(),
}
if v, ok := d.GetOk("description"); ok {
router.Description = v.(string)
}
if _, ok := d.GetOk("bgp"); ok {
prefix := "bgp.0"
if v, ok := d.GetOk(prefix + ".asn"); ok {
asn := v.(int)
bgp := &compute.RouterBgp{
Asn: int64(asn),
}
router.Bgp = bgp
}
}
op, err := routersService.Insert(project, region, router).Do()
log.Printf("[DEBUG] Creating new Router: %#v", obj)
res, err := Post(config, url, obj)
if err != nil {
return fmt.Errorf("Error Inserting Router %s into network %s: %s", name, network.Name, err)
return fmt.Errorf("Error creating Router: %s", err)
}
d.SetId(fmt.Sprintf("%s/%s", region, name))
err = computeOperationWait(config.clientCompute, op, project, "Inserting Router")
// Store the ID now
id, err := replaceVars(d, config, "{{region}}/{{name}}")
if err != nil {
return fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)
op := &compute.Operation{}
err = Convert(res, op)
if err != nil {
return err
}
waitErr := computeOperationWaitTime(
config.clientCompute, op, project, "Creating Router",
int(d.Timeout(schema.TimeoutCreate).Minutes()))
if waitErr != nil {
// The resource didn't actually create
d.SetId("")
return fmt.Errorf("Error Waiting to Insert Router %s into network %s: %s", name, network.Name, err)
return fmt.Errorf("Error waiting to create Router: %s", waitErr)
}
log.Printf("[DEBUG] Finished creating Router %q: %#v", d.Id(), res)
return resourceComputeRouterRead(d, meta)
}
func resourceComputeRouterRead(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
}
name := d.Get("name").(string)
routersService := config.clientCompute.Routers
router, err := routersService.Get(project, region, name).Do()
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/routers/{{name}}")
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 404 {
log.Printf("[WARN] Removing router %s/%s because it is gone", region, name)
d.SetId("")
return nil
}
return fmt.Errorf("Error Reading Router %s: %s", name, err)
return err
}
d.Set("self_link", router.SelfLink)
d.Set("network", router.Network)
res, err := Get(config, url)
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("ComputeRouter %q", d.Id()))
}
d.Set("name", router.Name)
d.Set("description", router.Description)
d.Set("region", region)
d.Set("project", project)
d.Set("bgp", flattenAsn(router.Bgp.Asn))
d.SetId(fmt.Sprintf("%s/%s", region, name))
if err := d.Set("creation_timestamp", flattenComputeRouterCreationTimestamp(res["creationTimestamp"])); err != nil {
return fmt.Errorf("Error reading Router: %s", err)
}
if err := d.Set("name", flattenComputeRouterName(res["name"])); err != nil {
return fmt.Errorf("Error reading Router: %s", err)
}
if err := d.Set("description", flattenComputeRouterDescription(res["description"])); err != nil {
return fmt.Errorf("Error reading Router: %s", err)
}
if err := d.Set("network", flattenComputeRouterNetwork(res["network"])); err != nil {
return fmt.Errorf("Error reading Router: %s", err)
}
if err := d.Set("bgp", flattenComputeRouterBgp(res["bgp"])); err != nil {
return fmt.Errorf("Error reading Router: %s", err)
}
if err := d.Set("region", flattenComputeRouterRegion(res["region"])); err != nil {
return fmt.Errorf("Error reading Router: %s", err)
}
if err := d.Set("self_link", ConvertSelfLinkToV1(res["selfLink"].(string))); err != nil {
return fmt.Errorf("Error reading Router: %s", err)
}
if err := d.Set("project", project); err != nil {
return fmt.Errorf("Error reading Router: %s", err)
}
return nil
}
func resourceComputeRouterUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
project, err := getProject(d, config)
if err != nil {
return err
}
obj := make(map[string]interface{})
nameProp, err := expandComputeRouterName(d.Get("name"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("name"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, nameProp)) {
obj["name"] = nameProp
}
descriptionProp, err := expandComputeRouterDescription(d.Get("description"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("description"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, descriptionProp)) {
obj["description"] = descriptionProp
}
networkProp, err := expandComputeRouterNetwork(d.Get("network"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("network"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, networkProp)) {
obj["network"] = networkProp
}
bgpProp, err := expandComputeRouterBgp(d.Get("bgp"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("bgp"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, bgpProp)) {
obj["bgp"] = bgpProp
}
regionProp, err := expandComputeRouterRegion(d.Get("region"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("region"); !isEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, regionProp)) {
obj["region"] = regionProp
}
lockName, err := replaceVars(d, config, "router/{{region}}/{{name}}")
if err != nil {
return err
}
mutexKV.Lock(lockName)
defer mutexKV.Unlock(lockName)
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/routers/{{name}}")
if err != nil {
return err
}
log.Printf("[DEBUG] Updating Router %q: %#v", d.Id(), obj)
res, err := sendRequest(config, "PUT", url, obj)
if err != nil {
return fmt.Errorf("Error updating Router %q: %s", d.Id(), err)
}
op := &compute.Operation{}
err = Convert(res, op)
if err != nil {
return err
}
err = computeOperationWaitTime(
config.clientCompute, op, project, "Updating Router",
int(d.Timeout(schema.TimeoutUpdate).Minutes()))
if err != nil {
return err
}
return resourceComputeRouterRead(d, meta)
}
func resourceComputeRouterDelete(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
}
name := d.Get("name").(string)
routerLock := getRouterLockName(region, name)
mutexKV.Lock(routerLock)
defer mutexKV.Unlock(routerLock)
routersService := config.clientCompute.Routers
op, err := routersService.Delete(project, region, name).Do()
lockName, err := replaceVars(d, config, "router/{{region}}/{{name}}")
if err != nil {
return fmt.Errorf("Error Reading Router %s: %s", name, err)
return err
}
mutexKV.Lock(lockName)
defer mutexKV.Unlock(lockName)
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/regions/{{region}}/routers/{{name}}")
if err != nil {
return err
}
err = computeOperationWait(config.clientCompute, op, project, "Deleting Router")
log.Printf("[DEBUG] Deleting Router %q", d.Id())
res, err := Delete(config, url)
if err != nil {
return fmt.Errorf("Error Waiting to Delete Router %s: %s", name, err)
return handleNotFoundError(err, d, "Router")
}
d.SetId("")
op := &compute.Operation{}
err = Convert(res, op)
if err != nil {
return err
}
err = computeOperationWaitTime(
config.clientCompute, op, project, "Deleting Router",
int(d.Timeout(schema.TimeoutDelete).Minutes()))
if err != nil {
return err
}
log.Printf("[DEBUG] Finished deleting Router %q: %#v", d.Id(), res)
return nil
}
func resourceComputeRouterImportState(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
parts := strings.Split(d.Id(), "/")
if len(parts) != 2 {
return nil, fmt.Errorf("Invalid router specifier. Expecting {region}/{name}")
}
func resourceComputeRouterImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
config := meta.(*Config)
parseImportId([]string{"projects/(?P<project>[^/]+)/regions/(?P<region>[^/]+)/routers/(?P<name>[^/]+)", "(?P<region>[^/]+)/(?P<name>[^/]+)", "(?P<project>[^/]+)/(?P<region>[^/]+)/(?P<name>[^/]+)", "(?P<name>[^/]+)"}, d, config)
d.Set("region", parts[0])
d.Set("name", parts[1])
// Replace import id for the resource id
id, err := replaceVars(d, config, "{{region}}/{{name}}")
if err != nil {
return nil, fmt.Errorf("Error constructing id: %s", err)
}
d.SetId(id)
return []*schema.ResourceData{d}, nil
}
func getRouterLink(config *Config, project string, region string, router string) (string, error) {
func flattenComputeRouterCreationTimestamp(v interface{}) interface{} {
return v
}
if !strings.HasPrefix(router, "https://www.googleapis.com/compute/") {
// Router value provided is just the name, lookup the router SelfLink
routerData, err := config.clientCompute.Routers.Get(
project, region, router).Do()
if err != nil {
return "", fmt.Errorf("Error reading router: %s", err)
}
router = routerData.SelfLink
func flattenComputeRouterName(v interface{}) interface{} {
return v
}
func flattenComputeRouterDescription(v interface{}) interface{} {
return v
}
func flattenComputeRouterNetwork(v interface{}) interface{} {
return v
}
func flattenComputeRouterBgp(v interface{}) interface{} {
if v == nil {
return nil
}
return router, nil
original := v.(map[string]interface{})
transformed := make(map[string]interface{})
transformed["asn"] =
flattenComputeRouterBgpAsn(original["asn"])
transformed["advertise_mode"] =
flattenComputeRouterBgpAdvertiseMode(original["advertiseMode"])
transformed["advertised_groups"] =
flattenComputeRouterBgpAdvertisedGroups(original["advertisedGroups"])
transformed["advertised_ip_ranges"] =
flattenComputeRouterBgpAdvertisedIpRanges(original["advertisedIpRanges"])
return []interface{}{transformed}
}
func flattenComputeRouterBgpAsn(v interface{}) interface{} {
// Handles the string fixed64 format
if strVal, ok := v.(string); ok {
if intVal, err := strconv.ParseInt(strVal, 10, 64); err == nil {
return intVal
} // let terraform core handle it if we can't convert the string to an int.
}
return v
}
func flattenAsn(asn int64) []map[string]interface{} {
result := make([]map[string]interface{}, 0, 1)
r := make(map[string]interface{})
r["asn"] = asn
result = append(result, r)
return result
func flattenComputeRouterBgpAdvertiseMode(v interface{}) interface{} {
return v
}
func flattenComputeRouterBgpAdvertisedGroups(v interface{}) interface{} {
return v
}
func flattenComputeRouterBgpAdvertisedIpRanges(v interface{}) interface{} {
if v == nil {
return v
}
l := v.([]interface{})
transformed := make([]interface{}, 0, len(l))
for _, raw := range l {
original := raw.(map[string]interface{})
transformed = append(transformed, map[string]interface{}{
"range": flattenComputeRouterBgpAdvertisedIpRangesRange(original["range"]),
"description": flattenComputeRouterBgpAdvertisedIpRangesDescription(original["description"]),
})
}
return transformed
}
func flattenComputeRouterBgpAdvertisedIpRangesRange(v interface{}) interface{} {
return v
}
func flattenComputeRouterBgpAdvertisedIpRangesDescription(v interface{}) interface{} {
return v
}
func flattenComputeRouterRegion(v interface{}) interface{} {
return NameFromSelfLinkStateFunc(v)
}
func expandComputeRouterName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeRouterDescription(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeRouterNetwork(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
f, err := parseGlobalFieldValue("networks", v.(string), "project", d, config, true)
if err != nil {
return nil, fmt.Errorf("Invalid value for network: %s", err)
}
return f.RelativeLink(), nil
}
func expandComputeRouterBgp(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
for _, raw := range l {
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})
transformedAsn, err := expandComputeRouterBgpAsn(original["asn"], d, config)
if err != nil {
return nil, err
}
transformed["asn"] = transformedAsn
transformedAdvertiseMode, err := expandComputeRouterBgpAdvertiseMode(original["advertise_mode"], d, config)
if err != nil {
return nil, err
}
transformed["advertiseMode"] = transformedAdvertiseMode
transformedAdvertisedGroups, err := expandComputeRouterBgpAdvertisedGroups(original["advertised_groups"], d, config)
if err != nil {
return nil, err
}
transformed["advertisedGroups"] = transformedAdvertisedGroups
transformedAdvertisedIpRanges, err := expandComputeRouterBgpAdvertisedIpRanges(original["advertised_ip_ranges"], d, config)
if err != nil {
return nil, err
}
transformed["advertisedIpRanges"] = transformedAdvertisedIpRanges
req = append(req, transformed)
}
return req, nil
}
func expandComputeRouterBgpAsn(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeRouterBgpAdvertiseMode(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeRouterBgpAdvertisedGroups(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeRouterBgpAdvertisedIpRanges(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
l := v.([]interface{})
req := make([]interface{}, 0, len(l))
for _, raw := range l {
original := raw.(map[string]interface{})
transformed := make(map[string]interface{})
transformedRange, err := expandComputeRouterBgpAdvertisedIpRangesRange(original["range"], d, config)
if err != nil {
return nil, err
}
transformed["range"] = transformedRange
transformedDescription, err := expandComputeRouterBgpAdvertisedIpRangesDescription(original["description"], d, config)
if err != nil {
return nil, err
}
transformed["description"] = transformedDescription
req = append(req, transformed)
}
return req, nil
}
func expandComputeRouterBgpAdvertisedIpRangesRange(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeRouterBgpAdvertisedIpRangesDescription(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
return v, nil
}
func expandComputeRouterRegion(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) {
f, err := parseGlobalFieldValue("regions", v.(string), "project", d, config, true)
if err != nil {
return nil, fmt.Errorf("Invalid value for region: %s", err)
}
return f.RelativeLink(), nil
}

View File

@ -12,6 +12,7 @@ import (
func TestAccComputeRouter_basic(t *testing.T) {
t.Parallel()
testId := acctest.RandString(10)
resourceRegion := "europe-west1"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
@ -19,13 +20,7 @@ func TestAccComputeRouter_basic(t *testing.T) {
CheckDestroy: testAccCheckComputeRouterDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeRouterBasic(resourceRegion),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeRouterExists(
"google_compute_router.foobar"),
resource.TestCheckResourceAttr(
"google_compute_router.foobar", "region", resourceRegion),
),
Config: testAccComputeRouterBasic(testId, resourceRegion),
},
resource.TestStep{
ResourceName: "google_compute_router.foobar",
@ -39,6 +34,7 @@ func TestAccComputeRouter_basic(t *testing.T) {
func TestAccComputeRouter_noRegion(t *testing.T) {
t.Parallel()
testId := acctest.RandString(10)
providerRegion := "us-central1"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
@ -46,13 +42,66 @@ func TestAccComputeRouter_noRegion(t *testing.T) {
CheckDestroy: testAccCheckComputeRouterDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeRouterNoRegion(providerRegion),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeRouterExists(
"google_compute_router.foobar"),
resource.TestCheckResourceAttr(
"google_compute_router.foobar", "region", providerRegion),
),
Config: testAccComputeRouterNoRegion(testId, providerRegion),
},
resource.TestStep{
ResourceName: "google_compute_router.foobar",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccComputeRouter_full(t *testing.T) {
t.Parallel()
testId := acctest.RandString(10)
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeRouterDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeRouterFull(testId),
},
resource.TestStep{
ResourceName: "google_compute_router.foobar",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
func TestAccComputeRouter_update(t *testing.T) {
t.Parallel()
testId := acctest.RandString(10)
region := getTestRegionFromEnv()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeRouterDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeRouterBasic(testId, region),
},
resource.TestStep{
ResourceName: "google_compute_router.foobar",
ImportState: true,
ImportStateVerify: true,
},
resource.TestStep{
Config: testAccComputeRouterFull(testId),
},
resource.TestStep{
ResourceName: "google_compute_router.foobar",
ImportState: true,
ImportStateVerify: true,
},
resource.TestStep{
Config: testAccComputeRouterBasic(testId, region),
},
resource.TestStep{
ResourceName: "google_compute_router.foobar",
@ -96,47 +145,11 @@ func testAccCheckComputeRouterDestroy(s *terraform.State) error {
return nil
}
func testAccCheckComputeRouterExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No ID is set")
}
config := testAccProvider.Meta().(*Config)
project, err := getTestProject(rs.Primary, config)
if err != nil {
return err
}
region, err := getTestRegion(rs.Primary, config)
if err != nil {
return err
}
name := rs.Primary.Attributes["name"]
routersService := config.clientCompute.Routers
_, err = routersService.Get(project, region, name).Do()
if err != nil {
return fmt.Errorf("Error Reading Router %s: %s", name, err)
}
return nil
}
}
func testAccComputeRouterBasic(resourceRegion string) string {
testId := acctest.RandString(10)
func testAccComputeRouterBasic(testId, resourceRegion string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
name = "router-test-%s"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "foobar" {
name = "router-test-subnetwork-%s"
@ -155,11 +168,11 @@ func testAccComputeRouterBasic(resourceRegion string) string {
`, testId, testId, resourceRegion, testId)
}
func testAccComputeRouterNoRegion(providerRegion string) string {
testId := acctest.RandString(10)
func testAccComputeRouterNoRegion(testId, providerRegion string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
name = "router-test-%s"
auto_create_subnetworks = false
}
resource "google_compute_subnetwork" "foobar" {
name = "router-test-subnetwork-%s"
@ -176,3 +189,28 @@ func testAccComputeRouterNoRegion(providerRegion string) string {
}
`, testId, testId, providerRegion, testId)
}
func testAccComputeRouterFull(testId string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
name = "router-test-%s"
auto_create_subnetworks = false
}
resource "google_compute_router" "foobar" {
name = "router-test-%s"
network = "${google_compute_network.foobar.name}"
bgp {
asn = 64514
advertise_mode = "CUSTOM"
advertised_groups = ["ALL_SUBNETS"]
advertised_ip_ranges {
range = "1.2.3.4"
}
advertised_ip_ranges {
range = "6.7.0.0/16"
}
}
}
`, testId, testId)
}

View File

@ -297,6 +297,7 @@ func resourceComputeSslPolicyUpdate(d *schema.ResourceData, meta interface{}) er
}
obj, err = resourceComputeSslPolicyUpdateEncoder(d, meta, obj)
url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/sslPolicies/{{name}}")
if err != nil {
return err

View File

@ -424,6 +424,7 @@ func resourceRedisInstanceUpdate(d *schema.ResourceData, meta interface{}) error
}
obj, err = resourceRedisInstanceEncoder(d, meta, obj)
url, err := replaceVars(d, config, "https://redis.googleapis.com/v1beta1/projects/{{project}}/locations/{{region}}/instances/{{name}}")
if err != nil {
return err

View File

@ -151,7 +151,6 @@ The following arguments are supported:
`next_hop_instance`. Omit if `next_hop_instance` is specified as
a URL.
## Attributes Reference
In addition to the arguments listed above, the following computed attributes are exported:

View File

@ -1,152 +1,162 @@
---
# ----------------------------------------------------------------------------
#
# *** AUTO GENERATED CODE *** AUTO GENERATED CODE ***
#
# ----------------------------------------------------------------------------
#
# This file is automatically generated by Magic Modules and manual
# changes will be clobbered when the file is regenerated.
#
# Please read more about how to change this file in
# .github/CONTRIBUTING.md.
#
# ----------------------------------------------------------------------------
layout: "google"
page_title: "Google: google_compute_router"
sidebar_current: "docs-google-compute-router-x"
sidebar_current: "docs-google-compute-router"
description: |-
Manages a Cloud Router resource.
Represents a Router resource.
---
# google\_compute\_router
Manages a Cloud Router resource. For more information see
[the official documentation](https://cloud.google.com/compute/docs/cloudrouter)
and
[API](https://cloud.google.com/compute/docs/reference/latest/routers).
Represents a Router resource.
To get more information about Router, see:
* [API documentation](https://cloud.google.com/compute/docs/reference/rest/v1/routers)
* How-to Guides
* [Google Cloud Router](https://cloud.google.com/router/docs/)
## Example Usage
```hcl
resource "google_compute_network" "foobar" {
name = "network-1"
}
resource "google_compute_subnetwork" "foobar" {
name = "subnet-1"
network = "${google_compute_network.foobar.self_link}"
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
}
resource "google_compute_address" "foobar" {
name = "vpn-gateway-1-address"
region = "${google_compute_subnetwork.foobar.region}"
}
resource "google_compute_vpn_gateway" "foobar" {
name = "vpn-gateway-1"
network = "${google_compute_network.foobar.self_link}"
region = "${google_compute_subnetwork.foobar.region}"
}
resource "google_compute_forwarding_rule" "foobar_esp" {
name = "vpn-gw-1-esp"
region = "${google_compute_vpn_gateway.foobar.region}"
ip_protocol = "ESP"
ip_address = "${google_compute_address.foobar.address}"
target = "${google_compute_vpn_gateway.foobar.self_link}"
}
resource "google_compute_forwarding_rule" "foobar_udp500" {
name = "vpn-gw-1-udp-500"
region = "${google_compute_forwarding_rule.foobar_esp.region}"
ip_protocol = "UDP"
port_range = "500-500"
ip_address = "${google_compute_address.foobar.address}"
target = "${google_compute_vpn_gateway.foobar.self_link}"
}
resource "google_compute_forwarding_rule" "foobar_udp4500" {
name = "vpn-gw-1-udp-4500"
region = "${google_compute_forwarding_rule.foobar_udp500.region}"
ip_protocol = "UDP"
port_range = "4500-4500"
ip_address = "${google_compute_address.foobar.address}"
target = "${google_compute_vpn_gateway.foobar.self_link}"
name = "my-network"
auto_create_subnetworks = false
}
resource "google_compute_router" "foobar" {
name = "router-1"
region = "${google_compute_forwarding_rule.foobar_udp500.region}"
network = "${google_compute_network.foobar.self_link}"
name = "my-router"
network = "${google_compute_network.foobar.name}"
bgp {
asn = 64512
asn = 64514
advertise_mode = "CUSTOM"
advertised_groups = ["ALL_SUBNETS"]
advertised_ip_ranges {
range = "1.2.3.4"
}
advertised_ip_ranges {
range = "6.7.0.0/16"
}
}
}
resource "google_compute_vpn_tunnel" "foobar" {
name = "vpn-tunnel-1"
region = "${google_compute_forwarding_rule.foobar_udp4500.region}"
target_vpn_gateway = "${google_compute_vpn_gateway.foobar.self_link}"
shared_secret = "unguessable"
peer_ip = "8.8.8.8"
router = "${google_compute_router.foobar.name}"
}
resource "google_compute_router_interface" "foobar" {
name = "interface-1"
router = "${google_compute_router.foobar.name}"
region = "${google_compute_router.foobar.region}"
ip_range = "169.254.1.1/30"
vpn_tunnel = "${google_compute_vpn_tunnel.foobar.name}"
}
resource "google_compute_router_peer" "foobar" {
name = "peer-1"
router = "${google_compute_router.foobar.name}"
region = "${google_compute_router.foobar.region}"
peer_ip_address = "169.254.1.2"
peer_asn = 65513
advertised_route_priority = 100
interface = "${google_compute_router_interface.foobar.name}"
}
```
## Argument Reference
The following arguments are supported:
* `name` - (Required) A unique name for the router, required by GCE. Changing
this forces a new router to be created.
* `network` - (Required) The name or resource link to the network this Cloud Router
will use to learn and announce routes. Changing this forces a new router to be created.
* `name` -
(Required)
Name of the resource. The name must be 1-63 characters long, and
comply with RFC1035. Specifically, the name must be 1-63 characters
long and match the regular expression `[a-z]([-a-z0-9]*[a-z0-9])?`
which means the first character must be a lowercase letter, and all
following characters must be a dash, lowercase letter, or digit,
except the last character, which cannot be a dash.
* `bgp` - (Required) BGP information specific to this router.
Changing this forces a new router to be created.
Structure is documented below.
* `network` -
(Required)
A reference to the network to which this router belongs.
- - -
* `description` - (Optional) A description of the resource.
Changing this forces a new router to be created.
* `project` - (Optional) The ID of the project in which the resource belongs. If it
is not provided, the provider project is used.
Changing this forces a new router to be created.
* `description` -
(Optional)
An optional description of this resource.
* `region` - (Optional) The region this router should sit in. If not specified,
the project region will be used. Changing this forces a new router to be
created.
* `bgp` -
(Optional)
BGP information specific to this router. Structure is documented below.
- - -
* `region` -
(Optional)
Region where the router resides.
* `project` (Optional) The ID of the project in which the resource belongs.
If it is not provided, the provider project is used.
The `bgp` block supports:
* `asn` - (Required) Local BGP Autonomous System Number (ASN). Must be an
RFC6996 private ASN.
* `asn` -
(Required)
Local BGP Autonomous System Number (ASN). Must be an RFC6996
private ASN, either 16-bit or 32-bit. The value will be fixed for
this router resource. All VPN tunnels that link to this router
will have the same local ASN.
* `advertise_mode` -
(Optional)
User-specified flag to indicate which mode to use for advertisement.
Valid values of this enum field are: DEFAULT, CUSTOM
* `advertised_groups` -
(Optional)
User-specified list of prefix groups to advertise in custom mode.
This field can only be populated if advertiseMode is CUSTOM and
is advertised to all peers of the router. These groups will be
advertised in addition to any specified prefixes. Leave this field
blank to advertise no custom groups.
This enum field has the one valid value: ALL_SUBNETS
* `advertised_ip_ranges` -
(Optional)
User-specified list of individual IP ranges to advertise in
custom mode. This field can only be populated if advertiseMode
is CUSTOM and is advertised to all peers of the router. These IP
ranges will be advertised in addition to any specified groups.
Leave this field blank to advertise no custom IP ranges. Structure is documented below.
The `advertised_ip_ranges` block supports:
* `range` -
(Optional)
The IP range to advertise. The value must be a
CIDR-formatted string.
* `description` -
(Optional)
User-specified description for the IP range.
## Attributes Reference
In addition to the arguments listed above, the following computed attributes are
exported:
In addition to the arguments listed above, the following computed attributes are exported:
* `creation_timestamp` -
Creation timestamp in RFC3339 text format.
* `self_link` - The URI of the created resource.
## Timeouts
This resource provides the following
[Timeouts](/docs/configuration/resources.html#timeouts) configuration options:
- `create` - Default is 4 minutes.
- `update` - Default is 4 minutes.
- `delete` - Default is 4 minutes.
## Import
Routers can be imported using the `region` and `name`, e.g.
Router can be imported using any of these accepted formats:
```
$ terraform import google_compute_router.foobar us-central1/router-1
$ terraform import google_compute_router.default projects/{{project}}/regions/{{region}}/routers/{{name}}
$ terraform import google_compute_router.default {{region}}/{{name}}
$ terraform import google_compute_router.default {{project}}/{{region}}/{{name}}
$ terraform import google_compute_router.default {{name}}
```