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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
|
|
||||||
"google.golang.org/api/appengine/v1"
|
"google.golang.org/api/appengine/v1"
|
||||||
)
|
)
|
||||||
|
@ -18,73 +13,30 @@ var (
|
||||||
|
|
||||||
type AppEngineOperationWaiter struct {
|
type AppEngineOperationWaiter struct {
|
||||||
Service *appengine.APIService
|
Service *appengine.APIService
|
||||||
Op *appengine.Operation
|
|
||||||
AppId string
|
AppId string
|
||||||
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *AppEngineOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *AppEngineOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return func() (interface{}, string, error) {
|
matches := appEngineOperationIdRegexp.FindStringSubmatch(w.Op.Name)
|
||||||
matches := appEngineOperationIdRegexp.FindStringSubmatch(w.Op.Name)
|
if len(matches) != 2 {
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
return w.Service.Apps.Operations.Get(w.AppId, matches[1]).Do()
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func appEngineOperationWait(client *appengine.APIService, op *appengine.Operation, appId, activity string) error {
|
func appEngineOperationWait(client *appengine.APIService, op *appengine.Operation, appId, activity string) error {
|
||||||
return appEngineOperationWaitTime(client, op, appId, activity, 4)
|
return appEngineOperationWaitTime(client, op, appId, activity, 4)
|
||||||
}
|
}
|
||||||
|
|
||||||
func appEngineOperationWaitTime(client *appengine.APIService, op *appengine.Operation, appId, activity string, timeoutMin int) error {
|
func appEngineOperationWaitTime(client *appengine.APIService, op *appengine.Operation, appId, activity string, timeoutMinutes int) error {
|
||||||
if op.Done {
|
|
||||||
if op.Error != nil {
|
|
||||||
return AppEngineOperationError(*op.Error)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
w := &AppEngineOperationWaiter{
|
w := &AppEngineOperationWaiter{
|
||||||
Service: client,
|
Service: client,
|
||||||
Op: op,
|
|
||||||
AppId: appId,
|
AppId: appId,
|
||||||
}
|
}
|
||||||
|
|
||||||
state := w.Conf()
|
if err := w.SetOp(op); err != nil {
|
||||||
state.Delay = 10 * time.Second
|
return err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
resultOp := opRaw.(*appengine.Operation)
|
|
||||||
if resultOp.Error != nil {
|
|
||||||
return AppEngineOperationError(*resultOp.Error)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +1,24 @@
|
||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/cloudfunctions/v1"
|
"google.golang.org/api/cloudfunctions/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CloudFunctionsOperationWaiter struct {
|
type CloudFunctionsOperationWaiter struct {
|
||||||
Service *cloudfunctions.Service
|
Service *cloudfunctions.Service
|
||||||
Op *cloudfunctions.Operation
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *CloudFunctionsOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *CloudFunctionsOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return func() (interface{}, string, error) {
|
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||||
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 {
|
func cloudFunctionsOperationWait(service *cloudfunctions.Service, op *cloudfunctions.Operation, activity string) error {
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
w := &CloudFunctionsOperationWaiter{
|
w := &CloudFunctionsOperationWaiter{
|
||||||
Service: client,
|
Service: service,
|
||||||
Op: op,
|
|
||||||
}
|
}
|
||||||
|
if err := w.SetOp(op); err != nil {
|
||||||
state := w.Conf()
|
return err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, 4)
|
||||||
resultOp := opRaw.(*cloudfunctions.Operation)
|
|
||||||
if resultOp.Error != nil {
|
|
||||||
return fmt.Errorf(resultOp.Error.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
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
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
composer "google.golang.org/api/composer/v1beta1"
|
composer "google.golang.org/api/composer/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ComposerOperationWaiter struct {
|
type ComposerOperationWaiter struct {
|
||||||
Service *composer.ProjectsLocationsService
|
Service *composer.ProjectsLocationsService
|
||||||
Op *composer.Operation
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ComposerOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *ComposerOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return func() (interface{}, string, error) {
|
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||||
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 {
|
func composerOperationWaitTime(service *composer.Service, op *composer.Operation, project, activity string, timeoutMinutes int) error {
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
w := &ComposerOperationWaiter{
|
w := &ComposerOperationWaiter{
|
||||||
Service: service.Projects.Locations,
|
Service: service.Projects.Locations,
|
||||||
Op: op,
|
|
||||||
}
|
}
|
||||||
|
if err := w.SetOp(op); err != nil {
|
||||||
state := w.Conf()
|
return err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
op = opRaw.(*composer.Operation)
|
|
||||||
if op.Error != nil {
|
|
||||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,6 @@ package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
|
|
||||||
computeBeta "google.golang.org/api/compute/v0.beta"
|
computeBeta "google.golang.org/api/compute/v0.beta"
|
||||||
"google.golang.org/api/compute/v1"
|
"google.golang.org/api/compute/v1"
|
||||||
|
@ -18,35 +13,70 @@ type ComputeOperationWaiter struct {
|
||||||
Project string
|
Project string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ComputeOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *ComputeOperationWaiter) State() string {
|
||||||
return func() (interface{}, string, error) {
|
return w.Op.Status
|
||||||
var op *compute.Operation
|
|
||||||
var err error
|
|
||||||
|
|
||||||
if w.Op.Zone != "" {
|
|
||||||
zone := GetResourceNameFromSelfLink(w.Op.Zone)
|
|
||||||
op, err = 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()
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", 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 {
|
func (w *ComputeOperationWaiter) Error() error {
|
||||||
return &resource.StateChangeConf{
|
if w.Op.Error != nil {
|
||||||
Pending: []string{"PENDING", "RUNNING"},
|
return ComputeOperationError(*w.Op.Error)
|
||||||
Target: []string{"DONE"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
}
|
||||||
|
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)
|
||||||
|
return w.Service.ZoneOperations.Get(w.Project, zone, w.Op.Name).Do()
|
||||||
|
} else if w.Op.Region != "" {
|
||||||
|
region := GetResourceNameFromSelfLink(w.Op.Region)
|
||||||
|
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 err
|
||||||
|
}
|
||||||
|
|
||||||
|
return computeOperationWaitTime(client, opV1, project, activity, timeoutMin)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComputeOperationError wraps compute.OperationError and implements the
|
// ComputeOperationError wraps compute.OperationError and implements the
|
||||||
|
@ -61,48 +91,3 @@ func (e ComputeOperationError) Error() string {
|
||||||
|
|
||||||
return buf.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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"google.golang.org/api/container/v1beta1"
|
||||||
"google.golang.org/api/container/v1"
|
|
||||||
containerBeta "google.golang.org/api/container/v1beta1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ContainerOperationWaiter struct {
|
type ContainerOperationWaiter struct {
|
||||||
Service *container.Service
|
Service *container.Service
|
||||||
Op *container.Operation
|
Op *container.Operation
|
||||||
Project string
|
|
||||||
Zone string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ContainerBetaOperationWaiter struct {
|
|
||||||
Service *containerBeta.Service
|
|
||||||
Op *containerBeta.Operation
|
|
||||||
Project string
|
Project string
|
||||||
Location string
|
Location string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ContainerOperationWaiter) Conf() *resource.StateChangeConf {
|
func (w *ContainerOperationWaiter) State() string {
|
||||||
return &resource.StateChangeConf{
|
return w.Op.Status
|
||||||
Pending: []string{"PENDING", "RUNNING"},
|
|
||||||
Target: []string{"DONE"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ContainerBetaOperationWaiter) Conf() *resource.StateChangeConf {
|
func (w *ContainerOperationWaiter) Error() error {
|
||||||
return &resource.StateChangeConf{
|
if w.Op.StatusMessage != "" {
|
||||||
Pending: []string{"PENDING", "RUNNING"},
|
return fmt.Errorf(w.Op.StatusMessage)
|
||||||
Target: []string{"DONE"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ContainerOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *ContainerOperationWaiter) SetOp(op interface{}) error {
|
||||||
return func() (interface{}, string, error) {
|
w.Op = op.(*container.Operation)
|
||||||
resp, err := w.Service.Projects.Zones.Operations.Get(
|
return nil
|
||||||
w.Project, w.Zone, w.Op.Name).Do()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
func (w *ContainerOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return func() (interface{}, string, error) {
|
name := fmt.Sprintf("projects/%s/locations/%s/operations/%s",
|
||||||
name := fmt.Sprintf("projects/%s/locations/%s/operations/%s",
|
w.Project, w.Location, w.Op.Name)
|
||||||
w.Project, w.Location, w.Op.Name)
|
return w.Service.Projects.Locations.Operations.Get(name).Do()
|
||||||
resp, err := w.Service.Projects.Locations.Operations.Get(name).Do()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
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 containerOperationWait(config *Config, op *container.Operation, project, zone, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
func (w *ContainerOperationWaiter) OpName() string {
|
||||||
if op.Status == "DONE" {
|
return w.Op.Name
|
||||||
if op.StatusMessage != "" {
|
}
|
||||||
return fmt.Errorf(op.StatusMessage)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
func (w *ContainerOperationWaiter) PendingStates() []string {
|
||||||
|
return []string{"PENDING", "RUNNING"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *ContainerOperationWaiter) TargetStates() []string {
|
||||||
|
return []string{"DONE"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func containerOperationWait(config *Config, op *container.Operation, project, location, activity string, timeoutMinutes int) error {
|
||||||
w := &ContainerOperationWaiter{
|
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,
|
Service: config.clientContainerBeta,
|
||||||
Op: op,
|
Op: op,
|
||||||
Project: project,
|
Project: project,
|
||||||
Location: location,
|
Location: location,
|
||||||
}
|
}
|
||||||
|
|
||||||
state := w.Conf()
|
if err := w.SetOp(op); err != nil {
|
||||||
return waitForState(state, activity, timeoutMinutes, minTimeoutSeconds)
|
return err
|
||||||
}
|
|
||||||
|
|
||||||
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.")
|
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +1,24 @@
|
||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/dataproc/v1"
|
"google.golang.org/api/dataproc/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DataprocClusterOperationWaiter struct {
|
type DataprocClusterOperationWaiter struct {
|
||||||
Service *dataproc.Service
|
Service *dataproc.Service
|
||||||
Op *dataproc.Operation
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *DataprocClusterOperationWaiter) Conf() *resource.StateChangeConf {
|
func (w *DataprocClusterOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return &resource.StateChangeConf{
|
return w.Service.Projects.Regions.Operations.Get(w.Op.Name).Do()
|
||||||
Pending: []string{"false"},
|
|
||||||
Target: []string{"true"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *DataprocClusterOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func dataprocClusterOperationWait(config *Config, op *dataproc.Operation, activity string, timeoutMinutes int) error {
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
w := &DataprocClusterOperationWaiter{
|
w := &DataprocClusterOperationWaiter{
|
||||||
Service: config.clientDataproc,
|
Service: config.clientDataproc,
|
||||||
Op: op,
|
|
||||||
}
|
}
|
||||||
|
if err := w.SetOp(op); err != nil {
|
||||||
state := w.Conf()
|
return err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
op = opRaw.(*dataproc.Operation)
|
|
||||||
if op.Error != nil {
|
|
||||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/dataproc/v1"
|
"google.golang.org/api/dataproc/v1"
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DataprocJobOperationWaiter struct {
|
type DataprocJobOperationWaiter struct {
|
||||||
|
@ -16,80 +11,46 @@ type DataprocJobOperationWaiter struct {
|
||||||
Region string
|
Region string
|
||||||
ProjectId string
|
ProjectId string
|
||||||
JobId string
|
JobId string
|
||||||
|
Status string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *DataprocJobOperationWaiter) ConfForDelete() *resource.StateChangeConf {
|
func (w *DataprocJobOperationWaiter) State() string {
|
||||||
return &resource.StateChangeConf{
|
return w.Status
|
||||||
Pending: []string{"EXISTS"},
|
|
||||||
Target: []string{"DELETED"},
|
|
||||||
Refresh: w.RefreshFuncForDelete(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *DataprocJobOperationWaiter) Conf() *resource.StateChangeConf {
|
func (w *DataprocJobOperationWaiter) Error() error {
|
||||||
// For more info on each of the states please see
|
// The "operation" is just the job, which has no special error field that we
|
||||||
// https://cloud.google.com/dataproc/docs/reference/rest/v1/projects.regions.jobs#JobStatus
|
// want to expose.
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
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 {
|
func dataprocJobOperationWait(config *Config, region, projectId, jobId string, activity string, timeoutMinutes, minTimeoutSeconds int) error {
|
||||||
w := &DataprocJobOperationWaiter{
|
w := &DataprocJobOperationWaiter{
|
||||||
Service: config.clientDataproc,
|
Service: config.clientDataproc,
|
||||||
|
@ -97,14 +58,42 @@ func dataprocJobOperationWait(config *Config, region, projectId, jobId string, a
|
||||||
ProjectId: projectId,
|
ProjectId: projectId,
|
||||||
JobId: jobId,
|
JobId: jobId,
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
state := w.Conf()
|
}
|
||||||
state.Timeout = time.Duration(timeoutMinutes) * time.Minute
|
|
||||||
state.MinTimeout = time.Duration(minTimeoutSeconds) * time.Second
|
type DataprocDeleteJobOperationWaiter struct {
|
||||||
_, err := state.WaitForState()
|
DataprocJobOperationWaiter
|
||||||
if err != nil {
|
}
|
||||||
return fmt.Errorf("Error waiting for operation %s: %s", activity, err)
|
|
||||||
}
|
func (w *DataprocDeleteJobOperationWaiter) PendingStates() []string {
|
||||||
|
return []string{"EXISTS", "ERROR"}
|
||||||
return nil
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if isGoogleApiErrorWithCode(err, http.StatusNotFound) {
|
||||||
|
w.Status = "DELETED"
|
||||||
|
return job, nil
|
||||||
|
}
|
||||||
|
w.Status = "ERROR"
|
||||||
|
}
|
||||||
|
w.Status = "EXISTS"
|
||||||
|
return job, err
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
func (w *DnsChangeWaiter) Conf() *resource.StateChangeConf {
|
||||||
state := &resource.StateChangeConf{
|
return &resource.StateChangeConf{
|
||||||
Pending: []string{"pending"},
|
Pending: []string{"pending"},
|
||||||
Target: []string{"done"},
|
Target: []string{"done"},
|
||||||
Refresh: w.RefreshFunc(),
|
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
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/redis/v1beta1"
|
"google.golang.org/api/redis/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RedisOperationWaiter struct {
|
type RedisOperationWaiter struct {
|
||||||
Service *redis.ProjectsLocationsService
|
Service *redis.ProjectsLocationsService
|
||||||
Op *redis.Operation
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *RedisOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *RedisOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return func() (interface{}, string, error) {
|
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||||
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 {
|
func redisOperationWaitTime(service *redis.Service, op *redis.Operation, project, activity string, timeoutMinutes int) error {
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
w := &RedisOperationWaiter{
|
w := &RedisOperationWaiter{
|
||||||
Service: service.Projects.Locations,
|
Service: service.Projects.Locations,
|
||||||
Op: op,
|
|
||||||
}
|
}
|
||||||
|
if err := w.SetOp(op); err != nil {
|
||||||
state := w.Conf()
|
return err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
op = opRaw.(*redis.Operation)
|
|
||||||
if op.Error != nil {
|
|
||||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -715,7 +715,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
|
||||||
defer mutexKV.Unlock(containerClusterMutexKey(project, location, clusterName))
|
defer mutexKV.Unlock(containerClusterMutexKey(project, location, clusterName))
|
||||||
|
|
||||||
parent := fmt.Sprintf("projects/%s/locations/%s", project, location)
|
parent := fmt.Sprintf("projects/%s/locations/%s", project, location)
|
||||||
var op interface{}
|
var op *containerBeta.Operation
|
||||||
err = retry(func() error {
|
err = retry(func() error {
|
||||||
op, err = config.clientContainerBeta.Projects.Locations.Clusters.Create(parent, req).Do()
|
op, err = config.clientContainerBeta.Projects.Locations.Clusters.Create(parent, req).Do()
|
||||||
return err
|
return err
|
||||||
|
@ -728,7 +728,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
|
||||||
|
|
||||||
// Wait until it's created
|
// Wait until it's created
|
||||||
timeoutInMinutes := int(d.Timeout(schema.TimeoutCreate).Minutes())
|
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 {
|
if waitErr != nil {
|
||||||
// The resource didn't actually create
|
// The resource didn't actually create
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
|
@ -743,7 +743,7 @@ func resourceContainerClusterCreate(d *schema.ResourceData, meta interface{}) er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errwrap.Wrapf("Error deleting default node pool: {{err}}", err)
|
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 {
|
if err != nil {
|
||||||
return errwrap.Wrapf("Error deleting default node pool: {{err}}", err)
|
return errwrap.Wrapf("Error deleting default node pool: {{err}}", err)
|
||||||
}
|
}
|
||||||
|
@ -878,7 +878,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Wait until it's updated
|
// 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
|
// 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.
|
// Call update serially.
|
||||||
|
@ -1071,7 +1071,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// 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")
|
log.Println("[DEBUG] done updating enable_legacy_abac")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1120,7 +1120,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// 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.
|
// Call update serially.
|
||||||
|
@ -1148,7 +1148,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// 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")
|
log.Println("[DEBUG] done updating network_policy")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1195,7 +1195,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// 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.
|
// Call update serially.
|
||||||
|
@ -1232,7 +1232,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// 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.
|
// Call update serially.
|
||||||
|
@ -1257,7 +1257,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// 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.
|
// Call update serially.
|
||||||
|
@ -1274,7 +1274,7 @@ func resourceContainerClusterUpdate(d *schema.ResourceData, meta interface{}) er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errwrap.Wrapf("Error deleting default node pool: {{err}}", err)
|
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 {
|
if err != nil {
|
||||||
return errwrap.Wrapf("Error deleting default node pool: {{err}}", err)
|
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))
|
mutexKV.Lock(containerClusterMutexKey(project, location, clusterName))
|
||||||
defer mutexKV.Unlock(containerClusterMutexKey(project, location, clusterName))
|
defer mutexKV.Unlock(containerClusterMutexKey(project, location, clusterName))
|
||||||
|
|
||||||
var op interface{}
|
var op *containerBeta.Operation
|
||||||
var count = 0
|
var count = 0
|
||||||
err = resource.Retry(30*time.Second, func() *resource.RetryError {
|
err = resource.Retry(30*time.Second, func() *resource.RetryError {
|
||||||
count++
|
count++
|
||||||
|
@ -1336,7 +1336,7 @@ func resourceContainerClusterDelete(d *schema.ResourceData, meta interface{}) er
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's deleted
|
// 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 {
|
if waitErr != nil {
|
||||||
return waitErr
|
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))
|
d.SetId(fmt.Sprintf("%s/%s/%s", nodePoolInfo.location, nodePoolInfo.cluster, nodePool.Name))
|
||||||
|
|
||||||
waitErr := containerBetaOperationWait(config,
|
waitErr := containerOperationWait(config,
|
||||||
operation, nodePoolInfo.project,
|
operation, nodePoolInfo.project,
|
||||||
nodePoolInfo.location, "creating GKE NodePool", int(timeout.Minutes()), 3)
|
nodePoolInfo.location, "creating GKE NodePool", int(timeout.Minutes()))
|
||||||
|
|
||||||
if waitErr != nil {
|
if waitErr != nil {
|
||||||
// The resource didn't actually create
|
// The resource didn't actually create
|
||||||
|
@ -369,7 +369,7 @@ func resourceContainerNodePoolDelete(d *schema.ResourceData, meta interface{}) e
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's deleted
|
// 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 {
|
if waitErr != nil {
|
||||||
return waitErr
|
return waitErr
|
||||||
}
|
}
|
||||||
|
@ -571,10 +571,10 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// Wait until it's updated
|
||||||
return containerBetaOperationWait(config, op,
|
return containerOperationWait(config, op,
|
||||||
nodePoolInfo.project,
|
nodePoolInfo.project,
|
||||||
nodePoolInfo.location, "updating GKE node pool",
|
nodePoolInfo.location, "updating GKE node pool",
|
||||||
timeoutInMinutes, 2)
|
timeoutInMinutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call update serially.
|
// Call update serially.
|
||||||
|
@ -605,10 +605,10 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// Wait until it's updated
|
||||||
return containerBetaOperationWait(config, op,
|
return containerOperationWait(config, op,
|
||||||
nodePoolInfo.project,
|
nodePoolInfo.project,
|
||||||
nodePoolInfo.location, "updating GKE node pool",
|
nodePoolInfo.location, "updating GKE node pool",
|
||||||
timeoutInMinutes, 2)
|
timeoutInMinutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call update serially.
|
// Call update serially.
|
||||||
|
@ -637,10 +637,10 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// Wait until it's updated
|
||||||
return containerBetaOperationWait(config, op,
|
return containerOperationWait(config, op,
|
||||||
nodePoolInfo.project,
|
nodePoolInfo.project,
|
||||||
nodePoolInfo.location, "updating GKE node pool size",
|
nodePoolInfo.location, "updating GKE node pool size",
|
||||||
timeoutInMinutes, 2)
|
timeoutInMinutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call update serially.
|
// Call update serially.
|
||||||
|
@ -676,9 +676,9 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// Wait until it's updated
|
||||||
return containerBetaOperationWait(config, op,
|
return containerOperationWait(config, op,
|
||||||
nodePoolInfo.project,
|
nodePoolInfo.project,
|
||||||
nodePoolInfo.location, "updating GKE node pool management", timeoutInMinutes, 2)
|
nodePoolInfo.location, "updating GKE node pool management", timeoutInMinutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call update serially.
|
// Call update serially.
|
||||||
|
@ -707,9 +707,9 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's updated
|
// Wait until it's updated
|
||||||
return containerBetaOperationWait(config, op,
|
return containerOperationWait(config, op,
|
||||||
nodePoolInfo.project,
|
nodePoolInfo.project,
|
||||||
nodePoolInfo.location, "updating GKE node pool version", timeoutInMinutes, 2)
|
nodePoolInfo.location, "updating GKE node pool version", timeoutInMinutes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call update serially.
|
// Call update serially.
|
||||||
|
|
|
@ -456,7 +456,7 @@ func resourceDataprocClusterCreate(d *schema.ResourceData, meta interface{}) err
|
||||||
|
|
||||||
// Wait until it's created
|
// Wait until it's created
|
||||||
timeoutInMinutes := int(d.Timeout(schema.TimeoutCreate).Minutes())
|
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 {
|
if waitErr != nil {
|
||||||
// The resource didn't actually create
|
// The resource didn't actually create
|
||||||
// Note that we do not remove the ID here - this resource tends to leave
|
// 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
|
// 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 {
|
if waitErr != nil {
|
||||||
return waitErr
|
return waitErr
|
||||||
}
|
}
|
||||||
|
@ -944,7 +944,7 @@ func resourceDataprocClusterDelete(d *schema.ResourceData, meta interface{}) err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until it's deleted
|
// 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 {
|
if waitErr != nil {
|
||||||
return waitErr
|
return waitErr
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,7 +280,7 @@ func enableServices(s []string, pid string, config *Config) error {
|
||||||
|
|
||||||
// Poll for the API to return
|
// Poll for the API to return
|
||||||
activity := fmt.Sprintf("apis %q to be enabled for %s", services, pid)
|
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 {
|
if waitErr != nil {
|
||||||
return waitErr
|
return waitErr
|
||||||
}
|
}
|
||||||
|
@ -342,7 +342,7 @@ func disableService(s, pid string, config *Config) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Wait for the operation to complete
|
// Wait for the operation to complete
|
||||||
_, waitErr := serviceUsageOperationWait(config, sop, "api to disable")
|
waitErr := serviceUsageOperationWait(config, sop, "api to disable")
|
||||||
if waitErr != nil {
|
if waitErr != nil {
|
||||||
return waitErr
|
return waitErr
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,76 +1,33 @@
|
||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/cloudresourcemanager/v1"
|
"google.golang.org/api/cloudresourcemanager/v1"
|
||||||
resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
|
resourceManagerV2Beta1 "google.golang.org/api/cloudresourcemanager/v2beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResourceManagerOperationWaiter struct {
|
type ResourceManagerOperationWaiter struct {
|
||||||
Service *cloudresourcemanager.Service
|
Service *cloudresourcemanager.Service
|
||||||
Op *cloudresourcemanager.Operation
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ResourceManagerOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *ResourceManagerOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return func() (interface{}, string, error) {
|
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||||
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 *ResourceManagerOperationWaiter) Conf() *resource.StateChangeConf {
|
func resourceManagerOperationWaitTime(service *cloudresourcemanager.Service, op *cloudresourcemanager.Operation, activity string, timeoutMin int) error {
|
||||||
return &resource.StateChangeConf{
|
w := &ResourceManagerOperationWaiter{
|
||||||
Pending: []string{"false"},
|
Service: service,
|
||||||
Target: []string{"true"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
}
|
||||||
|
if err := w.SetOp(op); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMin)
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceManagerOperationWait(service *cloudresourcemanager.Service, op *cloudresourcemanager.Operation, activity string) error {
|
func resourceManagerOperationWait(service *cloudresourcemanager.Service, op *cloudresourcemanager.Operation, activity string) error {
|
||||||
return resourceManagerOperationWaitTime(service, op, activity, 4)
|
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 {
|
func resourceManagerV2Beta1OperationWait(service *cloudresourcemanager.Service, op *resourceManagerV2Beta1.Operation, activity string) error {
|
||||||
return resourceManagerV2Beta1OperationWaitTime(service, op, activity, 4)
|
return resourceManagerV2Beta1OperationWaitTime(service, op, activity, 4)
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,26 +33,21 @@ func (w *ServiceAccountKeyWaiter) RefreshFunc() resource.StateRefreshFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ServiceAccountKeyWaiter) Conf() *resource.StateChangeConf {
|
func serviceAccountKeyWaitTime(client *iam.ProjectsServiceAccountsKeysService, keyName, publicKeyType, activity string, timeoutMinutes int) error {
|
||||||
return &resource.StateChangeConf{
|
|
||||||
Pending: []string{"PENDING"},
|
|
||||||
Target: []string{"DONE"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func serviceAccountKeyWaitTime(client *iam.ProjectsServiceAccountsKeysService, keyName, publicKeyType, activity string, timeoutMin int) error {
|
|
||||||
w := &ServiceAccountKeyWaiter{
|
w := &ServiceAccountKeyWaiter{
|
||||||
Service: client,
|
Service: client,
|
||||||
PublicKeyType: publicKeyType,
|
PublicKeyType: publicKeyType,
|
||||||
KeyName: keyName,
|
KeyName: keyName,
|
||||||
}
|
}
|
||||||
|
|
||||||
state := w.Conf()
|
c := &resource.StateChangeConf{
|
||||||
state.Delay = 10 * time.Second
|
Pending: []string{"PENDING"},
|
||||||
state.Timeout = time.Duration(timeoutMin) * time.Minute
|
Target: []string{"DONE"},
|
||||||
state.MinTimeout = 2 * time.Second
|
Refresh: w.RefreshFunc(),
|
||||||
_, err := state.WaitForState()
|
Timeout: time.Duration(timeoutMinutes) * time.Minute,
|
||||||
|
MinTimeout: 2 * time.Second,
|
||||||
|
}
|
||||||
|
_, err := c.WaitForState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
return fmt.Errorf("Error waiting for %s: %s", activity, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,75 +1,34 @@
|
||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/googleapi"
|
"google.golang.org/api/googleapi"
|
||||||
"google.golang.org/api/servicemanagement/v1"
|
"google.golang.org/api/servicemanagement/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ServiceManagementOperationWaiter struct {
|
type ServiceManagementOperationWaiter struct {
|
||||||
Service *servicemanagement.APIService
|
Service *servicemanagement.APIService
|
||||||
Op *servicemanagement.Operation
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ServiceManagementOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *ServiceManagementOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return func() (interface{}, string, error) {
|
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||||
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 serviceManagementOperationWait(config *Config, op *servicemanagement.Operation, activity string) (googleapi.RawMessage, error) {
|
func serviceManagementOperationWait(config *Config, op *servicemanagement.Operation, activity string) (googleapi.RawMessage, error) {
|
||||||
return serviceManagementOperationWaitTime(config, op, activity, 10)
|
return serviceManagementOperationWaitTime(config, op, activity, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
func serviceManagementOperationWaitTime(config *Config, op *servicemanagement.Operation, activity string, timeoutMin int) (googleapi.RawMessage, error) {
|
func serviceManagementOperationWaitTime(config *Config, op *servicemanagement.Operation, activity string, timeoutMinutes 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 := &ServiceManagementOperationWaiter{
|
w := &ServiceManagementOperationWaiter{
|
||||||
Service: config.clientServiceMan,
|
Service: config.clientServiceMan,
|
||||||
Op: op,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state := w.Conf()
|
if err := w.SetOp(op); err != nil {
|
||||||
state.Delay = 10 * time.Second
|
return nil, err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op = opRaw.(*servicemanagement.Operation)
|
if err := OperationWait(w, activity, timeoutMinutes); err != nil {
|
||||||
if op.Error != nil {
|
return nil, err
|
||||||
return nil, fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
|
||||||
}
|
}
|
||||||
|
return w.Op.Response, nil
|
||||||
return op.Response, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,75 +1,28 @@
|
||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
"google.golang.org/api/serviceusage/v1beta1"
|
"google.golang.org/api/serviceusage/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type serviceUsageOperationWaiter struct {
|
type ServiceUsageOperationWaiter struct {
|
||||||
Service *serviceusage.APIService
|
Service *serviceusage.APIService
|
||||||
Op *serviceusage.Operation
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *serviceUsageOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *ServiceUsageOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return func() (interface{}, string, error) {
|
return w.Service.Operations.Get(w.Op.Name).Do()
|
||||||
var op *serviceusage.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 *serviceUsageOperationWaiter) Conf() *resource.StateChangeConf {
|
func serviceUsageOperationWait(config *Config, op *serviceusage.Operation, activity string) error {
|
||||||
return &resource.StateChangeConf{
|
|
||||||
Pending: []string{"false"},
|
|
||||||
Target: []string{"true"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func serviceUsageOperationWait(config *Config, op *serviceusage.Operation, activity string) (googleapi.RawMessage, error) {
|
|
||||||
return serviceUsageOperationWaitTime(config, op, activity, 10)
|
return serviceUsageOperationWaitTime(config, op, activity, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
func serviceUsageOperationWaitTime(config *Config, op *serviceusage.Operation, activity string, timeoutMin int) (googleapi.RawMessage, error) {
|
func serviceUsageOperationWaitTime(config *Config, op *serviceusage.Operation, activity string, timeoutMinutes int) error {
|
||||||
if op.Done {
|
w := &ServiceUsageOperationWaiter{
|
||||||
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{
|
|
||||||
Service: config.clientServiceUsage,
|
Service: config.clientServiceUsage,
|
||||||
Op: op,
|
|
||||||
}
|
}
|
||||||
|
if err := w.SetOp(op); err != nil {
|
||||||
state := w.Conf()
|
return err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,69 +1,25 @@
|
||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/spanner/v1"
|
"google.golang.org/api/spanner/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SpannerDatabaseOperationWaiter struct {
|
type SpannerDatabaseOperationWaiter struct {
|
||||||
Service *spanner.Service
|
Service *spanner.Service
|
||||||
Op *spanner.Operation
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SpannerDatabaseOperationWaiter) Conf() *resource.StateChangeConf {
|
func (w *SpannerDatabaseOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return &resource.StateChangeConf{
|
return w.Service.Projects.Instances.Databases.Operations.Get(w.Op.Name).Do()
|
||||||
Pending: []string{"false"},
|
|
||||||
Target: []string{"true"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SpannerDatabaseOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func spannerDatabaseOperationWait(config *Config, op *spanner.Operation, activity string, timeoutMinutes int) error {
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
w := &SpannerDatabaseOperationWaiter{
|
w := &SpannerDatabaseOperationWaiter{
|
||||||
Service: config.clientSpanner,
|
Service: config.clientSpanner,
|
||||||
Op: op,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
state := w.Conf()
|
if err := w.SetOp(op); err != nil {
|
||||||
state.Delay = 10 * time.Second
|
return err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
op = opRaw.(*spanner.Operation)
|
|
||||||
if op.Error != nil {
|
|
||||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,69 +1,24 @@
|
||||||
package google
|
package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/spanner/v1"
|
"google.golang.org/api/spanner/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SpannerInstanceOperationWaiter struct {
|
type SpannerInstanceOperationWaiter struct {
|
||||||
Service *spanner.Service
|
Service *spanner.Service
|
||||||
Op *spanner.Operation
|
CommonOperationWaiter
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SpannerInstanceOperationWaiter) Conf() *resource.StateChangeConf {
|
func (w *SpannerInstanceOperationWaiter) QueryOp() (interface{}, error) {
|
||||||
return &resource.StateChangeConf{
|
return w.Service.Projects.Instances.Operations.Get(w.Op.Name).Do()
|
||||||
Pending: []string{"false"},
|
|
||||||
Target: []string{"true"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SpannerInstanceOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func spannerInstanceOperationWait(config *Config, op *spanner.Operation, activity string, timeoutMinutes int) error {
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
w := &SpannerInstanceOperationWaiter{
|
w := &SpannerInstanceOperationWaiter{
|
||||||
Service: config.clientSpanner,
|
Service: config.clientSpanner,
|
||||||
Op: op,
|
|
||||||
}
|
}
|
||||||
|
if err := w.SetOp(op); err != nil {
|
||||||
state := w.Conf()
|
return err
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
return OperationWait(w, activity, timeoutMinutes)
|
||||||
op = opRaw.(*spanner.Operation)
|
|
||||||
if op.Error != nil {
|
|
||||||
return fmt.Errorf("Error code %v, message: %s", op.Error.Code, op.Error.Message)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,7 @@ package google
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
|
||||||
"google.golang.org/api/googleapi"
|
|
||||||
"google.golang.org/api/sqladmin/v1beta4"
|
"google.golang.org/api/sqladmin/v1beta4"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -17,29 +12,52 @@ type SqlAdminOperationWaiter struct {
|
||||||
Project string
|
Project string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SqlAdminOperationWaiter) RefreshFunc() resource.StateRefreshFunc {
|
func (w *SqlAdminOperationWaiter) State() string {
|
||||||
return func() (interface{}, string, error) {
|
return w.Op.Status
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[DEBUG] Got %q when asking for operation %q", op.Status, w.Op.Name)
|
|
||||||
|
|
||||||
return op, op.Status, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *SqlAdminOperationWaiter) Conf() *resource.StateChangeConf {
|
func (w *SqlAdminOperationWaiter) Error() error {
|
||||||
return &resource.StateChangeConf{
|
if w.Op.Error != nil {
|
||||||
Pending: []string{"PENDING", "RUNNING"},
|
return SqlAdminOperationError(*w.Op.Error)
|
||||||
Target: []string{"DONE"},
|
|
||||||
Refresh: w.RefreshFunc(),
|
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
// SqlAdminOperationError wraps sqladmin.OperationError and implements the
|
||||||
|
@ -55,38 +73,3 @@ func (e SqlAdminOperationError) Error() string {
|
||||||
|
|
||||||
return buf.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
|
return nil
|
||||||
}
|
}
|
||||||
for _, e := range errwrap.GetAllType(err, &googleapi.Error{}) {
|
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) {
|
if isRetryableError(e) {
|
||||||
return resource.RetryableError(gerr)
|
return resource.RetryableError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resource.NonRetryableError(err)
|
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{} {
|
func extractFirstMapConfig(m []interface{}) map[string]interface{} {
|
||||||
if len(m) == 0 {
|
if len(m) == 0 {
|
||||||
return map[string]interface{}{}
|
return map[string]interface{}{}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user