diff --git a/scm/driver/harness/content.go b/scm/driver/harness/content.go index a5a0848d3..91e72ecee 100644 --- a/scm/driver/harness/content.go +++ b/scm/driver/harness/content.go @@ -18,8 +18,12 @@ type contentService struct { } func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm.Content, *scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, ref) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true&%s", repoId, path, ref, queryParams) out := new(fileContent) res, err := s.client.do(ctx, "GET", endpoint, nil, out) // decode raw output content @@ -33,8 +37,12 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm } func (s *contentService) Create(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/commits", repo) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/commits?%s", repoId, queryParams) a := action{ Action: "CREATE", Path: path, @@ -53,8 +61,12 @@ func (s *contentService) Create(ctx context.Context, repo, path string, params * } func (s *contentService) Update(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/commits", repo) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/commits?%s", repoId, queryParams) a := action{ Action: "UPDATE", Path: path, @@ -74,8 +86,12 @@ func (s *contentService) Update(ctx context.Context, repo, path string, params * } func (s *contentService) Delete(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/commits", repo) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/commits?%s", repoId, queryParams) a := action{ Action: "DELETE", Path: path, @@ -93,8 +109,12 @@ func (s *contentService) Delete(ctx context.Context, repo, path string, params * } func (s *contentService) List(ctx context.Context, repo, path, ref string, _ scm.ListOptions) ([]*scm.ContentInfo, *scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true", repo, path, ref) + slug := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(slug) + if err != nil { + return nil, nil, err + } + endpoint := fmt.Sprintf("api/v1/repos/%s/content/%s?git_ref=%s&include_commit=true&%s", repoId, path, ref, queryParams) out := new(contentList) res, err := s.client.do(ctx, "GET", endpoint, nil, &out) return convertContentInfoList(out.Content.Entries), res, err diff --git a/scm/driver/harness/git.go b/scm/driver/harness/git.go index 0416338b5..adbd34c26 100644 --- a/scm/driver/harness/git.go +++ b/scm/driver/harness/git.go @@ -19,7 +19,11 @@ type gitService struct { func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm.ReferenceInput) (*scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/branches", harnessURI) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/branches?%s", repoId, queryParams) in := &branchInput{ Name: params.Name, Target: params.Sha, @@ -29,7 +33,11 @@ func (s *gitService) CreateBranch(ctx context.Context, repo string, params *scm. func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Reference, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/branches/%s", harnessURI, name) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/branches/%s?%s", repoId, name, queryParams) out := new(branch) res, err := s.client.do(ctx, "GET", path, nil, out) return convertBranch(out), res, err @@ -37,7 +45,11 @@ func (s *gitService) FindBranch(ctx context.Context, repo, name string) (*scm.Re func (s *gitService) FindCommit(ctx context.Context, repo, ref string) (*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/commits/%s", harnessURI, ref) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/commits/%s?%s", repoId, ref, queryParams) out := new(commitInfo) res, err := s.client.do(ctx, "GET", path, nil, out) return convertCommitInfo(out), res, err @@ -49,7 +61,11 @@ func (s *gitService) FindTag(ctx context.Context, repo, name string) (*scm.Refer func (s *gitService) ListBranches(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/branches?%s", harnessURI, encodeListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/branches?%s&%s", repoId, encodeListOptions(opts), queryParams) out := []*branch{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertBranchList(out), res, err @@ -63,7 +79,11 @@ func (s *gitService) ListBranchesV2(ctx context.Context, repo string, opts scm.B func (s *gitService) ListCommits(ctx context.Context, repo string, opts scm.CommitListOptions) ([]*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/commits?%s", harnessURI, encodeCommitListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/commits?%s&%s", repoId, encodeCommitListOptions(opts), queryParams) out := new(commits) res, err := s.client.do(ctx, "GET", path, nil, &out) return convertCommitList(out), res, err @@ -75,7 +95,11 @@ func (s *gitService) ListTags(ctx context.Context, repo string, _ scm.ListOption func (s *gitService) ListChanges(ctx context.Context, repo, ref string, opts scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/commits/%s/diff?%s", harnessURI, ref, encodeListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/commits/%s/diff?%s&%s", repoId, ref, encodeListOptions(opts), queryParams) out := []*fileDiff{} res, err := s.client.do(ctx, "POST", path, nil, &out) return convertFileDiffs(out), res, err @@ -83,7 +107,11 @@ func (s *gitService) ListChanges(ctx context.Context, repo, ref string, opts scm func (s *gitService) CompareChanges(ctx context.Context, repo, source, target string, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/diff/%s...%s", harnessURI, source, target) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/diff/%s...%s?%s", repoId, source, target, queryParams) out := []*fileDiff{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertChangeList(out), res, err diff --git a/scm/driver/harness/pr.go b/scm/driver/harness/pr.go index f84012655..35cadd20a 100644 --- a/scm/driver/harness/pr.go +++ b/scm/driver/harness/pr.go @@ -20,7 +20,11 @@ type pullService struct { func (s *pullService) Find(ctx context.Context, repo string, index int) (*scm.PullRequest, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d", harnessURI, index) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d?%s", repoId, index, queryParams) out := new(pr) res, err := s.client.do(ctx, "GET", path, nil, out) return convertPullRequest(out), res, err @@ -33,7 +37,11 @@ func (s *pullService) FindComment(context.Context, string, int, int) (*scm.Comme func (s *pullService) List(ctx context.Context, repo string, opts scm.PullRequestListOptions) ([]*scm.PullRequest, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq?%s", harnessURI, encodePullRequestListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq?%s&%s", repoId, encodePullRequestListOptions(opts), queryParams) out := []*pr{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertPullRequestList(out), res, err @@ -45,7 +53,11 @@ func (s *pullService) ListComments(context.Context, string, int, scm.ListOptions func (s *pullService) ListCommits(ctx context.Context, repo string, index int, opts scm.ListOptions) ([]*scm.Commit, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/commits?%s", harnessURI, index, encodeListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/commits?%s&%s", repoId, index, encodeListOptions(opts), queryParams) out := []*commit{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertCommits(out), res, err @@ -53,7 +65,11 @@ func (s *pullService) ListCommits(ctx context.Context, repo string, index int, o func (s *pullService) ListChanges(ctx context.Context, repo string, number int, _ scm.ListOptions) ([]*scm.Change, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/diff", harnessURI, number) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/diff?%s", repoId, number, queryParams) out := []*fileDiff{} res, err := s.client.do(ctx, "POST", path, nil, &out) return convertFileDiffs(out), res, err @@ -61,7 +77,11 @@ func (s *pullService) ListChanges(ctx context.Context, repo string, number int, func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRequestInput) (*scm.PullRequest, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/pullreq", harnessURI) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq?%s", repoId, queryParams) in := &prInput{ Title: input.Title, Description: input.Body, @@ -74,8 +94,12 @@ func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRe } func (s *pullService) CreateComment(ctx context.Context, repo string, prNumber int, input *scm.CommentInput) (*scm.Comment, *scm.Response, error) { - harnessQueryParams := fmt.Sprintf("?accountIdentifier=%s&orgIdentifier=%s&projectIdentifier=%s", s.client.account, s.client.organization, s.client.project) - path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/comments%s", repo, prNumber, harnessQueryParams) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/pullreq/%d/comments?%s", repoId, prNumber, queryParams) in := &prComment{ Text: input.Body, } diff --git a/scm/driver/harness/repo.go b/scm/driver/harness/repo.go index 496bc1492..dc489a267 100644 --- a/scm/driver/harness/repo.go +++ b/scm/driver/harness/repo.go @@ -18,8 +18,12 @@ type repositoryService struct { } func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Repository, *scm.Response, error) { - repo = buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s", repo) + harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s?%s", repoId, queryParams) out := new(repository) res, err := s.client.do(ctx, "GET", path, nil, out) if err != nil { @@ -34,7 +38,11 @@ func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Reposit func (s *repositoryService) FindHook(ctx context.Context, repo string, id string) (*scm.Hook, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s", harnessURI, id) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s?%s", repoId, id, queryParams) out := new(hook) res, err := s.client.do(ctx, "GET", path, nil, &out) return convertHook(out), res, err @@ -45,8 +53,11 @@ func (s *repositoryService) FindPerms(ctx context.Context, repo string) (*scm.Pe } func (s *repositoryService) List(ctx context.Context, opts scm.ListOptions) ([]*scm.Repository, *scm.Response, error) { - harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, "") - path := fmt.Sprintf("api/v1/spaces/%s/repos?sort=path&order=asc&%s", harnessURI, encodeListOptions(opts)) + queryParams := fmt.Sprintf("%s=%s&%s=%s&%s=%s&%s=%s", + projectIdentifier, s.client.project, orgIdentifier, s.client.organization, accountIdentifier, s.client.account, + routingId, s.client.account) + + path := fmt.Sprintf("api/v1/repos?sort=path&order=asc&%s&%s", encodeListOptions(opts), queryParams) out := []*repository{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertRepositoryList(out), res, err @@ -59,7 +70,11 @@ func (s *repositoryService) ListV2(ctx context.Context, opts scm.RepoListOptions func (s *repositoryService) ListHooks(ctx context.Context, repo string, opts scm.ListOptions) ([]*scm.Hook, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/webhooks?sort=display_name&order=asc&%s", harnessURI, encodeListOptions(opts)) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/webhooks?sort=display_name&order=asc&%s&%s", repoId, encodeListOptions(opts), queryParams) out := []*hook{} res, err := s.client.do(ctx, "GET", path, nil, &out) return convertHookList(out), res, err @@ -71,7 +86,11 @@ func (s *repositoryService) ListStatus(ctx context.Context, repo string, ref str func (s *repositoryService) CreateHook(ctx context.Context, repo string, input *scm.HookInput) (*scm.Hook, *scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/webhooks", harnessURI) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/webhooks?%s", repoId, queryParams) in := new(hook) in.Enabled = true in.Identifier = input.Name @@ -96,7 +115,11 @@ func (s *repositoryService) UpdateHook(ctx context.Context, repo, id string, inp func (s *repositoryService) DeleteHook(ctx context.Context, repo string, id string) (*scm.Response, error) { harnessURI := buildHarnessURI(s.client.account, s.client.organization, s.client.project, repo) - path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s", harnessURI, id) + repoId, queryParams, err := getRepoAndQueryParams(harnessURI) + if err != nil { + return nil, err + } + path := fmt.Sprintf("api/v1/repos/%s/webhooks/%s?%s", repoId, id, queryParams) return s.client.do(ctx, "DELETE", path, nil, nil) } diff --git a/scm/driver/harness/util.go b/scm/driver/harness/util.go index d094c8257..4be210068 100644 --- a/scm/driver/harness/util.go +++ b/scm/driver/harness/util.go @@ -13,6 +13,13 @@ import ( "github.com/drone/go-scm/scm" ) +const ( + accountIdentifier = "accountIdentifier" + projectIdentifier = "projectIdentifier" + orgIdentifier = "orgIdentifier" + routingId = "routingId" +) + func buildHarnessURI(account, organization, project, repo string) (uri string) { if account != "" { if project != "" { @@ -32,6 +39,34 @@ func buildHarnessURI(account, organization, project, repo string) (uri string) { return repo } +func getRepoAndQueryParams(slug string) (string, string, error) { + params := url.Values{} + s := strings.TrimSuffix(slug, "/+") + splitSlug := strings.Split(s, "/") + if len(splitSlug) == 0 || len(splitSlug) == 1 { + return "", "", fmt.Errorf("split length: %d is small for slug %s", len(splitSlug), slug) + } + + params.Set(accountIdentifier, splitSlug[0]) + params.Set(routingId, splitSlug[0]) + var repoId string + switch len(splitSlug) { + case 2: + repoId = splitSlug[1] + case 3: + params.Set(orgIdentifier, splitSlug[1]) + repoId = splitSlug[2] + case 4: + params.Set(orgIdentifier, splitSlug[1]) + params.Set(projectIdentifier, splitSlug[2]) + repoId = splitSlug[3] + default: + return "", "", fmt.Errorf("split length more than %d encountered for slug %s", len(splitSlug), slug) + + } + return repoId, params.Encode(), nil +} + func encodeListOptions(opts scm.ListOptions) string { params := url.Values{} if opts.Page != 0 {