mirror of
https://github.com/letic/terraform-provider-google.git
synced 2024-07-01 07:42:40 +00:00
clean up operation code (#2734)
This commit is contained in:
parent
4a706f7225
commit
91a513ab83
|
@ -2,12 +2,7 @@ package google
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
|
||||
"google.golang.org/api/appengine/v1"
|
||||
)
|
||||
|
@ -18,73 +13,30 @@ var (
|
|||
|
||||
type AppEngineOperationWaiter struct {
|
||||
Service *appengine.APIService
|
||||
Op *appengine.Operation
|
||||
AppId string
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *AppEngineOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
func (w *AppEngineOperationWaiter) QueryOp() (interface{}, error) {
|
||||
matches := appEngineOperationIdRegexp.FindStringSubmatch(w.Op.Name)
|
||||
if len(matches) != 2 {
|
||||
return nil, "", fmt.Errorf("Expected %d results of parsing operation name, got %d from %s", 2, len(matches), w.Op.Name)
|
||||
return nil, fmt.Errorf("Expected %d results of parsing operation name, got %d from %s", 2, len(matches), w.Op.Name)
|
||||
}
|
||||
op, err := w.Service.Apps.Operations.Get(w.AppId, matches[1]).Do()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %v when asking for operation %q", op.Done, w.Op.Name)
|
||||
return op, strconv.FormatBool(op.Done), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (w *AppEngineOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"false"},
|
||||
Target: []string{"true"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
// AppEngineOperationError wraps appengine.Status and implements the
|
||||
// error interface so it can be returned.
|
||||
type AppEngineOperationError appengine.Status
|
||||
|
||||
func (e AppEngineOperationError) Error() string {
|
||||
return e.Message
|
||||
return w.Service.Apps.Operations.Get(w.AppId, matches[1]).Do()
|
||||
}
|
||||
|
||||
func appEngineOperationWait(client *appengine.APIService, op *appengine.Operation, appId, activity string) error {
|
||||
return appEngineOperationWaitTime(client, op, appId, activity, 4)
|
||||
}
|
||||
|
||||
func appEngineOperationWaitTime(client *appengine.APIService, op *appengine.Operation, appId, activity string, timeoutMin int) error {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return AppEngineOperationError(*op.Error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func appEngineOperationWaitTime(client *appengine.APIService, op *appengine.Operation, appId, activity string, timeoutMinutes int) error {
|
||||
w := &AppEngineOperationWaiter{
|
||||
Service: client,
|
||||
Op: op,
|
||||
AppId: appId,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resultOp := opRaw.(*appengine.Operation)
|
||||
if resultOp.Error != nil {
|
||||
return AppEngineOperationError(*resultOp.Error)
|
||||
}
|
||||
|
||||
return nil
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
|
|
@ -1,77 +1,24 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/cloudfunctions/v1"
|
||||
)
|
||||
|
||||
type CloudFunctionsOperationWaiter struct {
|
||||
Service *cloudfunctions.Service
|
||||
Op *cloudfunctions.Operation
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *CloudFunctionsOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
op, err := w.Service.Operations.Get(w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
status := "PENDING"
|
||||
if op.Done == true {
|
||||
status = "DONE"
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %q when asking for operation %q", status, w.Op.Name)
|
||||
return op, status, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (w *CloudFunctionsOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"PENDING"},
|
||||
Target: []string{"DONE"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
func cloudFunctionsOperationWait(client *cloudfunctions.Service,
|
||||
op *cloudfunctions.Operation, activity string) error {
|
||||
return cloudFunctionsOperationWaitTime(client, op, activity, 4)
|
||||
}
|
||||
|
||||
func cloudFunctionsOperationWaitTime(client *cloudfunctions.Service, op *cloudfunctions.Operation,
|
||||
activity string, timeoutMin int) error {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf(op.Error.Message)
|
||||
}
|
||||
return nil
|
||||
func (w *CloudFunctionsOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||
}
|
||||
|
||||
func cloudFunctionsOperationWait(service *cloudfunctions.Service, op *cloudfunctions.Operation, activity string) error {
|
||||
w := &CloudFunctionsOperationWaiter{
|
||||
Service: client,
|
||||
Op: op,
|
||||
Service: service,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resultOp := opRaw.(*cloudfunctions.Operation)
|
||||
if resultOp.Error != nil {
|
||||
return fmt.Errorf(resultOp.Error.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
return OperationWait(w, activity, 4)
|
||||
}
|
||||
|
|
143
google/common_operation.go
Normal file
143
google/common_operation.go
Normal file
|
@ -0,0 +1,143 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
cloudresourcemanager "google.golang.org/api/cloudresourcemanager/v1"
|
||||
)
|
||||
|
||||
type Waiter interface {
|
||||
// State returns the current status of the operation.
|
||||
State() string
|
||||
|
||||
// Error returns an error embedded in the operation we're waiting on, or nil
|
||||
// if the operation has no current error.
|
||||
Error() error
|
||||
|
||||
// SetOp sets the operation we're waiting on in a Waiter struct so that it
|
||||
// can be used in other methods.
|
||||
SetOp(interface{}) error
|
||||
|
||||
// QueryOp sends a request to the server to get the current status of the
|
||||
// operation.
|
||||
QueryOp() (interface{}, error)
|
||||
|
||||
// OpName is the name of the operation and is used to log its status.
|
||||
OpName() string
|
||||
|
||||
// PendingStates contains the values of State() that cause us to continue
|
||||
// refreshing the operation.
|
||||
PendingStates() []string
|
||||
|
||||
// TargetStates contain the values of State() that cause us to finish
|
||||
// refreshing the operation.
|
||||
TargetStates() []string
|
||||
}
|
||||
|
||||
type CommonOperationWaiter struct {
|
||||
Op CommonOperation
|
||||
}
|
||||
|
||||
func (w *CommonOperationWaiter) State() string {
|
||||
return fmt.Sprintf("done: %v", w.Op.Done)
|
||||
}
|
||||
|
||||
func (w *CommonOperationWaiter) Error() error {
|
||||
if w.Op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", w.Op.Error.Code, w.Op.Error.Message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *CommonOperationWaiter) SetOp(op interface{}) error {
|
||||
if err := Convert(op, &w.Op); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *CommonOperationWaiter) OpName() string {
|
||||
return w.Op.Name
|
||||
}
|
||||
|
||||
func (w *CommonOperationWaiter) PendingStates() []string {
|
||||
return []string{"done: false"}
|
||||
}
|
||||
|
||||
func (w *CommonOperationWaiter) TargetStates() []string {
|
||||
return []string{"done: true"}
|
||||
}
|
||||
|
||||
func OperationDone(w Waiter) bool {
|
||||
for _, s := range w.TargetStates() {
|
||||
if s == w.State() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func CommonRefreshFunc(w Waiter) resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
// First, read the operation from the server.
|
||||
op, err := w.QueryOp()
|
||||
|
||||
// If we got a non-retryable error, return it.
|
||||
if err != nil && !isRetryableError(err) {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
// Try to set the operation (so we can check it's Error/State),
|
||||
// and fail if we can't.
|
||||
if err = w.SetOp(op); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
// Fail if the operation object contains an error.
|
||||
if err = w.Error(); err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
log.Printf("[DEBUG] Got %v while polling for operation %s's status", w.State(), w.OpName())
|
||||
|
||||
return op, w.State(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func OperationWait(w Waiter, activity string, timeoutMinutes int) error {
|
||||
if OperationDone(w) {
|
||||
if w.Error() != nil {
|
||||
return w.Error()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
c := &resource.StateChangeConf{
|
||||
Pending: w.PendingStates(),
|
||||
Target: w.TargetStates(),
|
||||
Refresh: CommonRefreshFunc(w),
|
||||
Timeout: time.Duration(timeoutMinutes) * time.Minute,
|
||||
MinTimeout: 2 * time.Second,
|
||||
}
|
||||
opRaw, err := c.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
}
|
||||
|
||||
err = w.SetOp(opRaw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if w.Error() != nil {
|
||||
return w.Error()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// The cloud resource manager API operation is an example of one of many
|
||||
// interchangeable API operations. Choose it somewhat arbitrarily to represent
|
||||
// the "common" operation.
|
||||
type CommonOperation cloudresourcemanager.Operation
|
|
@ -1,67 +1,24 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
composer "google.golang.org/api/composer/v1beta1"
|
||||
)
|
||||
|
||||
type ComposerOperationWaiter struct {
|
||||
Service *composer.ProjectsLocationsService
|
||||
Op *composer.Operation
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *ComposerOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
op, err := w.Service.Operations.Get(w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %v while polling for operation %s's 'done' status", op.Done, w.Op.Name)
|
||||
|
||||
return op, fmt.Sprint(op.Done), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (w *ComposerOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"false"},
|
||||
Target: []string{"true"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
func composerOperationWaitTime(service *composer.Service, op *composer.Operation, project, activity string, timeoutMin int) error {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
return nil
|
||||
func (w *ComposerOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||
}
|
||||
|
||||
func composerOperationWaitTime(service *composer.Service, op *composer.Operation, project, activity string, timeoutMinutes int) error {
|
||||
w := &ComposerOperationWaiter{
|
||||
Service: service.Projects.Locations,
|
||||
Op: op,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
op = opRaw.(*composer.Operation)
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,6 @@ package google
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
|
||||
computeBeta "google.golang.org/api/compute/v0.beta"
|
||||
"google.golang.org/api/compute/v1"
|
||||
|
@ -18,35 +13,70 @@ type ComputeOperationWaiter struct {
|
|||
Project string
|
||||
}
|
||||
|
||||
func (w *ComputeOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
var op *compute.Operation
|
||||
var err error
|
||||
func (w *ComputeOperationWaiter) State() string {
|
||||
return w.Op.Status
|
||||
}
|
||||
|
||||
func (w *ComputeOperationWaiter) Error() error {
|
||||
if w.Op.Error != nil {
|
||||
return ComputeOperationError(*w.Op.Error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *ComputeOperationWaiter) SetOp(op interface{}) error {
|
||||
w.Op = op.(*compute.Operation)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *ComputeOperationWaiter) QueryOp() (interface{}, error) {
|
||||
if w.Op.Zone != "" {
|
||||
zone := GetResourceNameFromSelfLink(w.Op.Zone)
|
||||
op, err = w.Service.ZoneOperations.Get(w.Project, zone, w.Op.Name).Do()
|
||||
return w.Service.ZoneOperations.Get(w.Project, zone, w.Op.Name).Do()
|
||||
} else if w.Op.Region != "" {
|
||||
region := GetResourceNameFromSelfLink(w.Op.Region)
|
||||
op, err = w.Service.RegionOperations.Get(w.Project, region, w.Op.Name).Do()
|
||||
} else {
|
||||
op, err = w.Service.GlobalOperations.Get(w.Project, w.Op.Name).Do()
|
||||
return w.Service.RegionOperations.Get(w.Project, region, w.Op.Name).Do()
|
||||
}
|
||||
return w.Service.GlobalOperations.Get(w.Project, w.Op.Name).Do()
|
||||
}
|
||||
|
||||
func (w *ComputeOperationWaiter) OpName() string {
|
||||
return w.Op.Name
|
||||
}
|
||||
|
||||
func (w *ComputeOperationWaiter) PendingStates() []string {
|
||||
return []string{"PENDING", "RUNNING"}
|
||||
}
|
||||
|
||||
func (w *ComputeOperationWaiter) TargetStates() []string {
|
||||
return []string{"DONE"}
|
||||
}
|
||||
|
||||
func computeOperationWait(client *compute.Service, op *compute.Operation, project, activity string) error {
|
||||
return computeOperationWaitTime(client, op, project, activity, 4)
|
||||
}
|
||||
|
||||
func computeOperationWaitTime(client *compute.Service, op *compute.Operation, project, activity string, timeoutMinutes int) error {
|
||||
w := &ComputeOperationWaiter{
|
||||
Service: client,
|
||||
Op: op,
|
||||
Project: project,
|
||||
}
|
||||
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
||||
func computeBetaOperationWaitTime(client *compute.Service, op *computeBeta.Operation, project, activity string, timeoutMin int) error {
|
||||
opV1 := &compute.Operation{}
|
||||
err := Convert(op, opV1)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
return err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %q when asking for operation %q", op.Status, w.Op.Name)
|
||||
return op, op.Status, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (w *ComputeOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"PENDING", "RUNNING"},
|
||||
Target: []string{"DONE"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
return computeOperationWaitTime(client, opV1, project, activity, timeoutMin)
|
||||
}
|
||||
|
||||
// ComputeOperationError wraps compute.OperationError and implements the
|
||||
|
@ -61,48 +91,3 @@ func (e ComputeOperationError) Error() string {
|
|||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func computeOperationWait(client *compute.Service, op *compute.Operation, project, activity string) error {
|
||||
return computeOperationWaitTime(client, op, project, activity, 4)
|
||||
}
|
||||
|
||||
func computeOperationWaitTime(client *compute.Service, op *compute.Operation, project, activity string, timeoutMin int) error {
|
||||
if op.Status == "DONE" {
|
||||
if op.Error != nil {
|
||||
return ComputeOperationError(*op.Error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
w := &ComputeOperationWaiter{
|
||||
Service: client,
|
||||
Op: op,
|
||||
Project: project,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
}
|
||||
|
||||
resultOp := opRaw.(*compute.Operation)
|
||||
if resultOp.Error != nil {
|
||||
return ComputeOperationError(*resultOp.Error)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func computeBetaOperationWaitTime(client *compute.Service, op *computeBeta.Operation, project, activity string, timeoutMin int) error {
|
||||
opV1 := &compute.Operation{}
|
||||
err := Convert(op, opV1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return computeOperationWaitTime(client, opV1, project, activity, timeoutMin)
|
||||
}
|
||||
|
|
|
@ -2,142 +2,61 @@ package google
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/container/v1"
|
||||
containerBeta "google.golang.org/api/container/v1beta1"
|
||||
"google.golang.org/api/container/v1beta1"
|
||||
)
|
||||
|
||||
type ContainerOperationWaiter struct {
|
||||
Service *container.Service
|
||||
Op *container.Operation
|
||||
Project string
|
||||
Zone string
|
||||
}
|
||||
|
||||
type ContainerBetaOperationWaiter struct {
|
||||
Service *containerBeta.Service
|
||||
Op *containerBeta.Operation
|
||||
Project string
|
||||
Location string
|
||||
}
|
||||
|
||||
func (w *ContainerOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"PENDING", "RUNNING"},
|
||||
Target: []string{"DONE"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
func (w *ContainerOperationWaiter) State() string {
|
||||
return w.Op.Status
|
||||
}
|
||||
|
||||
func (w *ContainerBetaOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"PENDING", "RUNNING"},
|
||||
Target: []string{"DONE"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
func (w *ContainerOperationWaiter) Error() error {
|
||||
if w.Op.StatusMessage != "" {
|
||||
return fmt.Errorf(w.Op.StatusMessage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *ContainerOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
resp, err := w.Service.Projects.Zones.Operations.Get(
|
||||
w.Project, w.Zone, w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
func (w *ContainerOperationWaiter) SetOp(op interface{}) error {
|
||||
w.Op = op.(*container.Operation)
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.StatusMessage != "" {
|
||||
return resp, resp.Status, fmt.Errorf(resp.StatusMessage)
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Progress of operation %q: %q", w.Op.Name, resp.Status)
|
||||
|
||||
return resp, resp.Status, err
|
||||
}
|
||||
}
|
||||
|
||||
func (w *ContainerBetaOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
func (w *ContainerOperationWaiter) QueryOp() (interface{}, error) {
|
||||
name := fmt.Sprintf("projects/%s/locations/%s/operations/%s",
|
||||
w.Project, w.Location, w.Op.Name)
|
||||
resp, err := w.Service.Projects.Locations.Operations.Get(name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
return w.Service.Projects.Locations.Operations.Get(name).Do()
|
||||
}
|
||||
|
||||
if resp.StatusMessage != "" {
|
||||
return resp, resp.Status, fmt.Errorf(resp.StatusMessage)
|
||||
func (w *ContainerOperationWaiter) OpName() string {
|
||||
return w.Op.Name
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Progress of operation %q: %q", w.Op.Name, resp.Status)
|
||||
|
||||
return resp, resp.Status, err
|
||||
}
|
||||
func (w *ContainerOperationWaiter) PendingStates() []string {
|
||||
return []string{"PENDING", "RUNNING"}
|
||||
}
|
||||
|
||||
func containerOperationWait(config *Config, op *container.Operation, project, zone, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
||||
if op.Status == "DONE" {
|
||||
if op.StatusMessage != "" {
|
||||
return fmt.Errorf(op.StatusMessage)
|
||||
}
|
||||
return nil
|
||||
func (w *ContainerOperationWaiter) TargetStates() []string {
|
||||
return []string{"DONE"}
|
||||
}
|
||||
|
||||
func containerOperationWait(config *Config, op *container.Operation, project, location, activity string, timeoutMinutes int) error {
|
||||
w := &ContainerOperationWaiter{
|
||||
Service: config.clientContainer,
|
||||
Op: op,
|
||||
Project: project,
|
||||
Zone: zone,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
return waitForState(state, activity, timeoutMinutes, minTimeoutSeconds)
|
||||
}
|
||||
|
||||
func containerBetaOperationWait(config *Config, op *containerBeta.Operation, project, location, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
||||
if op.Status == "DONE" {
|
||||
if op.StatusMessage != "" {
|
||||
return fmt.Errorf(op.StatusMessage)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
w := &ContainerBetaOperationWaiter{
|
||||
Service: config.clientContainerBeta,
|
||||
Op: op,
|
||||
Project: project,
|
||||
Location: location,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
return waitForState(state, activity, timeoutMinutes, minTimeoutSeconds)
|
||||
}
|
||||
|
||||
func waitForState(state *resource.StateChangeConf, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
||||
state.Timeout = time.Duration(timeoutMinutes) * time.Minute
|
||||
state.MinTimeout = time.Duration(minTimeoutSeconds) * time.Second
|
||||
_, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func containerSharedOperationWait(config *Config, op interface{}, project, location, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
||||
if op == nil {
|
||||
panic("Attempted to wait on an Operation that was nil.")
|
||||
}
|
||||
|
||||
switch op.(type) {
|
||||
case *container.Operation:
|
||||
return containerOperationWait(config, op.(*container.Operation), project, location, activity, timeoutMinutes, minTimeoutSeconds)
|
||||
case *containerBeta.Operation:
|
||||
return containerBetaOperationWait(config, op.(*containerBeta.Operation), project, location, activity, timeoutMinutes, minTimeoutSeconds)
|
||||
default:
|
||||
panic("Attempted to wait on an Operation of unknown type.")
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
|
|
@ -1,66 +1,24 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/dataproc/v1"
|
||||
)
|
||||
|
||||
type DataprocClusterOperationWaiter struct {
|
||||
Service *dataproc.Service
|
||||
Op *dataproc.Operation
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *DataprocClusterOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"false"},
|
||||
Target: []string{"true"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
func (w *DataprocClusterOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
op, err := w.Service.Projects.Regions.Operations.Get(w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %v while polling for operation %s's 'done' status", op.Done, w.Op.Name)
|
||||
|
||||
return op, fmt.Sprint(op.Done), nil
|
||||
}
|
||||
}
|
||||
|
||||
func dataprocClusterOperationWait(config *Config, op *dataproc.Operation, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
return nil
|
||||
func (w *DataprocClusterOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Projects.Regions.Operations.Get(w.Op.Name).Do()
|
||||
}
|
||||
|
||||
func dataprocClusterOperationWait(config *Config, op *dataproc.Operation, activity string, timeoutMinutes int) error {
|
||||
w := &DataprocClusterOperationWaiter{
|
||||
Service: config.clientDataproc,
|
||||
Op: op,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Timeout = time.Duration(timeoutMinutes) * time.Minute
|
||||
state.MinTimeout = time.Duration(minTimeoutSeconds) * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
op = opRaw.(*dataproc.Operation)
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/dataproc/v1"
|
||||
"google.golang.org/api/googleapi"
|
||||
)
|
||||
|
||||
type DataprocJobOperationWaiter struct {
|
||||
|
@ -16,80 +11,46 @@ type DataprocJobOperationWaiter struct {
|
|||
Region string
|
||||
ProjectId string
|
||||
JobId string
|
||||
Status string
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) ConfForDelete() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"EXISTS"},
|
||||
Target: []string{"DELETED"},
|
||||
Refresh: w.RefreshFuncForDelete(),
|
||||
}
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
// For more info on each of the states please see
|
||||
// https://cloud.google.com/dataproc/docs/reference/rest/v1/projects.regions.jobs#JobStatus
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"PENDING", "CANCEL_PENDING", "CANCEL_STARTED", "SETUP_DONE", "RUNNING"},
|
||||
Target: []string{"CANCELLED", "DONE", "ATTEMPT_FAILURE", "ERROR"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
func isNotFound(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
ae, ok := err.(*googleapi.Error)
|
||||
return ok && ae.Code == http.StatusNotFound
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) RefreshFuncForDelete() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
_, err := w.Service.Projects.Regions.Jobs.Get(w.ProjectId, w.Region, w.JobId).Do()
|
||||
|
||||
if err != nil {
|
||||
if isNotFound(err) {
|
||||
return "NA", "DELETED", nil
|
||||
}
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return "JOB", "EXISTS", err
|
||||
}
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
job, err := w.Service.Projects.Regions.Jobs.Get(w.ProjectId, w.Region, w.JobId).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
return job, job.Status.State, err
|
||||
}
|
||||
}
|
||||
|
||||
func dataprocDeleteOperationWait(config *Config, region, projectId, jobId string, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
||||
w := &DataprocJobOperationWaiter{
|
||||
Service: config.clientDataproc,
|
||||
Region: region,
|
||||
ProjectId: projectId,
|
||||
JobId: jobId,
|
||||
}
|
||||
|
||||
state := w.ConfForDelete()
|
||||
state.Timeout = time.Duration(timeoutMinutes) * time.Minute
|
||||
state.MinTimeout = time.Duration(minTimeoutSeconds) * time.Second
|
||||
_, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
func (w *DataprocJobOperationWaiter) State() string {
|
||||
return w.Status
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) Error() error {
|
||||
// The "operation" is just the job, which has no special error field that we
|
||||
// want to expose.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) SetOp(job interface{}) error {
|
||||
// The "operation" is just the job. Instead of holding onto the whole job
|
||||
// object, we only care about the state, which gets set in QueryOp, so this
|
||||
// doesn't have to do anything.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) QueryOp() (interface{}, error) {
|
||||
job, err := w.Service.Projects.Regions.Jobs.Get(w.ProjectId, w.Region, w.JobId).Do()
|
||||
if job != nil {
|
||||
w.Status = job.Status.State
|
||||
}
|
||||
return job, err
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) OpName() string {
|
||||
return w.JobId
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) PendingStates() []string {
|
||||
return []string{"PENDING", "CANCEL_PENDING", "CANCEL_STARTED", "SETUP_DONE", "RUNNING"}
|
||||
}
|
||||
|
||||
func (w *DataprocJobOperationWaiter) TargetStates() []string {
|
||||
return []string{"CANCELLED", "DONE", "ATTEMPT_FAILURE", "ERROR"}
|
||||
}
|
||||
|
||||
func dataprocJobOperationWait(config *Config, region, projectId, jobId string, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
||||
w := &DataprocJobOperationWaiter{
|
||||
Service: config.clientDataproc,
|
||||
|
@ -97,14 +58,42 @@ func dataprocJobOperationWait(config *Config, region, projectId, jobId string, a
|
|||
ProjectId: projectId,
|
||||
JobId: jobId,
|
||||
}
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Timeout = time.Duration(timeoutMinutes) * time.Minute
|
||||
state.MinTimeout = time.Duration(minTimeoutSeconds) * time.Second
|
||||
_, err := state.WaitForState()
|
||||
type DataprocDeleteJobOperationWaiter struct {
|
||||
DataprocJobOperationWaiter
|
||||
}
|
||||
|
||||
func (w *DataprocDeleteJobOperationWaiter) PendingStates() []string {
|
||||
return []string{"EXISTS", "ERROR"}
|
||||
}
|
||||
|
||||
func (w *DataprocDeleteJobOperationWaiter) TargetStates() []string {
|
||||
return []string{"DELETED"}
|
||||
}
|
||||
|
||||
func (w *DataprocDeleteJobOperationWaiter) QueryOp() (interface{}, error) {
|
||||
job, err := w.Service.Projects.Regions.Jobs.Get(w.ProjectId, w.Region, w.JobId).Do()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for operation %s: %s", activity, err)
|
||||
if isGoogleApiErrorWithCode(err, http.StatusNotFound) {
|
||||
w.Status = "DELETED"
|
||||
return job, nil
|
||||
}
|
||||
w.Status = "ERROR"
|
||||
}
|
||||
w.Status = "EXISTS"
|
||||
return job, err
|
||||
}
|
||||
|
||||
return nil
|
||||
func dataprocDeleteOperationWait(config *Config, region, projectId, jobId string, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
||||
w := &DataprocDeleteJobOperationWaiter{
|
||||
DataprocJobOperationWaiter{
|
||||
Service: config.clientDataproc,
|
||||
Region: region,
|
||||
ProjectId: projectId,
|
||||
JobId: jobId,
|
||||
},
|
||||
}
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
|
|
@ -32,14 +32,11 @@ func (w *DnsChangeWaiter) RefreshFunc() resource.StateRefreshFunc {
|
|||
}
|
||||
|
||||
func (w *DnsChangeWaiter) Conf() *resource.StateChangeConf {
|
||||
state := &resource.StateChangeConf{
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"pending"},
|
||||
Target: []string{"done"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
Timeout: 10 * time.Minute,
|
||||
MinTimeout: 2 * time.Second,
|
||||
}
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = 10 * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
return state
|
||||
|
||||
}
|
||||
|
|
|
@ -1,67 +1,24 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/redis/v1beta1"
|
||||
)
|
||||
|
||||
type RedisOperationWaiter struct {
|
||||
Service *redis.ProjectsLocationsService
|
||||
Op *redis.Operation
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *RedisOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
op, err := w.Service.Operations.Get(w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %v while polling for operation %s's 'done' status", op.Done, w.Op.Name)
|
||||
|
||||
return op, fmt.Sprint(op.Done), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (w *RedisOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"false"},
|
||||
Target: []string{"true"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
func redisOperationWaitTime(service *redis.Service, op *redis.Operation, project, activity string, timeoutMin int) error {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
return nil
|
||||
func (w *RedisOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||
}
|
||||
|
||||
func redisOperationWaitTime(service *redis.Service, op *redis.Operation, project, activity string, timeoutMinutes int) error {
|
||||
w := &RedisOperationWaiter{
|
||||
Service: service.Projects.Locations,
|
||||
Op: op,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
op = opRaw.(*redis.Operation)
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
|
|
@ -715,7 +715,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
|
|||
defer mutexKV.Unlock(containerClusterMutexKey(project, location, clusterName))
|
||||
|
||||
parent := fmt.Sprintf("projects/%s/locations/%s", project, location)
|
||||
var op interface{}
|
||||
var op *containerBeta.Operation
|
||||
err = retry(func() error {
|
||||
op, err = config.clientContainerBeta.Projects.Locations.Clusters.Create(parent, req).Do()
|
||||
return err
|
||||
|
@ -728,7 +728,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
|
|||
|
||||
// Wait until it's created
|
||||
timeoutInMinutes := int(d.Timeout(schema.TimeoutCreate).Minutes())
|
||||
waitErr := containerSharedOperationWait(config, op, project, location, "creating GKE cluster", timeoutInMinutes, 3)
|
||||
waitErr := containerOperationWait(config, op, project, location, "creating GKE cluster", timeoutInMinutes)
|
||||
if waitErr != nil {
|
||||
// The resource didn't actually create
|
||||
d.SetId("")
|
||||
|
@ -743,7 +743,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
|
|||
if err != nil {
|
||||
return errwrap.Wrapf("Error deleting default node pool: {{err}}", err)
|
||||
}
|
||||
err = containerSharedOperationWait(config, op, project, location, "removing default node pool", timeoutInMinutes, 3)
|
||||
err = containerOperationWait(config, op, project, location, "removing default node pool", timeoutInMinutes)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error deleting default node pool: {{err}}", err)
|
||||
}
|
||||
|
@ -878,7 +878,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
return err
|
||||
}
|
||||
// Wait until it's updated
|
||||
return containerSharedOperationWait(config, op, project, location, updateDescription, timeoutInMinutes, 2)
|
||||
return containerOperationWait(config, op, project, location, updateDescription, timeoutInMinutes)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -993,7 +993,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerSharedOperationWait(config, op, project, location, "updating GKE cluster maintenance policy", timeoutInMinutes, 2)
|
||||
return containerOperationWait(config, op, project, location, "updating GKE cluster maintenance policy", timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
@ -1071,7 +1071,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
err = containerSharedOperationWait(config, op, project, location, "updating GKE legacy ABAC", timeoutInMinutes, 2)
|
||||
err = containerOperationWait(config, op, project, location, "updating GKE legacy ABAC", timeoutInMinutes)
|
||||
log.Println("[DEBUG] done updating enable_legacy_abac")
|
||||
return err
|
||||
}
|
||||
|
@ -1120,7 +1120,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerSharedOperationWait(config, op, project, location, "updating GKE logging service", timeoutInMinutes, 2)
|
||||
return containerOperationWait(config, op, project, location, "updating GKE logging service", timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
@ -1148,7 +1148,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
err = containerSharedOperationWait(config, op, project, location, "updating GKE cluster network policy", timeoutInMinutes, 2)
|
||||
err = containerOperationWait(config, op, project, location, "updating GKE cluster network policy", timeoutInMinutes)
|
||||
log.Println("[DEBUG] done updating network_policy")
|
||||
return err
|
||||
}
|
||||
|
@ -1195,7 +1195,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerSharedOperationWait(config, op, project, location, "updating GKE image type", timeoutInMinutes, 2)
|
||||
return containerOperationWait(config, op, project, location, "updating GKE image type", timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
@ -1232,7 +1232,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerSharedOperationWait(config, op, project, location, "updating master auth", timeoutInMinutes, 2)
|
||||
return containerOperationWait(config, op, project, location, "updating master auth", timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
@ -1257,7 +1257,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerSharedOperationWait(config, op, project, location, "updating GKE resource labels", timeoutInMinutes, 2)
|
||||
return containerOperationWait(config, op, project, location, "updating GKE resource labels", timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
@ -1274,7 +1274,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
if err != nil {
|
||||
return errwrap.Wrapf("Error deleting default node pool: {{err}}", err)
|
||||
}
|
||||
err = containerSharedOperationWait(config, op, project, location, "removing default node pool", timeoutInMinutes, 3)
|
||||
err = containerOperationWait(config, op, project, location, "removing default node pool", timeoutInMinutes)
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("Error deleting default node pool: {{err}}", err)
|
||||
}
|
||||
|
@ -1312,7 +1312,7 @@ func resourceContainerClusterDelete(d *schema.ResourceData, meta interface{}) er
|
|||
mutexKV.Lock(containerClusterMutexKey(project, location, clusterName))
|
||||
defer mutexKV.Unlock(containerClusterMutexKey(project, location, clusterName))
|
||||
|
||||
var op interface{}
|
||||
var op *containerBeta.Operation
|
||||
var count = 0
|
||||
err = resource.Retry(30*time.Second, func() *resource.RetryError {
|
||||
count++
|
||||
|
@ -1336,7 +1336,7 @@ func resourceContainerClusterDelete(d *schema.ResourceData, meta interface{}) er
|
|||
}
|
||||
|
||||
// Wait until it's deleted
|
||||
waitErr := containerSharedOperationWait(config, op, project, location, "deleting GKE cluster", timeoutInMinutes, 3)
|
||||
waitErr := containerOperationWait(config, op, project, location, "deleting GKE cluster", timeoutInMinutes)
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
|
|
|
@ -251,9 +251,9 @@ func resourceContainerNodePoolCreate(d *schema.ResourceData, meta interface{}) e
|
|||
|
||||
d.SetId(fmt.Sprintf("%s/%s/%s", nodePoolInfo.location, nodePoolInfo.cluster, nodePool.Name))
|
||||
|
||||
waitErr := containerBetaOperationWait(config,
|
||||
waitErr := containerOperationWait(config,
|
||||
operation, nodePoolInfo.project,
|
||||
nodePoolInfo.location, "creating GKE NodePool", int(timeout.Minutes()), 3)
|
||||
nodePoolInfo.location, "creating GKE NodePool", int(timeout.Minutes()))
|
||||
|
||||
if waitErr != nil {
|
||||
// The resource didn't actually create
|
||||
|
@ -369,7 +369,7 @@ func resourceContainerNodePoolDelete(d *schema.ResourceData, meta interface{}) e
|
|||
}
|
||||
|
||||
// Wait until it's deleted
|
||||
waitErr := containerBetaOperationWait(config, op, nodePoolInfo.project, nodePoolInfo.location, "deleting GKE NodePool", timeoutInMinutes, 2)
|
||||
waitErr := containerOperationWait(config, op, nodePoolInfo.project, nodePoolInfo.location, "deleting GKE NodePool", timeoutInMinutes)
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
|
@ -571,10 +571,10 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerBetaOperationWait(config, op,
|
||||
return containerOperationWait(config, op,
|
||||
nodePoolInfo.project,
|
||||
nodePoolInfo.location, "updating GKE node pool",
|
||||
timeoutInMinutes, 2)
|
||||
timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
@ -605,10 +605,10 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerBetaOperationWait(config, op,
|
||||
return containerOperationWait(config, op,
|
||||
nodePoolInfo.project,
|
||||
nodePoolInfo.location, "updating GKE node pool",
|
||||
timeoutInMinutes, 2)
|
||||
timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
@ -637,10 +637,10 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerBetaOperationWait(config, op,
|
||||
return containerOperationWait(config, op,
|
||||
nodePoolInfo.project,
|
||||
nodePoolInfo.location, "updating GKE node pool size",
|
||||
timeoutInMinutes, 2)
|
||||
timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
@ -676,9 +676,9 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerBetaOperationWait(config, op,
|
||||
return containerOperationWait(config, op,
|
||||
nodePoolInfo.project,
|
||||
nodePoolInfo.location, "updating GKE node pool management", timeoutInMinutes, 2)
|
||||
nodePoolInfo.location, "updating GKE node pool management", timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
@ -707,9 +707,9 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
return containerBetaOperationWait(config, op,
|
||||
return containerOperationWait(config, op,
|
||||
nodePoolInfo.project,
|
||||
nodePoolInfo.location, "updating GKE node pool version", timeoutInMinutes, 2)
|
||||
nodePoolInfo.location, "updating GKE node pool version", timeoutInMinutes)
|
||||
}
|
||||
|
||||
// Call update serially.
|
||||
|
|
|
@ -456,7 +456,7 @@ func resourceDataprocClusterCreate(d *schema.ResourceData, meta interface{}) err
|
|||
|
||||
// Wait until it's created
|
||||
timeoutInMinutes := int(d.Timeout(schema.TimeoutCreate).Minutes())
|
||||
waitErr := dataprocClusterOperationWait(config, op, "creating Dataproc cluster", timeoutInMinutes, 3)
|
||||
waitErr := dataprocClusterOperationWait(config, op, "creating Dataproc cluster", timeoutInMinutes)
|
||||
if waitErr != nil {
|
||||
// The resource didn't actually create
|
||||
// Note that we do not remove the ID here - this resource tends to leave
|
||||
|
@ -740,7 +740,7 @@ func resourceDataprocClusterUpdate(d *schema.ResourceData, meta interface{}) err
|
|||
}
|
||||
|
||||
// Wait until it's updated
|
||||
waitErr := dataprocClusterOperationWait(config, op, "updating Dataproc cluster ", timeoutInMinutes, 2)
|
||||
waitErr := dataprocClusterOperationWait(config, op, "updating Dataproc cluster ", timeoutInMinutes)
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
|
@ -944,7 +944,7 @@ func resourceDataprocClusterDelete(d *schema.ResourceData, meta interface{}) err
|
|||
}
|
||||
|
||||
// Wait until it's deleted
|
||||
waitErr := dataprocClusterOperationWait(config, op, "deleting Dataproc cluster", timeoutInMinutes, 3)
|
||||
waitErr := dataprocClusterOperationWait(config, op, "deleting Dataproc cluster", timeoutInMinutes)
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
|
|
|
@ -280,7 +280,7 @@ func enableServices(s []string, pid string, config *Config) error {
|
|||
|
||||
// Poll for the API to return
|
||||
activity := fmt.Sprintf("apis %q to be enabled for %s", services, pid)
|
||||
_, waitErr := serviceUsageOperationWait(config, sop, activity)
|
||||
waitErr := serviceUsageOperationWait(config, sop, activity)
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ func disableService(s, pid string, config *Config) error {
|
|||
return err
|
||||
}
|
||||
// Wait for the operation to complete
|
||||
_, waitErr := serviceUsageOperationWait(config, sop, "api to disable")
|
||||
waitErr := serviceUsageOperationWait(config, sop, "api to disable")
|
||||
if waitErr != nil {
|
||||
return waitErr
|
||||
}
|
||||
|
|
|
@ -1,76 +1,33 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/cloudresourcemanager/v1"
|
||||
resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
|
||||
)
|
||||
|
||||
type ResourceManagerOperationWaiter struct {
|
||||
Service *cloudresourcemanager.Service
|
||||
Op *cloudresourcemanager.Operation
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *ResourceManagerOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
op, err := w.Service.Operations.Get(w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
func (w *ResourceManagerOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %v while polling for operation %s's 'done' status", op.Done, w.Op.Name)
|
||||
|
||||
return op, fmt.Sprint(op.Done), nil
|
||||
func resourceManagerOperationWaitTime(service *cloudresourcemanager.Service, op *cloudresourcemanager.Operation, activity string, timeoutMin int) error {
|
||||
w := &ResourceManagerOperationWaiter{
|
||||
Service: service,
|
||||
}
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func (w *ResourceManagerOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"false"},
|
||||
Target: []string{"true"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
return OperationWait(w, activity, timeoutMin)
|
||||
}
|
||||
|
||||
func resourceManagerOperationWait(service *cloudresourcemanager.Service, op *cloudresourcemanager.Operation, activity string) error {
|
||||
return resourceManagerOperationWaitTime(service, op, activity, 4)
|
||||
}
|
||||
|
||||
func resourceManagerOperationWaitTime(service *cloudresourcemanager.Service, op *cloudresourcemanager.Operation, activity string, timeoutMin int) error {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
w := &ResourceManagerOperationWaiter{
|
||||
Service: service,
|
||||
Op: op,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
}
|
||||
|
||||
op = opRaw.(*cloudresourcemanager.Operation)
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceManagerV2Beta1OperationWait(service *cloudresourcemanager.Service, op *resourceManagerV2Beta1.Operation, activity string) error {
|
||||
return resourceManagerV2Beta1OperationWaitTime(service, op, activity, 4)
|
||||
}
|
||||
|
|
|
@ -33,26 +33,21 @@ func (w *ServiceAccountKeyWaiter) RefreshFunc() resource.StateRefreshFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func (w *ServiceAccountKeyWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"PENDING"},
|
||||
Target: []string{"DONE"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
func serviceAccountKeyWaitTime(client *iam.ProjectsServiceAccountsKeysService, keyName, publicKeyType, activity string, timeoutMin int) error {
|
||||
func serviceAccountKeyWaitTime(client *iam.ProjectsServiceAccountsKeysService, keyName, publicKeyType, activity string, timeoutMinutes int) error {
|
||||
w := &ServiceAccountKeyWaiter{
|
||||
Service: client,
|
||||
PublicKeyType: publicKeyType,
|
||||
KeyName: keyName,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
_, err := state.WaitForState()
|
||||
c := &resource.StateChangeConf{
|
||||
Pending: []string{"PENDING"},
|
||||
Target: []string{"DONE"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
Timeout: time.Duration(timeoutMinutes) * time.Minute,
|
||||
MinTimeout: 2 * time.Second,
|
||||
}
|
||||
_, err := c.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
}
|
||||
|
|
|
@ -1,75 +1,34 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/googleapi"
|
||||
"google.golang.org/api/servicemanagement/v1"
|
||||
)
|
||||
|
||||
type ServiceManagementOperationWaiter struct {
|
||||
Service *servicemanagement.APIService
|
||||
Op *servicemanagement.Operation
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *ServiceManagementOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
var op *servicemanagement.Operation
|
||||
var err error
|
||||
|
||||
op, err = w.Service.Operations.Get(w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %v while polling for operation %s's 'done' status", op.Done, w.Op.Name)
|
||||
|
||||
return op, fmt.Sprint(op.Done), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (w *ServiceManagementOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"false"},
|
||||
Target: []string{"true"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
func (w *ServiceManagementOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||
}
|
||||
|
||||
func serviceManagementOperationWait(config *Config, op *servicemanagement.Operation, activity string) (googleapi.RawMessage, error) {
|
||||
return serviceManagementOperationWaitTime(config, op, activity, 10)
|
||||
}
|
||||
|
||||
func serviceManagementOperationWaitTime(config *Config, op *servicemanagement.Operation, activity string, timeoutMin int) (googleapi.RawMessage, error) {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return nil, fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
return op.Response, nil
|
||||
}
|
||||
|
||||
func serviceManagementOperationWaitTime(config *Config, op *servicemanagement.Operation, activity string, timeoutMinutes int) (googleapi.RawMessage, error) {
|
||||
w := &ServiceManagementOperationWaiter{
|
||||
Service: config.clientServiceMan,
|
||||
Op: op,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
op = opRaw.(*servicemanagement.Operation)
|
||||
if op.Error != nil {
|
||||
return nil, fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
if err := OperationWait(w, activity, timeoutMinutes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return op.Response, nil
|
||||
return w.Op.Response, nil
|
||||
}
|
||||
|
|
|
@ -1,75 +1,28 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/googleapi"
|
||||
"google.golang.org/api/serviceusage/v1beta1"
|
||||
)
|
||||
|
||||
type serviceUsageOperationWaiter struct {
|
||||
type ServiceUsageOperationWaiter struct {
|
||||
Service *serviceusage.APIService
|
||||
Op *serviceusage.Operation
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *serviceUsageOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
var op *serviceusage.Operation
|
||||
var err error
|
||||
|
||||
op, err = w.Service.Operations.Get(w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
func (w *ServiceUsageOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %v while polling for operation %s's 'done' status", op.Done, w.Op.Name)
|
||||
|
||||
return op, fmt.Sprint(op.Done), nil
|
||||
}
|
||||
}
|
||||
|
||||
func (w *serviceUsageOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"false"},
|
||||
Target: []string{"true"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
func serviceUsageOperationWait(config *Config, op *serviceusage.Operation, activity string) (googleapi.RawMessage, error) {
|
||||
func serviceUsageOperationWait(config *Config, op *serviceusage.Operation, activity string) error {
|
||||
return serviceUsageOperationWaitTime(config, op, activity, 10)
|
||||
}
|
||||
|
||||
func serviceUsageOperationWaitTime(config *Config, op *serviceusage.Operation, activity string, timeoutMin int) (googleapi.RawMessage, error) {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return nil, fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
return op.Response, nil
|
||||
}
|
||||
|
||||
w := &serviceUsageOperationWaiter{
|
||||
func serviceUsageOperationWaitTime(config *Config, op *serviceusage.Operation, activity string, timeoutMinutes int) error {
|
||||
w := &ServiceUsageOperationWaiter{
|
||||
Service: config.clientServiceUsage,
|
||||
Op: op,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
op = opRaw.(*serviceusage.Operation)
|
||||
if op.Error != nil {
|
||||
return nil, fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
|
||||
return op.Response, nil
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
|
|
@ -1,69 +1,25 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/spanner/v1"
|
||||
)
|
||||
|
||||
type SpannerDatabaseOperationWaiter struct {
|
||||
Service *spanner.Service
|
||||
Op *spanner.Operation
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *SpannerDatabaseOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"false"},
|
||||
Target: []string{"true"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
func (w *SpannerDatabaseOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
|
||||
op, err := w.Service.Projects.Instances.Databases.Operations.Get(w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %v while polling for operation %s's 'done' status", op.Done, w.Op.Name)
|
||||
|
||||
return op, fmt.Sprint(op.Done), nil
|
||||
}
|
||||
}
|
||||
|
||||
func spannerDatabaseOperationWait(config *Config, op *spanner.Operation, activity string, timeoutMin int) error {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
return nil
|
||||
func (w *SpannerDatabaseOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Projects.Instances.Databases.Operations.Get(w.Op.Name).Do()
|
||||
}
|
||||
|
||||
func spannerDatabaseOperationWait(config *Config, op *spanner.Operation, activity string, timeoutMinutes int) error {
|
||||
w := &SpannerDatabaseOperationWaiter{
|
||||
Service: config.clientSpanner,
|
||||
Op: op,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
op = opRaw.(*spanner.Operation)
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
|
|
@ -1,69 +1,24 @@
|
|||
package google
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/spanner/v1"
|
||||
)
|
||||
|
||||
type SpannerInstanceOperationWaiter struct {
|
||||
Service *spanner.Service
|
||||
Op *spanner.Operation
|
||||
CommonOperationWaiter
|
||||
}
|
||||
|
||||
func (w *SpannerInstanceOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"false"},
|
||||
Target: []string{"true"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
}
|
||||
}
|
||||
|
||||
func (w *SpannerInstanceOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
|
||||
op, err := w.Service.Projects.Instances.Operations.Get(w.Op.Name).Do()
|
||||
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %v while polling for operation %s's 'done' status", op.Done, w.Op.Name)
|
||||
|
||||
return op, fmt.Sprint(op.Done), nil
|
||||
}
|
||||
}
|
||||
|
||||
func spannerInstanceOperationWait(config *Config, op *spanner.Operation, activity string, timeoutMin int) error {
|
||||
if op.Done {
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
return nil
|
||||
func (w *SpannerInstanceOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Projects.Instances.Operations.Get(w.Op.Name).Do()
|
||||
}
|
||||
|
||||
func spannerInstanceOperationWait(config *Config, op *spanner.Operation, activity string, timeoutMinutes int) error {
|
||||
w := &SpannerInstanceOperationWaiter{
|
||||
Service: config.clientSpanner,
|
||||
Op: op,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Delay = 10 * time.Second
|
||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
op = opRaw.(*spanner.Operation)
|
||||
if op.Error != nil {
|
||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
|
|
@ -2,12 +2,7 @@ package google
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"google.golang.org/api/googleapi"
|
||||
"google.golang.org/api/sqladmin/v1beta4"
|
||||
)
|
||||
|
||||
|
@ -17,29 +12,52 @@ type SqlAdminOperationWaiter struct {
|
|||
Project string
|
||||
}
|
||||
|
||||
func (w *SqlAdminOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||
return func() (interface{}, string, error) {
|
||||
log.Printf("[DEBUG] self_link: %s", w.Op.SelfLink)
|
||||
op, err := w.Service.Operations.Get(w.Project, w.Op.Name).Do()
|
||||
|
||||
if e, ok := err.(*googleapi.Error); ok && (e.Code == 429 || e.Code == 503) {
|
||||
return w.Op, "PENDING", nil
|
||||
} else if err != nil {
|
||||
return nil, "", err
|
||||
func (w *SqlAdminOperationWaiter) State() string {
|
||||
return w.Op.Status
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Got %q when asking for operation %q", op.Status, w.Op.Name)
|
||||
|
||||
return op, op.Status, nil
|
||||
func (w *SqlAdminOperationWaiter) Error() error {
|
||||
if w.Op.Error != nil {
|
||||
return SqlAdminOperationError(*w.Op.Error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *SqlAdminOperationWaiter) Conf() *resource.StateChangeConf {
|
||||
return &resource.StateChangeConf{
|
||||
Pending: []string{"PENDING", "RUNNING"},
|
||||
Target: []string{"DONE"},
|
||||
Refresh: w.RefreshFunc(),
|
||||
func (w *SqlAdminOperationWaiter) SetOp(op interface{}) error {
|
||||
w.Op = op.(*sqladmin.Operation)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *SqlAdminOperationWaiter) QueryOp() (interface{}, error) {
|
||||
return w.Service.Operations.Get(w.Project, w.Op.Name).Do()
|
||||
}
|
||||
|
||||
func (w *SqlAdminOperationWaiter) OpName() string {
|
||||
return w.Op.Name
|
||||
}
|
||||
|
||||
func (w *SqlAdminOperationWaiter) PendingStates() []string {
|
||||
return []string{"PENDING", "RUNNING"}
|
||||
}
|
||||
|
||||
func (w *SqlAdminOperationWaiter) TargetStates() []string {
|
||||
return []string{"DONE"}
|
||||
}
|
||||
|
||||
func sqladminOperationWait(config *Config, op *sqladmin.Operation, project, activity string) error {
|
||||
return sqladminOperationWaitTime(config, op, project, activity, 10)
|
||||
}
|
||||
|
||||
func sqladminOperationWaitTime(config *Config, op *sqladmin.Operation, project, activity string, timeoutMinutes int) error {
|
||||
w := &SqlAdminOperationWaiter{
|
||||
Service: config.clientSqlAdmin,
|
||||
Op: op,
|
||||
Project: project,
|
||||
}
|
||||
if err := w.SetOp(op); err != nil {
|
||||
return err
|
||||
}
|
||||
return OperationWait(w, activity, timeoutMinutes)
|
||||
}
|
||||
|
||||
// SqlAdminOperationError wraps sqladmin.OperationError and implements the
|
||||
|
@ -55,38 +73,3 @@ func (e SqlAdminOperationError) Error() string {
|
|||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func sqladminOperationWait(config *Config, op *sqladmin.Operation, project, activity string) error {
|
||||
return sqladminOperationWaitTime(config, op, project, activity, 10)
|
||||
}
|
||||
|
||||
func sqladminOperationWaitTime(config *Config, op *sqladmin.Operation, project, activity string, timeoutMinutes int) error {
|
||||
if op.Status == "DONE" {
|
||||
if op.Error != nil {
|
||||
return SqlAdminOperationError(*op.Error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
w := &SqlAdminOperationWaiter{
|
||||
Service: config.clientSqlAdmin,
|
||||
Op: op,
|
||||
Project: project,
|
||||
}
|
||||
|
||||
state := w.Conf()
|
||||
state.Timeout = time.Duration(timeoutMinutes) * time.Minute
|
||||
state.MinTimeout = 2 * time.Second
|
||||
state.Delay = 5 * time.Second
|
||||
opRaw, err := state.WaitForState()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for %s (op %s): %s", activity, op.Name, err)
|
||||
}
|
||||
|
||||
op = opRaw.(*sqladmin.Operation)
|
||||
if op.Error != nil {
|
||||
return SqlAdminOperationError(*op.Error)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -335,14 +335,21 @@ func retryTimeDuration(retryFunc func() error, duration time.Duration) error {
|
|||
return nil
|
||||
}
|
||||
for _, e := range errwrap.GetAllType(err, &googleapi.Error{}) {
|
||||
if gerr, ok := e.(*googleapi.Error); ok && (gerr.Code == 429 || gerr.Code == 500 || gerr.Code == 502 || gerr.Code == 503) {
|
||||
return resource.RetryableError(gerr)
|
||||
if isRetryableError(e) {
|
||||
return resource.RetryableError(e)
|
||||
}
|
||||
}
|
||||
return resource.NonRetryableError(err)
|
||||
})
|
||||
}
|
||||
|
||||
func isRetryableError(err error) bool {
|
||||
if gerr, ok := err.(*googleapi.Error); ok && (gerr.Code == 429 || gerr.Code == 500 || gerr.Code == 502 || gerr.Code == 503) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func extractFirstMapConfig(m []interface{}) map[string]interface{} {
|
||||
if len(m) == 0 {
|
||||
return map[string]interface{}{}
|
||||
|
|
Loading…
Reference in New Issue
Block a user