forked from hashicorp/go-tfe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfiguration_version.go
208 lines (171 loc) · 6.57 KB
/
configuration_version.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
package tfe
import (
"bytes"
"context"
"errors"
"fmt"
"net/url"
"os"
"time"
slug "github.com/hashicorp/go-slug"
)
// Compile-time proof of interface implementation.
var _ ConfigurationVersions = (*configurationVersions)(nil)
// ConfigurationVersions describes all the configuration version related
// methods that the Terraform Enterprise API supports.
//
// TFE API docs:
// https://www.terraform.io/docs/enterprise/api/configuration-versions.html
type ConfigurationVersions interface {
// List returns all configuration versions of a workspace.
List(ctx context.Context, workspaceID string, options ConfigurationVersionListOptions) (*ConfigurationVersionList, error)
// Create is used to create a new configuration version. The created
// configuration version will be usable once data is uploaded to it.
Create(ctx context.Context, workspaceID string, options ConfigurationVersionCreateOptions) (*ConfigurationVersion, error)
// Read a configuration version by its ID.
Read(ctx context.Context, cvID string) (*ConfigurationVersion, error)
// Upload packages and uploads Terraform configuration files. It requires
// the upload URL from a configuration version and the full path to the
// configuration files on disk.
Upload(ctx context.Context, url string, path string) error
}
// configurationVersions implements ConfigurationVersions.
type configurationVersions struct {
client *Client
}
// ConfigurationStatus represents a configuration version status.
type ConfigurationStatus string
//List all available configuration version statuses.
const (
ConfigurationErrored ConfigurationStatus = "errored"
ConfigurationPending ConfigurationStatus = "pending"
ConfigurationUploaded ConfigurationStatus = "uploaded"
)
// ConfigurationSource represents a source of a configuration version.
type ConfigurationSource string
// List all available configuration version sources.
const (
ConfigurationSourceAPI ConfigurationSource = "tfe-api"
ConfigurationSourceBitbucket ConfigurationSource = "bitbucket"
ConfigurationSourceGithub ConfigurationSource = "github"
ConfigurationSourceGitlab ConfigurationSource = "gitlab"
ConfigurationSourceTerraform ConfigurationSource = "terraform"
)
// ConfigurationVersionList represents a list of configuration versions.
type ConfigurationVersionList struct {
*Pagination
Items []*ConfigurationVersion
}
// ConfigurationVersion is a representation of an uploaded or ingressed
// Terraform configuration in TFE. A workspace must have at least one
// configuration version before any runs may be queued on it.
type ConfigurationVersion struct {
ID string `jsonapi:"primary,configuration-versions"`
AutoQueueRuns bool `jsonapi:"attr,auto-queue-runs"`
Error string `jsonapi:"attr,error"`
ErrorMessage string `jsonapi:"attr,error-message"`
Source ConfigurationSource `jsonapi:"attr,source"`
Speculative bool `jsonapi:"attr,speculative "`
Status ConfigurationStatus `jsonapi:"attr,status"`
StatusTimestamps *CVStatusTimestamps `jsonapi:"attr,status-timestamps"`
UploadURL string `jsonapi:"attr,upload-url"`
}
// CVStatusTimestamps holds the timestamps for individual configuration version
// statuses.
type CVStatusTimestamps struct {
FinishedAt time.Time `json:"finished-at"`
QueuedAt time.Time `json:"queued-at"`
StartedAt time.Time `json:"started-at"`
}
// ConfigurationVersionListOptions represents the options for listing
// configuration versions.
type ConfigurationVersionListOptions struct {
ListOptions
}
// List returns all configuration versions of a workspace.
func (s *configurationVersions) List(ctx context.Context, workspaceID string, options ConfigurationVersionListOptions) (*ConfigurationVersionList, error) {
if !validStringID(&workspaceID) {
return nil, errors.New("invalid value for workspace ID")
}
u := fmt.Sprintf("workspaces/%s/configuration-versions", url.QueryEscape(workspaceID))
req, err := s.client.newRequest("GET", u, &options)
if err != nil {
return nil, err
}
cvl := &ConfigurationVersionList{}
err = s.client.do(ctx, req, cvl)
if err != nil {
return nil, err
}
return cvl, nil
}
// ConfigurationVersionCreateOptions represents the options for creating a
// configuration version.
type ConfigurationVersionCreateOptions struct {
// For internal use only!
ID string `jsonapi:"primary,configuration-versions"`
// When true, runs are queued automatically when the configuration version
// is uploaded.
AutoQueueRuns *bool `jsonapi:"attr,auto-queue-runs,omitempty"`
// When true, this configuration version can only be used for planning.
Speculative *bool `jsonapi:"attr,speculative,omitempty"`
}
// Create is used to create a new configuration version. The created
// configuration version will be usable once data is uploaded to it.
func (s *configurationVersions) Create(ctx context.Context, workspaceID string, options ConfigurationVersionCreateOptions) (*ConfigurationVersion, error) {
if !validStringID(&workspaceID) {
return nil, errors.New("invalid value for workspace ID")
}
// Make sure we don't send a user provided ID.
options.ID = ""
u := fmt.Sprintf("workspaces/%s/configuration-versions", url.QueryEscape(workspaceID))
req, err := s.client.newRequest("POST", u, &options)
if err != nil {
return nil, err
}
cv := &ConfigurationVersion{}
err = s.client.do(ctx, req, cv)
if err != nil {
return nil, err
}
return cv, nil
}
// Read a configuration version by its ID.
func (s *configurationVersions) Read(ctx context.Context, cvID string) (*ConfigurationVersion, error) {
if !validStringID(&cvID) {
return nil, errors.New("invalid value for configuration version ID")
}
u := fmt.Sprintf("configuration-versions/%s", url.QueryEscape(cvID))
req, err := s.client.newRequest("GET", u, nil)
if err != nil {
return nil, err
}
cv := &ConfigurationVersion{}
err = s.client.do(ctx, req, cv)
if err != nil {
return nil, err
}
return cv, nil
}
// Upload packages and uploads Terraform configuration files. It requires the
// upload URL from a configuration version and the path to the configuration
// files on disk.
func (s *configurationVersions) Upload(ctx context.Context, url, path string) error {
file, err := os.Stat(path)
if err != nil {
return err
}
if !file.Mode().IsDir() {
return errors.New("path needs to be an existing directory")
}
body := bytes.NewBuffer(nil)
_, err = slug.Pack(path, body, true)
if err != nil {
return err
}
req, err := s.client.newRequest("PUT", url, body)
if err != nil {
return err
}
return s.client.do(ctx, req, nil)
}