forked from hashicorp/go-tfe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.go
253 lines (206 loc) · 6.78 KB
/
run.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
package tfe
import (
"errors"
"fmt"
"time"
)
// Runs handles communication with the run related methods of the Terraform
// Enterprise API.
//
// TFE API docs: https://www.terraform.io/docs/enterprise/api/run.html
type Runs struct {
client *Client
}
// RunStatus represents a run state.
type RunStatus string
//List all available run statuses.
const (
RunApplied RunStatus = "applied"
RunApplying RunStatus = "applying"
RunCanceled RunStatus = "canceled"
RunConfirmed RunStatus = "confirmed"
RunDiscarded RunStatus = "discarded"
RunErrored RunStatus = "errored"
RunPending RunStatus = "pending"
RunPlanned RunStatus = "planned"
RunPlanning RunStatus = "planning"
RunPolicyChecked RunStatus = "policy_checked"
RunPolicyChecking RunStatus = "policy_checking"
RunPolicyOverride RunStatus = "policy_override"
)
// RunSource represents a source type of a run.
type RunSource string
// List all available run sources.
const (
RunSourceAPI RunSource = "tfe-api"
RunSourceConfigurationVersion RunSource = "tfe-configuration-version"
RunSourceUI RunSource = "tfe-ui"
)
// Run represents a Terraform Enterprise run.
type Run struct {
ID string `jsonapi:"primary,runs"`
Actions *RunActions `jsonapi:"attr,actions"`
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
HasChanges bool `jsonapi:"attr,has-changes"`
IsDestroy bool `jsonapi:"attr,is-destroy"`
Message string `jsonapi:"attr,message"`
Permissions *RunPermissions `jsonapi:"attr,permissions"`
Source RunSource `jsonapi:"attr,source"`
Status RunStatus `jsonapi:"attr,status"`
StatusTimestamps *RunStatusTimestamps `jsonapi:"attr,status-timestamps"`
// Relations
ConfigurationVersion *ConfigurationVersion `jsonapi:"relation,configuration-version"`
Workspace *Workspace `jsonapi:"relation,workspace"`
}
// RunActions represents the run actions.
type RunActions struct {
IsCancelable bool `json:"is-cancelable"`
IsComfirmable bool `json:"is-comfirmable"`
IsDiscardable bool `json:"is-discardable"`
}
// RunPermissions represents the run permissions.
type RunPermissions struct {
CanApply bool `json:"can-apply"`
CanCancel bool `json:"can-cancel"`
CanDiscard bool `json:"can-discard"`
CanForceExecute bool `json:"can-force-execute"`
}
// RunStatusTimestamps holds the timestamps for individual run statuses.
type RunStatusTimestamps struct {
ErroredAt time.Time `json:"errored-at"`
FinishedAt time.Time `json:"finished-at"`
QueuedAt time.Time `json:"queued-at"`
StartedAt time.Time `json:"started-at"`
}
// RunListOptions represents the options for listing runs.
type RunListOptions struct {
ListOptions
}
// List runs of the given workspace.
func (s *Runs) List(workspaceID string, options RunListOptions) ([]*Run, error) {
if !validStringID(&workspaceID) {
return nil, errors.New("Invalid value for workspace ID")
}
u := fmt.Sprintf("workspaces/%s/runs", workspaceID)
req, err := s.client.newRequest("GET", u, &options)
if err != nil {
return nil, err
}
result, err := s.client.do(req, []*Run{})
if err != nil {
return nil, err
}
var rs []*Run
for _, r := range result.([]interface{}) {
rs = append(rs, r.(*Run))
}
return rs, nil
}
// RunCreateOptions represents the options for creating a new run.
type RunCreateOptions struct {
// For internal use only!
ID string `jsonapi:"primary,runs"`
// Specifies if this plan is a destroy plan, which will destroy all
// provisioned resources.
IsDestroy *bool `jsonapi:"attr,is-destroy,omitempty"`
// Specifies the message to be associated with this run.
Message *string `jsonapi:"attr,message,omitempty"`
// Specifies the configuration version to use for this run. If the
// configuration version object is omitted, the run will be created using the
// workspace's latest configuration version.
ConfigurationVersion *ConfigurationVersion `jsonapi:"relation,configuration-version"`
// Specifies the workspace where the run will be executed.
Workspace *Workspace `jsonapi:"relation,workspace"`
}
func (o RunCreateOptions) valid() error {
if o.Workspace == nil {
return errors.New("Workspace is required")
}
return nil
}
// Create is used to create a new run.
func (s *Runs) Create(options RunCreateOptions) (*Run, error) {
if err := options.valid(); err != nil {
return nil, err
}
// Make sure we don't send a user provided ID.
options.ID = ""
req, err := s.client.newRequest("POST", "runs", &options)
if err != nil {
return nil, err
}
r, err := s.client.do(req, &Run{})
if err != nil {
return nil, err
}
return r.(*Run), nil
}
// Retrieve a single run by its ID.
func (s *Runs) Retrieve(runID string) (*Run, error) {
if !validStringID(&runID) {
return nil, errors.New("Invalid value for run ID")
}
req, err := s.client.newRequest("GET", "runs/"+runID, nil)
if err != nil {
return nil, err
}
r, err := s.client.do(req, &Run{})
if err != nil {
return nil, err
}
return r.(*Run), nil
}
// RunApplyOptions represents the options for applying a run.
type RunApplyOptions struct {
// An optional comment about the run.
Comment *string `json:"comment,omitempty"`
}
// Apply a specific run by its ID.
func (s *Runs) Apply(runID string, options RunApplyOptions) error {
if !validStringID(&runID) {
return errors.New("Invalid value for run ID")
}
u := fmt.Sprintf("runs/%s/actions/apply", runID)
req, err := s.client.newRequest("POST", u, &options)
if err != nil {
return err
}
_, err = s.client.do(req, nil)
return err
}
// RunCancelOptions represents the options for canceling a run.
type RunCancelOptions struct {
// An optional explanation for why the run was canceled.
Comment *string `json:"comment,omitempty"`
}
// Cancel a specific run by its ID.
func (s *Runs) Cancel(runID string, options RunCancelOptions) error {
if !validStringID(&runID) {
return errors.New("Invalid value for run ID")
}
u := fmt.Sprintf("runs/%s/actions/cancel", runID)
req, err := s.client.newRequest("POST", u, &options)
if err != nil {
return err
}
_, err = s.client.do(req, nil)
return err
}
// RunDiscardOptions represents the options for discarding a run.
type RunDiscardOptions struct {
// An optional explanation for why the run was discarded.
Comment *string `json:"comment,omitempty"`
}
// Discard a specific run by its ID.
func (s *Runs) Discard(runID string, options RunDiscardOptions) error {
if !validStringID(&runID) {
return errors.New("Invalid value for run ID")
}
u := fmt.Sprintf("runs/%s/actions/discard", runID)
req, err := s.client.newRequest("POST", u, &options)
if err != nil {
return err
}
_, err = s.client.do(req, nil)
return err
}