@@ -21,16 +21,12 @@ import (
2121 "fmt"
2222 "io/ioutil"
2323 "os"
24- "path/filepath"
25- "strings"
2624 "time"
2725
2826 "github.com/blang/semver"
2927 "github.com/go-git/go-git/v5"
3028 "github.com/go-git/go-git/v5/plumbing"
3129 "github.com/go-git/go-git/v5/plumbing/transport"
32- "github.com/go-git/go-git/v5/plumbing/transport/http"
33- "github.com/go-git/go-git/v5/plumbing/transport/ssh"
3430 "github.com/go-logr/logr"
3531 corev1 "k8s.io/api/core/v1"
3632 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -40,6 +36,7 @@ import (
4036 "sigs.k8s.io/controller-runtime/pkg/client"
4137
4238 sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
39+ internalgit "github.com/fluxcd/source-controller/internal/git"
4340)
4441
4542// GitRepositoryReconciler reconciles a GitRepository object
@@ -78,7 +75,7 @@ func (r *GitRepositoryReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro
7875 r .gc (repo )
7976
8077 // try git clone
81- syncedRepo , err := r .sync (* repo .DeepCopy ())
78+ syncedRepo , err := r .sync (ctx , * repo .DeepCopy ())
8279 if err != nil {
8380 log .Info ("Git repository sync failed" , "error" , err .Error ())
8481 }
@@ -103,7 +100,7 @@ func (r *GitRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error {
103100 Complete (r )
104101}
105102
106- func (r * GitRepositoryReconciler ) sync (repository sourcev1.GitRepository ) (sourcev1.GitRepository , error ) {
103+ func (r * GitRepositoryReconciler ) sync (ctx context. Context , repository sourcev1.GitRepository ) (sourcev1.GitRepository , error ) {
107104 // set defaults: master branch, no tags fetching, max two commits
108105 branch := "master"
109106 revision := ""
@@ -129,18 +126,29 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc
129126 }
130127 }
131128
132- // create tmp dir for SSH known_hosts
133- tmpSSH , err := ioutil .TempDir ("" , repository .Name )
134- if err != nil {
135- err = fmt .Errorf ("tmp dir error: %w" , err )
136- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .StorageOperationFailedReason , err .Error ()), err
137- }
138- defer os .RemoveAll (tmpSSH )
129+ var auth transport.AuthMethod
130+ if repository .Spec .SecretRef != nil {
131+ name := types.NamespacedName {
132+ Namespace : repository .GetNamespace (),
133+ Name : repository .Spec .SecretRef .Name ,
134+ }
139135
140- auth , err := r .auth (repository , tmpSSH )
141- if err != nil {
142- err = fmt .Errorf ("auth error: %w" , err )
143- return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .AuthenticationFailedReason , err .Error ()), err
136+ var secret corev1.Secret
137+ err := r .Client .Get (ctx , name , & secret )
138+ if err != nil {
139+ err = fmt .Errorf ("auth secret error: %w" , err )
140+ return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .AuthenticationFailedReason , err .Error ()), err
141+ }
142+
143+ method , cleanup , err := internalgit .AuthMethodFromSecret (repository .Spec .URL , secret )
144+ if err != nil {
145+ err = fmt .Errorf ("auth error: %w" , err )
146+ return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .AuthenticationFailedReason , err .Error ()), err
147+ }
148+ if cleanup != nil {
149+ defer cleanup ()
150+ }
151+ auth = method
144152 }
145153
146154 // create tmp dir for the Git clone
@@ -321,74 +329,3 @@ func (r *GitRepositoryReconciler) gc(repository sourcev1.GitRepository) {
321329 }
322330 }
323331}
324-
325- func (r * GitRepositoryReconciler ) auth (repository sourcev1.GitRepository , tmp string ) (transport.AuthMethod , error ) {
326- if repository .Spec .SecretRef == nil {
327- return nil , nil
328- }
329-
330- name := types.NamespacedName {
331- Namespace : repository .GetNamespace (),
332- Name : repository .Spec .SecretRef .Name ,
333- }
334-
335- var secret corev1.Secret
336- err := r .Client .Get (context .TODO (), name , & secret )
337- if err != nil {
338- return nil , err
339- }
340-
341- credentials := secret .Data
342-
343- // HTTP auth
344- if strings .HasPrefix (repository .Spec .URL , "http" ) {
345- auth := & http.BasicAuth {}
346- if username , ok := credentials ["username" ]; ok {
347- auth .Username = string (username )
348- }
349- if password , ok := credentials ["password" ]; ok {
350- auth .Password = string (password )
351- }
352-
353- if auth .Username == "" || auth .Password == "" {
354- return nil , fmt .Errorf ("invalid '%s' secret data: required fields username and password" ,
355- repository .Spec .SecretRef .Name )
356- }
357-
358- return auth , nil
359- }
360-
361- // SSH auth
362- if strings .HasPrefix (repository .Spec .URL , "ssh" ) {
363- var privateKey []byte
364- if identity , ok := credentials ["identity" ]; ok {
365- privateKey = identity
366- } else {
367- return nil , fmt .Errorf ("invalid '%s' secret data: required field identity" , repository .Spec .SecretRef .Name )
368- }
369-
370- pk , err := ssh .NewPublicKeys ("git" , privateKey , "" )
371- if err != nil {
372- return nil , err
373- }
374-
375- known_hosts := filepath .Join (tmp , "known_hosts" )
376- if kh , ok := credentials ["known_hosts" ]; ok {
377- if err := ioutil .WriteFile (filepath .Join (tmp , "known_hosts" ), kh , 0644 ); err != nil {
378- return nil , err
379- }
380- } else {
381- return nil , fmt .Errorf ("invalid '%s' secret data: required field known_hosts" , repository .Spec .SecretRef .Name )
382- }
383-
384- callback , err := ssh .NewKnownHostsCallback (known_hosts )
385- if err != nil {
386- return nil , err
387- }
388- pk .HostKeyCallback = callback
389-
390- return pk , nil
391- }
392-
393- return nil , nil
394- }
0 commit comments