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