Skip to content

Commit

Permalink
Add Update Connector Support for VPC Access Connectors (#8205)
Browse files Browse the repository at this point in the history
* Add Update Connetor Support for VPC Access Connectors

* fix lint

* fix go lint

* fix tests

Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician committed Jul 14, 2023
1 parent 815e532 commit 878eca2
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .changelog/8205.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
vpcaccess: added support for updates to `google_vpc_access_connector` resource
```
2 changes: 2 additions & 0 deletions google/data_source_vpc_access_connector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ resource "google_vpc_access_connector" "connector" {
ip_cidr_range = "10.8.0.0/28"
network = "default"
region = "us-central1"
min_instances = 2
max_instances = 3
}
data "google_vpc_access_connector" "connector" {
Expand Down
2 changes: 2 additions & 0 deletions google/resource_app_engine_standard_app_version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ resource "google_vpc_access_connector" "bar" {
region = "us-central1"
ip_cidr_range = "10.8.0.0/28"
network = "default"
min_instances = 3
max_instances = 10
}
resource "google_app_engine_standard_app_version" "foo" {
Expand Down
2 changes: 2 additions & 0 deletions google/resource_cloudfunctions_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,8 @@ resource "google_vpc_access_connector" "%s" {
region = "us-central1"
ip_cidr_range = "%s"
network = google_compute_network.vpc.name
min_instances = 3
max_instances = 10
}
resource "google_storage_bucket" "bucket" {
Expand Down
6 changes: 5 additions & 1 deletion google/resource_vpc_access_connector_generated_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ func testAccVPCAccessConnector_vpcAccessConnectorExample(context map[string]inte
return acctest.Nprintf(`
resource "google_vpc_access_connector" "connector" {
name = "tf-test-vpc-con%{random_suffix}"
ip_cidr_range = "10.8.0.0/28"
ip_cidr_range = "10.18.0.0/28"
network = "default"
min_instances = 2
max_instances = 3
}
`, context)
}
Expand Down Expand Up @@ -98,6 +100,8 @@ resource "google_vpc_access_connector" "connector" {
name = google_compute_subnetwork.custom_test.name
}
machine_type = "e2-standard-4"
min_instances = 2
max_instances = 3
}
resource "google_compute_subnetwork" "custom_test" {
Expand Down
59 changes: 59 additions & 0 deletions google/resource_vpc_access_connector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,38 @@ func TestAccVPCAccessConnector_vpcAccessConnectorThroughput(t *testing.T) {
})
}

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

context := map[string]interface{}{
"random_suffix": RandString(t, 10),
}

VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: ProtoV5ProviderFactories(t),
CheckDestroy: testAccCheckVPCAccessConnectorDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccVPCAccessConnector_vpcAccessConnectorThroughput(context),
},
{
ResourceName: "google_vpc_access_connector.connector",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccVPCAccessConnector_vpcAccessConnectorMachineAndInstancesChanged(context),
},
{
ResourceName: "google_vpc_access_connector.connector",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccVPCAccessConnector_vpcAccessConnectorThroughput(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_vpc_access_connector" "connector" {
Expand All @@ -59,3 +91,30 @@ resource "google_compute_network" "custom_test" {
}
`, context)
}

func testAccVPCAccessConnector_vpcAccessConnectorMachineAndInstancesChanged(context map[string]interface{}) string {
return Nprintf(`
resource "google_vpc_access_connector" "connector" {
name = "tf-test-vpc-con%{random_suffix}"
subnet {
name = google_compute_subnetwork.custom_test.name
}
machine_type = "e2-micro"
min_instances = 3
max_instances = 5
region = "us-central1"
}
resource "google_compute_subnetwork" "custom_test" {
name = "tf-test-vpc-con%{random_suffix}"
ip_cidr_range = "10.2.0.0/28"
region = "us-central1"
network = google_compute_network.custom_test.id
}
resource "google_compute_network" "custom_test" {
name = "tf-test-vpc-con%{random_suffix}"
auto_create_subnetworks = false
}
`, context)
}
125 changes: 117 additions & 8 deletions google/services/vpcaccess/resource_vpc_access_connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,31 @@
package vpcaccess

import (
"context"
"fmt"
"log"
"reflect"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"

"github.com/hashicorp/terraform-provider-google/google/tpgresource"
transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport"
)

// Are the number of min/max instances reduced?
func AreInstancesReduced(_ context.Context, old, new, _ interface{}) bool {
return new.(int) < old.(int)
}

func ResourceVPCAccessConnector() *schema.Resource {
return &schema.Resource{
Create: resourceVPCAccessConnectorCreate,
Read: resourceVPCAccessConnectorRead,
Update: resourceVPCAccessConnectorUpdate,
Delete: resourceVPCAccessConnectorDelete,

Importer: &schema.ResourceImporter{
Expand All @@ -42,9 +51,14 @@ func ResourceVPCAccessConnector() *schema.Resource {

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(20 * time.Minute),
Update: schema.DefaultTimeout(20 * time.Minute),
Delete: schema.DefaultTimeout(20 * time.Minute),
},

CustomizeDiff: customdiff.All(
customdiff.ForceNewIfChange("min_instances", AreInstancesReduced),
customdiff.ForceNewIfChange("max_instances", AreInstancesReduced)),

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Expand All @@ -62,39 +76,36 @@ func ResourceVPCAccessConnector() *schema.Resource {
"machine_type": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: `Machine type of VM Instance underlying connector. Default is e2-micro`,
Default: "e2-micro",
},
"max_instances": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
ForceNew: true,
Description: `Maximum value of instances in autoscaling group underlying the connector.`,
},
"max_throughput": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(200, 1000),
Description: `Maximum throughput of the connector in Mbps, must be greater than 'min_throughput'. Default is 300.`,
Default: 300,
ValidateFunc: validation.IntBetween(300, 1000),
Description: `Maximum throughput of the connector in Mbps, must be greater than 'min_throughput'. Default is 1000.`,
},
"min_instances": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
ForceNew: true,
Description: `Minimum value of instances in autoscaling group underlying the connector.`,
},
"min_throughput": {
Type: schema.TypeInt,
Computed: true,
Optional: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(200, 1000),
ValidateFunc: validation.IntBetween(200, 900),
Description: `Minimum throughput of the connector in Mbps. Default and min is 200.`,
Default: 200,
},
"network": {
Type: schema.TypeString,
Expand Down Expand Up @@ -405,6 +416,104 @@ func resourceVPCAccessConnectorRead(d *schema.ResourceData, meta interface{}) er
return nil
}

func resourceVPCAccessConnectorUpdate(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
if err != nil {
return err
}

billingProject := ""

project, err := tpgresource.GetProject(d, config)
if err != nil {
return fmt.Errorf("Error fetching project for Connector: %s", err)
}
billingProject = project

obj := make(map[string]interface{})
machineTypeProp, err := expandVPCAccessConnectorMachineType(d.Get("machine_type"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("machine_type"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, machineTypeProp)) {
obj["machineType"] = machineTypeProp
}
minInstancesProp, err := expandVPCAccessConnectorMinInstances(d.Get("min_instances"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("min_instances"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, minInstancesProp)) {
obj["minInstances"] = minInstancesProp
}
maxInstancesProp, err := expandVPCAccessConnectorMaxInstances(d.Get("max_instances"), d, config)
if err != nil {
return err
} else if v, ok := d.GetOkExists("max_instances"); !tpgresource.IsEmptyValue(reflect.ValueOf(v)) && (ok || !reflect.DeepEqual(v, maxInstancesProp)) {
obj["maxInstances"] = maxInstancesProp
}

obj, err = resourceVPCAccessConnectorEncoder(d, meta, obj)
if err != nil {
return err
}

url, err := tpgresource.ReplaceVars(d, config, "{{VPCAccessBasePath}}projects/{{project}}/locations/{{region}}/connectors/{{name}}")
if err != nil {
return err
}

log.Printf("[DEBUG] Updating Connector %q: %#v", d.Id(), obj)
updateMask := []string{}

if d.HasChange("machine_type") {
updateMask = append(updateMask, "machineType")
}

if d.HasChange("min_instances") {
updateMask = append(updateMask, "minInstances")
}

if d.HasChange("max_instances") {
updateMask = append(updateMask, "maxInstances")
}
// updateMask is a URL parameter but not present in the schema, so ReplaceVars
// won't set it
url, err = transport_tpg.AddQueryParams(url, map[string]string{"updateMask": strings.Join(updateMask, ",")})
if err != nil {
return err
}

// err == nil indicates that the billing_project value was found
if bp, err := tpgresource.GetBillingProject(d, config); err == nil {
billingProject = bp
}

res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{
Config: config,
Method: "PATCH",
Project: billingProject,
RawURL: url,
UserAgent: userAgent,
Body: obj,
Timeout: d.Timeout(schema.TimeoutUpdate),
})

if err != nil {
return fmt.Errorf("Error updating Connector %q: %s", d.Id(), err)
} else {
log.Printf("[DEBUG] Finished updating Connector %q: %#v", d.Id(), res)
}

err = VPCAccessOperationWaitTime(
config, res, project, "Updating Connector", userAgent,
d.Timeout(schema.TimeoutUpdate))

if err != nil {
return err
}

return resourceVPCAccessConnectorRead(d, meta)
}

func resourceVPCAccessConnectorDelete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*transport_tpg.Config)
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)
Expand Down
9 changes: 7 additions & 2 deletions website/docs/r/vpc_access_connector.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ To get more information about Connector, see:
```hcl
resource "google_vpc_access_connector" "connector" {
name = "vpc-con"
ip_cidr_range = "10.8.0.0/28"
ip_cidr_range = "10.18.0.0/28"
network = "default"
min_instances = 2
max_instances = 3
}
```
<div class = "oics-button" style="float: right; margin: 0 0 -15px">
Expand All @@ -58,6 +60,8 @@ resource "google_vpc_access_connector" "connector" {
name = google_compute_subnetwork.custom_test.name
}
machine_type = "e2-standard-4"
min_instances = 2
max_instances = 3
}
resource "google_compute_subnetwork" "custom_test" {
Expand Down Expand Up @@ -112,7 +116,7 @@ The following arguments are supported:

* `max_throughput` -
(Optional)
Maximum throughput of the connector in Mbps, must be greater than `min_throughput`. Default is 300.
Maximum throughput of the connector in Mbps, must be greater than `min_throughput`. Default is 1000.

* `subnet` -
(Optional)
Expand Down Expand Up @@ -160,6 +164,7 @@ This resource provides the following
[Timeouts](https://developer.hashicorp.com/terraform/plugin/sdkv2/resources/retries-and-customizable-timeouts) configuration options:

- `create` - Default is 20 minutes.
- `update` - Default is 20 minutes.
- `delete` - Default is 20 minutes.

## Import
Expand Down

0 comments on commit 878eca2

Please sign in to comment.