Repository: xanzy/go-gitlab
Pull request #2005 (2024-09-03 13:19:13)

Add support for groups service accounts
Add support for groups service accounts

https://gitlab.com/gitlab-org/terraform-provider-gitlab/-/issues/5377


Patch:
diff --git a/group_serviceaccounts.go b/group_serviceaccounts.go
index 3ccb41b..1360057 100644
--- a/group_serviceaccounts.go
+++ b/group_serviceaccounts.go
@@ -31,18 +31,60 @@ type GroupServiceAccount struct {
 	UserName string `json:"username"`
 }
 
-// CreateServiceAccount create a new service account user for a group.
+// ListServiceAccountsOptions represents the available ListServiceAccounts() options.
 //
-// GitLab API docs:
-// https://docs.gitlab.com/ee/api/groups.html#create-service-account-user
-func (s *GroupsService) CreateServiceAccount(gid interface{}, options ...RequestOptionFunc) (*GroupServiceAccount, *Response, error) {
+// GitLab API docs: https://docs.gitlab.com/ee/api/group_service_accounts.html#list-service-account-users
+type ListServiceAccountsOptions struct {
+	ListOptions
+	OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
+	Sort    *string `url:"sort,omitempty" json:"sort,omitempty"`
+}
+
+// ListServiceAccounts gets a list of service acxcounts.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/group_service_accounts.html#list-service-account-users
+func (s *GroupsService) ListServiceAccounts(gid interface{}, opt *ListServiceAccountsOptions, options ...RequestOptionFunc) ([]*GroupServiceAccount, *Response, error) {
 	group, err := parseID(gid)
 	if err != nil {
 		return nil, nil, err
 	}
 	u := fmt.Sprintf("groups/%s/service_accounts", PathEscape(group))
 
-	req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
+	req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var sa []*GroupServiceAccount
+	resp, err := s.client.Do(req, &sa)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return sa, resp, nil
+}
+
+// CreateServiceAccountOptions represents the available CreateServiceAccount() options.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/group_service_accounts.html#create-a-service-account-user
+type CreateServiceAccountOptions struct {
+	Name     *string `url:"name,omitempty" json:"name,omitempty"`
+	Username *string `url:"username,omitempty" json:"username,omitempty"`
+}
+
+// Creates a service account user.
+//
+// This API endpoint works on top-level groups only. It does not work on subgroups.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#create-service-account-user
+func (s *GroupsService) CreateServiceAccount(gid interface{}, opt *CreateServiceAccountOptions, options ...RequestOptionFunc) (*GroupServiceAccount, *Response, error) {
+	group, err := parseID(gid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf("groups/%s/service_accounts", PathEscape(group))
+
+	req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
 	if err != nil {
 		return nil, nil, err
 	}
@@ -60,7 +102,7 @@ func (s *GroupsService) CreateServiceAccount(gid interface{}, options ...Request
 // CreateServiceAccountPersonalAccessToken() options.
 //
 // GitLab API docs:
-// https://docs.gitlab.com/ee/api/groups.html#create-personal-access-token-for-service-account-user
+// https://docs.gitlab.com/ee/api/group_service_accounts.html#create-a-personal-access-token-for-a-service-account-user
 type CreateServiceAccountPersonalAccessTokenOptions struct {
 	Scopes    *[]string `url:"scopes,omitempty" json:"scopes,omitempty"`
 	Name      *string   `url:"name,omitempty" json:"name,omitempty"`
@@ -71,7 +113,7 @@ type CreateServiceAccountPersonalAccessTokenOptions struct {
 // service account user for a group.
 //
 // GitLab API docs:
-// https://docs.gitlab.com/ee/api/groups.html#create-personal-access-token-for-service-account-user
+// https://docs.gitlab.com/ee/api/group_service_accounts.html#create-a-personal-access-token-for-a-service-account-user
 func (s *GroupsService) CreateServiceAccountPersonalAccessToken(gid interface{}, serviceAccount int, opt *CreateServiceAccountPersonalAccessTokenOptions, options ...RequestOptionFunc) (*PersonalAccessToken, *Response, error) {
 	group, err := parseID(gid)
 	if err != nil {
@@ -117,3 +159,23 @@ func (s *GroupsService) RotateServiceAccountPersonalAccessToken(gid interface{},
 
 	return pat, resp, nil
 }
+
+// DeleteServiceAccount Deletes a service account user.
+//
+// This API endpoint works on top-level groups only. It does not work on subgroups.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/group_service_accounts.html#delete-a-service-account-user
+func (s *GroupsService) DeleteServiceAccount(gid interface{}, serviceAccount int, options ...RequestOptionFunc) (*Response, error) {
+	group, err := parseID(gid)
+	if err != nil {
+		return nil, err
+	}
+	u := fmt.Sprintf("groups/%s/service_accounts/%d", PathEscape(group), serviceAccount)
+
+	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(req, nil)
+}


Test patch:
diff --git a/group_serviceaccounts_test.go b/group_serviceaccounts_test.go
index b878c8e..ba888ce 100644
--- a/group_serviceaccounts_test.go
+++ b/group_serviceaccounts_test.go
@@ -39,7 +39,10 @@ func TestCreateServiceAccount(t *testing.T) {
       }`)
 	})
 
-	sa, _, err := client.Groups.CreateServiceAccount(1)
+	sa, _, err := client.Groups.CreateServiceAccount(1, &CreateServiceAccountOptions{
+		Name:     Ptr("Service account user"),
+		Username: Ptr("service_account_group_345_6018816a18e515214e0c34c2b33523fc"),
+	})
 	if err != nil {
 		t.Error(err)
 	}