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

Add bootstrapped test networks for service networking tests #2920

Merged
merged 2 commits into from
Jan 7, 2020
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/terraform
2 changes: 1 addition & 1 deletion build/terraform-beta
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/terraform"
)

func TestAccServiceNetworkingConnectionCreate(t *testing.T) {
func TestAccServiceNetworkingConnection_create(t *testing.T) {
t.Parallel()

network := BootstrapSharedServiceNetworkingConsumerNetwork(t, "service-networking-connection-create")
addr := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
service := "servicenetworking.googleapis.com"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testServiceNetworkingConnectionDestroy(service, network),
Steps: []resource.TestStep{
{
Config: testAccServiceNetworkingConnection(
fmt.Sprintf("tf-test-%s", acctest.RandString(10)),
fmt.Sprintf("tf-test-%s", acctest.RandString(10)),
"servicenetworking.googleapis.com",
),
Config: testAccServiceNetworkingConnection(network, addr, "servicenetworking.googleapis.com"),
},
{
ResourceName: "google_service_networking_connection.foobar",
Expand All @@ -32,61 +33,29 @@ func TestAccServiceNetworkingConnectionCreate(t *testing.T) {
})
}

// Standard checkDestroy cannot be used here because destroying the network will delete
// all the networking connections so this would return false positives.
func TestAccServiceNetworkingConnectionDestroy(t *testing.T) {
func TestAccServiceNetworkingConnection_update(t *testing.T) {
t.Parallel()

network := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
addressRange := fmt.Sprintf("tf-test-%s", acctest.RandString(10))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccServiceNetworkingConnection(
network,
addressRange,
"servicenetworking.googleapis.com",
),
},
{
Config: testAccServiceNetworkingConnectionDestroy(network, addressRange),
Check: resource.ComposeTestCheckFunc(
testServiceNetworkingConnectionDestroy("servicenetworking.googleapis.com", network, getTestProjectFromEnv()),
),
},
},
})
}

func TestAccServiceNetworkingConnectionUpdate(t *testing.T) {
t.Parallel()
network := BootstrapSharedServiceNetworkingConsumerNetwork(t, "service-networking-connection-update")
addr1 := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
addr2 := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
service := "servicenetworking.googleapis.com"

network := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testServiceNetworkingConnectionDestroy(service, network),
Steps: []resource.TestStep{
{
Config: testAccServiceNetworkingConnection(
network,
fmt.Sprintf("tf-test-%s", acctest.RandString(10)),
"servicenetworking.googleapis.com",
),
Config: testAccServiceNetworkingConnection(network, addr1, "servicenetworking.googleapis.com"),
},
{
ResourceName: "google_service_networking_connection.foobar",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccServiceNetworkingConnection(
network,
fmt.Sprintf("tf-test-%s", acctest.RandString(10)),
"servicenetworking.googleapis.com",
),
Config: testAccServiceNetworkingConnection(network, addr2, "servicenetworking.googleapis.com"),
},
{
ResourceName: "google_service_networking_connection.foobar",
Expand All @@ -98,11 +67,11 @@ func TestAccServiceNetworkingConnectionUpdate(t *testing.T) {

}

func testServiceNetworkingConnectionDestroy(parent, network, project string) resource.TestCheckFunc {
func testServiceNetworkingConnectionDestroy(parent, network string) resource.TestCheckFunc {
return func(s *terraform.State) error {
config := testAccProvider.Meta().(*Config)
parentService := "services/" + parent
networkName := fmt.Sprintf("projects/%s/global/networks/%s", project, network)
networkName := fmt.Sprintf("projects/%s/global/networks/%s", getTestProjectFromEnv(), network)

response, err := config.clientServiceNetworking.Services.Connections.List(parentService).
Network(networkName).Do()
Expand All @@ -122,7 +91,7 @@ func testServiceNetworkingConnectionDestroy(parent, network, project string) res

func testAccServiceNetworkingConnection(networkName, addressRangeName, serviceName string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
data "google_compute_network" "servicenet" {
name = "%s"
}

Expand All @@ -131,29 +100,13 @@ resource "google_compute_global_address" "foobar" {
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.foobar.self_link
network = data.google_compute_network.servicenet.self_link
}

resource "google_service_networking_connection" "foobar" {
network = google_compute_network.foobar.self_link
network = data.google_compute_network.servicenet.self_link
service = "%s"
reserved_peering_ranges = [google_compute_global_address.foobar.name]
}
`, networkName, addressRangeName, serviceName)
}

func testAccServiceNetworkingConnectionDestroy(networkName, addressRangeName string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
name = "%s"
}

resource "google_compute_global_address" "foobar" {
name = "%s"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.foobar.self_link
}
`, networkName, addressRangeName)
}
Original file line number Diff line number Diff line change
Expand Up @@ -628,18 +628,18 @@ func TestAccSqlDatabaseInstance_withPrivateNetwork(t *testing.T) {
t.Parallel()

databaseName := "tf-test-" + acctest.RandString(10)
networkName := "tf-test-" + acctest.RandString(10)
addressName := "tf-test-" + acctest.RandString(10)
networkName := BootstrapSharedServiceNetworkingConsumerNetwork(t, "sql-instance-private")

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccSqlDatabaseInstanceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
{
Config: testAccSqlDatabaseInstance_withPrivateNetwork(databaseName, networkName, addressName),
},
resource.TestStep{
{
ResourceName: "google_sql_database_instance.instance",
ImportState: true,
ImportStateVerify: true,
Expand Down Expand Up @@ -789,21 +789,20 @@ resource "google_sql_database_instance" "instance-failover" {
<%# This test doesn't work in GA yet because service networking is still in beta -%>
func testAccSqlDatabaseInstance_withPrivateNetwork(databaseName, networkName, addressRangeName string) string {
return fmt.Sprintf(`
resource "google_compute_network" "foobar" {
data "google_compute_network" "servicenet" {
name = "%s"
auto_create_subnetworks = false
}

resource "google_compute_global_address" "foobar" {
name = "%s"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.foobar.self_link
network = data.google_compute_network.servicenet.self_link
}

resource "google_service_networking_connection" "foobar" {
network = google_compute_network.foobar.self_link
network = data.google_compute_network.servicenet.self_link
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.foobar.name]
}
Expand All @@ -816,7 +815,7 @@ resource "google_sql_database_instance" "instance" {
tier = "db-f1-micro"
ip_configuration {
ipv4_enabled = "false"
private_network = google_compute_network.foobar.self_link
private_network = data.google_compute_network.servicenet.self_link
}
}
}
Expand Down
61 changes: 61 additions & 0 deletions third_party/terraform/utils/bootstrap_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"log"
"os"
"testing"
"time"

"google.golang.org/api/cloudkms/v1"
"google.golang.org/api/iam/v1"
Expand Down Expand Up @@ -230,3 +231,63 @@ func BootstrapServiceAccount(t *testing.T, project, testRunner string) string {

return sa.Email
}

const SharedTestNetworkPrefix = "tf-bootstrap-net-"

// BootstrapSharedServiceNetworkingConsumerNetwork will return a shared compute network
// for service networking test to prevent hitting limits on tenancy projects.
//
// This will either return an existing network or create one if it hasn't been created
// in the project yet. One consumer network/tenant project we don't own is created
// per producer network (i.e. network created by test), with a hard limit set.
func BootstrapSharedServiceNetworkingConsumerNetwork(t *testing.T, testId string) string {
if v := os.Getenv("TF_ACC"); v == "" {
log.Println("Acceptance tests and bootstrapping skipped unless env 'TF_ACC' set")
// If not running acceptance tests, return an empty string
return ""
}

project := getTestProjectFromEnv()
networkName := SharedTestNetworkPrefix + testId
config := &Config{
Credentials: getTestCredsFromEnv(),
Project: project,
Region: getTestRegionFromEnv(),
Zone: getTestZoneFromEnv(),
}
ConfigureBasePaths(config)
if err := config.LoadAndValidate(context.Background()); err != nil {
t.Errorf("Unable to bootstrap network: %s", err)
}

log.Printf("[DEBUG] Getting shared test network %q", networkName)
_, err := config.clientCompute.Networks.Get(project, networkName).Do()
if err != nil && isGoogleApiErrorWithCode(err, 404) {
log.Printf("[DEBUG] Network %q not found, bootstrapping", networkName)
url := fmt.Sprintf("%sprojects/%s/global/networks", config.ComputeBasePath, project)
netObj := map[string]interface{}{
"name": networkName,
"autoCreateSubnetworks": false,
}

res, err := sendRequestWithTimeout(config, "POST", project, url, netObj, 4*time.Minute)
if err != nil {
t.Fatalf("Error bootstrapping shared test network %q: %s", networkName, err)
}

log.Printf("[DEBUG] Waiting for network creation to finish")
err = computeOperationWaitTime(config, res, project, "Error bootstrapping shared test network", 4)
if err != nil {
t.Fatalf("Error bootstrapping shared test network %q: %s", networkName, err)
}
}

network, err := config.clientCompute.Networks.Get(project, networkName).Do()
if err != nil {
t.Errorf("Error getting shared test network %q: %s", networkName, err)
}
if network == nil {
t.Fatalf("Error getting shared test network %q: is nil", networkName)
}
return network.Name
}