Skip to content

Commit

Permalink
add support for updating alias ips in instances (hashicorp#1084)
Browse files Browse the repository at this point in the history
  • Loading branch information
danawillow authored Feb 14, 2018
1 parent f785116 commit 2e665f2
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 13 deletions.
54 changes: 49 additions & 5 deletions google/resource_compute_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,20 +371,18 @@ func resourceComputeInstance() *schema.Resource {

"alias_ip_range": &schema.Schema{
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ip_cidr_range": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: ipCidrRangeDiffSuppress,
},
"subnetwork_range_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
},
},
Expand Down Expand Up @@ -923,9 +921,11 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err
return err
}

instance, err := getInstance(config, d)
// Use beta api directly in order to read network_interface.fingerprint without having to put it in the schema.
// Change back to getInstance(config, d) once updating alias ips is GA.
instance, err := config.clientComputeBeta.Instances.Get(project, zone, d.Id()).Do()
if err != nil {
return err
return handleNotFoundError(err, d, fmt.Sprintf("Instance %s", d.Get("name").(string)))
}

// Enable partial mode for the resource since it is possible
Expand Down Expand Up @@ -1111,6 +1111,50 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err
}
}
}

if d.HasChange(prefix + ".alias_ip_range") {
rereadFingerprint := false

// Alias IP ranges cannot be updated; they must be removed and then added.
if len(instNetworkInterface.AliasIpRanges) > 0 {
ni := &computeBeta.NetworkInterface{
Fingerprint: instNetworkInterface.Fingerprint,
ForceSendFields: []string{"AliasIpRanges"},
}
op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, d.Id(), networkName, ni).Do()
if err != nil {
return errwrap.Wrapf("Error removing alias_ip_range: {{err}}", err)
}
opErr := computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutUpdate).Minutes()), "updaing alias ip ranges")
if opErr != nil {
return opErr
}
rereadFingerprint = true
}

ranges := d.Get(prefix + ".alias_ip_range").([]interface{})
if len(ranges) > 0 {
if rereadFingerprint {
instance, err = config.clientComputeBeta.Instances.Get(project, zone, d.Id()).Do()
if err != nil {
return err
}
instNetworkInterface = instance.NetworkInterfaces[i]
}
ni := &computeBeta.NetworkInterface{
AliasIpRanges: expandAliasIpRanges(ranges),
Fingerprint: instNetworkInterface.Fingerprint,
}
op, err := config.clientComputeBeta.Instances.UpdateNetworkInterface(project, zone, d.Id(), networkName, ni).Do()
if err != nil {
return errwrap.Wrapf("Error adding alias_ip_range: {{err}}", err)
}
opErr := computeSharedOperationWaitTime(config.clientCompute, op, project, int(d.Timeout(schema.TimeoutUpdate).Minutes()), "updaing alias ip ranges")
if opErr != nil {
return opErr
}
}
}
d.SetPartial("network_interface")
}

Expand Down
66 changes: 58 additions & 8 deletions google/resource_compute_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -983,14 +983,16 @@ func TestAccComputeInstance_secondaryAliasIpRange(t *testing.T) {

var instance compute.Instance
instanceName := fmt.Sprintf("terraform-test-%s", acctest.RandString(10))
networkName := fmt.Sprintf("terraform-test-%s", acctest.RandString(10))
subnetName := fmt.Sprintf("terraform-test-%s", acctest.RandString(10))

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckComputeInstanceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccComputeInstance_secondaryAliasIpRange(instanceName),
Config: testAccComputeInstance_secondaryAliasIpRange(networkName, subnetName, instanceName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceExists("google_compute_instance.foobar", &instance),
testAccCheckComputeInstanceHasAliasIpRange(&instance, "inst-test-secondary", "172.16.0.0/24"),
Expand All @@ -1001,6 +1003,18 @@ func TestAccComputeInstance_secondaryAliasIpRange(t *testing.T) {
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-east1-d", instanceName),
},
resource.TestStep{
Config: testAccComputeInstance_secondaryAliasIpRangeUpdate(networkName, subnetName, instanceName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceExists("google_compute_instance.foobar", &instance),
testAccCheckComputeInstanceHasAliasIpRange(&instance, "", "10.0.1.0/24"),
),
},
resource.TestStep{
ResourceName: "google_compute_instance.foobar",
ImportState: true,
ImportStateId: fmt.Sprintf("%s/%s/%s", getTestProjectFromEnv(), "us-east1-d", instanceName),
},
},
})
}
Expand Down Expand Up @@ -2506,13 +2520,13 @@ resource "google_compute_instance" "foobar" {
}`, instance)
}

func testAccComputeInstance_secondaryAliasIpRange(instance string) string {
func testAccComputeInstance_secondaryAliasIpRange(network, subnet, instance string) string {
return fmt.Sprintf(`
resource "google_compute_network" "inst-test-network" {
name = "inst-test-network-%s"
name = "%s"
}
resource "google_compute_subnetwork" "inst-test-subnetwork" {
name = "inst-test-subnetwork-%s"
name = "%s"
ip_cidr_range = "10.0.0.0/16"
region = "us-east1"
network = "${google_compute_network.inst-test-network.self_link}"
Expand All @@ -2522,9 +2536,9 @@ resource "google_compute_subnetwork" "inst-test-subnetwork" {
}
}
resource "google_compute_instance" "foobar" {
name = "%s"
name = "%s"
machine_type = "n1-standard-1"
zone = "us-east1-d"
zone = "us-east1-d"
boot_disk {
initialize_params {
Expand All @@ -2537,10 +2551,46 @@ resource "google_compute_instance" "foobar" {
alias_ip_range {
subnetwork_range_name = "${google_compute_subnetwork.inst-test-subnetwork.secondary_ip_range.0.range_name}"
ip_cidr_range = "172.16.0.0/24"
ip_cidr_range = "172.16.0.0/24"
}
}
}`, network, subnet, instance)
}

func testAccComputeInstance_secondaryAliasIpRangeUpdate(network, subnet, instance string) string {
return fmt.Sprintf(`
resource "google_compute_network" "inst-test-network" {
name = "%s"
}
resource "google_compute_subnetwork" "inst-test-subnetwork" {
name = "%s"
ip_cidr_range = "10.0.0.0/16"
region = "us-east1"
network = "${google_compute_network.inst-test-network.self_link}"
secondary_ip_range {
range_name = "inst-test-secondary"
ip_cidr_range = "172.16.0.0/20"
}
}
resource "google_compute_instance" "foobar" {
name = "%s"
machine_type = "n1-standard-1"
zone = "us-east1-d"
boot_disk {
initialize_params {
image = "debian-8-jessie-v20160803"
}
}
network_interface {
subnetwork = "${google_compute_subnetwork.inst-test-subnetwork.self_link}"
alias_ip_range {
ip_cidr_range = "10.0.1.0/24"
}
}
}`, acctest.RandString(10), acctest.RandString(10), instance)
}`, network, subnet, instance)
}

// Set fields that require stopping the instance: machine_type, min_cpu_platform, and service_account
Expand Down

0 comments on commit 2e665f2

Please sign in to comment.