mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-09-07 09:36:44 +00:00
![Paddy](/assets/img/avatar_default.png)
Switch to using Go modules. This migrates our vendor.json to use Go 1.11's modules system, and replaces the vendor folder with the output of go mod vendor. The vendored code should remain basically the same; I believe some tree shaking of packages and support scripts/licenses/READMEs/etc. happened. This also fixes Travis and our Makefile to no longer use govendor.
180 lines
6.5 KiB
Go
180 lines
6.5 KiB
Go
// Copyright 2016 Google LLC
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
// Package longrunning supports Long Running Operations for the Google Cloud Libraries.
|
|
// See google.golang.org/genproto/googleapis/longrunning for its service definition.
|
|
//
|
|
// Users of the Google Cloud Libraries will typically not use this package directly.
|
|
// Instead they will call functions returning Operations and call their methods.
|
|
//
|
|
// This package is still experimental and subject to change.
|
|
package longrunning // import "cloud.google.com/go/longrunning"
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
autogen "cloud.google.com/go/longrunning/autogen"
|
|
"github.com/golang/protobuf/proto"
|
|
"github.com/golang/protobuf/ptypes"
|
|
gax "github.com/googleapis/gax-go"
|
|
pb "google.golang.org/genproto/googleapis/longrunning"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
// ErrNoMetadata is the error returned by Metadata if the operation contains no metadata.
|
|
var ErrNoMetadata = errors.New("operation contains no metadata")
|
|
|
|
// Operation represents the result of an API call that may not be ready yet.
|
|
type Operation struct {
|
|
c operationsClient
|
|
proto *pb.Operation
|
|
}
|
|
|
|
type operationsClient interface {
|
|
GetOperation(context.Context, *pb.GetOperationRequest, ...gax.CallOption) (*pb.Operation, error)
|
|
CancelOperation(context.Context, *pb.CancelOperationRequest, ...gax.CallOption) error
|
|
DeleteOperation(context.Context, *pb.DeleteOperationRequest, ...gax.CallOption) error
|
|
}
|
|
|
|
// InternalNewOperation is for use by the google Cloud Libraries only.
|
|
//
|
|
// InternalNewOperation returns an long-running operation, abstracting the raw pb.Operation.
|
|
// The conn parameter refers to a server that proto was received from.
|
|
func InternalNewOperation(inner *autogen.OperationsClient, proto *pb.Operation) *Operation {
|
|
return &Operation{
|
|
c: inner,
|
|
proto: proto,
|
|
}
|
|
}
|
|
|
|
// Name returns the name of the long-running operation.
|
|
// The name is assigned by the server and is unique within the service
|
|
// from which the operation is created.
|
|
func (op *Operation) Name() string {
|
|
return op.proto.Name
|
|
}
|
|
|
|
// Done reports whether the long-running operation has completed.
|
|
func (op *Operation) Done() bool {
|
|
return op.proto.Done
|
|
}
|
|
|
|
// Metadata unmarshals op's metadata into meta.
|
|
// If op does not contain any metadata, Metadata returns ErrNoMetadata and meta is unmodified.
|
|
func (op *Operation) Metadata(meta proto.Message) error {
|
|
if m := op.proto.Metadata; m != nil {
|
|
return ptypes.UnmarshalAny(m, meta)
|
|
}
|
|
return ErrNoMetadata
|
|
}
|
|
|
|
// Poll fetches the latest state of a long-running operation.
|
|
//
|
|
// If Poll fails, the error is returned and op is unmodified.
|
|
// If Poll succeeds and the operation has completed with failure,
|
|
// the error is returned and op.Done will return true.
|
|
// If Poll succeeds and the operation has completed successfully,
|
|
// op.Done will return true; if resp != nil, the response of the operation
|
|
// is stored in resp.
|
|
func (op *Operation) Poll(ctx context.Context, resp proto.Message, opts ...gax.CallOption) error {
|
|
if !op.Done() {
|
|
p, err := op.c.GetOperation(ctx, &pb.GetOperationRequest{Name: op.Name()}, opts...)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
op.proto = p
|
|
}
|
|
if !op.Done() {
|
|
return nil
|
|
}
|
|
|
|
switch r := op.proto.Result.(type) {
|
|
case *pb.Operation_Error:
|
|
// TODO (pongad): r.Details may contain further information
|
|
return status.Errorf(codes.Code(r.Error.Code), "%s", r.Error.Message)
|
|
case *pb.Operation_Response:
|
|
if resp == nil {
|
|
return nil
|
|
}
|
|
return ptypes.UnmarshalAny(r.Response, resp)
|
|
default:
|
|
return fmt.Errorf("unsupported result type %[1]T: %[1]v", r)
|
|
}
|
|
}
|
|
|
|
// DefaultWaitInterval is the polling interval used by Operation.Wait.
|
|
const DefaultWaitInterval = 60 * time.Second
|
|
|
|
// Wait is equivalent to WaitWithInterval using DefaultWaitInterval.
|
|
func (op *Operation) Wait(ctx context.Context, resp proto.Message, opts ...gax.CallOption) error {
|
|
return op.WaitWithInterval(ctx, resp, DefaultWaitInterval, opts...)
|
|
}
|
|
|
|
// WaitWithInterval blocks until the operation is completed.
|
|
// If resp != nil, Wait stores the response in resp.
|
|
// WaitWithInterval polls every interval, except initially
|
|
// when it polls using exponential backoff.
|
|
//
|
|
// See documentation of Poll for error-handling information.
|
|
func (op *Operation) WaitWithInterval(ctx context.Context, resp proto.Message, interval time.Duration, opts ...gax.CallOption) error {
|
|
bo := gax.Backoff{
|
|
Initial: 1 * time.Second,
|
|
Max: interval,
|
|
}
|
|
if bo.Max < bo.Initial {
|
|
bo.Max = bo.Initial
|
|
}
|
|
return op.wait(ctx, resp, &bo, gax.Sleep, opts...)
|
|
}
|
|
|
|
type sleeper func(context.Context, time.Duration) error
|
|
|
|
// wait implements Wait, taking exponentialBackoff and sleeper arguments for testing.
|
|
func (op *Operation) wait(ctx context.Context, resp proto.Message, bo *gax.Backoff, sl sleeper, opts ...gax.CallOption) error {
|
|
for {
|
|
if err := op.Poll(ctx, resp, opts...); err != nil {
|
|
return err
|
|
}
|
|
if op.Done() {
|
|
return nil
|
|
}
|
|
if err := sl(ctx, bo.Pause()); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
// Cancel starts asynchronous cancellation on a long-running operation. The server
|
|
// makes a best effort to cancel the operation, but success is not
|
|
// guaranteed. If the server doesn't support this method, it returns
|
|
// grpc.Code(error) == codes.Unimplemented. Clients can use
|
|
// Poll or other methods to check whether the cancellation succeeded or whether the
|
|
// operation completed despite cancellation. On successful cancellation,
|
|
// the operation is not deleted; instead, op.Poll returns an error
|
|
// with code Canceled.
|
|
func (op *Operation) Cancel(ctx context.Context, opts ...gax.CallOption) error {
|
|
return op.c.CancelOperation(ctx, &pb.CancelOperationRequest{Name: op.Name()}, opts...)
|
|
}
|
|
|
|
// Delete deletes a long-running operation. This method indicates that the client is
|
|
// no longer interested in the operation result. It does not cancel the
|
|
// operation. If the server doesn't support this method, grpc.Code(error) == codes.Unimplemented.
|
|
func (op *Operation) Delete(ctx context.Context, opts ...gax.CallOption) error {
|
|
return op.c.DeleteOperation(ctx, &pb.DeleteOperationRequest{Name: op.Name()}, opts...)
|
|
}
|