diff --git a/third_party/terraform/resources/resource_compute_network_peering.go b/third_party/terraform/resources/resource_compute_network_peering.go index 78f7bc033edb..adb8e63f0397 100644 --- a/third_party/terraform/resources/resource_compute_network_peering.go +++ b/third_party/terraform/resources/resource_compute_network_peering.go @@ -18,6 +18,7 @@ func resourceComputeNetworkPeering() *schema.Resource { return &schema.Resource{ Create: resourceComputeNetworkPeeringCreate, Read: resourceComputeNetworkPeeringRead, + Update: resourceComputeNetworkPeeringUpdate, Delete: resourceComputeNetworkPeeringDelete, Importer: &schema.ResourceImporter{ State: resourceComputeNetworkPeeringImport, @@ -25,6 +26,7 @@ func resourceComputeNetworkPeering() *schema.Resource { Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(4 * time.Minute), + Update: schema.DefaultTimeout(4 * time.Minute), Delete: schema.DefaultTimeout(4 * time.Minute), }, @@ -57,7 +59,6 @@ func resourceComputeNetworkPeering() *schema.Resource { "export_custom_routes": { Type: schema.TypeBool, - ForceNew: true, Optional: true, Default: false, Description: `Whether to export the custom routes to the peer network. Defaults to false.`, @@ -65,7 +66,6 @@ func resourceComputeNetworkPeering() *schema.Resource { "import_custom_routes": { Type: schema.TypeBool, - ForceNew: true, Optional: true, Default: false, Description: `Whether to export the custom routes from the peer network. Defaults to false.`, @@ -194,6 +194,46 @@ func resourceComputeNetworkPeeringRead(d *schema.ResourceData, meta interface{}) return nil } +func resourceComputeNetworkPeeringUpdate(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + userAgent, err := generateUserAgentString(d, config.userAgent) + if err != nil { + return err + } + + networkFieldValue, err := ParseNetworkFieldValue(d.Get("network").(string), d, config) + if err != nil { + return err + } + peerNetworkFieldValue, err := ParseNetworkFieldValue(d.Get("peer_network").(string), d, config) + if err != nil { + return err + } + + request := &compute.NetworksUpdatePeeringRequest{} + request.NetworkPeering = expandNetworkPeering(d) + + // Only one peering operation at a time can be performed for a given network. + // Lock on both networks, sorted so we don't deadlock for A <--> B peering pairs. + peeringLockNames := sortedNetworkPeeringMutexKeys(networkFieldValue, peerNetworkFieldValue) + for _, kn := range peeringLockNames { + mutexKV.Lock(kn) + defer mutexKV.Unlock(kn) + } + + updateOp, err := config.NewComputeClient(userAgent).Networks.UpdatePeering(networkFieldValue.Project, networkFieldValue.Name, request).Do() + if err != nil { + return fmt.Errorf("Error updating network peering: %s", err) + } + + err = computeOperationWaitTime(config, updateOp, networkFieldValue.Project, "Updating Network Peering", userAgent, d.Timeout(schema.TimeoutUpdate)) + if err != nil { + return err + } + + return resourceComputeNetworkPeeringRead(d, meta) +} + func resourceComputeNetworkPeeringDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) userAgent, err := generateUserAgentString(d, config.userAgent) diff --git a/third_party/terraform/tests/resource_compute_network_peering_test.go b/third_party/terraform/tests/resource_compute_network_peering_test.go index 5359369500db..34061b74e728 100644 --- a/third_party/terraform/tests/resource_compute_network_peering_test.go +++ b/third_party/terraform/tests/resource_compute_network_peering_test.go @@ -59,6 +59,41 @@ func TestAccComputeNetworkPeering_subnetRoutes(t *testing.T) { }) } +func TestAccComputeNetworkPeering_customRoutesUpdate(t *testing.T) { + t.Parallel() + + primaryNetworkName := fmt.Sprintf("network-test-1-%d", randInt(t)) + peeringName := fmt.Sprintf("peering-test-%d", randInt(t)) + importId := fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), primaryNetworkName, peeringName) + suffix := randString(t, 10) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccComputeNetworkPeeringDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeNetworkPeeringDefaultCustomRoutes(primaryNetworkName, peeringName, suffix), + }, + { + ResourceName: "google_compute_network_peering.bar", + ImportState: true, + ImportStateVerify: true, + ImportStateId: importId, + }, + { + Config: testAccComputeNetworkPeering_basic(primaryNetworkName, peeringName, suffix), + }, + { + ResourceName: "google_compute_network_peering.bar", + ImportState: true, + ImportStateVerify: true, + ImportStateId: importId, + }, + }, + }) +} + func testAccComputeNetworkPeeringDestroyProducer(t *testing.T) func(s *terraform.State) error { return func(s *terraform.State) error { config := googleProviderConfig(t) @@ -128,3 +163,29 @@ resource "google_compute_network_peering" "bar" { } `, primaryNetworkName, suffix, peeringName) } + +func testAccComputeNetworkPeeringDefaultCustomRoutes(primaryNetworkName, peeringName, suffix string) string { + s := ` +resource "google_compute_network" "network1" { + name = "%s" + auto_create_subnetworks = false +} + +resource "google_compute_network_peering" "foo" { + name = "%s" + network = google_compute_network.network1.self_link + peer_network = google_compute_network.network2.self_link +} + +resource "google_compute_network" "network2" { + name = "network-test-2-%s" + auto_create_subnetworks = false +} + +resource "google_compute_network_peering" "bar" { + network = google_compute_network.network2.self_link + peer_network = google_compute_network.network1.self_link + name = "peering-test-2-%s" +}` + return fmt.Sprintf(s, primaryNetworkName, peeringName, suffix, suffix) +}