2022-03-22 11:03:15 -04:00
|
|
|
package client
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-04-26 07:22:57 -04:00
|
|
|
"errors"
|
2022-03-22 11:03:15 -04:00
|
|
|
"fmt"
|
|
|
|
|
|
|
|
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
|
|
|
|
)
|
|
|
|
|
|
|
|
// waitForOperations waits until every operation in the opIDs slice is
|
|
|
|
// done or returns the first occurring error.
|
|
|
|
func (c *Client) waitForOperations(ctx context.Context, ops []Operation) error {
|
|
|
|
for _, op := range ops {
|
|
|
|
switch {
|
2022-04-26 07:22:57 -04:00
|
|
|
case op.Proto() == nil:
|
|
|
|
return errors.New("proto of operation is nil")
|
2022-03-22 11:03:15 -04:00
|
|
|
case op.Proto().Zone != nil:
|
|
|
|
if err := c.waitForZoneOperation(ctx, op); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
case op.Proto().Region != nil:
|
|
|
|
if err := c.waitForRegionOperation(ctx, op); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
if err := c.waitForGlobalOperation(ctx, op); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) waitForGlobalOperation(ctx context.Context, op Operation) error {
|
|
|
|
for {
|
|
|
|
if err := ctx.Err(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
waitReq := &computepb.WaitGlobalOperationRequest{
|
|
|
|
Operation: *op.Proto().Name,
|
|
|
|
Project: c.project,
|
|
|
|
}
|
|
|
|
zoneOp, err := c.operationGlobalAPI.Wait(ctx, waitReq)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unable to wait for the operation: %w", err)
|
|
|
|
}
|
|
|
|
if *zoneOp.Status.Enum() == computepb.Operation_DONE {
|
|
|
|
if opErr := zoneOp.Error; opErr != nil {
|
|
|
|
return fmt.Errorf("operation failed: %s", opErr.String())
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) waitForZoneOperation(ctx context.Context, op Operation) error {
|
|
|
|
for {
|
|
|
|
if err := ctx.Err(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
waitReq := &computepb.WaitZoneOperationRequest{
|
|
|
|
Operation: *op.Proto().Name,
|
|
|
|
Project: c.project,
|
|
|
|
Zone: c.zone,
|
|
|
|
}
|
|
|
|
zoneOp, err := c.operationZoneAPI.Wait(ctx, waitReq)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unable to wait for the operation: %w", err)
|
|
|
|
}
|
|
|
|
if *zoneOp.Status.Enum() == computepb.Operation_DONE {
|
|
|
|
if opErr := zoneOp.Error; opErr != nil {
|
|
|
|
return fmt.Errorf("operation failed: %s", opErr.String())
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) waitForRegionOperation(ctx context.Context, op Operation) error {
|
|
|
|
for {
|
|
|
|
if err := ctx.Err(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
waitReq := &computepb.WaitRegionOperationRequest{
|
|
|
|
Operation: *op.Proto().Name,
|
|
|
|
Project: c.project,
|
|
|
|
Region: c.region,
|
|
|
|
}
|
|
|
|
regionOp, err := c.operationRegionAPI.Wait(ctx, waitReq)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("unable to wait for the operation: %w", err)
|
|
|
|
}
|
|
|
|
if *regionOp.Status.Enum() == computepb.Operation_DONE {
|
|
|
|
if opErr := regionOp.Error; opErr != nil {
|
|
|
|
return fmt.Errorf("operation failed: %s", opErr.String())
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|