Skip to content

Commit

Permalink
fix: solve comments
Browse files Browse the repository at this point in the history
  • Loading branch information
renzodavid9 committed Feb 1, 2024
1 parent e87d7b4 commit bab5cfb
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 72 deletions.
43 changes: 35 additions & 8 deletions pkg/skaffold/gcbreposv2/repo_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package gcbreposv2
import (
"context"
"fmt"
"net/url"

cloudbuild "cloud.google.com/go/cloudbuild/apiv2"
cloudbuildpb "cloud.google.com/go/cloudbuild/apiv2/cloudbuildpb"
Expand All @@ -31,34 +32,50 @@ type cloudBuildRepoClient interface {
Close() error
}

type Repo struct {
// Original repo URI.
URI string

// URI with oauth2 format.
CloneURI string
}

var RepositoryManagerClient = repositoryManagerClient

func GetRepoInfo(ctx context.Context, gcpProject, gcpRegion, gcpConnectionName, gcpRepoName string) (repoURI string, readAccessToken string, err error) {
func GetRepoInfo(ctx context.Context, gcpProject, gcpRegion, gcpConnectionName, gcpRepoName string) (Repo, error) {
cbRepoRef := fmt.Sprintf("projects/%v/locations/%v/connections/%v/repositories/%v", gcpProject, gcpRegion, gcpConnectionName, gcpRepoName)
cbClient, err := RepositoryManagerClient(ctx)
if err != nil {
return "", "", fmt.Errorf("failed to create repository manager client: %w", err)
return Repo{}, fmt.Errorf("failed to create repository manager client: %w", err)
}
defer cbClient.Close()

repoURI, err = getrepoURI(ctx, cbClient, cbRepoRef)
repoURI, err := getRepoURI(ctx, cbClient, cbRepoRef)
if err != nil {
return Repo{}, fmt.Errorf("failed to get remote URI for repository %v: %w", gcpRepoName, err)
}

readAccessToken, err := getRepoReadAccessToken(ctx, cbClient, cbRepoRef)
if err != nil {
return "", "", fmt.Errorf("failed to get remote uri for repository %v: %w", gcpRepoName, err)
return Repo{}, fmt.Errorf("failed to get repository read access token for repo %v: %w", gcpRepoName, err)
}

readAccessToken, err = getRepoReadAccessToken(ctx, cbClient, cbRepoRef)
repoCloneURI, err := buildRepoURIWithToken(repoURI, readAccessToken)
if err != nil {
return "", "", fmt.Errorf("failed to get repository read access token for repo %v: %w", gcpRepoName, err)
return Repo{}, fmt.Errorf("failed to clone repo %s: trouble building repo URI with token: %w", repoURI, err)
}

return
return Repo{
URI: repoURI,
CloneURI: repoCloneURI,
}, nil
}

func repositoryManagerClient(ctx context.Context) (cloudBuildRepoClient, error) {
return cloudbuild.NewRepositoryManagerClient(ctx)
}

func getrepoURI(ctx context.Context, cbClient cloudBuildRepoClient, cbRepoRef string) (string, error) {
func getRepoURI(ctx context.Context, cbClient cloudBuildRepoClient, cbRepoRef string) (string, error) {
req := &cloudbuildpb.GetRepositoryRequest{
Name: cbRepoRef,
}
Expand All @@ -79,3 +96,13 @@ func getRepoReadAccessToken(ctx context.Context, cbClient cloudBuildRepoClient,
}
return resp.GetToken(), nil
}

func buildRepoURIWithToken(repoURI, readAccessToken string) (string, error) {
parsed, err := url.Parse(repoURI)
if err != nil {
return "", err
}

parsed.Host = fmt.Sprintf("oauth2:%v@%v", readAccessToken, parsed.Host)
return url.PathUnescape(parsed.String())
}
134 changes: 70 additions & 64 deletions pkg/skaffold/gcbreposv2/repo_resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,108 +28,114 @@ import (
)

type GCBReposClientMock struct {
Region string
Project string
Connection string
Repo string
GitRepo string
ReadToken string
ShouldErrorGetRepo bool
ShouldErrorGetToken bool
GitRepo string
ReadToken string
ErrorGetRepo bool
ErrorGetToken bool
}

const (
gcpProject = "my-project"
gcpRegion = "us-central1"
gcbConnection = "gcb-repo-connection"
gcbRepo = "repo-1"
)

func (c GCBReposClientMock) GetRepository(ctx context.Context, req *cloudbuildpb.GetRepositoryRequest, opts ...gax.CallOption) (*cloudbuildpb.Repository, error) {
if c.ShouldErrorGetRepo {
if c.ErrorGetRepo {
return nil, fmt.Errorf("failed to get repo")
}

if req.Name == fmt.Sprintf("projects/%v/locations/%v/connections/%v/repositories/%v", c.Project, c.Region, c.Connection, c.Repo) {
return &cloudbuildpb.Repository{
Name: c.Repo,
RemoteUri: c.GitRepo,
}, nil
validRepoIdentifier := fmt.Sprintf("projects/%v/locations/%v/connections/%v/repositories/%v", gcpProject, gcpRegion, gcbConnection, gcbRepo)
if req.Name != validRepoIdentifier {
return nil, fmt.Errorf("invalid request, expecting %v, got %v", validRepoIdentifier, req.Name)
}

return nil, fmt.Errorf("invalid request")
return &cloudbuildpb.Repository{
RemoteUri: c.GitRepo,
}, nil
}

func (c GCBReposClientMock) FetchReadToken(ctx context.Context, req *cloudbuildpb.FetchReadTokenRequest, opts ...gax.CallOption) (*cloudbuildpb.FetchReadTokenResponse, error) {
if c.ShouldErrorGetToken {
if c.ErrorGetToken {
return nil, fmt.Errorf("failed to get token")
}

if req.Repository == fmt.Sprintf("projects/%v/locations/%v/connections/%v/repositories/%v", c.Project, c.Region, c.Connection, c.Repo) {
return &cloudbuildpb.FetchReadTokenResponse{
Token: c.ReadToken,
}, nil
validRepoIdentifier := fmt.Sprintf("projects/%v/locations/%v/connections/%v/repositories/%v", gcpProject, gcpRegion, gcbConnection, gcbRepo)
if req.Repository != validRepoIdentifier {
return nil, fmt.Errorf("invalid request, expecting %v, got %v", validRepoIdentifier, req.Repository)
}
return nil, fmt.Errorf("invalid request")

return &cloudbuildpb.FetchReadTokenResponse{
Token: c.ReadToken,
}, nil
}

func (c GCBReposClientMock) Close() error { return nil }

func TestGetRepoURI(t *testing.T) {
func TestGetRepoInfo(t *testing.T) {
tests := []struct {
description string
gcpRegion string
gcpProject string
gcpConnection string
gcpRepo string
expectedGitRepo string
expectedToken string
readToken string
shouldErrorGetRepo bool
shouldErrorGetToken bool
errorMsg string
description string
expectedRepoInfo Repo
gcbMockClient GCBReposClientMock
shouldError bool
errorMsg string
}{
{
description: "correct repo connection string",
gcpRegion: "us-central1",
gcpProject: "my-project",
gcpConnection: "gcb-repo-connection",
gcpRepo: "repo-1",
expectedGitRepo: "https://github.com/org/repo-1",
description: "repo info correct",
expectedRepoInfo: Repo{
URI: "https://github.com/GoogleContainerTools/skaffold",
CloneURI: "https://oauth2:token123@github.com/GoogleContainerTools/skaffold",
},
gcbMockClient: GCBReposClientMock{
GitRepo: "https://github.com/GoogleContainerTools/skaffold",
ReadToken: "token123",
},
},
{
description: "failed getting GCB repo info",
gcpRepo: "repo-1",
shouldErrorGetRepo: true,
errorMsg: "failed to get remote uri for repository repo-1",
description: "failed getting GCB repo info",
expectedRepoInfo: Repo{},
shouldError: true,
errorMsg: fmt.Sprintf("failed to get remote URI for repository %v", gcbRepo),
gcbMockClient: GCBReposClientMock{
ErrorGetRepo: true,
},
},
{
description: "failed getting GCB repo read token",
gcpRepo: "repo-1",
shouldErrorGetToken: true,
errorMsg: "failed to get repository read access token for repo repo-1",
description: "failed getting GCB repo read token",
expectedRepoInfo: Repo{},
shouldError: true,
errorMsg: fmt.Sprintf("failed to get repository read access token for repo %v", gcbRepo),
gcbMockClient: GCBReposClientMock{
ErrorGetToken: true,
},
},
{
description: "failed to build clone repo URI",
expectedRepoInfo: Repo{},
shouldError: true,
errorMsg: "failed to clone repo :not-valid: trouble building repo URI with token",
gcbMockClient: GCBReposClientMock{
GitRepo: ":not-valid",
ReadToken: "token123",
},
},
}

for _, test := range tests {
testutil.Run(t, test.description, func(t *testutil.T) {
ctx := context.Background()
t.Override(&RepositoryManagerClient, func(ctx context.Context) (cloudBuildRepoClient, error) {
return GCBReposClientMock{
Region: test.gcpRegion,
Project: test.gcpProject,
Connection: test.gcpConnection,
Repo: test.gcpRepo,
GitRepo: test.expectedGitRepo,
ReadToken: test.expectedToken,
ShouldErrorGetRepo: test.shouldErrorGetRepo,
ShouldErrorGetToken: test.shouldErrorGetToken,
}, nil
return test.gcbMockClient, nil
})

uri, accessToken, err := GetRepoInfo(ctx, test.gcpProject, test.gcpRegion, test.gcpConnection, test.gcpRepo)
repoInfo, err := GetRepoInfo(ctx, gcpProject, gcpRegion, gcbConnection, gcbRepo)

shouldError := test.shouldErrorGetRepo || test.shouldErrorGetToken
if shouldError {
t.CheckError(shouldError, err)
t.CheckError(test.shouldError, err)
if test.shouldError {
t.CheckErrorContains(test.errorMsg, err)
}

t.CheckDeepEqual(test.expectedGitRepo, uri)
t.CheckDeepEqual(test.expectedToken, accessToken)
t.CheckDeepEqual(test.expectedRepoInfo, repoInfo)
})
}
}

0 comments on commit bab5cfb

Please sign in to comment.