Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BatchEnable Operation's response is not working even when APIs are enabled #2178

Open
dunefro opened this issue Sep 22, 2023 · 1 comment
Open
Assignees
Labels
type: question Request for information or clarification. Not an issue.

Comments

@dunefro
Copy link

dunefro commented Sep 22, 2023

Environment details

  • Programming language: golang
  • OS: macOS darwin 22.6.0
  • Language runtime version:
    go version go1.21.0 darwin/arm64
  • Package version: 0.142.0

Steps to reproduce

I am trying to enable certain APIs for my project

  1. Below is the code
func enableRequiredAPIS(projectName string) error {
  ctx := context.Background()
  projectParentName := fmt.Sprintf("projects/%s", projectName)
  serviceusageServiceClient, err := serviceusage.NewService(ctx)
  if err != nil {
  	return fmt.Errorf("enableRequiredAPIS: Error getting serviceusage.NewService type: %w", err)
  }
  serviceUsageServicesServiceClient := serviceusage.NewServicesService(serviceusageServiceClient)

  // get project information
  projectBatchGet := serviceUsageServicesServiceClient.BatchGet(projectParentName)

  // all the required services we want to check and enable
  allServices := []string{
  	fmt.Sprintf("%s/services/compute.googleapis.com", projectParentName),
  	fmt.Sprintf("%s/services/container.googleapis.com", projectParentName),
  	fmt.Sprintf("%s/services/secretmanager.googleapis.com", projectParentName),
  	fmt.Sprintf("%s/services/artifactregistry.googleapis.com", projectParentName),
  }
  // assigning service names
  projectBatchGet.Names(allServices...)
  resp, err := projectBatchGet.Do()
  if err != nil {
  	return fmt.Errorf("enableRequiredAPIS: Error getting batch GET for services %w", err)
  }
  var serviceToEnable []string
  for _, service := range resp.Services {
  	if service.State == "DISABLED" {
  		serviceName := strings.Replace(service.Name, fmt.Sprintf("%s/services/", service.Parent), "", 1)
  		utils.PrintInfoln(fmt.Sprintf("service %s not enabled for project %s", serviceName, projectName))
  		serviceToEnable = append(serviceToEnable, serviceName)
  	}
  }
  if len(serviceToEnable) != 0 {
  	enableOperation, err := serviceUsageServicesServiceClient.BatchEnable(projectParentName, &serviceusage.BatchEnableServicesRequest{
  		ServiceIds: serviceToEnable,
  	}).Do()
  	if err != nil {
  		return fmt.Errorf("enableRequiredAPIS: Error enabling services %w", err)
  	}
  	for {
  		fmt.Println("Waiting for the services to get enabled...")
  		fmt.Println("done", enableOperation.Done)
  		fmt.Println("statuscode", enableOperation.ServerResponse.HTTPStatusCode)
  		if enableOperation.Done {
  			fmt.Println("Successfully enabled all the services")
  			return nil
  		} else if opErr := enableOperation.Error; opErr != nil {
  			fmt.Println(fmt.Sprintf("Failed to enable services. error: %s %d", opErr.Message, opErr.Code))
  			return fmt.Errorf("enableRequiredAPIS: error enabling services, error %s %d", opErr.Message, opErr.Code)
  		} else {
  			fmt.Println(string(enableOperation.Response))
  			time.Sleep(3 * time.Second)
  		}
  	}
  }
  return nil
}
  1. When I am trying to execute the code to enable the APIs which are disabled, the for loop is running indefinitely.
  2. When I check the API from the console it gets enabled after certain time which is the ideal behaviour.
  3. The operation should return target and not ret, but I am not perfectly sure of this.

What should happen

I should either get an error or operation.Done should be marked as true

@dunefro dunefro added priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. labels Sep 22, 2023
@codyoss codyoss assigned quartzmo and unassigned codyoss Sep 22, 2023
@quartzmo quartzmo assigned noahdietz and unassigned quartzmo Sep 25, 2023
@noahdietz noahdietz added type: question Request for information or clarification. Not an issue. and removed priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. labels Sep 25, 2023
@noahdietz
Copy link
Contributor

Hello @dunefro, thanks for the issue. I don't think there is a bug in the client, but rather in the code that you've shared.

The *Operation returned by the ServicesBatchEnableCall.Do does not automatically poll the Operation. So, the code shared above is checking the same Operation from the initial response, thus looping forever.

Instead, you need to include a polling request via OperationsService.Get in your for loop after your time.Sleep call to refresh the local Operation state.

  	operations = NewOperationsService(serviceusageServiceClient)
  	// ...
  	for {
  		// ...
  		} else {
  			fmt.Println(string(enableOperation.Response))
  			time.Sleep(3 * time.Second)
  			// Poll the operation state, loop again to same operation evaluation logic.
  			enableOperation, err = operations.Get(enableOperation.Name).Do()
  			if err != nil {
  				fmt.Println("error polling operation:", err)
  				return err
  			}
  		}
  	}

I can't find a section in our top-level of docs that explain this, so I will add one.

Please close this if it works for you or I will close it in a few days as resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: question Request for information or clarification. Not an issue.
Projects
None yet
Development

No branches or pull requests

4 participants