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 support for updating alias ips in instances #1084

Merged
merged 1 commit into from
Feb 14, 2018
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
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