From f4e4d880c5cab2ff6a383badf5bcde40d0e5dacb Mon Sep 17 00:00:00 2001 From: The Magician Date: Thu, 14 Jun 2018 13:22:02 -0700 Subject: [PATCH] Autogenerate Route resource. (#1647) --- google/provider_compute_gen.go | 1 + google/resource_compute_route.go | 499 +++++++++++++++------ website/docs/r/compute_route.html.markdown | 152 +++++-- 3 files changed, 471 insertions(+), 181 deletions(-) diff --git a/google/provider_compute_gen.go b/google/provider_compute_gen.go index 0123ef93..a8b3d9fb 100644 --- a/google/provider_compute_gen.go +++ b/google/provider_compute_gen.go @@ -23,6 +23,7 @@ var GeneratedComputeResourcesMap = map[string]*schema.Resource{ "google_compute_global_address": resourceComputeGlobalAddress(), "google_compute_http_health_check": resourceComputeHttpHealthCheck(), "google_compute_https_health_check": resourceComputeHttpsHealthCheck(), + "google_compute_route": resourceComputeRoute(), "google_compute_ssl_policy": resourceComputeSslPolicy(), "google_compute_target_http_proxy": resourceComputeTargetHttpProxy(), "google_compute_target_https_proxy": resourceComputeTargetHttpsProxy(), diff --git a/google/resource_compute_route.go b/google/resource_compute_route.go index 836f7e2a..012589d1 100644 --- a/google/resource_compute_route.go +++ b/google/resource_compute_route.go @@ -1,11 +1,27 @@ +// ---------------------------------------------------------------------------- +// +// *** 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" + "strconv" + "time" "github.com/hashicorp/terraform/helper/schema" - "google.golang.org/api/compute/v1" + compute "google.golang.org/api/compute/v1" ) func resourceComputeRoute() *schema.Resource { @@ -13,96 +29,92 @@ func resourceComputeRoute() *schema.Resource { Create: resourceComputeRouteCreate, Read: resourceComputeRouteRead, Delete: resourceComputeRouteDelete, + Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, + State: resourceComputeRouteImport, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(240 * time.Second), + Delete: schema.DefaultTimeout(240 * time.Second), }, Schema: map[string]*schema.Schema{ - "name": &schema.Schema{ + "dest_range": { Type: schema.TypeString, Required: true, ForceNew: true, }, - - "dest_range": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateRegexp(`^[a-z]([-a-z0-9]*[a-z0-9])?$`), }, - - "network": &schema.Schema{ + "network": { Type: schema.TypeString, Required: true, ForceNew: true, DiffSuppressFunc: compareSelfLinkOrResourceName, }, - - "priority": &schema.Schema{ + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "priority": { Type: schema.TypeInt, Optional: true, ForceNew: true, Default: 1000, }, - - "next_hop_gateway": &schema.Schema{ + "tags": { + Type: schema.TypeSet, + Optional: true, + ForceNew: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Set: schema.HashString, + }, + "next_hop_gateway": { Type: schema.TypeString, Optional: true, ForceNew: true, DiffSuppressFunc: compareSelfLinkOrResourceName, }, - - "next_hop_instance": &schema.Schema{ + "next_hop_instance": { Type: schema.TypeString, Optional: true, ForceNew: true, DiffSuppressFunc: compareSelfLinkOrResourceName, }, - + "next_hop_ip": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "next_hop_vpn_tunnel": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "next_hop_network": { + Type: schema.TypeString, + Computed: true, + }, "next_hop_instance_zone": &schema.Schema{ Type: schema.TypeString, Optional: true, ForceNew: true, }, - - "next_hop_ip": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - ForceNew: true, - }, - - "next_hop_vpn_tunnel": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - ForceNew: true, - }, - - "project": &schema.Schema{ + "project": { Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, }, - - "description": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - ForceNew: true, - }, - - "tags": &schema.Schema{ - Type: schema.TypeSet, - Optional: true, - ForceNew: true, - Elem: &schema.Schema{Type: schema.TypeString}, - Set: schema.HashString, - }, - - "self_link": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, - - "next_hop_network": &schema.Schema{ + "self_link": { Type: schema.TypeString, Computed: true, }, @@ -118,81 +130,96 @@ func resourceComputeRouteCreate(d *schema.ResourceData, meta interface{}) error return err } - network, err := ParseNetworkFieldValue(d.Get("network").(string), d, config) + destRangeProp, err := expandComputeRouteDestRange(d.Get("dest_range"), d, config) + if err != nil { + return err + } + descriptionProp, err := expandComputeRouteDescription(d.Get("description"), d, config) + if err != nil { + return err + } + nameProp, err := expandComputeRouteName(d.Get("name"), d, config) + if err != nil { + return err + } + networkProp, err := expandComputeRouteNetwork(d.Get("network"), d, config) + if err != nil { + return err + } + priorityProp, err := expandComputeRoutePriority(d.Get("priority"), d, config) + if err != nil { + return err + } + tagsProp, err := expandComputeRouteTags(d.Get("tags"), d, config) + if err != nil { + return err + } + nextHopGatewayProp, err := expandComputeRouteNextHopGateway(d.Get("next_hop_gateway"), d, config) + if err != nil { + return err + } + nextHopInstanceProp, err := expandComputeRouteNextHopInstance(d.Get("next_hop_instance"), d, config) + if err != nil { + return err + } + nextHopIpProp, err := expandComputeRouteNextHopIp(d.Get("next_hop_ip"), d, config) + if err != nil { + return err + } + nextHopVpnTunnelProp, err := expandComputeRouteNextHopVpnTunnel(d.Get("next_hop_vpn_tunnel"), d, config) if err != nil { return err } - // Next hop data - var nextHopInstance, nextHopIp, nextHopGateway, - nextHopVpnTunnel string - if v, ok := d.GetOk("next_hop_ip"); ok { - nextHopIp = v.(string) - } - if v, ok := d.GetOk("next_hop_gateway"); ok { - if v == "default-internet-gateway" { - nextHopGateway = fmt.Sprintf("projects/%s/global/gateways/default-internet-gateway", project) - } else { - nextHopGateway = v.(string) - } - } - if v, ok := d.GetOk("next_hop_vpn_tunnel"); ok { - nextHopVpnTunnel = v.(string) - } - if v, ok := d.GetOk("next_hop_instance"); ok { - nextHopInstanceFieldValue, err := parseComputeRouteNextHopInstanceFieldValue(v.(string), d, config) - if err != nil { - return fmt.Errorf("Invalid next_hop_instance: %s", err) - } - - nextInstance, err := config.clientCompute.Instances.Get( - project, - nextHopInstanceFieldValue.Zone, - nextHopInstanceFieldValue.Name).Do() - if err != nil { - return fmt.Errorf("Error reading instance: %s", err) - } - - nextHopInstance = nextInstance.SelfLink + obj := map[string]interface{}{ + "destRange": destRangeProp, + "description": descriptionProp, + "name": nameProp, + "network": networkProp, + "priority": priorityProp, + "tags": tagsProp, + "nextHopGateway": nextHopGatewayProp, + "nextHopInstance": nextHopInstanceProp, + "nextHopIp": nextHopIpProp, + "nextHopVpnTunnel": nextHopVpnTunnelProp, } - // Tags - var tags []string - if v := d.Get("tags").(*schema.Set); v.Len() > 0 { - tags = make([]string, v.Len()) - for i, v := range v.List() { - tags[i] = v.(string) - } - } - - // Build the route parameter - route := &compute.Route{ - Name: d.Get("name").(string), - Description: d.Get("description").(string), - DestRange: d.Get("dest_range").(string), - Network: network.RelativeLink(), - NextHopInstance: nextHopInstance, - NextHopVpnTunnel: nextHopVpnTunnel, - NextHopIp: nextHopIp, - NextHopGateway: nextHopGateway, - Priority: int64(d.Get("priority").(int)), - Tags: tags, - } - log.Printf("[DEBUG] Route insert request: %#v", route) - op, err := config.clientCompute.Routes.Insert( - project, route).Do() - if err != nil { - return fmt.Errorf("Error creating route: %s", err) - } - - // It probably maybe worked, so store the ID now - d.SetId(route.Name) - - err = computeOperationWait(config.clientCompute, op, project, "Creating Route") + url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/routes") if err != nil { return err } + log.Printf("[DEBUG] Creating new Route: %#v", obj) + res, err := Post(config, url, obj) + if err != nil { + return fmt.Errorf("Error creating Route: %s", err) + } + + // Store the ID now + id, err := replaceVars(d, config, "{{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 Route", + int(d.Timeout(schema.TimeoutCreate).Minutes())) + + if waitErr != nil { + // The resource didn't actually create + d.SetId("") + return fmt.Errorf("Error waiting to create Route: %s", waitErr) + } + + log.Printf("[DEBUG] Finished creating Route %q: %#v", d.Id(), res) + return resourceComputeRouteRead(d, meta) } @@ -204,31 +231,60 @@ func resourceComputeRouteRead(d *schema.ResourceData, meta interface{}) error { return err } - route, err := config.clientCompute.Routes.Get( - project, d.Id()).Do() + url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/routes/{{name}}") if err != nil { - return handleNotFoundError(err, d, fmt.Sprintf("Route %q", d.Get("name").(string))) + return err } - nextHopInstanceFieldValue, err := parseComputeRouteNextHopInstanceFieldValue(route.NextHopInstance, d, config) + res, err := Get(config, url) if err != nil { - return fmt.Errorf("Invalid next_hop_instance: %s", err) + return handleNotFoundError(err, d, fmt.Sprintf("ComputeRoute %q", d.Id())) } - d.Set("name", route.Name) - d.Set("description", route.Description) - d.Set("dest_range", route.DestRange) - d.Set("network", route.Network) - d.Set("priority", route.Priority) - d.Set("next_hop_gateway", route.NextHopGateway) - d.Set("next_hop_instance", nextHopInstanceFieldValue.RelativeLink()) - d.Set("next_hop_instance_zone", nextHopInstanceFieldValue.Zone) - d.Set("next_hop_ip", route.NextHopIp) - d.Set("next_hop_vpn_tunnel", route.NextHopVpnTunnel) - d.Set("tags", route.Tags) - d.Set("next_hop_network", route.NextHopNetwork) - d.Set("project", project) - d.Set("self_link", route.SelfLink) + res, err = resourceComputeRouteDecoder(d, meta, res) + if err != nil { + return err + } + + if err := d.Set("dest_range", flattenComputeRouteDestRange(res["destRange"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("description", flattenComputeRouteDescription(res["description"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("name", flattenComputeRouteName(res["name"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("network", flattenComputeRouteNetwork(res["network"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("priority", flattenComputeRoutePriority(res["priority"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("tags", flattenComputeRouteTags(res["tags"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("next_hop_gateway", flattenComputeRouteNextHopGateway(res["nextHopGateway"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("next_hop_instance", flattenComputeRouteNextHopInstance(res["nextHopInstance"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("next_hop_ip", flattenComputeRouteNextHopIp(res["nextHopIp"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("next_hop_vpn_tunnel", flattenComputeRouteNextHopVpnTunnel(res["nextHopVpnTunnel"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("next_hop_network", flattenComputeRouteNextHopNetwork(res["nextHopNetwork"])); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("self_link", ConvertSelfLinkToV1(res["selfLink"].(string))); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } + if err := d.Set("project", project); err != nil { + return fmt.Errorf("Error reading Route: %s", err) + } return nil } @@ -241,22 +297,171 @@ func resourceComputeRouteDelete(d *schema.ResourceData, meta interface{}) error return err } - // Delete the route - op, err := config.clientCompute.Routes.Delete( - project, d.Id()).Do() - if err != nil { - return fmt.Errorf("Error deleting route: %s", err) - } - - err = computeOperationWait(config.clientCompute, op, project, "Deleting Route") + url, err := replaceVars(d, config, "https://www.googleapis.com/compute/v1/projects/{{project}}/global/routes/{{name}}") if err != nil { return err } - d.SetId("") + log.Printf("[DEBUG] Deleting Route %q", d.Id()) + res, err := Delete(config, url) + if err != nil { + return handleNotFoundError(err, d, "Route") + } + + op := &compute.Operation{} + err = Convert(res, op) + if err != nil { + return err + } + + err = computeOperationWaitTime( + config.clientCompute, op, project, "Deleting Route", + int(d.Timeout(schema.TimeoutDelete).Minutes())) + + if err != nil { + return err + } + + log.Printf("[DEBUG] Finished deleting Route %q: %#v", d.Id(), res) return nil } -func parseComputeRouteNextHopInstanceFieldValue(nextHopInstance string, d TerraformResourceData, config *Config) (*ZonalFieldValue, error) { - return parseZonalFieldValue("instances", nextHopInstance, "project", "next_hop_instance_zone", d, config, true) +func resourceComputeRouteImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + config := meta.(*Config) + parseImportId([]string{"projects/(?P[^/]+)/global/routes/(?P[^/]+)", "(?P[^/]+)/(?P[^/]+)", "(?P[^/]+)"}, d, config) + + // Replace import id for the resource id + id, err := replaceVars(d, config, "{{name}}") + if err != nil { + return nil, fmt.Errorf("Error constructing id: %s", err) + } + d.SetId(id) + + return []*schema.ResourceData{d}, nil +} + +func flattenComputeRouteDestRange(v interface{}) interface{} { + return v +} + +func flattenComputeRouteDescription(v interface{}) interface{} { + return v +} + +func flattenComputeRouteName(v interface{}) interface{} { + return v +} + +func flattenComputeRouteNetwork(v interface{}) interface{} { + return v +} + +func flattenComputeRoutePriority(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 flattenComputeRouteTags(v interface{}) interface{} { + return v +} + +func flattenComputeRouteNextHopGateway(v interface{}) interface{} { + return v +} + +func flattenComputeRouteNextHopInstance(v interface{}) interface{} { + return v +} + +func flattenComputeRouteNextHopIp(v interface{}) interface{} { + return v +} + +func flattenComputeRouteNextHopVpnTunnel(v interface{}) interface{} { + return v +} + +func flattenComputeRouteNextHopNetwork(v interface{}) interface{} { + return v +} + +func expandComputeRouteDestRange(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRouteDescription(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRouteName(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRouteNetwork(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 expandComputeRoutePriority(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRouteTags(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v.(*schema.Set).List(), nil +} + +func expandComputeRouteNextHopGateway(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + if v == "default-internet-gateway" { + project, err := getProject(d, config) + if err != nil { + return nil, err + } + return fmt.Sprintf("projects/%s/global/gateways/default-internet-gateway", project), nil + } else { + return v, nil + } +} + +func expandComputeRouteNextHopInstance(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + if v == "" { + return v, nil + } + val, err := parseZonalFieldValue("instances", v.(string), "project", "next_hop_instance_zone", d, config, true) + if err != nil { + return nil, err + } + nextInstance, err := config.clientCompute.Instances.Get(val.Project, val.Zone, val.Name).Do() + if err != nil { + return nil, err + } + return nextInstance.SelfLink, nil +} + +func expandComputeRouteNextHopIp(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func expandComputeRouteNextHopVpnTunnel(v interface{}, d *schema.ResourceData, config *Config) (interface{}, error) { + return v, nil +} + +func resourceComputeRouteDecoder(d *schema.ResourceData, meta interface{}, res map[string]interface{}) (map[string]interface{}, error) { + if v, ok := res["nextHopInstance"]; ok { + val, err := parseZonalFieldValue("instances", v.(string), "project", "next_hop_instance_zone", d, meta.(*Config), true) + if err != nil { + return nil, err + } + d.Set("next_hop_instance_zone", val.Zone) + res["nextHopInstance"] = val.RelativeLink() + } + + return res, nil } diff --git a/website/docs/r/compute_route.html.markdown b/website/docs/r/compute_route.html.markdown index 1f48eb07..61bf97e1 100644 --- a/website/docs/r/compute_route.html.markdown +++ b/website/docs/r/compute_route.html.markdown @@ -1,17 +1,53 @@ --- +# ---------------------------------------------------------------------------- +# +# *** 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_route" -sidebar_current: "docs-google-compute-route-x" +sidebar_current: "docs-google-compute-route" description: |- - Manages a network route within GCE. + Represents a Route resource. --- # google\_compute\_route -Manages a network route within GCE. For more information see -[the official documentation](https://cloud.google.com/compute/docs/vpc/routes) -and -[API](https://cloud.google.com/compute/docs/reference/latest/routes). +Represents a Route resource. + +A route is a rule that specifies how certain packets should be handled by +the virtual network. Routes are associated with virtual machines by tag, +and the set of routes for a particular virtual machine is called its +routing table. For each packet leaving a virtual machine, the system +searches that virtual machine's routing table for a single best matching +route. + +Routes match packets by destination IP address, preferring smaller or more +specific ranges over larger ones. If there is a tie, the system selects +the route with the smallest priority value. If there is still a tie, it +uses the layer three and four packet headers to select just one of the +remaining matching routes. The packet is then forwarded as specified by +the next_hop field of the winning route -- either to another virtual +machine destination, a virtual machine gateway or a Compute +Engine-operated gateway. Packets that do not match any route in the +sending virtual machine's routing table will be dropped. + +A Route resource must have exactly one specification of either +nextHopGateway, nextHopInstance, nextHopIp, or nextHopVpnTunnel. + +To get more information about Route, see: + +* [API documentation](https://cloud.google.com/compute/docs/reference/rest/v1/routes) +* How-to Guides + * [Using Routes](https://cloud.google.com/vpc/docs/using-routes) ## Example Usage @@ -40,52 +76,100 @@ resource "google_compute_route" "default" { The following arguments are supported: -* `name` - (Required) A unique name for the resource, required by GCE. - Changing this forces a new resource to be created. +* `dest_range` - + (Required) + The destination range of outgoing packets that this route applies to. + Only IPv4 is supported. +* `name` - + (Required) + Name of the resource. Provided by the client when the resource is + created. 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. +* `network` - + (Required) + The network that this route applies to. -* `dest_range` - (Required) The destination IPv4 address range that this - route applies to. - -* `network` - (Required) The name or self_link of the network to attach this route to. - -* `priority` - (Optional) The priority of this route, used to break ties. Defaults to 1000. - - - -* `next_hop_gateway` - (Optional) The URL of the internet gateway to route - to if this route is matched. The alias "default-internet-gateway" can also - be used. +* `description` - + (Optional) + An optional description of this resource. Provide this property + when you create the resource. +* `priority` - + (Optional) + The priority of this route. Priority is used to break ties in cases + where there is more than one matching route of equal prefix length. -* `next_hop_instance` - (Optional) The name of the VM instance to route to - if this route is matched. + In the case of two routes with equal prefix length, the one with the + lowest-numbered priority value wins. -* `next_hop_instance_zone` - (Required when `next_hop_instance` is specified) - The zone of the instance specified in `next_hop_instance`. + Default value is 1000. Valid range is 0 through 65535. +* `tags` - + (Optional) + A list of instance tags to which this route applies. +* `next_hop_gateway` - + (Optional) + URL to a gateway that should handle matching packets. -* `next_hop_ip` - (Optional) The IP address of the next hop if this route - is matched. + Currently, you can only specify the internet gateway, using a full or + partial valid URL: -* `next_hop_vpn_tunnel` - (Optional) The name of the VPN to route to if this - route is matched. + * https://www.googleapis.com/compute/v1/projects/project/global/gateways/default-internet-gateway + * projects/project/global/gateways/default-internet-gateway + * global/gateways/default-internet-gateway + You can also provide the string 'default-internet-gateway'. +* `next_hop_instance` - + (Optional) + URL to an instance that should handle matching packets. + You can specify this as a full or partial URL. For example: -* `project` - (Optional) The ID of the project in which the resource belongs. If it - is not provided, the provider project is used. + * https://www.googleapis.com/compute/v1/projects/project/zones/zone/instances/instance + * projects/project/zones/zone/instances/instance + * zones/zone/instances/instance + You can also provide just the instance name, with the zone in + `next_hop_instance_zone`. +* `next_hop_ip` - + (Optional) + Network IP address of an instance that should handle matching packets. +* `next_hop_vpn_tunnel` - + (Optional) + URL to a VpnTunnel that should handle matching packets. +* `project` (Optional) The ID of the project in which the resource belongs. + If it is not provided, the provider project is used. -* `tags` - (Optional) The tags that this route applies to. +* `next_hop_instance_zone` - (Optional when `next_hop_instance` is + specified) The zone of the instance specified in + `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: - -* `next_hop_network` - The name of the next hop network, if available. +In addition to the arguments listed above, the following computed attributes are exported: +* `next_hop_network` - + URL to a Network that should handle matching packets. * `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. +- `delete` - Default is 4 minutes. + ## Import -Network routes can be imported using the `name`, e.g. +Route can be imported using any of these accepted formats: ``` -$ terraform import google_compute_route.default network-route +$ terraform import google_compute_route.default projects/{{project}}/global/routes/{{name}} +$ terraform import google_compute_route.default {{project}}/{{name}} +$ terraform import google_compute_route.default {{name}} ```