-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Expand file tree
/
Copy pathscm-manager.go
More file actions
153 lines (134 loc) · 4.04 KB
/
Copy pathscm-manager.go
File metadata and controls
153 lines (134 loc) · 4.04 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 scm_provider
import (
"context"
"errors"
"fmt"
"net/http"
"os"
"github.com/argoproj/argo-cd/v2/applicationset/utils"
scmm "github.com/scm-manager/goscm"
)
type ScmManagerProvider struct {
client *scmm.Client
allBranches bool
}
const FilterLimit = 9999
var _ SCMProviderService = &ScmManagerProvider{}
func NewScmManagerProvider(ctx context.Context, token, url string, allBranches, insecure bool, scmRootCAPath string, caCerts []byte) (*ScmManagerProvider, error) {
if token == "" {
token = os.Getenv("SCMM_TOKEN")
}
httpClient := &http.Client{}
tr := http.DefaultTransport.(*http.Transport).Clone()
tr.TLSClientConfig = utils.GetTlsConfig(scmRootCAPath, insecure, caCerts)
httpClient.Transport = tr
client, err := scmm.NewClient(url, token)
if err != nil {
return nil, fmt.Errorf("error creating a new SCM-Manager client: %w", err)
}
client.SetHttpClient(httpClient)
return &ScmManagerProvider{
client: client,
allBranches: allBranches,
}, nil
}
func (g *ScmManagerProvider) GetBranches(ctx context.Context, repo *Repository) ([]*Repository, error) {
scmmRepo, err := g.client.GetRepo(repo.Organization, repo.Repository)
if err != nil {
return nil, err
}
if !g.allBranches {
defaultBranch, err := g.client.GetDefaultBranch(repo.Organization, repo.Repository)
if err != nil {
return nil, err
}
return []*Repository{
{
Organization: repo.Organization,
Repository: repo.Repository,
Branch: defaultBranch.Name,
URL: repo.URL,
SHA: defaultBranch.Revision,
Labels: make([]string, 0),
RepositoryId: scmmRepo.Namespace + "/" + scmmRepo.Name,
},
}, nil
}
repos := []*Repository{}
branches, err := g.client.ListRepoBranches(repo.Organization, repo.Repository)
if err != nil {
return nil, err
}
for _, branch := range branches.Embedded.Branches {
repos = append(repos, &Repository{
Organization: scmmRepo.Namespace,
Repository: scmmRepo.Name,
Branch: branch.Name,
URL: scmmRepo.Links.ProtocolUrl[0].Href,
SHA: branch.Revision,
Labels: make([]string, 0),
RepositoryId: scmmRepo.Namespace + "/" + scmmRepo.Name,
})
}
return repos, nil
}
func (g *ScmManagerProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) {
repos := []*Repository{}
filter := g.client.NewRepoListFilter()
filter.Limit = FilterLimit
scmmRepos, err := g.client.ListRepos(filter)
if err != nil {
return nil, err
}
for _, scmmRepo := range scmmRepos.Embedded.Repositories {
var url string
switch cloneProtocol {
// Default to SSH if unspecified (i.e. if ""). SSH Plugin needs to be installed
case "", "ssh":
url = getProtocolUrlByName(scmmRepo.Links.ProtocolUrl, "ssh")
case "https":
url = getProtocolUrlByName(scmmRepo.Links.ProtocolUrl, "http")
default:
return nil, fmt.Errorf("unknown clone protocol %v", cloneProtocol)
}
if url == "" {
return nil, errors.New("could not find valid repository protocol url")
}
defaultBranch, err := g.client.GetDefaultBranch(scmmRepo.Namespace, scmmRepo.Name)
if err != nil {
if errors.Is(err, scmm.ErrEmptyRepository) || errors.Is(err, scmm.ErrNoDefaultBranchFound) {
continue
}
return nil, err
}
repos = append(repos, &Repository{
Organization: scmmRepo.Namespace,
Repository: scmmRepo.Name,
Branch: defaultBranch.Name,
URL: url,
RepositoryId: scmmRepo.Namespace + "/" + scmmRepo.Name,
})
}
return repos, nil
}
func getProtocolUrlByName(urls []scmm.ProtocolUrl, name string) string {
for _, url := range urls {
if url.Name == name {
return url.Href
}
}
return ""
}
func (g *ScmManagerProvider) RepoHasPath(ctx context.Context, repo *Repository, path string) (bool, error) {
_, resp, err := g.client.GetContent(repo.Organization, repo.Repository, repo.Branch, path)
if resp != nil && resp.StatusCode == http.StatusNotFound {
return false, nil
}
if err != nil {
if err.Error() == "expect file, got directory" {
return true, nil
}
return false, err
}
return true, nil
}