Skip to content

Commit

Permalink
batch serviceusage reads (#4854)
Browse files Browse the repository at this point in the history
Signed-off-by: Modular Magician <magic-modules@google.com>
  • Loading branch information
modular-magician authored and danawillow committed Nov 11, 2019
1 parent 94eb8e9 commit 5caeadb
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 35 deletions.
5 changes: 4 additions & 1 deletion google/batcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"log"
"sync"
"time"

"github.com/hashicorp/errwrap"
)

const defaultBatchSendIntervalSec = 10
Expand Down Expand Up @@ -154,7 +156,8 @@ func (b *RequestBatcher) SendRequestWithTimeout(batchKey string, request *BatchR
select {
case resp := <-respCh:
if resp.err != nil {
return nil, fmt.Errorf("Batch %q for request %q returned error: %v", batchKey, request.DebugId, resp.err)
// use wrapf so we can potentially extract the original error type
return nil, errwrap.Wrapf(fmt.Sprintf("Batch %q for request %q returned error: {{err}}", batchKey, request.DebugId), resp.err)
}
return resp.body, nil
case <-ctx.Done():
Expand Down
41 changes: 7 additions & 34 deletions google/resource_google_project_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package google

import (
"fmt"
"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"google.golang.org/api/googleapi"
"google.golang.org/api/serviceusage/v1"
"log"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"google.golang.org/api/serviceusage/v1"
)

var ignoredProjectServices = []string{"dataproc-control.googleapis.com", "source.googleapis.com", "stackdriverprovisioning.googleapis.com"}
Expand Down Expand Up @@ -138,11 +137,13 @@ func resourceGoogleProjectServiceRead(d *schema.ResourceData, meta interface{})
}
srv := d.Get("service").(string)

enabled, err := isServiceEnabled(project, srv, config)
servicesRaw, err := BatchRequestReadServices(project, d, config)
if err != nil {
return handleNotFoundError(err, d, fmt.Sprintf("Project Service %s", d.Id()))
}
if enabled {
servicesList := servicesRaw.(map[string]struct{})

if _, ok := servicesList[srv]; ok {
d.Set("project", project)
d.Set("service", srv)
return nil
Expand Down Expand Up @@ -184,34 +185,6 @@ func resourceGoogleProjectServiceUpdate(d *schema.ResourceData, meta interface{}
return nil
}

// Retrieve enablement state for a given project's service
func isServiceEnabled(project, serviceName string, config *Config) (bool, error) {
// Verify project for services still exists
p, err := config.clientResourceManager.Projects.Get(project).Do()
if err != nil {
return false, err
}
if p.LifecycleState == "DELETE_REQUESTED" {
// Construct a 404 error for handleNotFoundError
return false, &googleapi.Error{
Code: 404,
Message: "Project deletion was requested",
}
}

resourceName := fmt.Sprintf("projects/%s/services/%s", project, serviceName)
var srv *serviceusage.GoogleApiServiceusageV1Service
err = retryTime(func() error {
var currErr error
srv, currErr = config.clientServiceUsage.Services.Get(resourceName).Do()
return currErr
}, 10)
if err != nil {
return false, errwrap.Wrapf(fmt.Sprintf("Failed to list enabled services for project %s: {{err}}", project), err)
}
return srv.State == "ENABLED", nil
}

// Disables a project service.
func disableServiceUsageProjectService(service, project string, d *schema.ResourceData, config *Config, disableDependentServices bool) error {
err := retryTimeDuration(func() error {
Expand Down
23 changes: 23 additions & 0 deletions google/serviceusage_batching.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

const (
batchKeyTmplServiceUsageEnableServices = "project/%s/services:batchEnable"
batchKeyTmplServiceUsageListServices = "project/%s/services"
)

// BatchRequestEnableServices can be used to batch requests to enable services
Expand Down Expand Up @@ -53,6 +54,22 @@ func BatchRequestEnableServices(services map[string]struct{}, project string, d
return err
}

func BatchRequestReadServices(project string, d *schema.ResourceData, config *Config) (interface{}, error) {
req := &BatchRequest{
ResourceName: project,
Body: nil,
// Use empty CombineF since the request is exactly the same no matter how many services we read.
CombineF: func(body interface{}, toAdd interface{}) (interface{}, error) { return nil, nil },
SendF: sendListServices(config, d.Timeout(schema.TimeoutRead)),
DebugId: fmt.Sprintf("List Project Services %s", project),
}

return config.requestBatcherServiceUsage.SendRequestWithTimeout(
fmt.Sprintf(batchKeyTmplServiceUsageListServices, project),
req,
d.Timeout(schema.TimeoutRead))
}

func combineServiceUsageServicesBatches(srvsRaw interface{}, toAddRaw interface{}) (interface{}, error) {
srvs, ok := srvsRaw.([]string)
if !ok {
Expand All @@ -75,3 +92,9 @@ func sendBatchFuncEnableServices(config *Config, timeout time.Duration) batcherS
return nil, enableServiceUsageProjectServices(toEnable, project, config, timeout)
}
}

func sendListServices(config *Config, timeout time.Duration) batcherSendFunc {
return func(project string, _ interface{}) (interface{}, error) {
return listCurrentlyEnabledServices(project, config, timeout)
}
}

0 comments on commit 5caeadb

Please sign in to comment.