Skip to content

Commit 1fa0898

Browse files
authored
Support Cloning From Private Git Repository (#2840)
1 parent 620b9cc commit 1fa0898

File tree

11 files changed

+216
-18
lines changed

11 files changed

+216
-18
lines changed

porch/api/porch/types_packagerevisions.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,14 @@ type GitPackage struct {
124124

125125
// Directory within the Git repository where the packages are stored. A subdirectory of this directory containing a Kptfile is considered a package.
126126
Directory string `json:"directory"`
127+
128+
// Reference to secret containing authentication credentials. Optional.
129+
SecretRef SecretRef `json:"secretRef,omitempty"`
130+
}
131+
132+
type SecretRef struct {
133+
// Name of the secret. The secret is expected to be located in the same namespace as the resource containing the reference.
134+
Name string `json:"name"`
127135
}
128136

129137
// OciPackage describes a repository compatible with the Open Coutainer Registry standard.

porch/api/porch/v1alpha1/types_packagerevisions.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,14 @@ type GitPackage struct {
125125

126126
// Directory within the Git repository where the packages are stored. A subdirectory of this directory containing a Kptfile is considered a package.
127127
Directory string `json:"directory"`
128+
129+
// Reference to secret containing authentication credentials. Optional.
130+
SecretRef SecretRef `json:"secretRef,omitempty"`
131+
}
132+
133+
type SecretRef struct {
134+
// Name of the secret. The secret is expected to be located in the same namespace as the resource containing the reference.
135+
Name string `json:"name"`
128136
}
129137

130138
// OciPackage describes a repository compatible with the Open Coutainer Registry standard.

porch/api/porch/v1alpha1/zz_generated.conversion.go

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

porch/api/porch/v1alpha1/zz_generated.deepcopy.go

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

porch/api/porch/zz_generated.deepcopy.go

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

porch/apiserver/pkg/e2e/suite.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type GitConfig struct {
5454
Branch string `json:"branch"`
5555
Directory string `json:"directory"`
5656
Username string `json:"username"`
57-
Password Password `json:"token"`
57+
Password Password `json:"password"`
5858
}
5959

6060
type OciConfig struct {

porch/apiserver/pkg/generated/openapi/zz_generated.openapi.go

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

porch/engine/pkg/engine/clone.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@ import (
3030
)
3131

3232
type clonePackageMutation struct {
33-
task *api.Task
34-
name string // package target name
33+
task *api.Task
34+
namespace string
35+
name string // package target name
36+
credentialResolver repository.CredentialResolver
3537
}
3638

3739
func (m *clonePackageMutation) Apply(ctx context.Context, resources repository.PackageResources) (repository.PackageResources, *api.Task, error) {
@@ -72,6 +74,9 @@ func (m *clonePackageMutation) cloneFromGit(ctx context.Context, gitPackage *api
7274
Repo: gitPackage.Repo,
7375
Branch: gitPackage.Ref,
7476
Directory: gitPackage.Directory,
77+
SecretRef: configapi.SecretRef{
78+
Name: gitPackage.SecretRef.Name,
79+
},
7580
}
7681

7782
dir, err := ioutil.TempDir("", "clone-git-package-*")
@@ -80,8 +85,7 @@ func (m *clonePackageMutation) cloneFromGit(ctx context.Context, gitPackage *api
8085
}
8186
defer os.RemoveAll(dir)
8287

83-
// TODO: Add support for authentication.
84-
var credentialResolver repository.CredentialResolver = nil
88+
credentialResolver := m.credentialResolver
8589
r, err := git.OpenRepository(ctx, "", "", &spec, credentialResolver, dir)
8690
if err != nil {
8791
return repository.PackageResources{}, fmt.Errorf("cannot clone Git repository: %w", err)

porch/engine/pkg/engine/clone_test.go

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"fmt"
2020
"io"
2121
"io/fs"
22+
"math/rand"
2223
"net"
2324
"net/http"
2425
"os"
@@ -111,8 +112,8 @@ func createRepoWithContents(t *testing.T, contentDir string) *gogit.Repository {
111112
return repo
112113
}
113114

114-
func startGitServer(t *testing.T, repo *gogit.Repository) string {
115-
server, err := git.NewGitServer(repo)
115+
func startGitServer(t *testing.T, repo *gogit.Repository, opts ...git.GitServerOption) string {
116+
server, err := git.NewGitServer(repo, opts...)
116117
if err != nil {
117118
t.Fatalf("Failed to create git server: %v", err)
118119
}
@@ -143,13 +144,31 @@ func startGitServer(t *testing.T, repo *gogit.Repository) string {
143144
return fmt.Sprintf("http://%s", address)
144145
}
145146

146-
type cr struct{}
147+
type credentialResolver struct {
148+
username, password string
149+
}
150+
151+
func randomString(n int) string {
152+
const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
153+
result := make([]byte, n)
154+
for i := range result {
155+
result[i] = letters[rand.Intn(len(letters))]
156+
}
157+
return string(result)
158+
}
159+
160+
func randomCredentials() *credentialResolver {
161+
return &credentialResolver{
162+
username: randomString(30),
163+
password: randomString(30),
164+
}
165+
}
147166

148-
func (cr) ResolveCredential(ctx context.Context, namespace, name string) (repository.Credential, error) {
167+
func (r *credentialResolver) ResolveCredential(ctx context.Context, namespace, name string) (repository.Credential, error) {
149168
return repository.Credential{
150169
Data: map[string][]byte{
151-
"username": []byte(""),
152-
"password": []byte(""),
170+
"username": []byte(r.username),
171+
"password": []byte(r.password),
153172
},
154173
}, nil
155174
}
@@ -159,8 +178,10 @@ func TestCloneGitBasicAuth(t *testing.T) {
159178
if err != nil {
160179
t.Fatalf("Failed to find testdata: %v", err)
161180
}
181+
182+
auth := randomCredentials()
162183
repo := createRepoWithContents(t, testdata)
163-
addr := startGitServer(t, repo)
184+
addr := startGitServer(t, repo, git.WithBasicAuth(auth.username, auth.password))
164185

165186
cpm := clonePackageMutation{
166187
task: &v1alpha1.Task{
@@ -172,13 +193,28 @@ func TestCloneGitBasicAuth(t *testing.T) {
172193
Repo: addr,
173194
Ref: "main",
174195
Directory: "configmap",
196+
SecretRef: v1alpha1.SecretRef{
197+
Name: "git-credentials",
198+
},
175199
},
176200
},
177201
},
178202
},
179-
name: "test-configmap",
203+
namespace: "test-namespace",
204+
name: "test-configmap",
205+
credentialResolver: &credentialResolver{
206+
username: "",
207+
password: "",
208+
},
180209
}
181210

211+
_, _, err = cpm.Apply(context.Background(), repository.PackageResources{})
212+
if err == nil {
213+
t.Errorf("Expected error (unauthorized); got none")
214+
}
215+
216+
cpm.credentialResolver = auth
217+
182218
r, _, err := cpm.Apply(context.Background(), repository.PackageResources{})
183219
if err != nil {
184220
t.Errorf("task apply failed: %v", err)

porch/engine/pkg/engine/engine.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,10 @@ func (cad *cadEngine) mapTaskToMutation(ctx context.Context, obj *api.PackageRev
106106
return nil, fmt.Errorf("clone not set for task of type %q", task.Type)
107107
}
108108
return &clonePackageMutation{
109-
task: task,
110-
name: obj.Spec.PackageName,
109+
task: task,
110+
namespace: obj.Namespace,
111+
name: obj.Spec.PackageName,
112+
credentialResolver: cad.credentialResolver,
111113
}, nil
112114

113115
case api.TaskTypePatch:

0 commit comments

Comments
 (0)