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	"net/url"
22	"time"
23)
24
25// ServicesService handles communication with the services related methods of
26// the GitLab API.
27//
28// GitLab API docs: https://docs.gitlab.com/ce/api/services.html
29type ServicesService struct {
30	client *Client
31}
32
33// Service represents a GitLab service.
34//
35// GitLab API docs: https://docs.gitlab.com/ce/api/services.html
36type Service struct {
37	ID                       int        `json:"id"`
38	Title                    string     `json:"title"`
39	CreatedAt                *time.Time `json:"created_at"`
40	UpdatedAt                *time.Time `json:"updated_at"`
41	Active                   bool       `json:"active"`
42	PushEvents               bool       `json:"push_events"`
43	IssuesEvents             bool       `json:"issues_events"`
44	ConfidentialIssuesEvents bool       `json:"confidential_issues_events"`
45	MergeRequestsEvents      bool       `json:"merge_requests_events"`
46	TagPushEvents            bool       `json:"tag_push_events"`
47	NoteEvents               bool       `json:"note_events"`
48	ConfidentialNoteEvents   bool       `json:"confidential_note_events"`
49	PipelineEvents           bool       `json:"pipeline_events"`
50	JobEvents                bool       `json:"job_events"`
51	WikiPageEvents           bool       `json:"wiki_page_events"`
52}
53
54// SetGitLabCIServiceOptions represents the available SetGitLabCIService()
55// options.
56//
57// GitLab API docs:
58// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service
59type SetGitLabCIServiceOptions struct {
60	Token      *string `url:"token,omitempty" json:"token,omitempty"`
61	ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"`
62}
63
64// SetGitLabCIService sets GitLab CI service for a project.
65//
66// GitLab API docs:
67// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service
68func (s *ServicesService) SetGitLabCIService(pid interface{}, opt *SetGitLabCIServiceOptions, options ...OptionFunc) (*Response, error) {
69	project, err := parseID(pid)
70	if err != nil {
71		return nil, err
72	}
73	u := fmt.Sprintf("projects/%s/services/gitlab-ci", url.QueryEscape(project))
74
75	req, err := s.client.NewRequest("PUT", u, opt, options)
76	if err != nil {
77		return nil, err
78	}
79
80	return s.client.Do(req, nil)
81}
82
83// DeleteGitLabCIService deletes GitLab CI service settings for a project.
84//
85// GitLab API docs:
86// https://docs.gitlab.com/ce/api/services.html#delete-gitlab-ci-service
87func (s *ServicesService) DeleteGitLabCIService(pid interface{}, options ...OptionFunc) (*Response, error) {
88	project, err := parseID(pid)
89	if err != nil {
90		return nil, err
91	}
92	u := fmt.Sprintf("projects/%s/services/gitlab-ci", url.QueryEscape(project))
93
94	req, err := s.client.NewRequest("DELETE", u, nil, options)
95	if err != nil {
96		return nil, err
97	}
98
99	return s.client.Do(req, nil)
100}
101
102// SetHipChatServiceOptions represents the available SetHipChatService()
103// options.
104//
105// GitLab API docs:
106// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service
107type SetHipChatServiceOptions struct {
108	Token *string `url:"token,omitempty" json:"token,omitempty" `
109	Room  *string `url:"room,omitempty" json:"room,omitempty"`
110}
111
112// SetHipChatService sets HipChat service for a project
113//
114// GitLab API docs:
115// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service
116func (s *ServicesService) SetHipChatService(pid interface{}, opt *SetHipChatServiceOptions, options ...OptionFunc) (*Response, error) {
117	project, err := parseID(pid)
118	if err != nil {
119		return nil, err
120	}
121	u := fmt.Sprintf("projects/%s/services/hipchat", url.QueryEscape(project))
122
123	req, err := s.client.NewRequest("PUT", u, opt, options)
124	if err != nil {
125		return nil, err
126	}
127
128	return s.client.Do(req, nil)
129}
130
131// DeleteHipChatService deletes HipChat service for project.
132//
133// GitLab API docs:
134// https://docs.gitlab.com/ce/api/services.html#delete-hipchat-service
135func (s *ServicesService) DeleteHipChatService(pid interface{}, options ...OptionFunc) (*Response, error) {
136	project, err := parseID(pid)
137	if err != nil {
138		return nil, err
139	}
140	u := fmt.Sprintf("projects/%s/services/hipchat", url.QueryEscape(project))
141
142	req, err := s.client.NewRequest("DELETE", u, nil, options)
143	if err != nil {
144		return nil, err
145	}
146
147	return s.client.Do(req, nil)
148}
149
150// DroneCIService represents Drone CI service settings.
151//
152// GitLab API docs:
153// https://docs.gitlab.com/ce/api/services.html#drone-ci
154type DroneCIService struct {
155	Service
156	Properties *DroneCIServiceProperties `json:"properties"`
157}
158
159// DroneCIServiceProperties represents Drone CI specific properties.
160//
161// GitLab API docs:
162// https://docs.gitlab.com/ce/api/services.html#drone-ci
163type DroneCIServiceProperties struct {
164	Token                 string `json:"token"`
165	DroneURL              string `json:"drone_url"`
166	EnableSSLVerification bool   `json:"enable_ssl_verification"`
167}
168
169// GetDroneCIService gets Drone CI service settings for a project.
170//
171// GitLab API docs:
172// https://docs.gitlab.com/ce/api/services.html#get-drone-ci-service-settings
173func (s *ServicesService) GetDroneCIService(pid interface{}, options ...OptionFunc) (*DroneCIService, *Response, error) {
174	project, err := parseID(pid)
175	if err != nil {
176		return nil, nil, err
177	}
178	u := fmt.Sprintf("projects/%s/services/drone-ci", url.QueryEscape(project))
179
180	req, err := s.client.NewRequest("GET", u, nil, options)
181	if err != nil {
182		return nil, nil, err
183	}
184
185	svc := new(DroneCIService)
186	resp, err := s.client.Do(req, svc)
187	if err != nil {
188		return nil, resp, err
189	}
190
191	return svc, resp, err
192}
193
194// SetDroneCIServiceOptions represents the available SetDroneCIService()
195// options.
196//
197// GitLab API docs:
198// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service
199type SetDroneCIServiceOptions struct {
200	Token                 *string `url:"token" json:"token" `
201	DroneURL              *string `url:"drone_url" json:"drone_url"`
202	EnableSSLVerification *bool   `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
203}
204
205// SetDroneCIService sets Drone CI service for a project.
206//
207// GitLab API docs:
208// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service
209func (s *ServicesService) SetDroneCIService(pid interface{}, opt *SetDroneCIServiceOptions, 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/drone-ci", url.QueryEscape(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// DeleteDroneCIService deletes Drone CI service settings for a project.
225//
226// GitLab API docs:
227// https://docs.gitlab.com/ce/api/services.html#delete-drone-ci-service
228func (s *ServicesService) DeleteDroneCIService(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/drone-ci", url.QueryEscape(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// SlackService represents Slack service settings.
244//
245// GitLab API docs:
246// https://docs.gitlab.com/ce/api/services.html#slack
247type SlackService struct {
248	Service
249	Properties *SlackServiceProperties `json:"properties"`
250}
251
252// SlackServiceProperties represents Slack specific properties.
253//
254// GitLab API docs:
255// https://docs.gitlab.com/ce/api/services.html#slack
256type SlackServiceProperties struct {
257	// Note: NotifyOnlyBrokenPipelines and NotifyOnlyDefaultBranch are not
258	// just "bool" because in some cases gitlab returns
259	// "notify_only_broken_pipelines": true, and in other cases
260	// "notify_only_broken_pipelines": "1". The same is for
261	// "notify_only_default_branch" field.
262	// We need to handle this, until the bug will be fixed.
263	// Ref: https://gitlab.com/gitlab-org/gitlab-ce/issues/50122
264
265	NotifyOnlyBrokenPipelines BoolValue `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"`
266	NotifyOnlyDefaultBranch   BoolValue `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"`
267	WebHook                   string    `url:"webhook,omitempty" json:"webhook,omitempty"`
268	Username                  string    `url:"username,omitempty" json:"username,omitempty"`
269	Channel                   string    `url:"channel,omitempty" json:"channel,omitempty"`
270	PushChannel               string    `url:"push_channel,omitempty" json:"push_channel,omitempty"`
271	IssueChannel              string    `url:"issue_channel,omitempty" json:"issue_channel,omitempty"`
272	ConfidentialIssueChannel  string    `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"`
273	MergeRequestChannel       string    `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"`
274	NoteChannel               string    `url:"note_channel,omitempty" json:"note_channel,omitempty"`
275	ConfidentialNoteChannel   string    `url:"confidential_note_channel,omitempty" json:"confidential_note_channel,omitempty"`
276	TagPushChannel            string    `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"`
277	PipelineChannel           string    `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"`
278	WikiPageChannel           string    `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"`
279}
280
281// GetSlackService gets Slack service settings for a project.
282//
283// GitLab API docs:
284// https://docs.gitlab.com/ce/api/services.html#get-slack-service-settings
285func (s *ServicesService) GetSlackService(pid interface{}, options ...OptionFunc) (*SlackService, *Response, error) {
286	project, err := parseID(pid)
287	if err != nil {
288		return nil, nil, err
289	}
290	u := fmt.Sprintf("projects/%s/services/slack", url.QueryEscape(project))
291
292	req, err := s.client.NewRequest("GET", u, nil, options)
293	if err != nil {
294		return nil, nil, err
295	}
296
297	svc := new(SlackService)
298	resp, err := s.client.Do(req, svc)
299	if err != nil {
300		return nil, resp, err
301	}
302
303	return svc, resp, err
304}
305
306// SetSlackServiceOptions represents the available SetSlackService()
307// options.
308//
309// GitLab API docs:
310// https://docs.gitlab.com/ce/api/services.html#edit-slack-service
311type SetSlackServiceOptions struct {
312	WebHook                   *string `url:"webhook,omitempty" json:"webhook,omitempty"`
313	Username                  *string `url:"username,omitempty" json:"username,omitempty"`
314	Channel                   *string `url:"channel,omitempty" json:"channel,omitempty"`
315	NotifyOnlyBrokenPipelines *bool   `url:"notify_only_broken_pipelines,omitempty" json:"notify_only_broken_pipelines,omitempty"`
316	NotifyOnlyDefaultBranch   *bool   `url:"notify_only_default_branch,omitempty" json:"notify_only_default_branch,omitempty"`
317	PushEvents                *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
318	PushChannel               *string `url:"push_channel,omitempty" json:"push_channel,omitempty"`
319	IssuesEvents              *bool   `url:"issues_events,omitempty" json:"issues_events,omitempty"`
320	IssueChannel              *string `url:"issue_channel,omitempty" json:"issue_channel,omitempty"`
321	ConfidentialIssuesEvents  *bool   `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"`
322	ConfidentialIssueChannel  *string `url:"confidential_issue_channel,omitempty" json:"confidential_issue_channel,omitempty"`
323	MergeRequestsEvents       *bool   `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
324	MergeRequestChannel       *string `url:"merge_request_channel,omitempty" json:"merge_request_channel,omitempty"`
325	TagPushEvents             *bool   `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
326	TagPushChannel            *string `url:"tag_push_channel,omitempty" json:"tag_push_channel,omitempty"`
327	NoteEvents                *bool   `url:"note_events,omitempty" json:"note_events,omitempty"`
328	NoteChannel               *string `url:"note_channel,omitempty" json:"note_channel,omitempty"`
329	ConfidentialNoteEvents    *bool   `url:"confidential_note_events" json:"confidential_note_events"`
330	// TODO: Currently, GitLab ignores this option (not implemented yet?), so
331	// there is no way to set it. Uncomment when this is fixed.
332	// See: https://gitlab.com/gitlab-org/gitlab-ce/issues/49730
333	//ConfidentialNoteChannel   *string `json:"confidential_note_channel,omitempty"`
334	PipelineEvents  *bool   `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
335	PipelineChannel *string `url:"pipeline_channel,omitempty" json:"pipeline_channel,omitempty"`
336	WikiPageChannel *string `url:"wiki_page_channel,omitempty" json:"wiki_page_channel,omitempty"`
337	WikiPageEvents  *bool   `url:"wiki_page_events" json:"wiki_page_events"`
338}
339
340// SetSlackService sets Slack service for a project
341//
342// GitLab API docs:
343// https://docs.gitlab.com/ce/api/services.html#edit-slack-service
344func (s *ServicesService) SetSlackService(pid interface{}, opt *SetSlackServiceOptions, options ...OptionFunc) (*Response, error) {
345	project, err := parseID(pid)
346	if err != nil {
347		return nil, err
348	}
349	u := fmt.Sprintf("projects/%s/services/slack", url.QueryEscape(project))
350
351	req, err := s.client.NewRequest("PUT", u, opt, options)
352	if err != nil {
353		return nil, err
354	}
355
356	return s.client.Do(req, nil)
357}
358
359// DeleteSlackService deletes Slack service for project.
360//
361// GitLab API docs:
362// https://docs.gitlab.com/ce/api/services.html#delete-slack-service
363func (s *ServicesService) DeleteSlackService(pid interface{}, options ...OptionFunc) (*Response, error) {
364	project, err := parseID(pid)
365	if err != nil {
366		return nil, err
367	}
368	u := fmt.Sprintf("projects/%s/services/slack", url.QueryEscape(project))
369
370	req, err := s.client.NewRequest("DELETE", u, nil, options)
371	if err != nil {
372		return nil, err
373	}
374
375	return s.client.Do(req, nil)
376}
377
378// JiraService represents Jira service settings.
379//
380// GitLab API docs:
381// https://docs.gitlab.com/ce/api/services.html#jira
382type JiraService struct {
383	Service
384	Properties *JiraServiceProperties `json:"properties"`
385}
386
387// JiraServiceProperties represents Jira specific properties.
388//
389// GitLab API docs:
390// https://docs.gitlab.com/ce/api/services.html#jira
391type JiraServiceProperties struct {
392	URL                   *string `url:"url,omitempty" json:"url,omitempty"`
393	ProjectKey            *string `url:"project_key,omitempty" json:"project_key,omitempty" `
394	Username              *string `url:"username,omitempty" json:"username,omitempty" `
395	Password              *string `url:"password,omitempty" json:"password,omitempty" `
396	JiraIssueTransitionID *string `url:"jira_issue_transition_id,omitempty" json:"jira_issue_transition_id,omitempty"`
397}
398
399// GetJiraService gets Jira service settings for a project.
400//
401// GitLab API docs:
402// https://docs.gitlab.com/ce/api/services.html#get-jira-service-settings
403func (s *ServicesService) GetJiraService(pid interface{}, options ...OptionFunc) (*JiraService, *Response, error) {
404	project, err := parseID(pid)
405	if err != nil {
406		return nil, nil, err
407	}
408	u := fmt.Sprintf("projects/%s/services/jira", url.QueryEscape(project))
409
410	req, err := s.client.NewRequest("GET", u, nil, options)
411	if err != nil {
412		return nil, nil, err
413	}
414
415	svc := new(JiraService)
416	resp, err := s.client.Do(req, svc)
417	if err != nil {
418		return nil, resp, err
419	}
420
421	return svc, resp, err
422}
423
424// SetJiraServiceOptions represents the available SetJiraService()
425// options.
426//
427// GitLab API docs:
428// https://docs.gitlab.com/ce/api/services.html#edit-jira-service
429type SetJiraServiceOptions JiraServiceProperties
430
431// SetJiraService sets Jira service for a project
432//
433// GitLab API docs:
434// https://docs.gitlab.com/ce/api/services.html#edit-jira-service
435func (s *ServicesService) SetJiraService(pid interface{}, opt *SetJiraServiceOptions, options ...OptionFunc) (*Response, error) {
436	project, err := parseID(pid)
437	if err != nil {
438		return nil, err
439	}
440	u := fmt.Sprintf("projects/%s/services/jira", url.QueryEscape(project))
441
442	req, err := s.client.NewRequest("PUT", u, opt, options)
443	if err != nil {
444		return nil, err
445	}
446
447	return s.client.Do(req, nil)
448}
449
450// DeleteJiraService deletes Jira service for project.
451//
452// GitLab API docs:
453// https://docs.gitlab.com/ce/api/services.html#delete-jira-service
454func (s *ServicesService) DeleteJiraService(pid interface{}, options ...OptionFunc) (*Response, error) {
455	project, err := parseID(pid)
456	if err != nil {
457		return nil, err
458	}
459	u := fmt.Sprintf("projects/%s/services/jira", url.QueryEscape(project))
460
461	req, err := s.client.NewRequest("DELETE", u, nil, options)
462	if err != nil {
463		return nil, err
464	}
465
466	return s.client.Do(req, nil)
467}
468
469// JenkinsCIService represents Jenkins CI service settings.
470//
471// GitLab API docs:
472// https://docs.gitlab.com/ee/api/services.html#jenkins-ci
473type JenkinsCIService struct {
474	Service
475	Properties *JenkinsCIServiceProperties `json:"properties"`
476}
477
478// JenkinsCIServiceProperties represents Jenkins CI specific properties.
479//
480// GitLab API docs:
481// https://docs.gitlab.com/ee/api/services.html#jenkins-ci
482type JenkinsCIServiceProperties struct {
483	URL         *string `url:"jenkins_url,omitempty" json:"jenkins_url,omitempty"`
484	ProjectName *string `url:"project_name,omitempty" json:"project_name,omitempty"`
485	Username    *string `url:"username,omitempty" json:"username,omitempty"`
486}
487
488// GetJenkinsCIService gets Jenkins CI service settings for a project.
489//
490// GitLab API docs:
491// https://docs.gitlab.com/ee/api/services.html#get-jenkins-ci-service-settings
492func (s *ServicesService) GetJenkinsCIService(pid interface{}, options ...OptionFunc) (*JenkinsCIService, *Response, error) {
493	project, err := parseID(pid)
494	if err != nil {
495		return nil, nil, err
496	}
497	u := fmt.Sprintf("projects/%s/services/jenkins", url.QueryEscape(project))
498
499	req, err := s.client.NewRequest("GET", u, nil, options)
500	if err != nil {
501		return nil, nil, err
502	}
503
504	svc := new(JenkinsCIService)
505	resp, err := s.client.Do(req, svc)
506	if err != nil {
507		return nil, resp, err
508	}
509
510	return svc, resp, err
511}
512
513// SetJenkinsCIServiceOptions represents the available SetJenkinsCIService()
514// options.
515//
516// GitLab API docs:
517// https://docs.gitlab.com/ee/api/services.html#jenkins-ci
518type SetJenkinsCIServiceOptions struct {
519	URL         *string `url:"jenkins_url,omitempty" json:"jenkins_url,omitempty"`
520	ProjectName *string `url:"project_name,omitempty" json:"project_name,omitempty"`
521	Username    *string `url:"username,omitempty" json:"username,omitempty"`
522	Password    *string `url:"password,omitempty" json:"password,omitempty"`
523}
524
525// SetJenkinsCIService sets Jenkins service for a project
526//
527// GitLab API docs:
528// https://docs.gitlab.com/ee/api/services.html#create-edit-jenkins-ci-service
529func (s *ServicesService) SetJenkinsCIService(pid interface{}, opt *SetJenkinsCIServiceOptions, options ...OptionFunc) (*Response, error) {
530	project, err := parseID(pid)
531	if err != nil {
532		return nil, err
533	}
534	u := fmt.Sprintf("projects/%s/services/jenkins", url.QueryEscape(project))
535
536	req, err := s.client.NewRequest("PUT", u, opt, options)
537	if err != nil {
538		return nil, err
539	}
540
541	return s.client.Do(req, nil)
542}
543
544// DeleteJenkinsCIService deletes Jenkins CI service for project.
545//
546// GitLab API docs:
547// https://docs.gitlab.com/ce/api/services.html#delete-jira-service
548func (s *ServicesService) DeleteJenkinsCIService(pid interface{}, options ...OptionFunc) (*Response, error) {
549	project, err := parseID(pid)
550	if err != nil {
551		return nil, err
552	}
553	u := fmt.Sprintf("projects/%s/services/jenkins", url.QueryEscape(project))
554
555	req, err := s.client.NewRequest("DELETE", u, nil, options)
556	if err != nil {
557		return nil, err
558	}
559
560	return s.client.Do(req, nil)
561}
562
563// MicrosoftTeamsService represents Microsoft Teams service settings.
564//
565// GitLab API docs:
566// https://docs.gitlab.com/ce/api/services.html#microsoft-teams
567type MicrosoftTeamsService struct {
568	Service
569	Properties *MicrosoftTeamsServiceProperties `json:"properties"`
570}
571
572// MicrosoftTeamsServiceProperties represents Microsoft Teams specific properties.
573//
574// GitLab API docs:
575// https://docs.gitlab.com/ce/api/services.html#microsoft-teams
576type MicrosoftTeamsServiceProperties struct {
577	WebHook string `json:"webhook"`
578}
579
580// GetMicrosoftTeamsService gets MicrosoftTeams service settings for a project.
581//
582// GitLab API docs:
583// https://docs.gitlab.com/ce/api/services.html#get-microsoft-teams-service-settings
584func (s *ServicesService) GetMicrosoftTeamsService(pid interface{}, options ...OptionFunc) (*MicrosoftTeamsService, *Response, error) {
585	project, err := parseID(pid)
586	if err != nil {
587		return nil, nil, err
588	}
589	u := fmt.Sprintf("projects/%s/services/microsoft-teams", url.QueryEscape(project))
590
591	req, err := s.client.NewRequest("GET", u, nil, options)
592	if err != nil {
593		return nil, nil, err
594	}
595
596	svc := new(MicrosoftTeamsService)
597	resp, err := s.client.Do(req, svc)
598	if err != nil {
599		return nil, resp, err
600	}
601
602	return svc, resp, err
603}
604
605// SetMicrosoftTeamsServiceOptions represents the available SetMicrosoftTeamsService()
606// options.
607//
608// GitLab API docs:
609// https://docs.gitlab.com/ce/api/services.html#create-edit-microsoft-teams-service
610type SetMicrosoftTeamsServiceOptions struct {
611	WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty"`
612}
613
614// SetMicrosoftTeamsService sets Microsoft Teams service for a project
615//
616// GitLab API docs:
617// https://docs.gitlab.com/ce/api/services.html#create-edit-microsoft-teams-service
618func (s *ServicesService) SetMicrosoftTeamsService(pid interface{}, opt *SetMicrosoftTeamsServiceOptions, options ...OptionFunc) (*Response, error) {
619	project, err := parseID(pid)
620	if err != nil {
621		return nil, err
622	}
623	u := fmt.Sprintf("projects/%s/services/microsoft-teams", url.QueryEscape(project))
624
625	req, err := s.client.NewRequest("PUT", u, opt, options)
626	if err != nil {
627		return nil, err
628	}
629	return s.client.Do(req, nil)
630}
631
632// DeleteMicrosoftTeamsService deletes Microsoft Teams service for project.
633//
634// GitLab API docs:
635// https://docs.gitlab.com/ce/api/services.html#delete-microsoft-teams-service
636func (s *ServicesService) DeleteMicrosoftTeamsService(pid interface{}, options ...OptionFunc) (*Response, error) {
637	project, err := parseID(pid)
638	if err != nil {
639		return nil, err
640	}
641	u := fmt.Sprintf("projects/%s/services/microsoft-teams", url.QueryEscape(project))
642
643	req, err := s.client.NewRequest("DELETE", u, nil, options)
644	if err != nil {
645		return nil, err
646	}
647
648	return s.client.Do(req, nil)
649}
650