providers/google: Add subnetwork_project field to enable cross-project networking in instance templates (#11110)

* Add subnetwork_project field to allow for XPN in GCE instance templates

* Missing os import

* Removing unneeded check

* fix formatting

* Add subnetwork_project to read
This commit is contained in:
zbikmarc 2017-01-12 15:05:13 +01:00 committed by Paul Stack
parent d796eb5779
commit 77037bed2c
3 changed files with 81 additions and 5 deletions

View File

@ -203,6 +203,12 @@ func resourceComputeInstanceTemplate() *schema.Resource {
ForceNew: true,
},
"subnetwork_project": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"access_config": &schema.Schema{
Type: schema.TypeList,
Optional: true,
@ -406,14 +412,16 @@ func buildNetworks(d *schema.ResourceData, meta interface{}) ([]*compute.Network
for i := 0; i < networksCount; i++ {
prefix := fmt.Sprintf("network_interface.%d", i)
var networkName, subnetworkName string
var networkName, subnetworkName, subnetworkProject string
if v, ok := d.GetOk(prefix + ".network"); ok {
networkName = v.(string)
}
if v, ok := d.GetOk(prefix + ".subnetwork"); ok {
subnetworkName = v.(string)
}
if v, ok := d.GetOk(prefix + ".subnetwork_project"); ok {
subnetworkProject = v.(string)
}
if networkName == "" && subnetworkName == "" {
return nil, fmt.Errorf("network or subnetwork must be provided")
}
@ -435,8 +443,11 @@ func buildNetworks(d *schema.ResourceData, meta interface{}) ([]*compute.Network
if err != nil {
return nil, err
}
if subnetworkProject == "" {
subnetworkProject = project
}
subnetwork, err := config.clientCompute.Subnetworks.Get(
project, region, subnetworkName).Do()
subnetworkProject, region, subnetworkName).Do()
if err != nil {
return nil, fmt.Errorf(
"Error referencing subnetwork '%s' in region '%s': %s",
@ -639,6 +650,7 @@ func flattenNetworkInterfaces(networkInterfaces []*compute.NetworkInterface) ([]
subnetworkUrl := strings.Split(networkInterface.Subnetwork, "/")
networkInterfaceMap["subnetwork"] = subnetworkUrl[len(subnetworkUrl)-1]
region = subnetworkUrl[len(subnetworkUrl)-3]
networkInterfaceMap["subnetwork_project"] = subnetworkUrl[len(subnetworkUrl)-5]
}
if networkInterface.AccessConfigs != nil {

View File

@ -2,6 +2,7 @@ package google
import (
"fmt"
"os"
"strings"
"testing"
@ -115,6 +116,27 @@ func TestAccComputeInstanceTemplate_subnet_custom(t *testing.T) {
})
}
func TestAccComputeInstanceTemplate_subnet_xpn(t *testing.T) {
var instanceTemplate compute.InstanceTemplate
var xpn_host = os.Getenv("GOOGLE_XPN_HOST_PROJECT")
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeInstanceTemplateDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeInstanceTemplate_subnet_xpn(xpn_host),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceTemplateExists(
"google_compute_instance_template.foobar", &instanceTemplate),
testAccCheckComputeInstanceTemplateSubnetwork(&instanceTemplate),
),
},
},
})
}
func TestAccComputeInstanceTemplate_metadata_startup_script(t *testing.T) {
var instanceTemplate compute.InstanceTemplate
@ -467,6 +489,45 @@ resource "google_compute_instance_template" "foobar" {
}
}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10))
func testAccComputeInstanceTemplate_subnet_xpn(xpn_host string) string {
return fmt.Sprintf(`
resource "google_compute_network" "network" {
name = "network-%s"
auto_create_subnetworks = false
project = "%s"
}
resource "google_compute_subnetwork" "subnetwork" {
name = "subnetwork-%s"
ip_cidr_range = "10.0.0.0/24"
region = "us-central1"
network = "${google_compute_network.network.self_link}"
project = "%s"
}
resource "google_compute_instance_template" "foobar" {
name = "instance-test-%s"
machine_type = "n1-standard-1"
region = "us-central1"
disk {
source_image = "debian-8-jessie-v20160803"
auto_delete = true
disk_size_gb = 10
boot = true
}
network_interface {
subnetwork = "${google_compute_subnetwork.subnetwork.name}"
subnetwork_project = "${google_compute_subnetwork.subnetwork.project}"
}
metadata {
foo = "bar"
}
}`, acctest.RandString(10), xpn_host, acctest.RandString(10), xpn_host, acctest.RandString(10))
}
var testAccComputeInstanceTemplate_startup_script = fmt.Sprintf(`
resource "google_compute_instance_template" "foobar" {
name = "instance-test-%s"
@ -486,6 +547,6 @@ resource "google_compute_instance_template" "foobar" {
network_interface{
network = "default"
}
metadata_startup_script = "echo 'Hello'"
}`, acctest.RandString(10))

View File

@ -138,7 +138,7 @@ The following arguments are supported:
* `metadata_startup_script` - (Optional) An alternative to using the
startup-script metadata key, mostly to match the compute_instance resource.
This replaces the startup-script metadata key on the created instance and
This replaces the startup-script metadata key on the created instance and
thus the two mechanisms are not allowed to be used simultaneously.
* `network_interface` - (Required) Networks to attach to instances created from
@ -208,6 +208,9 @@ The `network_interface` block supports:
to. The subnetwork must exist in the same `region` this instance will be
created in. Either `network` or `subnetwork` must be provided.
* `subnetwork_project` - (Optional) The project in which the subnetwork belongs.
If it is not provided, the provider project is used.
* `access_config` - (Optional) Access configurations, i.e. IPs via which this
instance can be accessed via the Internet. Omit to ensure that the instance
is not accessible from the Internet (this means that ssh provisioners will