Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#11206] Add subnetwork and private_ip_address arguments to CR interface #13105

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/6766.txt
@@ -0,0 +1,3 @@
```release-note:enhancement
compute: added subnetwork and private_ip_address arguments to resource_compute_router_interface
```
53 changes: 41 additions & 12 deletions google/resource_compute_router_interface.go
Expand Up @@ -42,28 +42,44 @@ func resourceComputeRouterInterface() *schema.Resource {
},
"vpn_tunnel": {
Type: schema.TypeString,
ConflictsWith: []string{"interconnect_attachment"},
Optional: true,
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
AtLeastOneOf: []string{"vpn_tunnel", "interconnect_attachment", "ip_range"},
Description: `The name or resource link to the VPN tunnel this interface will be linked to. Changing this forces a new interface to be created. Only one of vpn_tunnel and interconnect_attachment can be specified.`,
AtLeastOneOf: []string{"ip_range", "interconnect_attachment", "subnetwork", "vpn_tunnel"},
ConflictsWith: []string{"interconnect_attachment", "subnetwork"},
Description: `The name or resource link to the VPN tunnel this interface will be linked to. Changing this forces a new interface to be created. Only one of vpn_tunnel, interconnect_attachment or subnetwork can be specified.`,
},
"interconnect_attachment": {
Type: schema.TypeString,
ConflictsWith: []string{"vpn_tunnel"},
Optional: true,
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
AtLeastOneOf: []string{"vpn_tunnel", "interconnect_attachment", "ip_range"},
Description: `The name or resource link to the VLAN interconnect for this interface. Changing this forces a new interface to be created. Only one of vpn_tunnel and interconnect_attachment can be specified.`,
AtLeastOneOf: []string{"ip_range", "interconnect_attachment", "subnetwork", "vpn_tunnel"},
ConflictsWith: []string{"subnetwork", "vpn_tunnel"},
Description: `The name or resource link to the VLAN interconnect for this interface. Changing this forces a new interface to be created. Only one of interconnect_attachment, subnetwork or vpn_tunnel can be specified.`,
},
"ip_range": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
AtLeastOneOf: []string{"vpn_tunnel", "interconnect_attachment", "ip_range"},
Description: `IP address and range of the interface. The IP range must be in the RFC3927 link-local IP space. Changing this forces a new interface to be created.`,
Computed: true,
AtLeastOneOf: []string{"ip_range", "interconnect_attachment", "subnetwork", "vpn_tunnel"},
Description: `The IP address and range of the interface. The IP range must be in the RFC3927 link-local IP space. Changing this forces a new interface to be created.`,
},
"private_ip_address": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: `The regional private internal IP address that is used to establish BGP sessions to a VM instance acting as a third-party Router Appliance. Changing this forces a new interface to be created.`,
},
"subnetwork": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
DiffSuppressFunc: compareSelfLinkOrResourceName,
AtLeastOneOf: []string{"ip_range", "interconnect_attachment", "subnetwork", "vpn_tunnel"},
ConflictsWith: []string{"interconnect_attachment", "vpn_tunnel"},
Description: `The URI of the subnetwork resource that this interface belongs to, which must be in the same region as the Cloud Router. Changing this forces a new interface to be created. Only one of subnetwork, interconnect_attachment or vpn_tunnel can be specified.`,
},
"project": {
Type: schema.TypeString,
Expand All @@ -72,7 +88,6 @@ func resourceComputeRouterInterface() *schema.Resource {
ForceNew: true,
Description: `The ID of the project in which this interface's router belongs. If it is not provided, the provider project is used. Changing this forces a new interface to be created.`,
},

"region": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -85,7 +100,7 @@ func resourceComputeRouterInterface() *schema.Resource {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: `The name of the interface that is redundant to this interface.`,
Description: `The name of the interface that is redundant to this interface. Changing this forces a new interface to be created.`,
},
},
UseJSONNumber: true,
Expand Down Expand Up @@ -144,8 +159,12 @@ func resourceComputeRouterInterfaceCreate(d *schema.ResourceData, meta interface
iface.RedundantInterface = riVal.(string)
}

if ipVal, ok := d.GetOk("ip_range"); ok {
iface.IpRange = ipVal.(string)
if ipRangeVal, ok := d.GetOk("ip_range"); ok {
iface.IpRange = ipRangeVal.(string)
}

if privateIpVal, ok := d.GetOk("private_ip_address"); ok {
iface.PrivateIpAddress = privateIpVal.(string)
}

if vpnVal, ok := d.GetOk("vpn_tunnel"); ok {
Expand All @@ -164,6 +183,10 @@ func resourceComputeRouterInterfaceCreate(d *schema.ResourceData, meta interface
iface.LinkedInterconnectAttachment = interconnectAttachment
}

if subVal, ok := d.GetOk("subnetwork"); ok {
iface.Subnetwork = subVal.(string)
}

log.Printf("[INFO] Adding interface %s", ifaceName)
ifaces = append(ifaces, iface)
patchRouter := &compute.Router{
Expand Down Expand Up @@ -231,6 +254,12 @@ func resourceComputeRouterInterfaceRead(d *schema.ResourceData, meta interface{}
if err := d.Set("ip_range", iface.IpRange); err != nil {
return fmt.Errorf("Error setting ip_range: %s", err)
}
if err := d.Set("private_ip_address", iface.PrivateIpAddress); err != nil {
return fmt.Errorf("Error setting private_ip_address: %s", err)
}
if err := d.Set("subnetwork", iface.Subnetwork); err != nil {
return fmt.Errorf("Error setting subnetwork: %s", err)
}
if err := d.Set("region", region); err != nil {
return fmt.Errorf("Error setting region: %s", err)
}
Expand Down
62 changes: 62 additions & 0 deletions google/resource_compute_router_interface_test.go
Expand Up @@ -82,6 +82,29 @@ func TestAccComputeRouterInterface_withTunnel(t *testing.T) {
})
}

func TestAccComputeRouterInterface_withPrivateIpAddress(t *testing.T) {
t.Parallel()

routerName := fmt.Sprintf("tf-test-router-%s", randString(t, 10))
vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeRouterInterfaceDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccComputeRouterInterfaceWithPrivateIpAddress(routerName),
Check: testAccCheckComputeRouterInterfaceExists(
t, "google_compute_router_interface.foobar"),
},
{
ResourceName: "google_compute_router_interface.foobar",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckComputeRouterInterfaceDestroyProducer(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
config := googleProviderConfig(t)
Expand Down Expand Up @@ -435,3 +458,42 @@ resource "google_compute_router_interface" "foobar" {
}
`, routerName, routerName, routerName, routerName, routerName, routerName, routerName, routerName)
}

func testAccComputeRouterInterfaceWithPrivateIpAddress(routerName string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
name = "tf-test-%s"
}

resource "google_compute_subnetwork" "foobar" {
name = "tf-test-router-interface-subnetwork-%s"
network = google_compute_network.foobar.self_link
ip_cidr_range = "10.0.0.0/16"
region = "us-central1"
}

resource "google_compute_address" "foobar" {
name = "%s-addr"
region = google_compute_subnetwork.foobar.region
subnetwork = google_compute_subnetwork.foobar.id
address_type = "INTERNAL"
}

resource "google_compute_router" "foobar" {
name = "%s"
region = google_compute_subnetwork.foobar.region
network = google_compute_network.foobar.self_link
bgp {
asn = 64514
}
}

resource "google_compute_router_interface" "foobar" {
name = "%s"
router = google_compute_router.foobar.name
region = google_compute_router.foobar.region
subnetwork = google_compute_subnetwork.foobar.self_link
private_ip_address = google_compute_address.foobar.address
}
`, routerName, routerName, routerName, routerName, routerName)
}
32 changes: 18 additions & 14 deletions website/docs/r/compute_router_interface.html.markdown
Expand Up @@ -34,9 +34,7 @@ The following arguments are supported:
* `router` - (Required) The name of the router this interface will be attached to.
Changing this forces a new interface to be created.

In addition to the above required fields, a router interface must have specified
either `ip_range` or exactly one of `vpn_tunnel` or `interconnect_attachment`,
or both.
In addition to the above required fields, a router interface must have specified either `ip_range` or exactly one of `vpn_tunnel`, `interconnect_attachment` or `subnetwork`, or both.

- - -

Expand All @@ -45,23 +43,29 @@ or both.

* `vpn_tunnel` - (Optional) The name or resource link to the VPN tunnel this
interface will be linked to. Changing this forces a new interface to be created. Only
one of `vpn_tunnel` and `interconnect_attachment` can be specified.
one of `vpn_tunnel`, `interconnect_attachment` or `subnetwork` can be specified.

* `interconnect_attachment` - (Optional) The name or resource link to the
VLAN interconnect for this interface. Changing this forces a new interface to
be created. Only one of `vpn_tunnel` and `interconnect_attachment` can be
specified.
VLAN interconnect for this interface. Changing this forces a new interface to
be created. Only one of `vpn_tunnel`, `interconnect_attachment` or `subnetwork` can be specified.

* `redundant_interface` - (Optional) The name of the interface that is redundant to
this interface. Changing this forces a new interface to
be created.
this interface. Changing this forces a new interface to be created.

* `project` - (Optional) The ID of the project in which this interface's router belongs. If it
is not provided, the provider project is used. Changing this forces a new interface to be created.
* `project` - (Optional) The ID of the project in which this interface's router belongs.
If it is not provided, the provider project is used. Changing this forces a new interface to be created.

* `region` - (Optional) The region this interface's router sits in. If not specified,
the project region will be used. Changing this forces a new interface to be
created.
* `subnetwork` - (Optional) The URI of the subnetwork resource that this interface
belongs to, which must be in the same region as the Cloud Router. When you establish a BGP session to a VM instance using this interface, the VM instance must belong to the same subnetwork as the subnetwork specified here. Changing this forces a new interface to be created. Only one of `vpn_tunnel`, `interconnect_attachment` or `subnetwork` can be specified.

* `private_ip_address` - (Optional) The regional private internal IP address that is used
to establish BGP sessions to a VM instance acting as a third-party Router Appliance. Changing this forces a new interface to be created.

* `project` - (Optional) The ID of the project in which this interface's routerbelongs.
If it is not provided, the provider project is used. Changing this forces a new interface to be created.

* `region` - (Optional) The region this interface's router sits in.
If not specified, the project region will be used. Changing this forces a new interface to be created.

## Attributes Reference

Expand Down