provider/google: fix container instance group URLs
Google Container Engine's cluster API returned instance group manager URLs when it meant to return instance group URLs. See #4336 for details about the bug. While this is undeniably an upstream problem, this PR: * detects the error, meaning it will work as expected when the API is fixed. * corrects the error by requesting the instance group manager, then retrieving its instance group URL, and using that instead. * adds a test that exercises the error and the solution, to ensure it is functioning properly.
This commit is contained in:
parent
b58709aa91
commit
6cce8d6c1a
|
@ -13,6 +13,10 @@ import (
|
||||||
"google.golang.org/api/googleapi"
|
"google.golang.org/api/googleapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
instanceGroupManagerURL = regexp.MustCompile("^https://www.googleapis.com/compute/v1/projects/([a-z][a-z0-9-]{5}(?:[-a-z0-9]{0,23}[a-z0-9])?)/zones/([a-z0-9-]*)/instanceGroupManagers/([^/]*)")
|
||||||
|
)
|
||||||
|
|
||||||
func resourceContainerCluster() *schema.Resource {
|
func resourceContainerCluster() *schema.Resource {
|
||||||
return &schema.Resource{
|
return &schema.Resource{
|
||||||
Create: resourceContainerClusterCreate,
|
Create: resourceContainerClusterCreate,
|
||||||
|
@ -474,7 +478,28 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro
|
||||||
d.Set("network", d.Get("network").(string))
|
d.Set("network", d.Get("network").(string))
|
||||||
d.Set("subnetwork", cluster.Subnetwork)
|
d.Set("subnetwork", cluster.Subnetwork)
|
||||||
d.Set("node_config", flattenClusterNodeConfig(cluster.NodeConfig))
|
d.Set("node_config", flattenClusterNodeConfig(cluster.NodeConfig))
|
||||||
d.Set("instance_group_urls", cluster.InstanceGroupUrls)
|
|
||||||
|
// container engine's API currently mistakenly returns the instance group manager's
|
||||||
|
// URL instead of the instance group's URL in its responses. This shim detects that
|
||||||
|
// error, and corrects it, by fetching the instance group manager URL and retrieving
|
||||||
|
// the instance group manager, then using that to look up the instance group URL, which
|
||||||
|
// is then substituted.
|
||||||
|
//
|
||||||
|
// This should be removed when the API response is fixed.
|
||||||
|
instanceGroupURLs := make([]string, 0, len(cluster.InstanceGroupUrls))
|
||||||
|
for _, u := range cluster.InstanceGroupUrls {
|
||||||
|
if !instanceGroupManagerURL.MatchString(u) {
|
||||||
|
instanceGroupURLs = append(instanceGroupURLs, u)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
matches := instanceGroupManagerURL.FindStringSubmatch(u)
|
||||||
|
instanceGroupManager, err := config.clientCompute.InstanceGroupManagers.Get(matches[1], matches[2], matches[3]).Do()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Error reading instance group manager returned as an instance group URL: %s", err)
|
||||||
|
}
|
||||||
|
instanceGroupURLs = append(instanceGroupURLs, instanceGroupManager.InstanceGroup)
|
||||||
|
}
|
||||||
|
d.Set("instance_group_urls", instanceGroupURLs)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,11 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/acctest"
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccContainerCluster_basic(t *testing.T) {
|
func TestAccContainerCluster_basic(t *testing.T) {
|
||||||
|
@ -116,6 +117,23 @@ func TestAccContainerCluster_network(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccContainerCluster_backend(t *testing.T) {
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckContainerClusterDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccContainerCluster_backendRef,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckContainerClusterExists(
|
||||||
|
"google_container_cluster.primary"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testAccCheckContainerClusterDestroy(s *terraform.State) error {
|
func testAccCheckContainerClusterDestroy(s *terraform.State) error {
|
||||||
config := testAccProvider.Meta().(*Config)
|
config := testAccProvider.Meta().(*Config)
|
||||||
|
|
||||||
|
@ -296,3 +314,49 @@ resource "google_container_cluster" "with_net_ref_by_name" {
|
||||||
|
|
||||||
network = "${google_compute_network.container_network.name}"
|
network = "${google_compute_network.container_network.name}"
|
||||||
}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10))
|
}`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10))
|
||||||
|
|
||||||
|
var testAccContainerCluster_backendRef = fmt.Sprintf(`
|
||||||
|
resource "google_compute_backend_service" "my-backend-service" {
|
||||||
|
name = "terraform-test-%s"
|
||||||
|
port_name = "http"
|
||||||
|
protocol = "HTTP"
|
||||||
|
|
||||||
|
backend {
|
||||||
|
group = "${element(google_container_cluster.primary.instance_group_urls, 1)}"
|
||||||
|
}
|
||||||
|
|
||||||
|
health_checks = ["${google_compute_http_health_check.default.self_link}"]
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_compute_http_health_check" "default" {
|
||||||
|
name = "terraform-test-%s"
|
||||||
|
request_path = "/"
|
||||||
|
check_interval_sec = 1
|
||||||
|
timeout_sec = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "google_container_cluster" "primary" {
|
||||||
|
name = "terraform-test-%s"
|
||||||
|
zone = "us-central1-a"
|
||||||
|
initial_node_count = 3
|
||||||
|
|
||||||
|
additional_zones = [
|
||||||
|
"us-central1-b",
|
||||||
|
"us-central1-c",
|
||||||
|
]
|
||||||
|
|
||||||
|
master_auth {
|
||||||
|
username = "mr.yoda"
|
||||||
|
password = "adoy.rm"
|
||||||
|
}
|
||||||
|
|
||||||
|
node_config {
|
||||||
|
oauth_scopes = [
|
||||||
|
"https://www.googleapis.com/auth/compute",
|
||||||
|
"https://www.googleapis.com/auth/devstorage.read_only",
|
||||||
|
"https://www.googleapis.com/auth/logging.write",
|
||||||
|
"https://www.googleapis.com/auth/monitoring",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`, acctest.RandString(10), acctest.RandString(10), acctest.RandString(10))
|
||||||
|
|
Loading…
Reference in New Issue