forked from hashicorp/terraform-provider-google
-
Notifications
You must be signed in to change notification settings - Fork 0
/
container_operation.go
143 lines (118 loc) · 3.87 KB
/
container_operation.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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"
)
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 *ContainerBetaOperationWaiter) Conf() *resource.StateChangeConf {
return &resource.StateChangeConf{
Pending: []string{"PENDING", "RUNNING"},
Target: []string{"DONE"},
Refresh: w.RefreshFunc(),
}
}
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
}
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) {
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
}
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 {
if op.Status == "DONE" {
if op.StatusMessage != "" {
return fmt.Errorf(op.StatusMessage)
}
return nil
}
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.")
}
}