mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-10-07 03:01:06 +00:00
Support distributionPolicy
when creating regional instance group managers. (#1092)
* Support `distributionPolicy` when creating regional instance group managers. * Better match the API structure of distributionPolicy. * Switch to "distribution_policy_zones". This approach lets us more simply allow a list of zones to use, while providing a deprecation path for implementing the distribution policy field more holistically, avoiding backwards-incompatible changes. * fix typo * use slice instead of Set for flattenDP
This commit is contained in:
parent
1d1cfa64c4
commit
08e81f528c
@ -1,19 +1,25 @@
|
|||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/hashicorp/terraform/helper/validation"
|
"github.com/hashicorp/terraform/helper/validation"
|
||||||
"log"
|
|
||||||
|
|
||||||
"fmt"
|
|
||||||
computeBeta "google.golang.org/api/compute/v0.beta"
|
computeBeta "google.golang.org/api/compute/v0.beta"
|
||||||
"google.golang.org/api/compute/v1"
|
"google.golang.org/api/compute/v1"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var RegionInstanceGroupManagerBaseApiVersion = v1
|
var RegionInstanceGroupManagerBaseApiVersion = v1
|
||||||
var RegionInstanceGroupManagerVersionedFeatures = []Feature{Feature{Version: v0beta, Item: "auto_healing_policies"}}
|
var RegionInstanceGroupManagerVersionedFeatures = []Feature{
|
||||||
|
Feature{Version: v0beta, Item: "auto_healing_policies"},
|
||||||
|
Feature{Version: v0beta, Item: "distribution_policy_zones"},
|
||||||
|
}
|
||||||
|
|
||||||
func resourceComputeRegionInstanceGroupManager() *schema.Resource {
|
func resourceComputeRegionInstanceGroupManager() *schema.Resource {
|
||||||
return &schema.Resource{
|
return &schema.Resource{
|
||||||
@ -109,7 +115,6 @@ func resourceComputeRegionInstanceGroupManager() *schema.Resource {
|
|||||||
},
|
},
|
||||||
Set: selfLinkRelativePathHash,
|
Set: selfLinkRelativePathHash,
|
||||||
},
|
},
|
||||||
|
|
||||||
"target_size": &schema.Schema{
|
"target_size": &schema.Schema{
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
@ -145,6 +150,18 @@ func resourceComputeRegionInstanceGroupManager() *schema.Resource {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"distribution_policy_zones": &schema.Schema{
|
||||||
|
Type: schema.TypeSet,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
Computed: true,
|
||||||
|
Set: hashZoneFromSelfLinkOrResourceName,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
DiffSuppressFunc: compareSelfLinkOrResourceName,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,6 +184,7 @@ func resourceComputeRegionInstanceGroupManagerCreate(d *schema.ResourceData, met
|
|||||||
NamedPorts: getNamedPortsBeta(d.Get("named_port").([]interface{})),
|
NamedPorts: getNamedPortsBeta(d.Get("named_port").([]interface{})),
|
||||||
TargetPools: convertStringSet(d.Get("target_pools").(*schema.Set)),
|
TargetPools: convertStringSet(d.Get("target_pools").(*schema.Set)),
|
||||||
AutoHealingPolicies: expandAutoHealingPolicies(d.Get("auto_healing_policies").([]interface{})),
|
AutoHealingPolicies: expandAutoHealingPolicies(d.Get("auto_healing_policies").([]interface{})),
|
||||||
|
DistributionPolicy: expandDistributionPolicy(d.Get("distribution_policy_zones").(*schema.Set)),
|
||||||
// Force send TargetSize to allow size of 0.
|
// Force send TargetSize to allow size of 0.
|
||||||
ForceSendFields: []string{"TargetSize"},
|
ForceSendFields: []string{"TargetSize"},
|
||||||
}
|
}
|
||||||
@ -212,6 +230,7 @@ func getManager(d *schema.ResourceData, meta interface{}) (*computeBeta.Instance
|
|||||||
|
|
||||||
region := d.Get("region").(string)
|
region := d.Get("region").(string)
|
||||||
manager := &computeBeta.InstanceGroupManager{}
|
manager := &computeBeta.InstanceGroupManager{}
|
||||||
|
|
||||||
switch computeApiVersion {
|
switch computeApiVersion {
|
||||||
case v1:
|
case v1:
|
||||||
v1Manager := &compute.InstanceGroupManager{}
|
v1Manager := &compute.InstanceGroupManager{}
|
||||||
@ -226,7 +245,7 @@ func getManager(d *schema.ResourceData, meta interface{}) (*computeBeta.Instance
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
handleNotFoundError(err, d, fmt.Sprintf("Region Instance Manager %q", d.Get("name").(string)))
|
return nil, handleNotFoundError(err, d, fmt.Sprintf("Region Instance Manager %q", d.Get("name").(string)))
|
||||||
}
|
}
|
||||||
return manager, nil
|
return manager, nil
|
||||||
}
|
}
|
||||||
@ -270,6 +289,9 @@ func resourceComputeRegionInstanceGroupManagerRead(d *schema.ResourceData, meta
|
|||||||
d.Set("fingerprint", manager.Fingerprint)
|
d.Set("fingerprint", manager.Fingerprint)
|
||||||
d.Set("instance_group", manager.InstanceGroup)
|
d.Set("instance_group", manager.InstanceGroup)
|
||||||
d.Set("auto_healing_policies", flattenAutoHealingPolicies(manager.AutoHealingPolicies))
|
d.Set("auto_healing_policies", flattenAutoHealingPolicies(manager.AutoHealingPolicies))
|
||||||
|
if err := d.Set("distribution_policy_zones", flattenDistributionPolicy(manager.DistributionPolicy)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
d.Set("self_link", ConvertSelfLinkToV1(manager.SelfLink))
|
d.Set("self_link", ConvertSelfLinkToV1(manager.SelfLink))
|
||||||
|
|
||||||
if d.Get("wait_for_instances").(bool) {
|
if d.Get("wait_for_instances").(bool) {
|
||||||
@ -509,3 +531,39 @@ func resourceComputeRegionInstanceGroupManagerDelete(d *schema.ResourceData, met
|
|||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func expandDistributionPolicy(configured *schema.Set) *computeBeta.DistributionPolicy {
|
||||||
|
if configured.Len() == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
distributionPolicyZoneConfigs := make([]*computeBeta.DistributionPolicyZoneConfiguration, 0, configured.Len())
|
||||||
|
for _, raw := range configured.List() {
|
||||||
|
data := raw.(string)
|
||||||
|
distributionPolicyZoneConfig := computeBeta.DistributionPolicyZoneConfiguration{
|
||||||
|
Zone: "zones/" + data,
|
||||||
|
}
|
||||||
|
|
||||||
|
distributionPolicyZoneConfigs = append(distributionPolicyZoneConfigs, &distributionPolicyZoneConfig)
|
||||||
|
}
|
||||||
|
return &computeBeta.DistributionPolicy{Zones: distributionPolicyZoneConfigs}
|
||||||
|
}
|
||||||
|
|
||||||
|
func flattenDistributionPolicy(distributionPolicy *computeBeta.DistributionPolicy) []string {
|
||||||
|
zones := make([]string, 0)
|
||||||
|
|
||||||
|
if distributionPolicy != nil {
|
||||||
|
for _, zone := range distributionPolicy.Zones {
|
||||||
|
zones = append(zones, zone.Zone)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return zones
|
||||||
|
}
|
||||||
|
|
||||||
|
func hashZoneFromSelfLinkOrResourceName(value interface{}) int {
|
||||||
|
parts := strings.Split(value.(string), "/")
|
||||||
|
resource := parts[len(parts)-1]
|
||||||
|
|
||||||
|
return hashcode.String(resource)
|
||||||
|
}
|
||||||
|
@ -204,6 +204,32 @@ func TestAccRegionInstanceGroupManager_autoHealingPolicies(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccRegionInstanceGroupManager_distributionPolicy(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var manager computeBeta.InstanceGroupManager
|
||||||
|
|
||||||
|
template := fmt.Sprintf("igm-test-%s", acctest.RandString(10))
|
||||||
|
igm := fmt.Sprintf("igm-test-%s", acctest.RandString(10))
|
||||||
|
zones := []string{"us-central1-a", "us-central1-b"}
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckRegionInstanceGroupManagerDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccRegionInstanceGroupManager_distributionPolicy(template, igm, zones),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckRegionInstanceGroupManagerBetaExists(
|
||||||
|
"google_compute_region_instance_group_manager.igm-basic", &manager),
|
||||||
|
testAccCheckRegionInstanceGroupManagerDistributionPolicy("google_compute_region_instance_group_manager.igm-basic", zones),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testAccCheckRegionInstanceGroupManagerDestroy(s *terraform.State) error {
|
func testAccCheckRegionInstanceGroupManagerDestroy(s *terraform.State) error {
|
||||||
config := testAccProvider.Meta().(*Config)
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
|
||||||
@ -401,6 +427,51 @@ func testAccCheckRegionInstanceGroupManagerAutoHealingPolicies(n, hck string, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccCheckRegionInstanceGroupManagerDistributionPolicy(n string, zones []string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Not found: %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("No ID is set")
|
||||||
|
}
|
||||||
|
|
||||||
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
|
||||||
|
manager, err := config.clientComputeBeta.RegionInstanceGroupManagers.Get(
|
||||||
|
config.Project, rs.Primary.Attributes["region"], rs.Primary.ID).Do()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if manager.DistributionPolicy == nil {
|
||||||
|
return fmt.Errorf("Expected distribution policy to exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
zoneConfigs := manager.DistributionPolicy.Zones
|
||||||
|
if len(zoneConfigs) != len(zones) {
|
||||||
|
return fmt.Errorf("Expected number of zones in distribution policy to match; had %d, expected %d", len(zoneConfigs), len(zones))
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(zones)
|
||||||
|
sortedExisting := make([]string, 0)
|
||||||
|
for _, zone := range zoneConfigs {
|
||||||
|
sortedExisting = append(sortedExisting, zone.Zone)
|
||||||
|
}
|
||||||
|
sort.Strings(sortedExisting)
|
||||||
|
|
||||||
|
for i := 0; i < len(zones); i++ {
|
||||||
|
if !strings.HasSuffix(sortedExisting[i], zones[i]) {
|
||||||
|
return fmt.Errorf("found mismatched zone configuration: expected entry #%d as '%s', got %s", i, zones[i], sortedExisting[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func testAccCheckRegionInstanceGroupManagerTemplateTags(n string, tags []string) resource.TestCheckFunc {
|
func testAccCheckRegionInstanceGroupManagerTemplateTags(n string, tags []string) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
rs, ok := s.RootModule().Resources[n]
|
rs, ok := s.RootModule().Resources[n]
|
||||||
@ -798,3 +869,35 @@ resource "google_compute_http_health_check" "zero" {
|
|||||||
}
|
}
|
||||||
`, template, target, igm, hck)
|
`, template, target, igm, hck)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccRegionInstanceGroupManager_distributionPolicy(template, igm string, zones []string) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "google_compute_instance_template" "igm-basic" {
|
||||||
|
name = "%s"
|
||||||
|
machine_type = "n1-standard-1"
|
||||||
|
can_ip_forward = false
|
||||||
|
tags = ["foo", "bar"]
|
||||||
|
disk {
|
||||||
|
source_image = "debian-cloud/debian-8-jessie-v20160803"
|
||||||
|
auto_delete = true
|
||||||
|
boot = true
|
||||||
|
}
|
||||||
|
network_interface {
|
||||||
|
network = "default"
|
||||||
|
}
|
||||||
|
metadata {
|
||||||
|
foo = "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_region_instance_group_manager" "igm-basic" {
|
||||||
|
description = "Terraform test instance group manager"
|
||||||
|
name = "%s"
|
||||||
|
instance_template = "${google_compute_instance_template.igm-basic.self_link}"
|
||||||
|
base_instance_name = "igm-basic"
|
||||||
|
region = "us-central1"
|
||||||
|
target_size = 2
|
||||||
|
distribution_policy_zones = ["%s"]
|
||||||
|
}
|
||||||
|
`, template, igm, strings.Join(zones, "\",\""))
|
||||||
|
}
|
||||||
|
@ -37,6 +37,7 @@ resource "google_compute_region_instance_group_manager" "appserver" {
|
|||||||
base_instance_name = "app"
|
base_instance_name = "app"
|
||||||
instance_template = "${google_compute_instance_template.appserver.self_link}"
|
instance_template = "${google_compute_instance_template.appserver.self_link}"
|
||||||
region = "us-central1"
|
region = "us-central1"
|
||||||
|
distribution_policy_zones = ["us-central1-a", "us-central1-f"]
|
||||||
|
|
||||||
target_pools = ["${google_compute_target_pool.appserver.self_link}"]
|
target_pools = ["${google_compute_target_pool.appserver.self_link}"]
|
||||||
target_size = 2
|
target_size = 2
|
||||||
@ -99,6 +100,10 @@ The following arguments are supported:
|
|||||||
* `auto_healing_policies` - (Optional, [Beta](/docs/providers/google/index.html#beta-features)) The autohealing policies for this managed instance
|
* `auto_healing_policies` - (Optional, [Beta](/docs/providers/google/index.html#beta-features)) The autohealing policies for this managed instance
|
||||||
group. You can specify only one value. Structure is documented below. For more information, see the [official documentation](https://cloud.google.com/compute/docs/instance-groups/creating-groups-of-managed-instances#monitoring_groups).
|
group. You can specify only one value. Structure is documented below. For more information, see the [official documentation](https://cloud.google.com/compute/docs/instance-groups/creating-groups-of-managed-instances#monitoring_groups).
|
||||||
|
|
||||||
|
* `distribution_policy_zones` - (Optional, [Beta](/docs/providers/google/index.html#beta-features)) The distribution policy for this managed instance
|
||||||
|
group. You can specify one or more values. For more information, see the [official documentation](https://cloud.google.com/compute/docs/instance-groups/distributing-instances-with-regional-instance-groups#selectingzones).
|
||||||
|
|
||||||
|
|
||||||
The `named_port` block supports: (Include a `named_port` block for each named-port required).
|
The `named_port` block supports: (Include a `named_port` block for each named-port required).
|
||||||
|
|
||||||
* `name` - (Required) The name of the port.
|
* `name` - (Required) The name of the port.
|
||||||
|
Loading…
Reference in New Issue
Block a user