1//
2// Copyright 2021, 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	"encoding/json"
21	"fmt"
22	"net/http"
23	"strconv"
24	"time"
25)
26
27// ServicesService handles communication with the services related methods of
28// the GitLab API.
29//
30// GitLab API docs: https://docs.gitlab.com/ce/api/services.html
31type ServicesService struct {
32	client *Client
33}
34
35// Service represents a GitLab service.
36//
37// GitLab API docs: https://docs.gitlab.com/ce/api/services.html
38type Service struct {
39	ID                       int        `json:"id"`
40	Title                    string     `json:"title"`
41	Slug                     string     `json:"slug"`
42	CreatedAt                *time.Time `json:"created_at"`
43	UpdatedAt                *time.Time `json:"updated_at"`
44	Active                   bool       `json:"active"`
45	PushEvents               bool       `json:"push_events"`
46	IssuesEvents             bool       `json:"issues_events"`
47	ConfidentialIssuesEvents bool       `json:"confidential_issues_events"`
48	CommitEvents             bool       `json:"commit_events"`
49	MergeRequestsEvents      bool       `json:"merge_requests_events"`
50	CommentOnEventEnabled    bool       `json:"comment_on_event_enabled"`
51	TagPushEvents            bool       `json:"tag_push_events"`
52	NoteEvents               bool       `json:"note_events"`
53	ConfidentialNoteEvents   bool       `json:"confidential_note_events"`
54	PipelineEvents           bool       `json:"pipeline_events"`
55	JobEvents                bool       `json:"job_events"`
56	WikiPageEvents           bool       `json:"wiki_page_events"`
57	DeploymentEvents         bool       `json:"deployment_events"`
58}
59
60// ListServices gets a list of all active services.
61//
62// GitLab API docs: https://docs.gitlab.com/ce/api/services.html#list-all-active-services
63func (s *ServicesService) ListServices(pid interface{}, options ...RequestOptionFunc) ([]*Service, *Response, error) {
64	project, err := parseID(pid)
65	if err != nil {
66		return nil, nil, err
67	}
68	u := fmt.Sprintf("projects/%s/services", PathEscape(project))
69
70	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
71	if err != nil {
72		return nil, nil, err
73	}
74
75	var svcs []*Service
76	resp, err := s.client.Do(req, &svcs)
77	if err != nil {
78		return nil, resp, err
79	}
80
81	return svcs, resp, err
82}
83
84// CustomIssueTrackerService represents Custom Issue Tracker service settings.
85//
86// GitLab API docs:
87// https://docs.gitlab.com/ce/api/services.html#custom-issue-tracker
88type CustomIssueTrackerService struct {
89	Service
90	Properties *CustomIssueTrackerServiceProperties `json:"properties"`
91}
92
93// CustomIssueTrackerServiceProperties represents Custom Issue Tracker specific properties.
94//
95// GitLab API docs:
96// https://docs.gitlab.com/ce/api/services.html#custom-issue-tracker
97type CustomIssueTrackerServiceProperties struct {
98	ProjectURL  string `json:"project_url,omitempty"`
99	IssuesURL   string `json:"issues_url,omitempty"`
100	NewIssueURL string `json:"new_issue_url,omitempty"`
101}
102
103// GetCustomIssueTrackerService gets Custom Issue Tracker service settings for a project.
104//
105// GitLab API docs:
106// https://docs.gitlab.com/ce/api/services.html#get-custom-issue-tracker-service-settings
107func (s *ServicesService) GetCustomIssueTrackerService(pid interface{}, options ...RequestOptionFunc) (*CustomIssueTrackerService, *Response, error) {
108	project, err := parseID(pid)
109	if err != nil {
110		return nil, nil, err
111	}
112	u := fmt.Sprintf("projects/%s/services/custom-issue-tracker", PathEscape(project))
113
114	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
115	if err != nil {
116		return nil, nil, err
117	}
118
119	svc := new(CustomIssueTrackerService)
120	resp, err := s.client.Do(req, svc)
121	if err != nil {
122		return nil, resp, err
123	}
124
125	return svc, resp, err
126}
127
128// SetCustomIssueTrackerServiceOptions represents the available SetCustomIssueTrackerService()
129// options.
130//
131// GitLab API docs:
132// https://docs.gitlab.com/ce/api/services.html#createedit-custom-issue-tracker-service
133type SetCustomIssueTrackerServiceOptions struct {
134	NewIssueURL *string `url:"new_issue_url,omitempty" json:"new_issue_url,omitempty"`
135	IssuesURL   *string `url:"issues_url,omitempty" json:"issues_url,omitempty"`
136	ProjectURL  *string `url:"project_url,omitempty" json:"project_url,omitempty"`
137	Description *string `url:"description,omitempty" json:"description,omitempty"`
138	Title       *string `url:"title,omitempty" json:"title,omitempty"`
139	PushEvents  *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
140}
141
142// SetCustomIssueTrackerService sets Custom Issue Tracker service for a project.
143//
144// GitLab API docs:
145// https://docs.gitlab.com/ce/api/services.html#createedit-custom-issue-tracker-service
146func (s *ServicesService) SetCustomIssueTrackerService(pid interface{}, opt *SetCustomIssueTrackerServiceOptions, options ...RequestOptionFunc) (*Response, error) {
147	project, err := parseID(pid)
148	if err != nil {
149		return nil, err
150	}
151	u := fmt.Sprintf("projects/%s/services/custom-issue-tracker", PathEscape(project))
152
153	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
154	if err != nil {
155		return nil, err
156	}
157
158	return s.client.Do(req, nil)
159}
160
161// DeleteCustomIssueTrackerService deletes Custom Issue Tracker service settings for a project.
162//
163// GitLab API docs:
164// https://docs.gitlab.com/ce/api/services.html#delete-custom-issue-tracker-service
165func (s *ServicesService) DeleteCustomIssueTrackerService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
166	project, err := parseID(pid)
167	if err != nil {
168		return nil, err
169	}
170	u := fmt.Sprintf("projects/%s/services/custom-issue-tracker", PathEscape(project))
171
172	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
173	if err != nil {
174		return nil, err
175	}
176
177	return s.client.Do(req, nil)
178}
179
180// DroneCIService represents Drone CI service settings.
181//
182// GitLab API docs:
183// https://docs.gitlab.com/ce/api/services.html#drone-ci
184type DroneCIService struct {
185	Service
186	Properties *DroneCIServiceProperties `json:"properties"`
187}
188
189// DroneCIServiceProperties represents Drone CI specific properties.
190//
191// GitLab API docs:
192// https://docs.gitlab.com/ce/api/services.html#drone-ci
193type DroneCIServiceProperties struct {
194	Token                 string `json:"token"`
195	DroneURL              string `json:"drone_url"`
196	EnableSSLVerification bool   `json:"enable_ssl_verification"`
197}
198
199// GetDroneCIService gets Drone CI service settings for a project.
200//
201// GitLab API docs:
202// https://docs.gitlab.com/ce/api/services.html#get-drone-ci-service-settings
203func (s *ServicesService) GetDroneCIService(pid interface{}, options ...RequestOptionFunc) (*DroneCIService, *Response, error) {
204	project, err := parseID(pid)
205	if err != nil {
206		return nil, nil, err
207	}
208	u := fmt.Sprintf("projects/%s/services/drone-ci", PathEscape(project))
209
210	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
211	if err != nil {
212		return nil, nil, err
213	}
214
215	svc := new(DroneCIService)
216	resp, err := s.client.Do(req, svc)
217	if err != nil {
218		return nil, resp, err
219	}
220
221	return svc, resp, err
222}
223
224// SetDroneCIServiceOptions represents the available SetDroneCIService()
225// options.
226//
227// GitLab API docs:
228// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service
229type SetDroneCIServiceOptions struct {
230	Token                 *string `url:"token,omitempty" json:"token,omitempty"`
231	DroneURL              *string `url:"drone_url,omitempty" json:"drone_url,omitempty"`
232	EnableSSLVerification *bool   `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
233}
234
235// SetDroneCIService sets Drone CI service for a project.
236//
237// GitLab API docs:
238// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service
239func (s *ServicesService) SetDroneCIService(pid interface{}, opt *SetDroneCIServiceOptions, options ...RequestOptionFunc) (*Response, error) {
240	project, err := parseID(pid)
241	if err != nil {
242		return nil, err
243	}
244	u := fmt.Sprintf("projects/%s/services/drone-ci", PathEscape(project))
245
246	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
247	if err != nil {
248		return nil, err
249	}
250
251	return s.client.Do(req, nil)
252}
253
254// DeleteDroneCIService deletes Drone CI service settings for a project.
255//
256// GitLab API docs:
257// https://docs.gitlab.com/ce/api/services.html#delete-drone-ci-service
258func (s *ServicesService) DeleteDroneCIService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
259	project, err := parseID(pid)
260	if err != nil {
261		return nil, err
262	}
263	u := fmt.Sprintf("projects/%s/services/drone-ci", PathEscape(project))
264
265	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
266	if err != nil {
267		return nil, err
268	}
269
270	return s.client.Do(req, nil)
271}
272
273// ExternalWikiService represents External Wiki service settings.
274//
275// GitLab API docs:
276// https://docs.gitlab.com/ce/api/services.html#external-wiki
277type ExternalWikiService struct {
278	Service
279	Properties *ExternalWikiServiceProperties `json:"properties"`
280}
281
282// ExternalWikiServiceProperties represents External Wiki specific properties.
283//
284// GitLab API docs:
285// https://docs.gitlab.com/ce/api/services.html#external-wiki
286type ExternalWikiServiceProperties struct {
287	ExternalWikiURL string `json:"external_wiki_url"`
288}
289
290// GetExternalWikiService gets External Wiki service settings for a project.
291//
292// GitLab API docs:
293// https://docs.gitlab.com/ce/api/services.html#get-external-wiki-service-settings
294func (s *ServicesService) GetExternalWikiService(pid interface{}, options ...RequestOptionFunc) (*ExternalWikiService, *Response, error) {
295	project, err := parseID(pid)
296	if err != nil {
297		return nil, nil, err
298	}
299	u := fmt.Sprintf("projects/%s/services/external-wiki", PathEscape(project))
300
301	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
302	if err != nil {
303		return nil, nil, err
304	}
305
306	svc := new(ExternalWikiService)
307	resp, err := s.client.Do(req, svc)
308	if err != nil {
309		return nil, resp, err
310	}
311
312	return svc, resp, err
313}
314
315// SetExternalWikiServiceOptions represents the available SetExternalWikiService()
316// options.
317//
318// GitLab API docs:
319// https://docs.gitlab.com/ce/api/services.html#createedit-external-wiki-service
320type SetExternalWikiServiceOptions struct {
321	ExternalWikiURL *string `url:"external_wiki_url,omitempty" json:"external_wiki_url,omitempty"`
322}
323
324// SetExternalWikiService sets External Wiki service for a project.
325//
326// GitLab API docs:
327// https://docs.gitlab.com/ce/api/services.html#createedit-external-wiki-service
328func (s *ServicesService) SetExternalWikiService(pid interface{}, opt *SetExternalWikiServiceOptions, options ...RequestOptionFunc) (*Response, error) {
329	project, err := parseID(pid)
330	if err != nil {
331		return nil, err
332	}
333	u := fmt.Sprintf("projects/%s/services/external-wiki", PathEscape(project))
334
335	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
336	if err != nil {
337		return nil, err
338	}
339
340	return s.client.Do(req, nil)
341}
342
343// DeleteExternalWikiService deletes External Wiki service for project.
344//
345// GitLab API docs:
346// https://docs.gitlab.com/ce/api/services.html#delete-external-wiki-service
347func (s *ServicesService) DeleteExternalWikiService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
348	project, err := parseID(pid)
349	if err != nil {
350		return nil, err
351	}
352	u := fmt.Sprintf("projects/%s/services/external-wiki", PathEscape(project))
353
354	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
355	if err != nil {
356		return nil, err
357	}
358
359	return s.client.Do(req, nil)
360}
361
362// GithubService represents Github service settings.
363//
364// GitLab API docs:
365// https://docs.gitlab.com/ce/api/services.html#github-premium
366type GithubService struct {
367	Service
368	Properties *GithubServiceProperties `json:"properties"`
369}
370
371// GithubServiceProperties represents Github specific properties.
372//
373// GitLab API docs:
374// https://docs.gitlab.com/ce/api/services.html#github-premium
375type GithubServiceProperties struct {
376	RepositoryURL string `json:"repository_url"`
377	StaticContext bool   `json:"static_context"`
378}
379
380// GetGithubService gets Github service settings for a project.
381//
382// GitLab API docs:
383// https://docs.gitlab.com/ce/api/services.html#get-github-service-settings
384func (s *ServicesService) GetGithubService(pid interface{}, options ...RequestOptionFunc) (*GithubService, *Response, error) {
385	project, err := parseID(pid)
386	if err != nil {
387		return nil, nil, err
388	}
389	u := fmt.Sprintf("projects/%s/services/github", PathEscape(project))
390
391	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
392	if err != nil {
393		return nil, nil, err
394	}
395
396	svc := new(GithubService)
397	resp, err := s.client.Do(req, svc)
398	if err != nil {
399		return nil, resp, err
400	}
401
402	return svc, resp, err
403}
404
405// SetGithubServiceOptions represents the available SetGithubService()
406// options.
407//
408// GitLab API docs:
409// https://docs.gitlab.com/ce/api/services.html#createedit-github-service
410type SetGithubServiceOptions struct {
411	Token         *string `url:"token,omitempty" json:"token,omitempty"`
412	RepositoryURL *string `url:"repository_url,omitempty" json:"repository_url,omitempty"`
413	StaticContext *bool   `url:"static_context,omitempty" json:"static_context,omitempty"`
414}
415
416// SetGithubService sets Github service for a project
417//
418// GitLab API docs:
419// https://docs.gitlab.com/ce/api/services.html#createedit-github-service
420func (s *ServicesService) SetGithubService(pid interface{}, opt *SetGithubServiceOptions, options ...RequestOptionFunc) (*Response, error) {
421	project, err := parseID(pid)
422	if err != nil {
423		return nil, err
424	}
425	u := fmt.Sprintf("projects/%s/services/github", PathEscape(project))
426
427	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
428	if err != nil {
429		return nil, err
430	}
431
432	return s.client.Do(req, nil)
433}
434
435// DeleteGithubService deletes Github service for a project
436//
437// GitLab API docs:
438// https://docs.gitlab.com/ce/api/services.html#delete-github-service
439func (s *ServicesService) DeleteGithubService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
440	project, err := parseID(pid)
441	if err != nil {
442		return nil, err
443	}
444	u := fmt.Sprintf("projects/%s/services/github", PathEscape(project))
445
446	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
447	if err != nil {
448		return nil, err
449	}
450
451	return s.client.Do(req, nil)
452}
453
454// SetGitLabCIServiceOptions represents the available SetGitLabCIService()
455// options.
456//
457// GitLab API docs:
458// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service
459type SetGitLabCIServiceOptions struct {
460	Token      *string `url:"token,omitempty" json:"token,omitempty"`
461	ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"`
462}
463
464// SetGitLabCIService sets GitLab CI service for a project.
465//
466// GitLab API docs:
467// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service
468func (s *ServicesService) SetGitLabCIService(pid interface{}, opt *SetGitLabCIServiceOptions, options ...RequestOptionFunc) (*Response, error) {
469	project, err := parseID(pid)
470	if err != nil {
471		return nil, err
472	}
473	u := fmt.Sprintf("projects/%s/services/gitlab-ci", PathEscape(project))
474
475	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
476	if err != nil {
477		return nil, err
478	}
479
480	return s.client.Do(req, nil)
481}
482
483// DeleteGitLabCIService deletes GitLab CI service settings for a project.
484//
485// GitLab API docs:
486// https://docs.gitlab.com/ce/api/services.html#delete-gitlab-ci-service
487func (s *ServicesService) DeleteGitLabCIService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
488	project, err := parseID(pid)
489	if err != nil {
490		return nil, err
491	}
492	u := fmt.Sprintf("projects/%s/services/gitlab-ci", PathEscape(project))
493
494	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
495	if err != nil {
496		return nil, err
497	}
498
499	return s.client.Do(req, nil)
500}
501
502// SetHipChatServiceOptions represents the available SetHipChatService()
503// options.
504//
505// GitLab API docs:
506// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service
507type SetHipChatServiceOptions struct {
508	Token *string `url:"token,omitempty" json:"token,omitempty" `
509	Room  *string `url:"room,omitempty" json:"room,omitempty"`
510}
511
512// SetHipChatService sets HipChat service for a project
513//
514// GitLab API docs:
515// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service
516func (s *ServicesService) SetHipChatService(pid interface{}, opt *SetHipChatServiceOptions, options ...RequestOptionFunc) (*Response, error) {
517	project, err := parseID(pid)
518	if err != nil {
519		return nil, err
520	}
521	u := fmt.Sprintf("projects/%s/services/hipchat", PathEscape(project))
522
523	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
524	if err != nil {
525		return nil, err
526	}
527
528	return s.client.Do(req, nil)
529}
530
531// DeleteHipChatService deletes HipChat service for project.
532//
533// GitLab API docs:
534// https://docs.gitlab.com/ce/api/services.html#delete-hipchat-service
535func (s *ServicesService) DeleteHipChatService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
536	project, err := parseID(pid)
537	if err != nil {
538		return nil, err
539	}
540	u := fmt.Sprintf("projects/%s/services/hipchat", PathEscape(project))
541
542	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
543	if err != nil {
544		return nil, err
545	}
546
547	return s.client.Do(req, nil)
548}
549
550// JenkinsCIService represents Jenkins CI service settings.
551//
552// GitLab API docs:
553// https://docs.gitlab.com/ee/api/services.html#jenkins-ci
554type JenkinsCIService struct {
555	Service
556	Properties *JenkinsCIServiceProperties `json:"properties"`
557}
558
559// JenkinsCIServiceProperties represents Jenkins CI specific properties.
560//
561// GitLab API docs:
562// https://docs.gitlab.com/ee/api/services.html#jenkins-ci
563type JenkinsCIServiceProperties struct {
564	URL         string `json:"jenkins_url"`
565	ProjectName string `json:"project_name"`
566	Username    string `json:"username"`
567}
568
569// GetJenkinsCIService gets Jenkins CI service settings for a project.
570//
571// GitLab API docs:
572// https://docs.gitlab.com/ee/api/services.html#get-jenkins-ci-service-settings
573func (s *ServicesService) GetJenkinsCIService(pid interface{}, options ...RequestOptionFunc) (*JenkinsCIService, *Response, error) {
574	project, err := parseID(pid)
575	if err != nil {
576		return nil, nil, err
577	}
578	u := fmt.Sprintf("projects/%s/services/jenkins", PathEscape(project))
579
580	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
581	if err != nil {
582		return nil, nil, err
583	}
584
585	svc := new(JenkinsCIService)
586	resp, err := s.client.Do(req, svc)
587	if err != nil {
588		return nil, resp, err
589	}
590
591	return svc, resp, err
592}
593
594// SetJenkinsCIServiceOptions represents the available SetJenkinsCIService()
595// options.
596//
597// GitLab API docs:
598// https://docs.gitlab.com/ee/api/services.html#jenkins-ci
599type SetJenkinsCIServiceOptions struct {
600	URL                 *string `url:"jenkins_url,omitempty" json:"jenkins_url,omitempty"`
601	ProjectName         *string `url:"project_name,omitempty" json:"project_name,omitempty"`
602	Username            *string `url:"username,omitempty" json:"username,omitempty"`
603	Password            *string `url:"password,omitempty" json:"password,omitempty"`
604	PushEvents          *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
605	MergeRequestsEvents *bool   `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
606	TagPushEvents       *bool   `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
607}
608
609// SetJenkinsCIService sets Jenkins service for a project
610//
611// GitLab API docs:
612// https://docs.gitlab.com/ee/api/services.html#create-edit-jenkins-ci-service
613func (s *ServicesService) SetJenkinsCIService(pid interface{}, opt *SetJenkinsCIServiceOptions, options ...RequestOptionFunc) (*Response, error) {
614	project, err := parseID(pid)
615	if err != nil {
616		return nil, err
617	}
618	u := fmt.Sprintf("projects/%s/services/jenkins", PathEscape(project))
619
620	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
621	if err != nil {
622		return nil, err
623	}
624
625	return s.client.Do(req, nil)
626}
627
628// DeleteJenkinsCIService deletes Jenkins CI service for project.
629//
630// GitLab API docs:
631// https://docs.gitlab.com/ce/api/services.html#delete-jira-service
632func (s *ServicesService) DeleteJenkinsCIService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
633	project, err := parseID(pid)
634	if err != nil {
635		return nil, err
636	}
637	u := fmt.Sprintf("projects/%s/services/jenkins", PathEscape(project))
638
639	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
640	if err != nil {
641		return nil, err
642	}
643
644	return s.client.Do(req, nil)
645}
646
647// JiraService represents Jira service settings.
648//
649// GitLab API docs:
650// https://docs.gitlab.com/ce/api/services.html#jira
651type JiraService struct {
652	Service
653	Properties *JiraServiceProperties `json:"properties"`
654}
655
656// JiraServiceProperties represents Jira specific properties.
657//
658// GitLab API docs:
659// https://docs.gitlab.com/ce/api/services.html#jira
660type JiraServiceProperties struct {
661	URL                   string `json:"url"`
662	APIURL                string `json:"api_url"`
663	ProjectKey            string `json:"project_key" `
664	Username              string `json:"username" `
665	Password              string `json:"password" `
666	JiraIssueTransitionID string `json:"jira_issue_transition_id"`
667}
668
669// UnmarshalJSON decodes the Jira Service Properties.
670//
671// This allows support of JiraIssueTransitionID for both type string (>11.9) and float64 (<11.9)
672func (p *JiraServiceProperties) UnmarshalJSON(b []byte) error {
673	type Alias JiraServiceProperties
674	raw := struct {
675		*Alias
676		JiraIssueTransitionID interface{} `json:"jira_issue_transition_id"`
677	}{
678		Alias: (*Alias)(p),
679	}
680
681	if err := json.Unmarshal(b, &raw); err != nil {
682		return err
683	}
684
685	switch id := raw.JiraIssueTransitionID.(type) {
686	case nil:
687		// No action needed.
688	case string:
689		p.JiraIssueTransitionID = id
690	case float64:
691		p.JiraIssueTransitionID = strconv.Itoa(int(id))
692	default:
693		return fmt.Errorf("failed to unmarshal JiraTransitionID of type: %T", id)
694	}
695
696	return nil
697}
698
699// GetJiraService gets Jira service settings for a project.
700//
701// GitLab API docs:
702// https://docs.gitlab.com/ce/api/services.html#get-jira-service-settings
703func (s *ServicesService) GetJiraService(pid interface{}, options ...RequestOptionFunc) (*JiraService, *Response, error) {
704	project, err := parseID(pid)
705	if err != nil {
706		return nil, nil, err
707	}
708	u := fmt.Sprintf("projects/%s/services/jira", PathEscape(project))
709
710	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
711	if err != nil {
712		return nil, nil, err
713	}
714
715	svc := new(JiraService)
716	resp, err := s.client.Do(req, svc)
717	if err != nil {
718		return nil, resp, err
719	}
720
721	return svc, resp, err
722}
723
724// SetJiraServiceOptions represents the available SetJiraService()
725// options.
726//
727// GitLab API docs:
728// https://docs.gitlab.com/ce/api/services.html#edit-jira-service
729type SetJiraServiceOptions struct {
730	URL                   *string `url:"url,omitempty" json:"url,omitempty"`
731	APIURL                *string `url:"api_url,omitempty" json:"api_url,omitempty"`
732	ProjectKey            *string `url:"project_key,omitempty" json:"project_key,omitempty" `
733	Username              *string `url:"username,omitempty" json:"username,omitempty" `
734	Password              *string `url:"password,omitempty" json:"password,omitempty" `
735	Active                *bool   `url:"active,omitempty" json:"active,omitempty"`
736	JiraIssueTransitionID *string `url:"jira_issue_transition_id,omitempty" json:"jira_issue_transition_id,omitempty"`
737	CommitEvents          *bool   `url:"commit_events,omitempty" json:"commit_events,omitempty"`
738	MergeRequestsEvents   *bool   `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
739	CommentOnEventEnabled *bool   `url:"comment_on_event_enabled,omitempty" json:"comment_on_event_enabled,omitempty"`
740}
741
742// SetJiraService sets Jira service for a project
743//
744// GitLab API docs:
745// https://docs.gitlab.com/ce/api/services.html#edit-jira-service
746func (s *ServicesService) SetJiraService(pid interface{}, opt *SetJiraServiceOptions, options ...RequestOptionFunc) (*Response, error) {
747	project, err := parseID(pid)
748	if err != nil {
749		return nil, err
750	}
751	u := fmt.Sprintf("projects/%s/services/jira", PathEscape(project))
752
753	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
754	if err != nil {
755		return nil, err
756	}
757
758	return s.client.Do(req, nil)
759}
760
761// DeleteJiraService deletes Jira service for project.
762//
763// GitLab API docs:
764// https://docs.gitlab.com/ce/api/services.html#delete-jira-service
765func (s *ServicesService) DeleteJiraService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
766	project, err := parseID(pid)
767	if err != nil {
768		return nil, err
769	}
770	u := fmt.Sprintf("projects/%s/services/jira", PathEscape(project))
771
772	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
773	if err != nil {
774		return nil, err
775	}
776
777	return s.client.Do(req, nil)
778}
779
780// MattermostService represents Mattermost service settings.
781//
782// GitLab API docs:
783// https://docs.gitlab.com/ce/api/services.html#mattermost-notifications
784type MattermostService struct {
785	Service
786	Properties *MattermostServiceProperties `json:"properties"`
787}
788
789// MattermostServiceProperties represents Mattermost specific properties.
790//
791// GitLab API docs:
792// https://docs.gitlab.com/ce/api/services.html#mattermost-notifications
793type MattermostServiceProperties struct {
794	WebHook                   string    `json:"webhook"`
795	Username                  string    `json:"username"`
796	Channel                   string    `json:"channel"`
797	NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines"`
798	BranchesToBeNotified      string    `json:"branches_to_be_notified"`
799	ConfidentialIssueChannel  string    `json:"confidential_issue_channel"`
800	ConfidentialNoteChannel   string    `json:"confidential_note_channel"`
801	IssueChannel              string    `json:"issue_channel"`
802	MergeRequestChannel       string    `json:"merge_request_channel"`
803	NoteChannel               string    `json:"note_channel"`
804	TagPushChannel            string    `json:"tag_push_channel"`
805	PipelineChannel           string    `json:"pipeline_channel"`
806	PushChannel               string    `json:"push_channel"`
807	WikiPageChannel           string    `json:"wiki_page_channel"`
808}
809
810// GetMattermostService gets Mattermost service settings for a project.
811//
812// GitLab API docs:
813// https://docs.gitlab.com/ce/api/services.html#get-slack-service-settings
814func (s *ServicesService) GetMattermostService(pid interface{}, options ...RequestOptionFunc) (*MattermostService, *Response, error) {
815	project, err := parseID(pid)
816	if err != nil {
817		return nil, nil, err
818	}
819	u := fmt.Sprintf("projects/%s/services/mattermost", PathEscape(project))
820
821	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
822	if err != nil {
823		return nil, nil, err
824	}
825
826	svc := new(MattermostService)
827	resp, err := s.client.Do(req, svc)
828	if err != nil {
829		return nil, resp, err
830	}
831
832	return svc, resp, err
833}
834
835// SetMattermostServiceOptions represents the available SetMattermostService()
836// options.
837//
838// GitLab API docs:
839// https://docs.gitlab.com/ce/api/services.html#createedit-mattermost-notifications-service
840type SetMattermostServiceOptions struct {
841	WebHook                   *string `url:"webhook,omitempty" json:"webhook,omitempty"`
842	Username                  *string `url:"username,omitempty" json:"username,omitempty"`
843	Channel                   *string `url:"channel,omitempty" json:"channel,omitempty"`
844	NotifyOnlyBrokenPipelines *bool   `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"`
845	BranchesToBeNotified      *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"`
846	ConfidentialIssueChannel  *string `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"`
847	ConfidentialIssuesEvents  *bool   `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"`
848	ConfidentialNoteChannel   *string `json:"confidential_note_channel,omitempty"`
849	ConfidentialNoteEvents    *bool   `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"`
850	IssueChannel              *string `url:"issue_channel,omitempty" json:"issue_channel,omitempty"`
851	IssuesEvents              *bool   `url:"issues_events,omitempty" json:"issues_events,omitempty"`
852	MergeRequestChannel       *string `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"`
853	MergeRequestsEvents       *bool   `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
854	TagPushChannel            *string `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"`
855	TagPushEvents             *bool   `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
856	NoteChannel               *string `url:"note_channel,omitempty" json:"note_channel,omitempty"`
857	NoteEvents                *bool   `url:"note_events,omitempty" json:"note_events,omitempty"`
858	PipelineChannel           *string `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"`
859	PipelineEvents            *bool   `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
860	PushChannel               *string `url:"push_channel,omitempty" json:"push_channel,omitempty"`
861	PushEvents                *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
862	WikiPageChannel           *string `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"`
863	WikiPageEvents            *bool   `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"`
864}
865
866// SetMattermostService sets Mattermost service for a project.
867//
868// GitLab API docs:
869// https://docs.gitlab.com/ce/api/services.html#createedit-mattermost-notifications-service
870func (s *ServicesService) SetMattermostService(pid interface{}, opt *SetMattermostServiceOptions, options ...RequestOptionFunc) (*Response, error) {
871	project, err := parseID(pid)
872	if err != nil {
873		return nil, err
874	}
875	u := fmt.Sprintf("projects/%s/services/mattermost", PathEscape(project))
876
877	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
878	if err != nil {
879		return nil, err
880	}
881
882	return s.client.Do(req, nil)
883}
884
885// DeleteMattermostService deletes Mattermost service for project.
886//
887// GitLab API docs:
888// https://docs.gitlab.com/ce/api/services.html#delete-mattermost-notifications-service
889func (s *ServicesService) DeleteMattermostService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
890	project, err := parseID(pid)
891	if err != nil {
892		return nil, err
893	}
894	u := fmt.Sprintf("projects/%s/services/mattermost", PathEscape(project))
895
896	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
897	if err != nil {
898		return nil, err
899	}
900
901	return s.client.Do(req, nil)
902}
903
904// MicrosoftTeamsService represents Microsoft Teams service settings.
905//
906// GitLab API docs:
907// https://docs.gitlab.com/ce/api/services.html#microsoft-teams
908type MicrosoftTeamsService struct {
909	Service
910	Properties *MicrosoftTeamsServiceProperties `json:"properties"`
911}
912
913// MicrosoftTeamsServiceProperties represents Microsoft Teams specific properties.
914//
915// GitLab API docs:
916// https://docs.gitlab.com/ce/api/services.html#microsoft-teams
917type MicrosoftTeamsServiceProperties struct {
918	WebHook                   string    `json:"webhook"`
919	NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines"`
920	BranchesToBeNotified      string    `json:"branches_to_be_notified"`
921	IssuesEvents              BoolValue `json:"issues_events"`
922	ConfidentialIssuesEvents  BoolValue `json:"confidential_issues_events"`
923	MergeRequestsEvents       BoolValue `json:"merge_requests_events"`
924	TagPushEvents             BoolValue `json:"tag_push_events"`
925	NoteEvents                BoolValue `json:"note_events"`
926	ConfidentialNoteEvents    BoolValue `json:"confidential_note_events"`
927	PipelineEvents            BoolValue `json:"pipeline_events"`
928	WikiPageEvents            BoolValue `json:"wiki_page_events"`
929}
930
931// GetMicrosoftTeamsService gets MicrosoftTeams service settings for a project.
932//
933// GitLab API docs:
934// https://docs.gitlab.com/ce/api/services.html#get-microsoft-teams-service-settings
935func (s *ServicesService) GetMicrosoftTeamsService(pid interface{}, options ...RequestOptionFunc) (*MicrosoftTeamsService, *Response, error) {
936	project, err := parseID(pid)
937	if err != nil {
938		return nil, nil, err
939	}
940	u := fmt.Sprintf("projects/%s/services/microsoft-teams", PathEscape(project))
941
942	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
943	if err != nil {
944		return nil, nil, err
945	}
946
947	svc := new(MicrosoftTeamsService)
948	resp, err := s.client.Do(req, svc)
949	if err != nil {
950		return nil, resp, err
951	}
952
953	return svc, resp, err
954}
955
956// SetMicrosoftTeamsServiceOptions represents the available SetMicrosoftTeamsService()
957// options.
958//
959// GitLab API docs:
960// https://docs.gitlab.com/ce/api/services.html#create-edit-microsoft-teams-service
961type SetMicrosoftTeamsServiceOptions struct {
962	WebHook                   *string `url:"webhook,omitempty" json:"webhook,omitempty"`
963	NotifyOnlyBrokenPipelines *bool   `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"`
964	BranchesToBeNotified      *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"`
965	PushEvents                *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
966	IssuesEvents              *bool   `url:"issues_events,omitempty" json:"issues_events,omitempty"`
967	ConfidentialIssuesEvents  *bool   `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"`
968	MergeRequestsEvents       *bool   `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
969	TagPushEvents             *bool   `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
970	NoteEvents                *bool   `url:"note_events,omitempty" json:"note_events,omitempty"`
971	ConfidentialNoteEvents    *bool   `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"`
972	PipelineEvents            *bool   `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
973	WikiPageEvents            *bool   `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"`
974}
975
976// SetMicrosoftTeamsService sets Microsoft Teams service for a project
977//
978// GitLab API docs:
979// https://docs.gitlab.com/ce/api/services.html#create-edit-microsoft-teams-service
980func (s *ServicesService) SetMicrosoftTeamsService(pid interface{}, opt *SetMicrosoftTeamsServiceOptions, options ...RequestOptionFunc) (*Response, error) {
981	project, err := parseID(pid)
982	if err != nil {
983		return nil, err
984	}
985	u := fmt.Sprintf("projects/%s/services/microsoft-teams", PathEscape(project))
986
987	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
988	if err != nil {
989		return nil, err
990	}
991	return s.client.Do(req, nil)
992}
993
994// DeleteMicrosoftTeamsService deletes Microsoft Teams service for project.
995//
996// GitLab API docs:
997// https://docs.gitlab.com/ce/api/services.html#delete-microsoft-teams-service
998func (s *ServicesService) DeleteMicrosoftTeamsService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
999	project, err := parseID(pid)
1000	if err != nil {
1001		return nil, err
1002	}
1003	u := fmt.Sprintf("projects/%s/services/microsoft-teams", PathEscape(project))
1004
1005	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
1006	if err != nil {
1007		return nil, err
1008	}
1009
1010	return s.client.Do(req, nil)
1011}
1012
1013// PipelinesEmailService represents Pipelines Email service settings.
1014//
1015// GitLab API docs:
1016// https://docs.gitlab.com/ee/api/services.html#pipeline-emails
1017type PipelinesEmailService struct {
1018	Service
1019	Properties *PipelinesEmailProperties `json:"properties"`
1020}
1021
1022// PipelinesEmailProperties represents PipelinesEmail specific properties.
1023//
1024// GitLab API docs:
1025// https://docs.gitlab.com/ee/api/services.html#pipeline-emails
1026type PipelinesEmailProperties struct {
1027	Recipients                string    `json:"recipients"`
1028	NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines"`
1029	NotifyOnlyDefaultBranch   BoolValue `json:"notify_only_default_branch"`
1030	BranchesToBeNotified      string    `json:"branches_to_be_notified"`
1031}
1032
1033// GetPipelinesEmailService gets Pipelines Email service settings for a project.
1034//
1035// GitLab API docs:
1036// https://docs.gitlab.com/ee/api/services.html#get-pipeline-emails-service-settings
1037func (s *ServicesService) GetPipelinesEmailService(pid interface{}, options ...RequestOptionFunc) (*PipelinesEmailService, *Response, error) {
1038	project, err := parseID(pid)
1039	if err != nil {
1040		return nil, nil, err
1041	}
1042	u := fmt.Sprintf("projects/%s/services/pipelines-email", PathEscape(project))
1043
1044	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
1045	if err != nil {
1046		return nil, nil, err
1047	}
1048
1049	svc := new(PipelinesEmailService)
1050	resp, err := s.client.Do(req, svc)
1051	if err != nil {
1052		return nil, resp, err
1053	}
1054
1055	return svc, resp, err
1056}
1057
1058// SetPipelinesEmailServiceOptions represents the available
1059// SetPipelinesEmailService() options.
1060//
1061// GitLab API docs:
1062// https://docs.gitlab.com/ee/api/services.html#pipeline-emails
1063type SetPipelinesEmailServiceOptions struct {
1064	Recipients                *string `url:"recipients,omitempty" json:"recipients,omitempty"`
1065	NotifyOnlyBrokenPipelines *bool   `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"`
1066	NotifyOnlyDefaultBranch   *bool   `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"`
1067	AddPusher                 *bool   `url:"add_pusher,omitempty" json:"add_pusher,omitempty"`
1068	BranchesToBeNotified      *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"`
1069	PipelineEvents            *bool   `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
1070}
1071
1072// SetPipelinesEmailService sets Pipelines Email service for a project.
1073//
1074// GitLab API docs:
1075// https://docs.gitlab.com/ee/api/services.html#pipeline-emails
1076func (s *ServicesService) SetPipelinesEmailService(pid interface{}, opt *SetPipelinesEmailServiceOptions, options ...RequestOptionFunc) (*Response, error) {
1077	project, err := parseID(pid)
1078	if err != nil {
1079		return nil, err
1080	}
1081	u := fmt.Sprintf("projects/%s/services/pipelines-email", PathEscape(project))
1082
1083	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
1084	if err != nil {
1085		return nil, err
1086	}
1087
1088	return s.client.Do(req, nil)
1089}
1090
1091// DeletePipelinesEmailService deletes Pipelines Email service settings for a project.
1092//
1093// GitLab API docs:
1094// https://docs.gitlab.com/ee/api/services.html#delete-pipeline-emails-service
1095func (s *ServicesService) DeletePipelinesEmailService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
1096	project, err := parseID(pid)
1097	if err != nil {
1098		return nil, err
1099	}
1100	u := fmt.Sprintf("projects/%s/services/pipelines-email", PathEscape(project))
1101
1102	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
1103	if err != nil {
1104		return nil, err
1105	}
1106
1107	return s.client.Do(req, nil)
1108}
1109
1110// PrometheusService represents Prometheus service settings.
1111//
1112// GitLab API docs:
1113// https://docs.gitlab.com/ee/api/services.html#prometheus
1114type PrometheusService struct {
1115	Service
1116	Properties *PrometheusServiceProperties `json:"properties"`
1117}
1118
1119// PrometheusServiceProperties represents Prometheus specific properties.
1120//
1121// GitLab API docs:
1122// https://docs.gitlab.com/ee/api/services.html#prometheus
1123type PrometheusServiceProperties struct {
1124	APIURL                      string `json:"api_url"`
1125	GoogleIAPAudienceClientID   string `json:"google_iap_audience_client_id"`
1126	GoogleIAPServiceAccountJSON string `json:"google_iap_service_account_json"`
1127}
1128
1129// GetPrometheusService gets Prometheus service settings for a project.
1130//
1131// GitLab API docs:
1132// https://docs.gitlab.com/ee/api/services.html#get-prometheus-service-settings
1133func (s *ServicesService) GetPrometheusService(pid interface{}, options ...RequestOptionFunc) (*PrometheusService, *Response, error) {
1134	project, err := parseID(pid)
1135	if err != nil {
1136		return nil, nil, err
1137	}
1138	u := fmt.Sprintf("projects/%s/services/prometheus", PathEscape(project))
1139
1140	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
1141	if err != nil {
1142		return nil, nil, err
1143	}
1144
1145	svc := new(PrometheusService)
1146	resp, err := s.client.Do(req, svc)
1147	if err != nil {
1148		return nil, resp, err
1149	}
1150
1151	return svc, resp, err
1152}
1153
1154// SetPrometheusServiceOptions represents the available SetPrometheusService()
1155// options.
1156//
1157// GitLab API docs:
1158// https://docs.gitlab.com/ee/api/services.html#createedit-prometheus-service
1159type SetPrometheusServiceOptions struct {
1160	APIURL                      *string `url:"api_url,omitempty" json:"api_url,omitempty"`
1161	GoogleIAPAudienceClientID   *string `url:"google_iap_audience_client_id,omitempty" json:"google_iap_audience_client_id,omitempty"`
1162	GoogleIAPServiceAccountJSON *string `url:"google_iap_service_account_json,omitempty" json:"google_iap_service_account_json,omitempty"`
1163}
1164
1165// SetPrometheusService sets Prometheus service for a project.
1166//
1167// GitLab API docs:
1168// https://docs.gitlab.com/ee/api/services.html#createedit-prometheus-service
1169func (s *ServicesService) SetPrometheusService(pid interface{}, opt *SetPrometheusServiceOptions, options ...RequestOptionFunc) (*Response, error) {
1170	project, err := parseID(pid)
1171	if err != nil {
1172		return nil, err
1173	}
1174	u := fmt.Sprintf("projects/%s/services/prometheus", PathEscape(project))
1175
1176	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
1177	if err != nil {
1178		return nil, err
1179	}
1180
1181	return s.client.Do(req, nil)
1182}
1183
1184// DeletePrometheusService deletes Prometheus service settings for a project.
1185//
1186// GitLab API docs:
1187// https://docs.gitlab.com/ee/api/services.html#delete-prometheus-service
1188func (s *ServicesService) DeletePrometheusService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
1189	project, err := parseID(pid)
1190	if err != nil {
1191		return nil, err
1192	}
1193	u := fmt.Sprintf("projects/%s/services/prometheus", PathEscape(project))
1194
1195	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
1196	if err != nil {
1197		return nil, err
1198	}
1199
1200	return s.client.Do(req, nil)
1201}
1202
1203// SlackService represents Slack service settings.
1204//
1205// GitLab API docs:
1206// https://docs.gitlab.com/ce/api/services.html#slack
1207type SlackService struct {
1208	Service
1209	Properties *SlackServiceProperties `json:"properties"`
1210}
1211
1212// SlackServiceProperties represents Slack specific properties.
1213//
1214// GitLab API docs:
1215// https://docs.gitlab.com/ce/api/services.html#slack
1216type SlackServiceProperties struct {
1217	WebHook                   string    `json:"webhook"`
1218	Username                  string    `json:"username"`
1219	Channel                   string    `json:"channel"`
1220	NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines"`
1221	NotifyOnlyDefaultBranch   BoolValue `json:"notify_only_default_branch"`
1222	BranchesToBeNotified      string    `json:"branches_to_be_notified"`
1223	ConfidentialIssueChannel  string    `json:"confidential_issue_channel"`
1224	ConfidentialNoteChannel   string    `json:"confidential_note_channel"`
1225	DeploymentChannel         string    `json:"deployment_channel"`
1226	IssueChannel              string    `json:"issue_channel"`
1227	MergeRequestChannel       string    `json:"merge_request_channel"`
1228	NoteChannel               string    `json:"note_channel"`
1229	TagPushChannel            string    `json:"tag_push_channel"`
1230	PipelineChannel           string    `json:"pipeline_channel"`
1231	PushChannel               string    `json:"push_channel"`
1232	WikiPageChannel           string    `json:"wiki_page_channel"`
1233}
1234
1235// GetSlackService gets Slack service settings for a project.
1236//
1237// GitLab API docs:
1238// https://docs.gitlab.com/ce/api/services.html#get-slack-service-settings
1239func (s *ServicesService) GetSlackService(pid interface{}, options ...RequestOptionFunc) (*SlackService, *Response, error) {
1240	project, err := parseID(pid)
1241	if err != nil {
1242		return nil, nil, err
1243	}
1244	u := fmt.Sprintf("projects/%s/services/slack", PathEscape(project))
1245
1246	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
1247	if err != nil {
1248		return nil, nil, err
1249	}
1250
1251	svc := new(SlackService)
1252	resp, err := s.client.Do(req, svc)
1253	if err != nil {
1254		return nil, resp, err
1255	}
1256
1257	return svc, resp, err
1258}
1259
1260// SetSlackServiceOptions represents the available SetSlackService()
1261// options.
1262//
1263// GitLab API docs:
1264// https://docs.gitlab.com/ce/api/services.html#edit-slack-service
1265type SetSlackServiceOptions struct {
1266	WebHook                   *string `url:"webhook,omitempty" json:"webhook,omitempty"`
1267	Username                  *string `url:"username,omitempty" json:"username,omitempty"`
1268	Channel                   *string `url:"channel,omitempty" json:"channel,omitempty"`
1269	NotifyOnlyBrokenPipelines *bool   `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"`
1270	NotifyOnlyDefaultBranch   *bool   `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"`
1271	BranchesToBeNotified      *string `url:"branches_to_be_notified,omitempty" json:"branches_to_be_notified,omitempty"`
1272	ConfidentialIssueChannel  *string `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"`
1273	ConfidentialIssuesEvents  *bool   `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"`
1274	// TODO: Currently, GitLab ignores this option (not implemented yet?), so
1275	// there is no way to set it. Uncomment when this is fixed.
1276	// See: https://gitlab.com/gitlab-org/gitlab-ce/issues/49730
1277	//ConfidentialNoteChannel   *string `json:"confidential_note_channel,omitempty"`
1278	ConfidentialNoteEvents *bool   `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"`
1279	DeploymentChannel      *string `url:"deployment_channel,omitempty" json:"deployment_channel,omitempty"`
1280	DeploymentEvents       *bool   `url:"deployment_events,omitempty" json:"deployment_events,omitempty"`
1281	IssueChannel           *string `url:"issue_channel,omitempty" json:"issue_channel,omitempty"`
1282	IssuesEvents           *bool   `url:"issues_events,omitempty" json:"issues_events,omitempty"`
1283	MergeRequestChannel    *string `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"`
1284	MergeRequestsEvents    *bool   `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
1285	TagPushChannel         *string `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"`
1286	TagPushEvents          *bool   `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
1287	NoteChannel            *string `url:"note_channel,omitempty" json:"note_channel,omitempty"`
1288	NoteEvents             *bool   `url:"note_events,omitempty" json:"note_events,omitempty"`
1289	PipelineChannel        *string `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"`
1290	PipelineEvents         *bool   `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
1291	PushChannel            *string `url:"push_channel,omitempty" json:"push_channel,omitempty"`
1292	PushEvents             *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
1293	WikiPageChannel        *string `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"`
1294	WikiPageEvents         *bool   `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"`
1295}
1296
1297// SetSlackService sets Slack service for a project
1298//
1299// GitLab API docs:
1300// https://docs.gitlab.com/ce/api/services.html#edit-slack-service
1301func (s *ServicesService) SetSlackService(pid interface{}, opt *SetSlackServiceOptions, options ...RequestOptionFunc) (*Response, error) {
1302	project, err := parseID(pid)
1303	if err != nil {
1304		return nil, err
1305	}
1306	u := fmt.Sprintf("projects/%s/services/slack", PathEscape(project))
1307
1308	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
1309	if err != nil {
1310		return nil, err
1311	}
1312
1313	return s.client.Do(req, nil)
1314}
1315
1316// DeleteSlackService deletes Slack service for project.
1317//
1318// GitLab API docs:
1319// https://docs.gitlab.com/ce/api/services.html#delete-slack-service
1320func (s *ServicesService) DeleteSlackService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
1321	project, err := parseID(pid)
1322	if err != nil {
1323		return nil, err
1324	}
1325	u := fmt.Sprintf("projects/%s/services/slack", PathEscape(project))
1326
1327	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
1328	if err != nil {
1329		return nil, err
1330	}
1331
1332	return s.client.Do(req, nil)
1333}
1334
1335// SlackSlashCommandsService represents Slack slash commands settings.
1336//
1337// GitLab API docs:
1338// https://docs.gitlab.com/ee/api/integrations.html#slack-slash-commands
1339type SlackSlashCommandsService struct {
1340	Service
1341	Properties *SlackSlashCommandsProperties `json:"properties"`
1342}
1343
1344// SlackSlashCommandsProperties represents Slack slash commands specific properties.
1345//
1346// GitLab API docs:
1347// https://docs.gitlab.com/ee/api/integrations.html#slack-slash-commands
1348type SlackSlashCommandsProperties struct {
1349	Token string `json:"token"`
1350}
1351
1352// GetSlackSlashCommandsService gets Slack slash commands service settings for a project.
1353//
1354// GitLab API docs:
1355// https://docs.gitlab.com/ee/api/integrations.html#get-slack-slash-command-integration-settings
1356func (s *ServicesService) GetSlackSlashCommandsService(pid interface{}, options ...RequestOptionFunc) (*SlackSlashCommandsService, *Response, error) {
1357	project, err := parseID(pid)
1358	if err != nil {
1359		return nil, nil, err
1360	}
1361	u := fmt.Sprintf("projects/%s/services/slack-slash-commands", PathEscape(project))
1362
1363	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
1364	if err != nil {
1365		return nil, nil, err
1366	}
1367
1368	svc := new(SlackSlashCommandsService)
1369	resp, err := s.client.Do(req, svc)
1370	if err != nil {
1371		return nil, resp, err
1372	}
1373
1374	return svc, resp, err
1375}
1376
1377// SetSlackSlashCommandsServiceOptions represents the available SetSlackSlashCommandsService()
1378// options.
1379//
1380// GitLab API docs:
1381// https://docs.gitlab.com/ee/api/services.html#createedit-slack-slash-command-service
1382type SetSlackSlashCommandsServiceOptions struct {
1383	Token *string `url:"token,omitempty" json:"token,omitempty"`
1384}
1385
1386// SetSlackSlashCommandsService sets Slack slash commands service for a project
1387//
1388// GitLab API docs:
1389// https://docs.gitlab.com/13.12/ee/api/services.html#createedit-slack-slash-command-service
1390func (s *ServicesService) SetSlackSlashCommandsService(pid interface{}, opt *SetSlackSlashCommandsServiceOptions, options ...RequestOptionFunc) (*Response, error) {
1391	project, err := parseID(pid)
1392	if err != nil {
1393		return nil, err
1394	}
1395	u := fmt.Sprintf("projects/%s/services/slack-slash-commands", PathEscape(project))
1396
1397	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
1398	if err != nil {
1399		return nil, err
1400	}
1401
1402	return s.client.Do(req, nil)
1403}
1404
1405// DeleteSlackSlashCommandsService deletes Slack slash commands service for project.
1406//
1407// GitLab API docs:
1408// https://docs.gitlab.com/13.12/ee/api/services.html#delete-slack-slash-command-service
1409func (s *ServicesService) DeleteSlackSlashCommandsService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
1410	project, err := parseID(pid)
1411	if err != nil {
1412		return nil, err
1413	}
1414	u := fmt.Sprintf("projects/%s/services/slack-slash-commands", PathEscape(project))
1415
1416	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
1417	if err != nil {
1418		return nil, err
1419	}
1420
1421	return s.client.Do(req, nil)
1422}
1423
1424// YouTrackService represents YouTrack service settings.
1425//
1426// GitLab API docs:
1427// https://docs.gitlab.com/ce/api/services.html#youtrack
1428type YouTrackService struct {
1429	Service
1430	Properties *YouTrackServiceProperties `json:"properties"`
1431}
1432
1433// YouTrackServiceProperties represents YouTrack specific properties.
1434//
1435// GitLab API docs:
1436// https://docs.gitlab.com/ce/api/services.html#youtrack
1437type YouTrackServiceProperties struct {
1438	IssuesURL   string `json:"issues_url"`
1439	ProjectURL  string `json:"project_url"`
1440	Description string `json:"description"`
1441	PushEvents  bool   `json:"push_events"`
1442}
1443
1444// GetYouTrackService gets YouTrack service settings for a project.
1445//
1446// GitLab API docs:
1447// https://docs.gitlab.com/ce/api/services.html#get-youtrack-service-settings
1448func (s *ServicesService) GetYouTrackService(pid interface{}, options ...RequestOptionFunc) (*YouTrackService, *Response, error) {
1449	project, err := parseID(pid)
1450	if err != nil {
1451		return nil, nil, err
1452	}
1453	u := fmt.Sprintf("projects/%s/services/youtrack", PathEscape(project))
1454
1455	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
1456	if err != nil {
1457		return nil, nil, err
1458	}
1459
1460	svc := new(YouTrackService)
1461	resp, err := s.client.Do(req, svc)
1462	if err != nil {
1463		return nil, resp, err
1464	}
1465
1466	return svc, resp, err
1467}
1468
1469// SetYouTrackServiceOptions represents the available SetYouTrackService()
1470// options.
1471//
1472// GitLab API docs:
1473// https://docs.gitlab.com/ce/api/services.html#createedit-youtrack-service
1474type SetYouTrackServiceOptions struct {
1475	IssuesURL   *string `url:"issues_url,omitempty" json:"issues_url,omitempty"`
1476	ProjectURL  *string `url:"project_url,omitempty" json:"project_url,omitempty"`
1477	Description *string `url:"description,omitempty" json:"description,omitempty"`
1478	PushEvents  *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
1479}
1480
1481// SetYouTrackService sets YouTrack service for a project
1482//
1483// GitLab API docs:
1484// https://docs.gitlab.com/ce/api/services.html#createedit-youtrack-service
1485func (s *ServicesService) SetYouTrackService(pid interface{}, opt *SetYouTrackServiceOptions, options ...RequestOptionFunc) (*Response, error) {
1486	project, err := parseID(pid)
1487	if err != nil {
1488		return nil, err
1489	}
1490	u := fmt.Sprintf("projects/%s/services/youtrack", PathEscape(project))
1491
1492	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
1493	if err != nil {
1494		return nil, err
1495	}
1496
1497	return s.client.Do(req, nil)
1498}
1499
1500// DeleteYouTrackService deletes YouTrack service settings for a project.
1501//
1502// GitLab API docs:
1503// https://docs.gitlab.com/ce/api/services.html#delete-youtrack-service
1504func (s *ServicesService) DeleteYouTrackService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
1505	project, err := parseID(pid)
1506	if err != nil {
1507		return nil, err
1508	}
1509	u := fmt.Sprintf("projects/%s/services/youtrack", PathEscape(project))
1510
1511	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
1512	if err != nil {
1513		return nil, err
1514	}
1515
1516	return s.client.Do(req, nil)
1517}
1518