mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-03 01:01:06 +00:00
Implement in-place updates of secondary IP ranges (#811)
This commit is contained in:
parent
13eb96cf6a
commit
4da0e984f6
@ -7,9 +7,17 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
computeBeta "google.golang.org/api/compute/v0.beta"
|
||||||
"google.golang.org/api/compute/v1"
|
"google.golang.org/api/compute/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
SubnetworkBaseApiVersion = v1
|
||||||
|
SubnetworkVersionedFeatures = []Feature{
|
||||||
|
{Version: v0beta, Item: "secondary_ip_range"},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func resourceComputeSubnetwork() *schema.Resource {
|
func resourceComputeSubnetwork() *schema.Resource {
|
||||||
return &schema.Resource{
|
return &schema.Resource{
|
||||||
Create: resourceComputeSubnetworkCreate,
|
Create: resourceComputeSubnetworkCreate,
|
||||||
@ -46,6 +54,11 @@ func resourceComputeSubnetwork() *schema.Resource {
|
|||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"fingerprint": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
|
||||||
"gateway_address": &schema.Schema{
|
"gateway_address": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
@ -73,19 +86,16 @@ func resourceComputeSubnetwork() *schema.Resource {
|
|||||||
"secondary_ip_range": &schema.Schema{
|
"secondary_ip_range": &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"range_name": &schema.Schema{
|
"range_name": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validateGCPName,
|
ValidateFunc: validateGCPName,
|
||||||
},
|
},
|
||||||
"ip_cidr_range": &schema.Schema{
|
"ip_cidr_range": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -151,6 +161,11 @@ func resourceComputeSubnetworkCreate(d *schema.ResourceData, meta interface{}) e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func resourceComputeSubnetworkRead(d *schema.ResourceData, meta interface{}) error {
|
func resourceComputeSubnetworkRead(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
computeApiVersion := getComputeApiVersion(d, SubnetworkBaseApiVersion, SubnetworkVersionedFeatures)
|
||||||
|
if computeApiVersion == v0beta {
|
||||||
|
return resourceComputeSubnetworkReadV0Beta(d, meta)
|
||||||
|
}
|
||||||
|
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
region, err := getRegion(d, config)
|
region, err := getRegion(d, config)
|
||||||
@ -184,7 +199,43 @@ func resourceComputeSubnetworkRead(d *schema.ResourceData, meta interface{}) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resourceComputeSubnetworkReadV0Beta(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
config := meta.(*Config)
|
||||||
|
|
||||||
|
region, err := getRegion(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
project, err := getProject(d, config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
name := d.Get("name").(string)
|
||||||
|
|
||||||
|
subnetwork, err := config.clientComputeBeta.Subnetworks.Get(project, region, name).Do()
|
||||||
|
if err != nil {
|
||||||
|
return handleNotFoundError(err, d, fmt.Sprintf("Subnetwork %q", name))
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("name", subnetwork.Name)
|
||||||
|
d.Set("ip_cidr_range", subnetwork.IpCidrRange)
|
||||||
|
d.Set("network", subnetwork.Network)
|
||||||
|
d.Set("description", subnetwork.Description)
|
||||||
|
d.Set("private_ip_google_access", subnetwork.PrivateIpGoogleAccess)
|
||||||
|
d.Set("gateway_address", subnetwork.GatewayAddress)
|
||||||
|
d.Set("secondary_ip_range", flattenSecondaryRangesV0Beta(subnetwork.SecondaryIpRanges))
|
||||||
|
d.Set("project", project)
|
||||||
|
d.Set("region", region)
|
||||||
|
d.Set("self_link", ConvertSelfLinkToV1(subnetwork.SelfLink))
|
||||||
|
d.Set("fingerprint", subnetwork.Fingerprint)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func resourceComputeSubnetworkUpdate(d *schema.ResourceData, meta interface{}) error {
|
func resourceComputeSubnetworkUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||||
|
computeApiVersion := getComputeApiVersion(d, SubnetworkBaseApiVersion, SubnetworkVersionedFeatures)
|
||||||
config := meta.(*Config)
|
config := meta.(*Config)
|
||||||
|
|
||||||
region, err := getRegion(d, config)
|
region, err := getRegion(d, config)
|
||||||
@ -221,6 +272,26 @@ func resourceComputeSubnetworkUpdate(d *schema.ResourceData, meta interface{}) e
|
|||||||
d.SetPartial("private_ip_google_access")
|
d.SetPartial("private_ip_google_access")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if d.HasChange("secondary_ip_range") && computeApiVersion == v0beta {
|
||||||
|
v0BetaSubnetwork := &computeBeta.Subnetwork{
|
||||||
|
SecondaryIpRanges: expandSecondaryRangesV0Beta(d.Get("secondary_ip_range").([]interface{})),
|
||||||
|
Fingerprint: d.Get("fingerprint").(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
op, err := config.clientComputeBeta.Subnetworks.Patch(
|
||||||
|
project, region, d.Get("name").(string), v0BetaSubnetwork).Do()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error updating subnetwork SecondaryIpRanges: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = computeSharedOperationWait(config.clientCompute, op, project, "Updating Subnetwork SecondaryIpRanges")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetPartial("secondary_ip_range")
|
||||||
|
}
|
||||||
|
|
||||||
d.Partial(false)
|
d.Partial(false)
|
||||||
|
|
||||||
return resourceComputeSubnetworkRead(d, meta)
|
return resourceComputeSubnetworkRead(d, meta)
|
||||||
@ -298,6 +369,20 @@ func expandSecondaryRanges(configured []interface{}) []*compute.SubnetworkSecond
|
|||||||
return secondaryRanges
|
return secondaryRanges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func expandSecondaryRangesV0Beta(configured []interface{}) []*computeBeta.SubnetworkSecondaryRange {
|
||||||
|
secondaryRanges := make([]*computeBeta.SubnetworkSecondaryRange, 0, len(configured))
|
||||||
|
for _, raw := range configured {
|
||||||
|
data := raw.(map[string]interface{})
|
||||||
|
secondaryRange := computeBeta.SubnetworkSecondaryRange{
|
||||||
|
RangeName: data["range_name"].(string),
|
||||||
|
IpCidrRange: data["ip_cidr_range"].(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
secondaryRanges = append(secondaryRanges, &secondaryRange)
|
||||||
|
}
|
||||||
|
return secondaryRanges
|
||||||
|
}
|
||||||
|
|
||||||
func flattenSecondaryRanges(secondaryRanges []*compute.SubnetworkSecondaryRange) []map[string]interface{} {
|
func flattenSecondaryRanges(secondaryRanges []*compute.SubnetworkSecondaryRange) []map[string]interface{} {
|
||||||
secondaryRangesSchema := make([]map[string]interface{}, 0, len(secondaryRanges))
|
secondaryRangesSchema := make([]map[string]interface{}, 0, len(secondaryRanges))
|
||||||
for _, secondaryRange := range secondaryRanges {
|
for _, secondaryRange := range secondaryRanges {
|
||||||
@ -310,3 +395,16 @@ func flattenSecondaryRanges(secondaryRanges []*compute.SubnetworkSecondaryRange)
|
|||||||
}
|
}
|
||||||
return secondaryRangesSchema
|
return secondaryRangesSchema
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func flattenSecondaryRangesV0Beta(secondaryRanges []*computeBeta.SubnetworkSecondaryRange) []map[string]interface{} {
|
||||||
|
secondaryRangesSchema := make([]map[string]interface{}, 0, len(secondaryRanges))
|
||||||
|
for _, secondaryRange := range secondaryRanges {
|
||||||
|
data := map[string]interface{}{
|
||||||
|
"range_name": secondaryRange.RangeName,
|
||||||
|
"ip_cidr_range": secondaryRange.IpCidrRange,
|
||||||
|
}
|
||||||
|
|
||||||
|
secondaryRangesSchema = append(secondaryRangesSchema, data)
|
||||||
|
}
|
||||||
|
return secondaryRangesSchema
|
||||||
|
}
|
||||||
|
@ -74,6 +74,46 @@ func TestAccComputeSubnetwork_update(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccComputeSubnetwork_secondaryIpRangesUpdate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var subnetwork compute.Subnetwork
|
||||||
|
|
||||||
|
cnName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
|
||||||
|
subnetworkName := fmt.Sprintf("tf-test-%s", acctest.RandString(10))
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckComputeSubnetworkDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccComputeSubnetwork_secondaryIpRanges_update1(cnName, subnetworkName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckComputeSubnetworkExists("google_compute_subnetwork.network-with-private-secondary-ip-ranges", &subnetwork),
|
||||||
|
testAccCheckComputeSubnetworkHasSecondaryIpRange(&subnetwork, "tf-test-secondary-range-update1", "192.168.10.0/24"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccComputeSubnetwork_secondaryIpRanges_update2(cnName, subnetworkName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckComputeSubnetworkExists("google_compute_subnetwork.network-with-private-secondary-ip-ranges", &subnetwork),
|
||||||
|
testAccCheckComputeSubnetworkHasSecondaryIpRange(&subnetwork, "tf-test-secondary-range-update1", "192.168.10.0/24"),
|
||||||
|
testAccCheckComputeSubnetworkHasSecondaryIpRange(&subnetwork, "tf-test-secondary-range-update2", "192.168.11.0/24"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccComputeSubnetwork_secondaryIpRanges_update3(cnName, subnetworkName),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckComputeSubnetworkExists("google_compute_subnetwork.network-with-private-secondary-ip-ranges", &subnetwork),
|
||||||
|
testAccCheckComputeSubnetworkHasSecondaryIpRange(&subnetwork, "tf-test-secondary-range-update1", "192.168.10.0/24"),
|
||||||
|
testAccCheckComputeSubnetworkHasNotSecondaryIpRange(&subnetwork, "tf-test-secondary-range-update2", "192.168.11.0/24"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccComputeSubnetwork_secondaryIpRanges(t *testing.T) {
|
func TestAccComputeSubnetwork_secondaryIpRanges(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
@ -162,6 +202,20 @@ func testAccCheckComputeSubnetworkHasSecondaryIpRange(subnetwork *compute.Subnet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccCheckComputeSubnetworkHasNotSecondaryIpRange(subnetwork *compute.Subnetwork, rangeName, ipCidrRange string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
for _, secondaryRange := range subnetwork.SecondaryIpRanges {
|
||||||
|
if secondaryRange.RangeName == rangeName {
|
||||||
|
if secondaryRange.IpCidrRange == ipCidrRange {
|
||||||
|
return fmt.Errorf("Secondary range %s has the wrong ip_cidr_range. Expected %s, got %s", rangeName, ipCidrRange, secondaryRange.IpCidrRange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testAccComputeSubnetwork_basic(cnName, subnetwork1Name, subnetwork2Name, subnetwork3Name string) string {
|
func testAccComputeSubnetwork_basic(cnName, subnetwork1Name, subnetwork2Name, subnetwork3Name string) string {
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
resource "google_compute_network" "custom-test" {
|
resource "google_compute_network" "custom-test" {
|
||||||
@ -246,3 +300,67 @@ resource "google_compute_subnetwork" "network-with-private-secondary-ip-range" {
|
|||||||
}
|
}
|
||||||
`, cnName, subnetworkName)
|
`, cnName, subnetworkName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccComputeSubnetwork_secondaryIpRanges_update1(cnName, subnetworkName string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "google_compute_network" "custom-test" {
|
||||||
|
name = "%s"
|
||||||
|
auto_create_subnetworks = false
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges" {
|
||||||
|
name = "%s"
|
||||||
|
ip_cidr_range = "10.2.0.0/16"
|
||||||
|
region = "us-central1"
|
||||||
|
network = "${google_compute_network.custom-test.self_link}"
|
||||||
|
secondary_ip_range {
|
||||||
|
range_name = "tf-test-secondary-range-update1"
|
||||||
|
ip_cidr_range = "192.168.10.0/24"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, cnName, subnetworkName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccComputeSubnetwork_secondaryIpRanges_update2(cnName, subnetworkName string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "google_compute_network" "custom-test" {
|
||||||
|
name = "%s"
|
||||||
|
auto_create_subnetworks = false
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges" {
|
||||||
|
name = "%s"
|
||||||
|
ip_cidr_range = "10.2.0.0/16"
|
||||||
|
region = "us-central1"
|
||||||
|
network = "${google_compute_network.custom-test.self_link}"
|
||||||
|
secondary_ip_range {
|
||||||
|
range_name = "tf-test-secondary-range-update1"
|
||||||
|
ip_cidr_range = "192.168.10.0/24"
|
||||||
|
}
|
||||||
|
secondary_ip_range {
|
||||||
|
range_name = "tf-test-secondary-range-update2"
|
||||||
|
ip_cidr_range = "192.168.11.0/24"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`, cnName, subnetworkName)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccComputeSubnetwork_secondaryIpRanges_update3(cnName, subnetworkName string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "google_compute_network" "custom-test" {
|
||||||
|
name = "%s"
|
||||||
|
auto_create_subnetworks = false
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_subnetwork" "network-with-private-secondary-ip-ranges" {
|
||||||
|
name = "%s"
|
||||||
|
ip_cidr_range = "10.2.0.0/16"
|
||||||
|
region = "us-central1"
|
||||||
|
network = "${google_compute_network.custom-test.self_link}"
|
||||||
|
secondary_ip_range {
|
||||||
|
range_name = "tf-test-secondary-range-update1"
|
||||||
|
ip_cidr_range = "192.168.10.0/24"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, cnName, subnetworkName)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user