This repository was archived by the owner on May 1, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlist.go
More file actions
153 lines (131 loc) · 4.47 KB
/
list.go
File metadata and controls
153 lines (131 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Package projects holds the data structures and logic necessary to interact with the Gitlab API and enumerate projects.
package projects
import (
"context"
"fmt"
"github.com/xanzy/go-gitlab"
)
// EnumerateProjectsOptions holds the options for enumerating projects.
// The Mine field is used to filter projects that are owned by the authenticated user, only returning projects that are owned
// by the authenticated user when set to true.
// The Archived field is used to filter for archived projects, including archived when set to true.
// The GroupID field is used to filter projects by group ID, only returning projects that are part of the specified group.
type EnumerateProjectsOptions struct {
Mine bool `json:"mine"`
Archived bool `json:"archived"`
GroupID string `json:"group_id"`
}
// FindGroupByName searches for a group by name using the provided Gitlab client. If the group is found, it is returned.
// If the group is not found, an error is returned.
func FindGroupByName(ctx context.Context, client *gitlab.Client, groupName string) (*gitlab.Group, error) {
options := &gitlab.ListGroupsOptions{
Search: gitlab.Ptr(groupName),
}
groups, _, err := client.Groups.ListGroups(options)
if err != nil {
return nil, err
}
for _, group := range groups {
if group.Name == groupName {
return group, nil
}
}
return nil, fmt.Errorf("group %s not found", groupName)
}
// EnumerateProjects enumerates projects using the provided Gitlab client and options. The function returns a GitlabResourceReport
// containing the resources and non-fatal errors encountered during the enumeration process.
func EnumerateProjects(ctx context.Context, baseURL string, options *EnumerateProjectsOptions, client *gitlab.Client) (*GitlabResourceReport, error) {
report := &GitlabResourceReport{
Resources: GitlabResources{},
Errors: []string{},
BaseURL: baseURL,
}
filterOptions := gitlab.ListProjectsOptions{
ListOptions: gitlab.ListOptions{
Page: 1,
PerPage: 100,
},
}
if options.Archived {
filterOptions.Archived = gitlab.Ptr(options.Archived)
}
if options.Mine {
filterOptions.Owned = gitlab.Ptr(options.Mine)
}
for {
projects, resp, err := client.Projects.ListProjects(&filterOptions)
if err != nil {
report.Errors = append(report.Errors, err.Error())
break
}
report.Resources.Projects = append(report.Resources.Projects, projects...)
if resp.NextPage == 0 {
break
}
filterOptions.ListOptions.Page = resp.NextPage
}
return report, nil
}
// EnumerateProjectsForGroup enumerates projects for a specific group using the provided Gitlab client and options. The function
// returns a GitlabResourceReport containing the resources and non-fatal errors encountered during the enumeration process.
func EnumerateProjectsForGroup(ctx context.Context, baseURL string, client *gitlab.Client, options *EnumerateProjectsOptions) (*GitlabResourceReport, error) {
report := &GitlabResourceReport{
Resources: GitlabResources{},
Errors: []string{},
BaseURL: baseURL,
}
err := fetchGroupAndSubgroupProjects(ctx, client, options.GroupID, options, report)
if err != nil {
report.Errors = append(report.Errors, err.Error())
}
return report, nil
}
func fetchGroupAndSubgroupProjects(ctx context.Context, client *gitlab.Client, groupID string, options *EnumerateProjectsOptions, report *GitlabResourceReport) error {
filterOptions := gitlab.ListGroupProjectsOptions{
ListOptions: gitlab.ListOptions{
Page: 1,
PerPage: 100,
},
}
if options.Archived {
filterOptions.Archived = gitlab.Ptr(options.Archived)
}
if options.Mine {
filterOptions.Owned = gitlab.Ptr(options.Mine)
}
for {
projects, resp, err := client.Groups.ListGroupProjects(groupID, &filterOptions)
if err != nil {
return err
}
report.Resources.Projects = append(report.Resources.Projects, projects...)
if resp.NextPage == 0 {
break
}
filterOptions.ListOptions.Page = resp.NextPage
}
// Fetch subgroups
subGroupOptions := gitlab.ListSubGroupsOptions{
ListOptions: gitlab.ListOptions{
Page: 1,
PerPage: 100,
},
}
for {
subgroups, resp, err := client.Groups.ListSubGroups(groupID, &subGroupOptions)
if err != nil {
return err
}
for _, subgroup := range subgroups {
err := fetchGroupAndSubgroupProjects(ctx, client, fmt.Sprintf("%d", subgroup.ID), options, report)
if err != nil {
report.Errors = append(report.Errors, err.Error())
}
}
if resp.NextPage == 0 {
break
}
subGroupOptions.Page = resp.NextPage
}
return nil
}