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