1//
2// Copyright 2017, Sander van Harmelen
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17package gitlab
18
19import (
20 "fmt"
21 "time"
22)
23
24// RunnersService handles communication with the runner related methods of the
25// GitLab API.
26//
27// GitLab API docs: https://docs.gitlab.com/ce/api/runners.html
28type RunnersService struct {
29 client *Client
30}
31
32// Runner represents a GitLab CI Runner.
33//
34// GitLab API docs: https://docs.gitlab.com/ce/api/runners.html
35type Runner struct {
36 ID int `json:"id"`
37 Description string `json:"description"`
38 Active bool `json:"active"`
39 IsShared bool `json:"is_shared"`
40 IPAddress string `json:"ip_address"`
41 Name string `json:"name"`
42 Online bool `json:"online"`
43 Status string `json:"status"`
44 Token string `json:"token"`
45}
46
47// RunnerDetails represents the GitLab CI runner details.
48//
49// GitLab API docs: https://docs.gitlab.com/ce/api/runners.html
50type RunnerDetails struct {
51 Active bool `json:"active"`
52 Architecture string `json:"architecture"`
53 Description string `json:"description"`
54 ID int `json:"id"`
55 IPAddress string `json:"ip_address"`
56 IsShared bool `json:"is_shared"`
57 ContactedAt *time.Time `json:"contacted_at"`
58 Name string `json:"name"`
59 Online bool `json:"online"`
60 Status string `json:"status"`
61 Platform string `json:"platform"`
62 Projects []struct {
63 ID int `json:"id"`
64 Name string `json:"name"`
65 NameWithNamespace string `json:"name_with_namespace"`
66 Path string `json:"path"`
67 PathWithNamespace string `json:"path_with_namespace"`
68 } `json:"projects"`
69 Token string `json:"token"`
70 Revision string `json:"revision"`
71 TagList []string `json:"tag_list"`
72 Version string `json:"version"`
73 AccessLevel string `json:"access_level"`
74 MaximumTimeout int `json:"maximum_timeout"`
75}
76
77// ListRunnersOptions represents the available ListRunners() options.
78//
79// GitLab API docs:
80// https://docs.gitlab.com/ce/api/runners.html#list-owned-runners
81type ListRunnersOptions struct {
82 ListOptions
83 Scope *string `url:"scope,omitempty" json:"scope,omitempty"`
84 Status *string `url:"status,omitempty" json:"status,omitempty"`
85 Type *string `url:"type,omitempty" json:"type,omitempty"`
86}
87
88// ListRunners gets a list of runners accessible by the authenticated user.
89//
90// GitLab API docs:
91// https://docs.gitlab.com/ce/api/runners.html#list-owned-runners
92func (s *RunnersService) ListRunners(opt *ListRunnersOptions, options ...OptionFunc) ([]*Runner, *Response, error) {
93 req, err := s.client.NewRequest("GET", "runners", opt, options)
94 if err != nil {
95 return nil, nil, err
96 }
97
98 var rs []*Runner
99 resp, err := s.client.Do(req, &rs)
100 if err != nil {
101 return nil, resp, err
102 }
103
104 return rs, resp, err
105}
106
107// ListAllRunners gets a list of all runners in the GitLab instance. Access is
108// restricted to users with admin privileges.
109//
110// GitLab API docs:
111// https://docs.gitlab.com/ce/api/runners.html#list-all-runners
112func (s *RunnersService) ListAllRunners(opt *ListRunnersOptions, options ...OptionFunc) ([]*Runner, *Response, error) {
113 req, err := s.client.NewRequest("GET", "runners/all", opt, options)
114 if err != nil {
115 return nil, nil, err
116 }
117
118 var rs []*Runner
119 resp, err := s.client.Do(req, &rs)
120 if err != nil {
121 return nil, resp, err
122 }
123
124 return rs, resp, err
125}
126
127// GetRunnerDetails returns details for given runner.
128//
129// GitLab API docs:
130// https://docs.gitlab.com/ce/api/runners.html#get-runner-39-s-details
131func (s *RunnersService) GetRunnerDetails(rid interface{}, options ...OptionFunc) (*RunnerDetails, *Response, error) {
132 runner, err := parseID(rid)
133 if err != nil {
134 return nil, nil, err
135 }
136 u := fmt.Sprintf("runners/%s", runner)
137
138 req, err := s.client.NewRequest("GET", u, nil, options)
139 if err != nil {
140 return nil, nil, err
141 }
142
143 var rs *RunnerDetails
144 resp, err := s.client.Do(req, &rs)
145 if err != nil {
146 return nil, resp, err
147 }
148
149 return rs, resp, err
150}
151
152// UpdateRunnerDetailsOptions represents the available UpdateRunnerDetails() options.
153//
154// GitLab API docs:
155// https://docs.gitlab.com/ce/api/runners.html#update-runner-39-s-details
156type UpdateRunnerDetailsOptions struct {
157 Description *string `url:"description,omitempty" json:"description,omitempty"`
158 Active *bool `url:"active,omitempty" json:"active,omitempty"`
159 TagList []string `url:"tag_list[],omitempty" json:"tag_list,omitempty"`
160 RunUntagged *bool `url:"run_untagged,omitempty" json:"run_untagged,omitempty"`
161 Locked *bool `url:"locked,omitempty" json:"locked,omitempty"`
162 AccessLevel *string `url:"access_level,omitempty" json:"access_level,omitempty"`
163 MaximumTimeout *int `url:"maximum_timeout,omitempty" json:"maximum_timeout,omitempty"`
164}
165
166// UpdateRunnerDetails updates details for a given runner.
167//
168// GitLab API docs:
169// https://docs.gitlab.com/ce/api/runners.html#update-runner-39-s-details
170func (s *RunnersService) UpdateRunnerDetails(rid interface{}, opt *UpdateRunnerDetailsOptions, options ...OptionFunc) (*RunnerDetails, *Response, error) {
171 runner, err := parseID(rid)
172 if err != nil {
173 return nil, nil, err
174 }
175 u := fmt.Sprintf("runners/%s", runner)
176
177 req, err := s.client.NewRequest("PUT", u, opt, options)
178 if err != nil {
179 return nil, nil, err
180 }
181
182 var rs *RunnerDetails
183 resp, err := s.client.Do(req, &rs)
184 if err != nil {
185 return nil, resp, err
186 }
187
188 return rs, resp, err
189}
190
191// RemoveRunner removes a runner.
192//
193// GitLab API docs:
194// https://docs.gitlab.com/ce/api/runners.html#remove-a-runner
195func (s *RunnersService) RemoveRunner(rid interface{}, options ...OptionFunc) (*Response, error) {
196 runner, err := parseID(rid)
197 if err != nil {
198 return nil, err
199 }
200 u := fmt.Sprintf("runners/%s", runner)
201
202 req, err := s.client.NewRequest("DELETE", u, nil, options)
203 if err != nil {
204 return nil, err
205 }
206
207 return s.client.Do(req, nil)
208}
209
210// ListRunnerJobsOptions represents the available ListRunnerJobs()
211// options. Status can be one of: running, success, failed, canceled.
212//
213// GitLab API docs:
214// https://docs.gitlab.com/ce/api/runners.html#list-runner-39-s-jobs
215type ListRunnerJobsOptions struct {
216 ListOptions
217 Status *string `url:"status,omitempty" json:"status,omitempty"`
218}
219
220// ListRunnerJobs gets a list of jobs that are being processed or were processed by specified Runner.
221//
222// GitLab API docs:
223// https://docs.gitlab.com/ce/api/runners.html#list-runner-39-s-jobs
224func (s *RunnersService) ListRunnerJobs(rid interface{}, opt *ListRunnerJobsOptions, options ...OptionFunc) ([]*Job, *Response, error) {
225 runner, err := parseID(rid)
226 if err != nil {
227 return nil, nil, err
228 }
229 u := fmt.Sprintf("runners/%s/jobs", runner)
230
231 req, err := s.client.NewRequest("GET", u, opt, options)
232 if err != nil {
233 return nil, nil, err
234 }
235
236 var rs []*Job
237 resp, err := s.client.Do(req, &rs)
238 if err != nil {
239 return nil, resp, err
240 }
241
242 return rs, resp, err
243}
244
245// ListProjectRunnersOptions represents the available ListProjectRunners()
246// options.
247//
248// GitLab API docs:
249// https://docs.gitlab.com/ce/api/runners.html#list-project-s-runners
250type ListProjectRunnersOptions ListRunnersOptions
251
252// ListProjectRunners gets a list of runners accessible by the authenticated user.
253//
254// GitLab API docs:
255// https://docs.gitlab.com/ce/api/runners.html#list-project-s-runners
256func (s *RunnersService) ListProjectRunners(pid interface{}, opt *ListProjectRunnersOptions, options ...OptionFunc) ([]*Runner, *Response, error) {
257 project, err := parseID(pid)
258 if err != nil {
259 return nil, nil, err
260 }
261 u := fmt.Sprintf("projects/%s/runners", pathEscape(project))
262
263 req, err := s.client.NewRequest("GET", u, opt, options)
264 if err != nil {
265 return nil, nil, err
266 }
267
268 var rs []*Runner
269 resp, err := s.client.Do(req, &rs)
270 if err != nil {
271 return nil, resp, err
272 }
273
274 return rs, resp, err
275}
276
277// EnableProjectRunnerOptions represents the available EnableProjectRunner()
278// options.
279//
280// GitLab API docs:
281// https://docs.gitlab.com/ce/api/runners.html#enable-a-runner-in-project
282type EnableProjectRunnerOptions struct {
283 RunnerID int `json:"runner_id"`
284}
285
286// EnableProjectRunner enables an available specific runner in the project.
287//
288// GitLab API docs:
289// https://docs.gitlab.com/ce/api/runners.html#enable-a-runner-in-project
290func (s *RunnersService) EnableProjectRunner(pid interface{}, opt *EnableProjectRunnerOptions, options ...OptionFunc) (*Runner, *Response, error) {
291 project, err := parseID(pid)
292 if err != nil {
293 return nil, nil, err
294 }
295 u := fmt.Sprintf("projects/%s/runners", pathEscape(project))
296
297 req, err := s.client.NewRequest("POST", u, opt, options)
298 if err != nil {
299 return nil, nil, err
300 }
301
302 var r *Runner
303 resp, err := s.client.Do(req, &r)
304 if err != nil {
305 return nil, resp, err
306 }
307
308 return r, resp, err
309}
310
311// DisableProjectRunner disables a specific runner from project.
312//
313// GitLab API docs:
314// https://docs.gitlab.com/ce/api/runners.html#disable-a-runner-from-project
315func (s *RunnersService) DisableProjectRunner(pid interface{}, runner int, options ...OptionFunc) (*Response, error) {
316 project, err := parseID(pid)
317 if err != nil {
318 return nil, err
319 }
320 u := fmt.Sprintf("projects/%s/runners/%d", pathEscape(project), runner)
321
322 req, err := s.client.NewRequest("DELETE", u, nil, options)
323 if err != nil {
324 return nil, err
325 }
326
327 return s.client.Do(req, nil)
328}
329
330// RegisterNewRunnerOptions represents the available RegisterNewRunner()
331// options.
332//
333// GitLab API docs:
334// https://docs.gitlab.com/ce/api/runners.html#register-a-new-runner
335type RegisterNewRunnerOptions struct {
336 Token *string `url:"token" json:"token"`
337 Description *string `url:"description,omitempty" json:"description,omitempty"`
338 Info *string `url:"info,omitempty" json:"info,omitempty"`
339 Active *bool `url:"active,omitempty" json:"active,omitempty"`
340 Locked *bool `url:"locked,omitempty" json:"locked,omitempty"`
341 RunUntagged *bool `url:"run_untagged,omitempty" json:"run_untagged,omitempty"`
342 TagList []string `url:"tag_list[],omitempty" json:"tag_list,omitempty"`
343 MaximumTimeout *int `url:"maximum_timeout,omitempty" json:"maximum_timeout,omitempty"`
344}
345
346// RegisterNewRunner registers a new Runner for the instance.
347//
348// GitLab API docs:
349// https://docs.gitlab.com/ce/api/runners.html#register-a-new-runner
350func (s *RunnersService) RegisterNewRunner(opt *RegisterNewRunnerOptions, options ...OptionFunc) (*Runner, *Response, error) {
351 req, err := s.client.NewRequest("POST", "runners", opt, options)
352 if err != nil {
353 return nil, nil, err
354 }
355
356 var r *Runner
357 resp, err := s.client.Do(req, &r)
358 if err != nil {
359 return nil, resp, err
360 }
361
362 return r, resp, err
363}
364
365// DeleteRegisteredRunnerOptions represents the available
366// DeleteRegisteredRunner() options.
367//
368// GitLab API docs:
369// https://docs.gitlab.com/ce/api/runners.html#delete-a-registered-runner
370type DeleteRegisteredRunnerOptions struct {
371 Token *string `url:"token" json:"token"`
372}
373
374// DeleteRegisteredRunner registers a new Runner for the instance.
375//
376// GitLab API docs:
377// https://docs.gitlab.com/ce/api/runners.html#delete-a-registered-runner
378func (s *RunnersService) DeleteRegisteredRunner(opt *DeleteRegisteredRunnerOptions, options ...OptionFunc) (*Response, error) {
379 req, err := s.client.NewRequest("DELETE", "runners", opt, options)
380 if err != nil {
381 return nil, err
382 }
383
384 return s.client.Do(req, nil)
385}
386
387// VerifyRegisteredRunnerOptions represents the available
388// VerifyRegisteredRunner() options.
389//
390// GitLab API docs:
391// https://docs.gitlab.com/ce/api/runners.html#verify-authentication-for-a-registered-runner
392type VerifyRegisteredRunnerOptions struct {
393 Token *string `url:"token" json:"token"`
394}
395
396// VerifyRegisteredRunner registers a new Runner for the instance.
397//
398// GitLab API docs:
399// https://docs.gitlab.com/ce/api/runners.html#verify-authentication-for-a-registered-runner
400func (s *RunnersService) VerifyRegisteredRunner(opt *VerifyRegisteredRunnerOptions, options ...OptionFunc) (*Response, error) {
401 req, err := s.client.NewRequest("POST", "runners/verify", opt, options)
402 if err != nil {
403 return nil, err
404 }
405
406 return s.client.Do(req, nil)
407}