Skip to content

Commit

Permalink
feat: add support for Bitbucket Server (SCM + PR); add filters for PR (
Browse files Browse the repository at this point in the history
…#9049)

Signed-off-by: mlosicki <mlosicki@users.noreply.github.com>
  • Loading branch information
mlosicki committed Apr 11, 2022
1 parent 3c0854f commit c305a02
Show file tree
Hide file tree
Showing 22 changed files with 2,531 additions and 13 deletions.
15 changes: 14 additions & 1 deletion applicationset/generators/pull_request.go
Expand Up @@ -9,6 +9,7 @@ import (
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/argoproj/argo-cd/v2/applicationset/services/pull_request"
pullrequest "github.com/argoproj/argo-cd/v2/applicationset/services/pull_request"
argoprojiov1alpha1 "github.com/argoproj/argo-cd/v2/pkg/apis/applicationset/v1alpha1"
)
Expand Down Expand Up @@ -61,7 +62,7 @@ func (g *PullRequestGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
return nil, fmt.Errorf("failed to select pull request service provider: %v", err)
}

pulls, err := svc.List(ctx)
pulls, err := pull_request.ListPullRequests(ctx, svc, appSetGenerator.PullRequest.Filters)
if err != nil {
return nil, fmt.Errorf("error listing repos: %v", err)
}
Expand Down Expand Up @@ -94,6 +95,18 @@ func (g *PullRequestGenerator) selectServiceProvider(ctx context.Context, genera
}
return pullrequest.NewGiteaService(ctx, token, providerConfig.API, providerConfig.Owner, providerConfig.Repo, providerConfig.Insecure)
}
if generatorConfig.BitbucketServer != nil {
providerConfig := generatorConfig.BitbucketServer
if providerConfig.BasicAuth != nil {
password, err := g.getSecretRef(ctx, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace)
if err != nil {
return nil, fmt.Errorf("error fetching Secret token: %v", err)
}
return pullrequest.NewBitbucketServiceBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.Repo)
} else {
return pullrequest.NewBitbucketServiceNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.Repo)
}
}
return nil, fmt.Errorf("no Pull Request provider implementation configured")
}

Expand Down
15 changes: 15 additions & 0 deletions applicationset/generators/scm_provider.go
Expand Up @@ -86,6 +86,21 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha
if err != nil {
return nil, fmt.Errorf("error initializing Gitea service: %v", err)
}
} else if providerConfig.BitbucketServer != nil {
providerConfig := providerConfig.BitbucketServer
var scmError error
if providerConfig.BasicAuth != nil {
password, err := g.getSecretRef(ctx, providerConfig.BasicAuth.PasswordRef, applicationSetInfo.Namespace)
if err != nil {
return nil, fmt.Errorf("error fetching Secret token: %v", err)
}
provider, scmError = scm_provider.NewBitbucketServerProviderBasicAuth(ctx, providerConfig.BasicAuth.Username, password, providerConfig.API, providerConfig.Project, providerConfig.AllBranches)
} else {
provider, scmError = scm_provider.NewBitbucketServerProviderNoAuth(ctx, providerConfig.API, providerConfig.Project, providerConfig.AllBranches)
}
if scmError != nil {
return nil, fmt.Errorf("error initializing Bitbucket Server service: %v", scmError)
}
} else {
return nil, fmt.Errorf("no SCM provider implementation configured")
}
Expand Down
82 changes: 82 additions & 0 deletions applicationset/services/pull_request/bitbucket_server.go
@@ -0,0 +1,82 @@
package pull_request

import (
"context"
"fmt"

"github.com/argoproj/argo-cd/v2/applicationset/utils"
bitbucketv1 "github.com/gfleury/go-bitbucket-v1"
log "github.com/sirupsen/logrus"
)

type BitbucketService struct {
client *bitbucketv1.APIClient
projectKey string
repositorySlug string
// Not supported for PRs by Bitbucket Server
// labels []string
}

var _ PullRequestService = (*BitbucketService)(nil)

func NewBitbucketServiceBasicAuth(ctx context.Context, username, password, url, projectKey, repositorySlug string) (PullRequestService, error) {
bitbucketConfig := bitbucketv1.NewConfiguration(url)
// Avoid the XSRF check
bitbucketConfig.AddDefaultHeader("x-atlassian-token", "no-check")
bitbucketConfig.AddDefaultHeader("x-requested-with", "XMLHttpRequest")

ctx = context.WithValue(ctx, bitbucketv1.ContextBasicAuth, bitbucketv1.BasicAuth{
UserName: username,
Password: password,
})
return newBitbucketService(ctx, bitbucketConfig, projectKey, repositorySlug)
}

func NewBitbucketServiceNoAuth(ctx context.Context, url, projectKey, repositorySlug string) (PullRequestService, error) {
return newBitbucketService(ctx, bitbucketv1.NewConfiguration(url), projectKey, repositorySlug)
}

func newBitbucketService(ctx context.Context, bitbucketConfig *bitbucketv1.Configuration, projectKey, repositorySlug string) (PullRequestService, error) {
bitbucketConfig.BasePath = utils.NormalizeBitbucketBasePath(bitbucketConfig.BasePath)
bitbucketClient := bitbucketv1.NewAPIClient(ctx, bitbucketConfig)

return &BitbucketService{
client: bitbucketClient,
projectKey: projectKey,
repositorySlug: repositorySlug,
}, nil
}

func (b *BitbucketService) List(_ context.Context) ([]*PullRequest, error) {
paged := map[string]interface{}{
"limit": 100,
}

pullRequests := []*PullRequest{}
for {
response, err := b.client.DefaultApi.GetPullRequestsPage(b.projectKey, b.repositorySlug, paged)
if err != nil {
return nil, fmt.Errorf("error listing pull requests for %s/%s: %v", b.projectKey, b.repositorySlug, err)
}
pulls, err := bitbucketv1.GetPullRequestsResponse(response)
if err != nil {
log.Errorf("error parsing pull request response '%v'", response.Values)
return nil, fmt.Errorf("error parsing pull request response for %s/%s: %v", b.projectKey, b.repositorySlug, err)
}

for _, pull := range pulls {
pullRequests = append(pullRequests, &PullRequest{
Number: pull.ID,
Branch: pull.FromRef.DisplayID, // ID: refs/heads/main DisplayID: main
HeadSHA: pull.FromRef.LatestCommit, // This is not defined in the official docs, but works in practice
})
}

hasNextPage, nextPageStart := bitbucketv1.HasNextPage(response)
if !hasNextPage {
break
}
paged["start"] = nextPageStart
}
return pullRequests, nil
}

0 comments on commit c305a02

Please sign in to comment.