Skip to content

Commit a302b4d

Browse files
committed
QueryRuns basic interface
1 parent 4318b5e commit a302b4d

File tree

4 files changed

+538
-0
lines changed

4 files changed

+538
-0
lines changed

errors.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,8 @@ var (
392392

393393
ErrInvalidTestRunID = errors.New("invalid value for test run id")
394394

395+
ErrInvalidQueryRunID = errors.New("invalid value for query run id")
396+
395397
ErrTerraformVersionValidForPlanOnly = errors.New("setting terraform-version is only valid when plan-only is set to true")
396398

397399
ErrStateMustBeOmitted = errors.New("when uploading state, the State and JSONState strings must be omitted from options")

query_runs.go

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
package tfe
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/url"
7+
"time"
8+
)
9+
10+
// Compile-time proof of interface implementation.
11+
var _ QueryRuns = (*queryRuns)(nil)
12+
13+
// QueryRuns describes all the run related methods that the Terraform Enterprise
14+
// API supports.
15+
//
16+
// NOTE WELL: This is a beta feature and is subject to change until noted otherwise in the
17+
// release notes.
18+
type QueryRuns interface {
19+
// List all the query runs of the given workspace.
20+
List(ctx context.Context, workspaceID string, options *QueryRunListOptions) (*QueryRunList, error)
21+
22+
// Create a new query run with the given options.
23+
Create(ctx context.Context, options QueryRunCreateOptions) (*QueryRun, error)
24+
25+
// Read a query run by its ID.
26+
Read(ctx context.Context, queryRunID string) (*QueryRun, error)
27+
28+
// ReadWithOptions reads a query run by its ID using the options supplied
29+
ReadWithOptions(ctx context.Context, queryRunID string, options *QueryRunReadOptions) (*QueryRun, error)
30+
31+
// Cancel a query run by its ID.
32+
Cancel(ctx context.Context, runID string) error
33+
34+
// Force-cancel a query run by its ID.
35+
ForceCancel(ctx context.Context, runID string) error
36+
}
37+
38+
// QueryRunCreateOptions represents the options for creating a new run.
39+
type QueryRunCreateOptions struct {
40+
// Type is a public field utilized by JSON:API to
41+
// set the resource type via the field tag.
42+
// It is not a user-defined value and does not need to be set.
43+
// https://jsonapi.org/format/#crud-creating
44+
Type string `jsonapi:"primary,queries"`
45+
46+
// TerraformVersion specifies the Terraform version to use in this run.
47+
// Only valid for plan-only runs; must be a valid Terraform version available to the organization.
48+
TerraformVersion *string `jsonapi:"attr,terraform-version,omitempty"`
49+
50+
Source QueryRunSource `jsonapi:"attr,source"`
51+
52+
// Specifies the configuration version to use for this run. If the
53+
// configuration version object is omitted, the run will be created using the
54+
// workspace's latest configuration version.
55+
ConfigurationVersion *ConfigurationVersion `jsonapi:"relation,configuration-version"`
56+
57+
// Specifies the workspace where the run will be executed.
58+
Workspace *Workspace `jsonapi:"relation,workspace"`
59+
60+
// Variables allows you to specify terraform input variables for
61+
// a particular run, prioritized over variables defined on the workspace.
62+
Variables []*RunVariable `jsonapi:"attr,variables,omitempty"`
63+
}
64+
65+
// QueryRunStatusTimestamps holds the timestamps for individual run statuses.
66+
type QueryRunStatusTimestamps struct {
67+
CanceledAt time.Time `jsonapi:"attr,canceled-at,rfc3339"`
68+
ErroredAt time.Time `jsonapi:"attr,errored-at,rfc3339"`
69+
ForceCanceledAt time.Time `jsonapi:"attr,force-canceled-at,rfc3339"`
70+
QueuingAt time.Time `jsonapi:"attr,queuing-at,rfc3339"`
71+
FinishedAt time.Time `jsonapi:"attr,finished-at,rfc3339"`
72+
RunningAt time.Time `jsonapi:"attr,running-at,rfc3339"`
73+
}
74+
75+
// QueryRunIncludeOpt represents the available options for include query params.
76+
// https://developer.hashicorp.com/terraform/cloud-docs/api-docs/run#available-related-resources
77+
type QueryRunIncludeOpt string
78+
79+
// QueryRunSource represents the available sources for query runs.
80+
type QueryRunSource string
81+
82+
// List all available run sources.
83+
const (
84+
QueryRunSourceAPI QueryRunSource = "tfe-api"
85+
)
86+
87+
const (
88+
QueryRunCreatedBy RunIncludeOpt = "created_by"
89+
QueryRunConfigVer RunIncludeOpt = "configuration_version"
90+
)
91+
92+
// queryRuns implements QueryRuns.
93+
type queryRuns struct {
94+
client *Client
95+
}
96+
97+
// QueryRunList represents a list of runs.
98+
type QueryRunList struct {
99+
*Pagination
100+
Items []*QueryRun
101+
}
102+
103+
// QueryRunListOptions represents the options for listing runs.
104+
type QueryRunListOptions struct {
105+
ListOptions
106+
// Optional: A list of relations to include. See available resources:
107+
// https://developer.hashicorp.com/terraform/cloud-docs/api-docs/run#available-related-resources
108+
Include []QueryRunIncludeOpt `url:"include,omitempty"`
109+
}
110+
111+
type QueryRunReadOptions struct {
112+
// Optional: A list of relations to include. See available resources:
113+
// https://developer.hashicorp.com/terraform/cloud-docs/api-docs/run#available-related-resources
114+
Include []QueryRunIncludeOpt `url:"include,omitempty"`
115+
}
116+
117+
// Run represents a Terraform Enterprise run.
118+
type QueryRun struct {
119+
ID string `jsonapi:"primary,queries"`
120+
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
121+
Source RunSource `jsonapi:"attr,source"`
122+
Status RunStatus `jsonapi:"attr,status"`
123+
StatusTimestamps *RunStatusTimestamps `jsonapi:"attr,status-timestamps"`
124+
TerraformVersion string `jsonapi:"attr,terraform-version"`
125+
Variables []*RunVariableAttr `jsonapi:"attr,variables"`
126+
127+
// Relations
128+
ConfigurationVersion *ConfigurationVersion `jsonapi:"relation,configuration-version"`
129+
CreatedBy *User `jsonapi:"relation,created-by"`
130+
CanceledBy *User `jsonapi:"relation,canceled-by"`
131+
Workspace *Workspace `jsonapi:"relation,workspace"`
132+
}
133+
134+
func (o *QueryRunListOptions) valid() error {
135+
return nil
136+
}
137+
138+
func (o QueryRunCreateOptions) valid() error {
139+
if o.Workspace == nil {
140+
return ErrRequiredWorkspace
141+
}
142+
143+
return nil
144+
}
145+
146+
func (r *queryRuns) List(ctx context.Context, workspaceID string, options *QueryRunListOptions) (*QueryRunList, error) {
147+
if workspaceID == "" {
148+
return nil, ErrInvalidWorkspaceID
149+
}
150+
if err := options.valid(); err != nil {
151+
return nil, err
152+
}
153+
154+
u := fmt.Sprintf("workspaces/%s/queries", url.PathEscape(workspaceID))
155+
req, err := r.client.NewRequest("GET", u, options)
156+
if err != nil {
157+
return nil, err
158+
}
159+
160+
var runs QueryRunList
161+
if err := req.Do(ctx, &runs); err != nil {
162+
return nil, err
163+
}
164+
165+
return &runs, nil
166+
}
167+
168+
func (r *queryRuns) Create(ctx context.Context, options QueryRunCreateOptions) (*QueryRun, error) {
169+
if err := options.valid(); err != nil {
170+
return nil, err
171+
}
172+
173+
req, err := r.client.NewRequest("POST", "queries", &options)
174+
if err != nil {
175+
return nil, err
176+
}
177+
178+
var run QueryRun
179+
if err := req.Do(ctx, &run); err != nil {
180+
return nil, err
181+
}
182+
183+
return &run, nil
184+
}
185+
186+
func (r *queryRuns) Read(ctx context.Context, queryRunID string) (*QueryRun, error) {
187+
return r.ReadWithOptions(ctx, queryRunID, &QueryRunReadOptions{})
188+
}
189+
190+
func (r *queryRuns) ReadWithOptions(ctx context.Context, queryRunID string, options *QueryRunReadOptions) (*QueryRun, error) {
191+
if queryRunID == "" {
192+
return nil, ErrInvalidQueryRunID
193+
}
194+
195+
u := fmt.Sprintf("queries/%s", url.PathEscape(queryRunID))
196+
req, err := r.client.NewRequest("GET", u, options)
197+
if err != nil {
198+
return nil, err
199+
}
200+
201+
var run QueryRun
202+
if err := req.Do(ctx, &run); err != nil {
203+
return nil, err
204+
}
205+
206+
return &run, nil
207+
}
208+
209+
func (r *queryRuns) Cancel(ctx context.Context, queryRunID string) error {
210+
if queryRunID == "" {
211+
return ErrInvalidQueryRunID
212+
}
213+
214+
u := fmt.Sprintf("queries/%s/actions/cancel", url.PathEscape(queryRunID))
215+
req, err := r.client.NewRequest("POST", u, nil)
216+
if err != nil {
217+
return err
218+
}
219+
220+
return req.Do(ctx, nil)
221+
}
222+
223+
func (r *queryRuns) ForceCancel(ctx context.Context, queryRunID string) error {
224+
if queryRunID == "" {
225+
return ErrInvalidQueryRunID
226+
}
227+
228+
u := fmt.Sprintf("queries/%s/actions/force-cancel", url.PathEscape(queryRunID))
229+
req, err := r.client.NewRequest("POST", u, nil)
230+
if err != nil {
231+
return err
232+
}
233+
234+
return req.Do(ctx, nil)
235+
}

0 commit comments

Comments
 (0)