From 211ba0429933ea56d160206b21bc938812cef65b Mon Sep 17 00:00:00 2001 From: Riley Karson Date: Mon, 14 Oct 2019 09:22:47 -0700 Subject: [PATCH] Implement basepath patches in the provider. (#2443) Merged PR #2443. --- .../custom_expand/compute_full_url.erb | 8 ++++++- .../custom_expand/self_link_from_name.erb | 8 +++++-- .../data_source_google_compute_zones.go | 12 +++++++++-- .../resource_compute_instance_group.go | 2 +- .../resources/resource_compute_target_pool.go | 21 ++++++++++++------- .../resource_container_cluster.go.erb | 12 ++++------- .../resources/resource_google_project.go | 9 +++++--- 7 files changed, 47 insertions(+), 25 deletions(-) diff --git a/templates/terraform/custom_expand/compute_full_url.erb b/templates/terraform/custom_expand/compute_full_url.erb index 9bb1dd785e6c..32dbb4da8be5 100644 --- a/templates/terraform/custom_expand/compute_full_url.erb +++ b/templates/terraform/custom_expand/compute_full_url.erb @@ -20,5 +20,11 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d T if err != nil { return nil, fmt.Errorf("Invalid value for <%= property.name.underscore -%>: %s", err) } - return "https://www.googleapis.com/compute/v1/" + f.RelativeLink(), nil + + url, err := replaceVars(d, config, "{{ComputeBasePath}}"+f.RelativeLink()) + if err != nil { + return nil, err + } + + return url, nil } diff --git a/templates/terraform/custom_expand/self_link_from_name.erb b/templates/terraform/custom_expand/self_link_from_name.erb index 380369602984..1fa6d99471eb 100644 --- a/templates/terraform/custom_expand/self_link_from_name.erb +++ b/templates/terraform/custom_expand/self_link_from_name.erb @@ -21,8 +21,12 @@ func expand<%= prefix -%><%= titlelize_property(property) -%>(v interface{}, d T // Anything that starts with a URL scheme is assumed to be a self link worth using. return v, nil } else if strings.HasPrefix(v.(string), "projects/") { - // If the self link references a project, we'll just stuck the compute v1 prefix on it. - return "https://www.googleapis.com/compute/v1/" + v.(string), nil + // If the self link references a project, we'll just stuck the compute prefix on it + url, err := replaceVars(d, config, "{{ComputeBasePath}}" + v.(string)) + if err != nil { + return "", err + } + return url, nil } else if strings.HasPrefix(v.(string), "regions/") || strings.HasPrefix(v.(string), "zones/") { // For regional or zonal resources which include their region or zone, just put the project in front. url, err := replaceVars(d, config, "{{ComputeBasePath}}projects/{{project}}/") diff --git a/third_party/terraform/data_sources/data_source_google_compute_zones.go b/third_party/terraform/data_sources/data_source_google_compute_zones.go index 38c3ca49e1d3..981026e9ab20 100644 --- a/third_party/terraform/data_sources/data_source_google_compute_zones.go +++ b/third_party/terraform/data_sources/data_source_google_compute_zones.go @@ -51,8 +51,16 @@ func dataSourceGoogleComputeZonesRead(d *schema.ResourceData, meta interface{}) return err } - regionUrl := fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/regions/%s", - project, region) + // we want to share exactly the same base path as the compute client or the + // region string may mismatch, giving us no results + // note that the client's BasePath includes a `projects/` suffix, so that'll + // need to be added to the URL below if the source changes + computeClientBasePath := config.clientCompute.BasePath + + regionUrl, err := replaceVars(d, config, fmt.Sprintf("%s%s/regions/%s", computeClientBasePath, project, region)) + if err != nil { + return err + } filter := fmt.Sprintf("(region eq %s)", regionUrl) if s, ok := d.GetOk("status"); ok { diff --git a/third_party/terraform/resources/resource_compute_instance_group.go b/third_party/terraform/resources/resource_compute_instance_group.go index 00604d854103..d4f9ad3542a9 100644 --- a/third_party/terraform/resources/resource_compute_instance_group.go +++ b/third_party/terraform/resources/resource_compute_instance_group.go @@ -108,7 +108,7 @@ func getInstanceReferences(instanceUrls []string) (refs []*compute.InstanceRefer func validInstanceURLs(instanceUrls []string) bool { for _, v := range instanceUrls { - if !strings.HasPrefix(v, "https://www.googleapis.com/compute/v1/") { + if !strings.HasPrefix(v, "https://") { return false } } diff --git a/third_party/terraform/resources/resource_compute_target_pool.go b/third_party/terraform/resources/resource_compute_target_pool.go index 191684e87e55..cc25a52f21a8 100644 --- a/third_party/terraform/resources/resource_compute_target_pool.go +++ b/third_party/terraform/resources/resource_compute_target_pool.go @@ -136,20 +136,25 @@ func convertHealthChecks(healthChecks []interface{}, d *schema.ResourceData, con // Instances do not need to exist yet, so we simply generate URLs. // Instances can be full URLS or zone/name -func convertInstancesToUrls(project string, names *schema.Set) ([]string, error) { +func convertInstancesToUrls(d *schema.ResourceData, config *Config, project string, names *schema.Set) ([]string, error) { urls := make([]string, len(names.List())) for i, nameI := range names.List() { name := nameI.(string) - if strings.HasPrefix(name, "https://www.googleapis.com/compute/v1/") { + // assume that any URI will start with https:// + if strings.HasPrefix(name, "https://") { urls[i] = name } else { splitName := strings.Split(name, "/") if len(splitName) != 2 { return nil, fmt.Errorf("Invalid instance name, require URL or zone/name: %s", name) } else { - urls[i] = fmt.Sprintf( - "https://www.googleapis.com/compute/v1/projects/%s/zones/%s/instances/%s", - project, splitName[0], splitName[1]) + url, err := replaceVars(d, config, fmt.Sprintf( + "{{ComputeBasePath}}projects/%s/zones/%s/instances/%s", + project, splitName[0], splitName[1])) + if err != nil { + return nil, err + } + urls[i] = url } } } @@ -174,7 +179,7 @@ func resourceComputeTargetPoolCreate(d *schema.ResourceData, meta interface{}) e return err } - instanceUrls, err := convertInstancesToUrls(project, d.Get("instances").(*schema.Set)) + instanceUrls, err := convertInstancesToUrls(d, config, project, d.Get("instances").(*schema.Set)) if err != nil { return err } @@ -310,11 +315,11 @@ func resourceComputeTargetPoolUpdate(d *schema.ResourceData, meta interface{}) e old := old_.(*schema.Set) new := new_.(*schema.Set) - addUrls, err := convertInstancesToUrls(project, new.Difference(old)) + addUrls, err := convertInstancesToUrls(d, config, project, new.Difference(old)) if err != nil { return err } - removeUrls, err := convertInstancesToUrls(project, old.Difference(new)) + removeUrls, err := convertInstancesToUrls(d, config, project, old.Difference(new)) if err != nil { return err } diff --git a/third_party/terraform/resources/resource_container_cluster.go.erb b/third_party/terraform/resources/resource_container_cluster.go.erb index 9d10ae89ca65..cf09740c5d06 100644 --- a/third_party/terraform/resources/resource_container_cluster.go.erb +++ b/third_party/terraform/resources/resource_container_cluster.go.erb @@ -18,7 +18,7 @@ import ( ) var ( - instanceGroupManagerURL = regexp.MustCompile(fmt.Sprintf("^https://www.googleapis.com/compute/v1/projects/(%s)/zones/([a-z0-9-]*)/instanceGroupManagers/([^/]*)", ProjectRegex)) + instanceGroupManagerURL = regexp.MustCompile(fmt.Sprintf("projects/(%s)/zones/([a-z0-9-]*)/instanceGroupManagers/([^/]*)", ProjectRegex)) networkConfig = &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -2094,13 +2094,9 @@ func waitForContainerClusterReady(config *Config, project, location, clusterName }) } -// 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. +// container engine's API returns the instance group manager's URL instead of the instance +// group's URL in its responses, while the field is named as if it should have been the group +// and not the manager. This shim should be supported for backwards compatibility reasons. func getInstanceGroupUrlsFromManagerUrls(config *Config, igmUrls []string) ([]string, error) { instanceGroupURLs := make([]string, 0, len(igmUrls)) for _, u := range igmUrls { diff --git a/third_party/terraform/resources/resource_google_project.go b/third_party/terraform/resources/resource_google_project.go index fff44dfed136..02e7247c2d10 100644 --- a/third_party/terraform/resources/resource_google_project.go +++ b/third_party/terraform/resources/resource_google_project.go @@ -274,7 +274,7 @@ func resourceGoogleProjectCreate(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error enabling the Compute Engine API required to delete the default network: %s", err) } - if err = forceDeleteComputeNetwork(project.ProjectId, "default", config); err != nil { + if err = forceDeleteComputeNetwork(d, config, project.ProjectId, "default"); err != nil { if isGoogleApiErrorWithCode(err, 404) { log.Printf("[DEBUG] Default network not found for project %q, no need to delete it", project.ProjectId) } else { @@ -495,8 +495,11 @@ func resourceProjectImportState(d *schema.ResourceData, meta interface{}) ([]*sc } // Delete a compute network along with the firewall rules inside it. -func forceDeleteComputeNetwork(projectId, networkName string, config *Config) error { - networkLink := fmt.Sprintf("https://www.googleapis.com/compute/v1/projects/%s/global/networks/%s", projectId, networkName) +func forceDeleteComputeNetwork(d *schema.ResourceData, config *Config, projectId, networkName string) error { + networkLink, err := replaceVars(d, config, fmt.Sprintf("{{ComputeBasePath}}%s/global/networks/%s", projectId, networkName)) + if err != nil { + return err + } token := "" for paginate := true; paginate; {