services.go

  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	"encoding/json"
 21	"fmt"
 22	"strconv"
 23	"time"
 24)
 25
 26// ServicesService handles communication with the services related methods of
 27// the GitLab API.
 28//
 29// GitLab API docs: https://docs.gitlab.com/ce/api/services.html
 30type ServicesService struct {
 31	client *Client
 32}
 33
 34// Service represents a GitLab service.
 35//
 36// GitLab API docs: https://docs.gitlab.com/ce/api/services.html
 37type Service struct {
 38	ID                       int        `json:"id"`
 39	Title                    string     `json:"title"`
 40	CreatedAt                *time.Time `json:"created_at"`
 41	UpdatedAt                *time.Time `json:"updated_at"`
 42	Active                   bool       `json:"active"`
 43	PushEvents               bool       `json:"push_events"`
 44	IssuesEvents             bool       `json:"issues_events"`
 45	ConfidentialIssuesEvents bool       `json:"confidential_issues_events"`
 46	MergeRequestsEvents      bool       `json:"merge_requests_events"`
 47	TagPushEvents            bool       `json:"tag_push_events"`
 48	NoteEvents               bool       `json:"note_events"`
 49	ConfidentialNoteEvents   bool       `json:"confidential_note_events"`
 50	PipelineEvents           bool       `json:"pipeline_events"`
 51	JobEvents                bool       `json:"job_events"`
 52	WikiPageEvents           bool       `json:"wiki_page_events"`
 53}
 54
 55// SetGitLabCIServiceOptions represents the available SetGitLabCIService()
 56// options.
 57//
 58// GitLab API docs:
 59// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service
 60type SetGitLabCIServiceOptions struct {
 61	Token      *string `url:"token,omitempty" json:"token,omitempty"`
 62	ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"`
 63}
 64
 65// SetGitLabCIService sets GitLab CI service for a project.
 66//
 67// GitLab API docs:
 68// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service
 69func (s *ServicesService) SetGitLabCIService(pid interface{}, opt *SetGitLabCIServiceOptions, options ...OptionFunc) (*Response, error) {
 70	project, err := parseID(pid)
 71	if err != nil {
 72		return nil, err
 73	}
 74	u := fmt.Sprintf("projects/%s/services/gitlab-ci", pathEscape(project))
 75
 76	req, err := s.client.NewRequest("PUT", u, opt, options)
 77	if err != nil {
 78		return nil, err
 79	}
 80
 81	return s.client.Do(req, nil)
 82}
 83
 84// DeleteGitLabCIService deletes GitLab CI service settings for a project.
 85//
 86// GitLab API docs:
 87// https://docs.gitlab.com/ce/api/services.html#delete-gitlab-ci-service
 88func (s *ServicesService) DeleteGitLabCIService(pid interface{}, options ...OptionFunc) (*Response, error) {
 89	project, err := parseID(pid)
 90	if err != nil {
 91		return nil, err
 92	}
 93	u := fmt.Sprintf("projects/%s/services/gitlab-ci", pathEscape(project))
 94
 95	req, err := s.client.NewRequest("DELETE", u, nil, options)
 96	if err != nil {
 97		return nil, err
 98	}
 99
100	return s.client.Do(req, nil)
101}
102
103// GithubService represents Github service settings.
104//
105// GitLab API docs:
106// https://docs.gitlab.com/ce/api/services.html#github-premium
107type GithubService struct {
108	Service
109	Properties *GithubServiceProperties `json:"properties"`
110}
111
112// GithubServiceProperties represents Github specific properties.
113//
114// GitLab API docs:
115// https://docs.gitlab.com/ce/api/services.html#github-premium
116type GithubServiceProperties struct {
117	RepositoryURL string `json:"repository_url,omitempty"`
118	StaticContext string `json:"static_context,omitempty"`
119}
120
121// GetGithubService gets Github service settings for a project.
122//
123// GitLab API docs:
124// https://docs.gitlab.com/ce/api/services.html#get-github-service-settings
125func (s *ServicesService) GetGithubService(pid interface{}, options ...OptionFunc) (*GithubService, *Response, error) {
126	project, err := parseID(pid)
127	if err != nil {
128		return nil, nil, err
129	}
130	u := fmt.Sprintf("projects/%s/services/github", pathEscape(project))
131
132	req, err := s.client.NewRequest("GET", u, nil, options)
133	if err != nil {
134		return nil, nil, err
135	}
136
137	svc := new(GithubService)
138	resp, err := s.client.Do(req, svc)
139	if err != nil {
140		return nil, resp, err
141	}
142
143	return svc, resp, err
144}
145
146// SetGithubServiceOptions represents the available SetGithubService()
147// options.
148//
149// GitLab API docs:
150// https://docs.gitlab.com/ce/api/services.html#createedit-github-service
151type SetGithubServiceOptions struct {
152	Token         *string `url:"token,omitempty" json:"token,omitempty"`
153	RepositoryURL *string `url:"repository_url,omitempty" json:"repository_url,omitempty"`
154	StaticContext *bool   `url:"static_context,omitempty" json:"static_context,omitempty"`
155}
156
157// SetGithubService sets Github service for a project
158//
159// GitLab API docs:
160// https://docs.gitlab.com/ce/api/services.html#createedit-github-service
161func (s *ServicesService) SetGithubService(pid interface{}, opt *SetGithubServiceOptions, options ...OptionFunc) (*Response, error) {
162	project, err := parseID(pid)
163	if err != nil {
164		return nil, err
165	}
166	u := fmt.Sprintf("projects/%s/services/github", pathEscape(project))
167
168	req, err := s.client.NewRequest("PUT", u, opt, options)
169	if err != nil {
170		return nil, err
171	}
172
173	return s.client.Do(req, nil)
174}
175
176// DeleteGithubService deletes Github service for a project
177//
178// GitLab API docs:
179// https://docs.gitlab.com/ce/api/services.html#delete-github-service
180func (s *ServicesService) DeleteGithubService(pid interface{}, options ...OptionFunc) (*Response, error) {
181	project, err := parseID(pid)
182	if err != nil {
183		return nil, err
184	}
185	u := fmt.Sprintf("projects/%s/services/github", pathEscape(project))
186
187	req, err := s.client.NewRequest("DELETE", u, nil, options)
188	if err != nil {
189		return nil, err
190	}
191
192	return s.client.Do(req, nil)
193}
194
195// SetHipChatServiceOptions represents the available SetHipChatService()
196// options.
197//
198// GitLab API docs:
199// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service
200type SetHipChatServiceOptions struct {
201	Token *string `url:"token,omitempty" json:"token,omitempty" `
202	Room  *string `url:"room,omitempty" json:"room,omitempty"`
203}
204
205// SetHipChatService sets HipChat service for a project
206//
207// GitLab API docs:
208// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service
209func (s *ServicesService) SetHipChatService(pid interface{}, opt *SetHipChatServiceOptions, options ...OptionFunc) (*Response, error) {
210	project, err := parseID(pid)
211	if err != nil {
212		return nil, err
213	}
214	u := fmt.Sprintf("projects/%s/services/hipchat", pathEscape(project))
215
216	req, err := s.client.NewRequest("PUT", u, opt, options)
217	if err != nil {
218		return nil, err
219	}
220
221	return s.client.Do(req, nil)
222}
223
224// DeleteHipChatService deletes HipChat service for project.
225//
226// GitLab API docs:
227// https://docs.gitlab.com/ce/api/services.html#delete-hipchat-service
228func (s *ServicesService) DeleteHipChatService(pid interface{}, options ...OptionFunc) (*Response, error) {
229	project, err := parseID(pid)
230	if err != nil {
231		return nil, err
232	}
233	u := fmt.Sprintf("projects/%s/services/hipchat", pathEscape(project))
234
235	req, err := s.client.NewRequest("DELETE", u, nil, options)
236	if err != nil {
237		return nil, err
238	}
239
240	return s.client.Do(req, nil)
241}
242
243// DroneCIService represents Drone CI service settings.
244//
245// GitLab API docs:
246// https://docs.gitlab.com/ce/api/services.html#drone-ci
247type DroneCIService struct {
248	Service
249	Properties *DroneCIServiceProperties `json:"properties"`
250}
251
252// DroneCIServiceProperties represents Drone CI specific properties.
253//
254// GitLab API docs:
255// https://docs.gitlab.com/ce/api/services.html#drone-ci
256type DroneCIServiceProperties struct {
257	Token                 string `json:"token"`
258	DroneURL              string `json:"drone_url"`
259	EnableSSLVerification bool   `json:"enable_ssl_verification"`
260}
261
262// GetDroneCIService gets Drone CI service settings for a project.
263//
264// GitLab API docs:
265// https://docs.gitlab.com/ce/api/services.html#get-drone-ci-service-settings
266func (s *ServicesService) GetDroneCIService(pid interface{}, options ...OptionFunc) (*DroneCIService, *Response, error) {
267	project, err := parseID(pid)
268	if err != nil {
269		return nil, nil, err
270	}
271	u := fmt.Sprintf("projects/%s/services/drone-ci", pathEscape(project))
272
273	req, err := s.client.NewRequest("GET", u, nil, options)
274	if err != nil {
275		return nil, nil, err
276	}
277
278	svc := new(DroneCIService)
279	resp, err := s.client.Do(req, svc)
280	if err != nil {
281		return nil, resp, err
282	}
283
284	return svc, resp, err
285}
286
287// SetDroneCIServiceOptions represents the available SetDroneCIService()
288// options.
289//
290// GitLab API docs:
291// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service
292type SetDroneCIServiceOptions struct {
293	Token                 *string `url:"token" json:"token" `
294	DroneURL              *string `url:"drone_url" json:"drone_url"`
295	EnableSSLVerification *bool   `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
296}
297
298// SetDroneCIService sets Drone CI service for a project.
299//
300// GitLab API docs:
301// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service
302func (s *ServicesService) SetDroneCIService(pid interface{}, opt *SetDroneCIServiceOptions, options ...OptionFunc) (*Response, error) {
303	project, err := parseID(pid)
304	if err != nil {
305		return nil, err
306	}
307	u := fmt.Sprintf("projects/%s/services/drone-ci", pathEscape(project))
308
309	req, err := s.client.NewRequest("PUT", u, opt, options)
310	if err != nil {
311		return nil, err
312	}
313
314	return s.client.Do(req, nil)
315}
316
317// DeleteDroneCIService deletes Drone CI service settings for a project.
318//
319// GitLab API docs:
320// https://docs.gitlab.com/ce/api/services.html#delete-drone-ci-service
321func (s *ServicesService) DeleteDroneCIService(pid interface{}, options ...OptionFunc) (*Response, error) {
322	project, err := parseID(pid)
323	if err != nil {
324		return nil, err
325	}
326	u := fmt.Sprintf("projects/%s/services/drone-ci", pathEscape(project))
327
328	req, err := s.client.NewRequest("DELETE", u, nil, options)
329	if err != nil {
330		return nil, err
331	}
332
333	return s.client.Do(req, nil)
334}
335
336// SlackService represents Slack service settings.
337//
338// GitLab API docs:
339// https://docs.gitlab.com/ce/api/services.html#slack
340type SlackService struct {
341	Service
342	Properties *SlackServiceProperties `json:"properties"`
343}
344
345// SlackServiceProperties represents Slack specific properties.
346//
347// GitLab API docs:
348// https://docs.gitlab.com/ce/api/services.html#slack
349type SlackServiceProperties struct {
350	WebHook                   string    `json:"webhook,omitempty"`
351	Username                  string    `json:"username,omitempty"`
352	Channel                   string    `json:"channel,omitempty"`
353	NotifyOnlyBrokenPipelines BoolValue `json:"notify_only_broken_pipelines,omitempty"`
354	NotifyOnlyDefaultBranch   BoolValue `json:"notify_only_default_branch,omitempty"`
355	ConfidentialIssueChannel  string    `json:"confidential_issue_channel,omitempty"`
356	ConfidentialNoteChannel   string    `json:"confidential_note_channel,omitempty"`
357	DeploymentChannel         string    `json:"deployment_channel,omitempty"`
358	IssueChannel              string    `json:"issue_channel,omitempty"`
359	MergeRequestChannel       string    `json:"merge_request_channel,omitempty"`
360	NoteChannel               string    `json:"note_channel,omitempty"`
361	TagPushChannel            string    `json:"tag_push_channel,omitempty"`
362	PipelineChannel           string    `json:"pipeline_channel,omitempty"`
363	PushChannel               string    `json:"push_channel,omitempty"`
364	WikiPageChannel           string    `json:"wiki_page_channel,omitempty"`
365}
366
367// GetSlackService gets Slack service settings for a project.
368//
369// GitLab API docs:
370// https://docs.gitlab.com/ce/api/services.html#get-slack-service-settings
371func (s *ServicesService) GetSlackService(pid interface{}, options ...OptionFunc) (*SlackService, *Response, error) {
372	project, err := parseID(pid)
373	if err != nil {
374		return nil, nil, err
375	}
376	u := fmt.Sprintf("projects/%s/services/slack", pathEscape(project))
377
378	req, err := s.client.NewRequest("GET", u, nil, options)
379	if err != nil {
380		return nil, nil, err
381	}
382
383	svc := new(SlackService)
384	resp, err := s.client.Do(req, svc)
385	if err != nil {
386		return nil, resp, err
387	}
388
389	return svc, resp, err
390}
391
392// SetSlackServiceOptions represents the available SetSlackService()
393// options.
394//
395// GitLab API docs:
396// https://docs.gitlab.com/ce/api/services.html#edit-slack-service
397type SetSlackServiceOptions struct {
398	WebHook                   *string `url:"webhook,omitempty" json:"webhook,omitempty"`
399	Username                  *string `url:"username,omitempty" json:"username,omitempty"`
400	Channel                   *string `url:"channel,omitempty" json:"channel,omitempty"`
401	NotifyOnlyBrokenPipelines *bool   `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"`
402	NotifyOnlyDefaultBranch   *bool   `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"`
403	ConfidentialIssueChannel  *string `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"`
404	ConfidentialIssuesEvents  *bool   `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"`
405	// TODO: Currently, GitLab ignores this option (not implemented yet?), so
406	// there is no way to set it. Uncomment when this is fixed.
407	// See: https://gitlab.com/gitlab-org/gitlab-ce/issues/49730
408	//ConfidentialNoteChannel   *string `json:"confidential_note_channel,omitempty"`
409	ConfidentialNoteEvents *bool   `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"`
410	DeploymentChannel      *string `url:"deployment_channel,omitempty" json:"deployment_channel,omitempty"`
411	DeploymentEvents       *bool   `url:"deployment_events,omitempty" json:"deployment_events,omitempty"`
412	IssueChannel           *string `url:"issue_channel,omitempty" json:"issue_channel,omitempty"`
413	IssuesEvents           *bool   `url:"issues_events,omitempty" json:"issues_events,omitempty"`
414	MergeRequestChannel    *string `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"`
415	MergeRequestsEvents    *bool   `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
416	TagPushChannel         *string `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"`
417	TagPushEvents          *bool   `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
418	NoteChannel            *string `url:"note_channel,omitempty" json:"note_channel,omitempty"`
419	NoteEvents             *bool   `url:"note_events,omitempty" json:"note_events,omitempty"`
420	PipelineChannel        *string `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"`
421	PipelineEvents         *bool   `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
422	PushChannel            *string `url:"push_channel,omitempty" json:"push_channel,omitempty"`
423	PushEvents             *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
424	WikiPageChannel        *string `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"`
425	WikiPageEvents         *bool   `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"`
426}
427
428// SetSlackService sets Slack service for a project
429//
430// GitLab API docs:
431// https://docs.gitlab.com/ce/api/services.html#edit-slack-service
432func (s *ServicesService) SetSlackService(pid interface{}, opt *SetSlackServiceOptions, options ...OptionFunc) (*Response, error) {
433	project, err := parseID(pid)
434	if err != nil {
435		return nil, err
436	}
437	u := fmt.Sprintf("projects/%s/services/slack", pathEscape(project))
438
439	req, err := s.client.NewRequest("PUT", u, opt, options)
440	if err != nil {
441		return nil, err
442	}
443
444	return s.client.Do(req, nil)
445}
446
447// DeleteSlackService deletes Slack service for project.
448//
449// GitLab API docs:
450// https://docs.gitlab.com/ce/api/services.html#delete-slack-service
451func (s *ServicesService) DeleteSlackService(pid interface{}, options ...OptionFunc) (*Response, error) {
452	project, err := parseID(pid)
453	if err != nil {
454		return nil, err
455	}
456	u := fmt.Sprintf("projects/%s/services/slack", pathEscape(project))
457
458	req, err := s.client.NewRequest("DELETE", u, nil, options)
459	if err != nil {
460		return nil, err
461	}
462
463	return s.client.Do(req, nil)
464}
465
466// JiraService represents Jira service settings.
467//
468// GitLab API docs:
469// https://docs.gitlab.com/ce/api/services.html#jira
470type JiraService struct {
471	Service
472	Properties *JiraServiceProperties `json:"properties"`
473}
474
475// JiraServiceProperties represents Jira specific properties.
476//
477// GitLab API docs:
478// https://docs.gitlab.com/ce/api/services.html#jira
479type JiraServiceProperties struct {
480	URL                   string `json:"url,omitempty"`
481	APIURL                string `json:"api_url,omitempty"`
482	ProjectKey            string `json:"project_key,omitempty" `
483	Username              string `json:"username,omitempty" `
484	Password              string `json:"password,omitempty" `
485	JiraIssueTransitionID string `json:"jira_issue_transition_id,omitempty"`
486}
487
488// UnmarshalJSON decodes the Jira Service Properties.
489//
490// This allows support of JiraIssueTransitionID for both type string (>11.9) and float64 (<11.9)
491func (p *JiraServiceProperties) UnmarshalJSON(b []byte) error {
492	type Alias JiraServiceProperties
493	raw := struct {
494		*Alias
495		JiraIssueTransitionID interface{} `json:"jira_issue_transition_id"`
496	}{
497		Alias: (*Alias)(p),
498	}
499
500	if err := json.Unmarshal(b, &raw); err != nil {
501		return err
502	}
503
504	switch id := raw.JiraIssueTransitionID.(type) {
505	case nil:
506		// No action needed.
507	case string:
508		p.JiraIssueTransitionID = id
509	case float64:
510		p.JiraIssueTransitionID = strconv.Itoa(int(id))
511	default:
512		return fmt.Errorf("failed to unmarshal JiraTransitionID of type: %T", id)
513	}
514
515	return nil
516}
517
518// GetJiraService gets Jira service settings for a project.
519//
520// GitLab API docs:
521// https://docs.gitlab.com/ce/api/services.html#get-jira-service-settings
522func (s *ServicesService) GetJiraService(pid interface{}, options ...OptionFunc) (*JiraService, *Response, error) {
523	project, err := parseID(pid)
524	if err != nil {
525		return nil, nil, err
526	}
527	u := fmt.Sprintf("projects/%s/services/jira", pathEscape(project))
528
529	req, err := s.client.NewRequest("GET", u, nil, options)
530	if err != nil {
531		return nil, nil, err
532	}
533
534	svc := new(JiraService)
535	resp, err := s.client.Do(req, svc)
536	if err != nil {
537		return nil, resp, err
538	}
539
540	return svc, resp, err
541}
542
543// SetJiraServiceOptions represents the available SetJiraService()
544// options.
545//
546// GitLab API docs:
547// https://docs.gitlab.com/ce/api/services.html#edit-jira-service
548type SetJiraServiceOptions struct {
549	URL                   *string `url:"url,omitempty" json:"url,omitempty"`
550	APIURL                *string `url:"api_url,omitempty" json:"api_url,omitempty"`
551	ProjectKey            *string `url:"project_key,omitempty" json:"project_key,omitempty" `
552	Username              *string `url:"username,omitempty" json:"username,omitempty" `
553	Password              *string `url:"password,omitempty" json:"password,omitempty" `
554	JiraIssueTransitionID *string `url:"jira_issue_transition_id,omitempty" json:"jira_issue_transition_id,omitempty"`
555}
556
557// SetJiraService sets Jira service for a project
558//
559// GitLab API docs:
560// https://docs.gitlab.com/ce/api/services.html#edit-jira-service
561func (s *ServicesService) SetJiraService(pid interface{}, opt *SetJiraServiceOptions, options ...OptionFunc) (*Response, error) {
562	project, err := parseID(pid)
563	if err != nil {
564		return nil, err
565	}
566	u := fmt.Sprintf("projects/%s/services/jira", pathEscape(project))
567
568	req, err := s.client.NewRequest("PUT", u, opt, options)
569	if err != nil {
570		return nil, err
571	}
572
573	return s.client.Do(req, nil)
574}
575
576// DeleteJiraService deletes Jira service for project.
577//
578// GitLab API docs:
579// https://docs.gitlab.com/ce/api/services.html#delete-jira-service
580func (s *ServicesService) DeleteJiraService(pid interface{}, options ...OptionFunc) (*Response, error) {
581	project, err := parseID(pid)
582	if err != nil {
583		return nil, err
584	}
585	u := fmt.Sprintf("projects/%s/services/jira", pathEscape(project))
586
587	req, err := s.client.NewRequest("DELETE", u, nil, options)
588	if err != nil {
589		return nil, err
590	}
591
592	return s.client.Do(req, nil)
593}
594
595// JenkinsCIService represents Jenkins CI service settings.
596//
597// GitLab API docs:
598// https://docs.gitlab.com/ee/api/services.html#jenkins-ci
599type JenkinsCIService struct {
600	Service
601	Properties *JenkinsCIServiceProperties `json:"properties"`
602}
603
604// JenkinsCIServiceProperties represents Jenkins CI specific properties.
605//
606// GitLab API docs:
607// https://docs.gitlab.com/ee/api/services.html#jenkins-ci
608type JenkinsCIServiceProperties struct {
609	URL         string `json:"jenkins_url,omitempty"`
610	ProjectName string `json:"project_name,omitempty"`
611	Username    string `json:"username,omitempty"`
612}
613
614// GetJenkinsCIService gets Jenkins CI service settings for a project.
615//
616// GitLab API docs:
617// https://docs.gitlab.com/ee/api/services.html#get-jenkins-ci-service-settings
618func (s *ServicesService) GetJenkinsCIService(pid interface{}, options ...OptionFunc) (*JenkinsCIService, *Response, error) {
619	project, err := parseID(pid)
620	if err != nil {
621		return nil, nil, err
622	}
623	u := fmt.Sprintf("projects/%s/services/jenkins", pathEscape(project))
624
625	req, err := s.client.NewRequest("GET", u, nil, options)
626	if err != nil {
627		return nil, nil, err
628	}
629
630	svc := new(JenkinsCIService)
631	resp, err := s.client.Do(req, svc)
632	if err != nil {
633		return nil, resp, err
634	}
635
636	return svc, resp, err
637}
638
639// SetJenkinsCIServiceOptions represents the available SetJenkinsCIService()
640// options.
641//
642// GitLab API docs:
643// https://docs.gitlab.com/ee/api/services.html#jenkins-ci
644type SetJenkinsCIServiceOptions struct {
645	URL         *string `url:"jenkins_url,omitempty" json:"jenkins_url,omitempty"`
646	ProjectName *string `url:"project_name,omitempty" json:"project_name,omitempty"`
647	Username    *string `url:"username,omitempty" json:"username,omitempty"`
648	Password    *string `url:"password,omitempty" json:"password,omitempty"`
649}
650
651// SetJenkinsCIService sets Jenkins service for a project
652//
653// GitLab API docs:
654// https://docs.gitlab.com/ee/api/services.html#create-edit-jenkins-ci-service
655func (s *ServicesService) SetJenkinsCIService(pid interface{}, opt *SetJenkinsCIServiceOptions, options ...OptionFunc) (*Response, error) {
656	project, err := parseID(pid)
657	if err != nil {
658		return nil, err
659	}
660	u := fmt.Sprintf("projects/%s/services/jenkins", pathEscape(project))
661
662	req, err := s.client.NewRequest("PUT", u, opt, options)
663	if err != nil {
664		return nil, err
665	}
666
667	return s.client.Do(req, nil)
668}
669
670// DeleteJenkinsCIService deletes Jenkins CI service for project.
671//
672// GitLab API docs:
673// https://docs.gitlab.com/ce/api/services.html#delete-jira-service
674func (s *ServicesService) DeleteJenkinsCIService(pid interface{}, options ...OptionFunc) (*Response, error) {
675	project, err := parseID(pid)
676	if err != nil {
677		return nil, err
678	}
679	u := fmt.Sprintf("projects/%s/services/jenkins", pathEscape(project))
680
681	req, err := s.client.NewRequest("DELETE", u, nil, options)
682	if err != nil {
683		return nil, err
684	}
685
686	return s.client.Do(req, nil)
687}
688
689// MicrosoftTeamsService represents Microsoft Teams service settings.
690//
691// GitLab API docs:
692// https://docs.gitlab.com/ce/api/services.html#microsoft-teams
693type MicrosoftTeamsService struct {
694	Service
695	Properties *MicrosoftTeamsServiceProperties `json:"properties"`
696}
697
698// MicrosoftTeamsServiceProperties represents Microsoft Teams specific properties.
699//
700// GitLab API docs:
701// https://docs.gitlab.com/ce/api/services.html#microsoft-teams
702type MicrosoftTeamsServiceProperties struct {
703	WebHook string `json:"webhook"`
704}
705
706// GetMicrosoftTeamsService gets MicrosoftTeams service settings for a project.
707//
708// GitLab API docs:
709// https://docs.gitlab.com/ce/api/services.html#get-microsoft-teams-service-settings
710func (s *ServicesService) GetMicrosoftTeamsService(pid interface{}, options ...OptionFunc) (*MicrosoftTeamsService, *Response, error) {
711	project, err := parseID(pid)
712	if err != nil {
713		return nil, nil, err
714	}
715	u := fmt.Sprintf("projects/%s/services/microsoft-teams", pathEscape(project))
716
717	req, err := s.client.NewRequest("GET", u, nil, options)
718	if err != nil {
719		return nil, nil, err
720	}
721
722	svc := new(MicrosoftTeamsService)
723	resp, err := s.client.Do(req, svc)
724	if err != nil {
725		return nil, resp, err
726	}
727
728	return svc, resp, err
729}
730
731// SetMicrosoftTeamsServiceOptions represents the available SetMicrosoftTeamsService()
732// options.
733//
734// GitLab API docs:
735// https://docs.gitlab.com/ce/api/services.html#create-edit-microsoft-teams-service
736type SetMicrosoftTeamsServiceOptions struct {
737	WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty"`
738}
739
740// SetMicrosoftTeamsService sets Microsoft Teams service for a project
741//
742// GitLab API docs:
743// https://docs.gitlab.com/ce/api/services.html#create-edit-microsoft-teams-service
744func (s *ServicesService) SetMicrosoftTeamsService(pid interface{}, opt *SetMicrosoftTeamsServiceOptions, options ...OptionFunc) (*Response, error) {
745	project, err := parseID(pid)
746	if err != nil {
747		return nil, err
748	}
749	u := fmt.Sprintf("projects/%s/services/microsoft-teams", pathEscape(project))
750
751	req, err := s.client.NewRequest("PUT", u, opt, options)
752	if err != nil {
753		return nil, err
754	}
755	return s.client.Do(req, nil)
756}
757
758// DeleteMicrosoftTeamsService deletes Microsoft Teams service for project.
759//
760// GitLab API docs:
761// https://docs.gitlab.com/ce/api/services.html#delete-microsoft-teams-service
762func (s *ServicesService) DeleteMicrosoftTeamsService(pid interface{}, options ...OptionFunc) (*Response, error) {
763	project, err := parseID(pid)
764	if err != nil {
765		return nil, err
766	}
767	u := fmt.Sprintf("projects/%s/services/microsoft-teams", pathEscape(project))
768
769	req, err := s.client.NewRequest("DELETE", u, nil, options)
770	if err != nil {
771		return nil, err
772	}
773
774	return s.client.Do(req, nil)
775}
776
777// ExternalWikiService represents External Wiki service settings.
778//
779// GitLab API docs:
780// https://docs.gitlab.com/ce/api/services.html#external-wiki
781type ExternalWikiService struct {
782	Service
783	Properties *ExternalWikiServiceProperties `json:"properties"`
784}
785
786// ExternalWikiServiceProperties represents External Wiki specific properties.
787//
788// GitLab API docs:
789// https://docs.gitlab.com/ce/api/services.html#external-wiki
790type ExternalWikiServiceProperties struct {
791	ExternalWikiURL string `json:"external_wiki_url"`
792}
793
794// GetExternalWikiService gets External Wiki service settings for a project.
795//
796// GitLab API docs:
797// https://docs.gitlab.com/ce/api/services.html#get-external-wiki-service-settings
798func (s *ServicesService) GetExternalWikiService(pid interface{}, options ...OptionFunc) (*ExternalWikiService, *Response, error) {
799	project, err := parseID(pid)
800	if err != nil {
801		return nil, nil, err
802	}
803	u := fmt.Sprintf("projects/%s/services/external-wiki", pathEscape(project))
804
805	req, err := s.client.NewRequest("GET", u, nil, options)
806	if err != nil {
807		return nil, nil, err
808	}
809
810	svc := new(ExternalWikiService)
811	resp, err := s.client.Do(req, svc)
812	if err != nil {
813		return nil, resp, err
814	}
815
816	return svc, resp, err
817}
818
819// SetExternalWikiServiceOptions represents the available SetExternalWikiService()
820// options.
821//
822// GitLab API docs:
823// https://docs.gitlab.com/ce/api/services.html#createedit-external-wiki-service
824type SetExternalWikiServiceOptions struct {
825	ExternalWikiURL *string `url:"external_wiki_url,omitempty" json:"external_wiki_url,omitempty"`
826}
827
828// SetExternalWikiService sets External Wiki service for a project.
829//
830// GitLab API docs:
831// https://docs.gitlab.com/ce/api/services.html#createedit-external-wiki-service
832func (s *ServicesService) SetExternalWikiService(pid interface{}, opt *SetExternalWikiServiceOptions, options ...OptionFunc) (*Response, error) {
833	project, err := parseID(pid)
834	if err != nil {
835		return nil, err
836	}
837	u := fmt.Sprintf("projects/%s/services/external-wiki", pathEscape(project))
838
839	req, err := s.client.NewRequest("PUT", u, opt, options)
840	if err != nil {
841		return nil, err
842	}
843
844	return s.client.Do(req, nil)
845}
846
847// DeleteExternalWikiService deletes External Wiki service for project.
848//
849// GitLab API docs:
850// https://docs.gitlab.com/ce/api/services.html#delete-external-wiki-service
851func (s *ServicesService) DeleteExternalWikiService(pid interface{}, options ...OptionFunc) (*Response, error) {
852	project, err := parseID(pid)
853	if err != nil {
854		return nil, err
855	}
856	u := fmt.Sprintf("projects/%s/services/external-wiki", pathEscape(project))
857
858	req, err := s.client.NewRequest("DELETE", u, nil, options)
859	if err != nil {
860		return nil, err
861	}
862
863	return s.client.Do(req, nil)
864}