Skip to content

Commit

Permalink
provider/google: fix container instance group URLs
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
paddycarver committed Mar 7, 2017
1 parent b58709a commit 6cce8d6
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
27 changes: 26 additions & 1 deletion builtin/providers/google/resource_container_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import (
"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 {
return &schema.Resource{
Create: resourceContainerClusterCreate,
Expand Down Expand Up @@ -474,7 +478,28 @@ func resourceContainerClusterRead(d *schema.ResourceData, meta interface{}) erro
d.Set("network", d.Get("network").(string))
d.Set("subnetwork", cluster.Subnetwork)
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
}
Expand Down
66 changes: 65 additions & 1 deletion builtin/providers/google/resource_container_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"fmt"
"testing"

"strconv"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
"strconv"
)

func TestAccContainerCluster_basic(t *testing.T) {
Expand Down Expand Up @@ -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 {
config := testAccProvider.Meta().(*Config)

Expand Down Expand Up @@ -296,3 +314,49 @@ resource "google_container_cluster" "with_net_ref_by_name" {
network = "${google_compute_network.container_network.name}"
}`, 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))

0 comments on commit 6cce8d6

Please sign in to comment.