From 6d6106f74eebea4dcee0b79567be6518b5bdf239 Mon Sep 17 00:00:00 2001 From: Tiger Kaovilai Date: Wed, 25 Dec 2024 12:00:44 +0700 Subject: [PATCH] Add CACert from BSL config for download requests. Signed-off-by: Tiger Kaovilai --- pkg/apis/velero/v1/download_request_types.go | 3 ++ .../util/downloadrequest/downloadrequest.go | 29 ++++++++++++++----- pkg/controller/download_request_controller.go | 3 ++ pkg/plugin/velero/object_store.go | 2 ++ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/pkg/apis/velero/v1/download_request_types.go b/pkg/apis/velero/v1/download_request_types.go index f23118fe50..842d32de1e 100644 --- a/pkg/apis/velero/v1/download_request_types.go +++ b/pkg/apis/velero/v1/download_request_types.go @@ -79,6 +79,9 @@ type DownloadRequestStatus struct { // +optional DownloadURL string `json:"downloadURL,omitempty"` + // CaCert contains cacert value to use + CaCert string + // Expiration is when this DownloadRequest expires and can be deleted by the system. // +optional // +nullable diff --git a/pkg/cmd/util/downloadrequest/downloadrequest.go b/pkg/cmd/util/downloadrequest/downloadrequest.go index 7a85920fa8..ce798dddb0 100644 --- a/pkg/cmd/util/downloadrequest/downloadrequest.go +++ b/pkg/cmd/util/downloadrequest/downloadrequest.go @@ -54,49 +54,50 @@ func Stream( ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() - downloadURL, err := getDownloadURL(ctx, kbClient, namespace, name, kind) + downloadURL, caCertByteString, err := getDownloadURL(ctx, kbClient, namespace, name, kind) if err != nil { return err } - if err := download(ctx, downloadURL, kind, w, insecureSkipTLSVerify, caCertFile); err != nil { + if err := download(ctx, downloadURL, kind, w, insecureSkipTLSVerify, caCertFile, caCertByteString); err != nil { return err } return nil } +// returns downloadURL and caCert func getDownloadURL( ctx context.Context, kbClient kbclient.Client, namespace, name string, kind veleroV1api.DownloadTargetKind, -) (string, error) { +) (string, string, error) { uuid, err := uuid.NewRandom() if err != nil { - return "", err + return "", "", err } reqName := fmt.Sprintf("%s-%s", name, uuid.String()) created := builder.ForDownloadRequest(namespace, reqName).Target(kind, name).Result() if err := kbClient.Create(ctx, created, &kbclient.CreateOptions{}); err != nil { - return "", errors.WithStack(err) + return "", "", errors.WithStack(err) } for { select { case <-ctx.Done(): - return "", ErrDownloadRequestDownloadURLTimeout + return "", "", ErrDownloadRequestDownloadURLTimeout case <-time.After(25 * time.Millisecond): updated := &veleroV1api.DownloadRequest{} if err := kbClient.Get(ctx, kbclient.ObjectKey{Name: created.Name, Namespace: namespace}, updated); err != nil { - return "", errors.WithStack(err) + return "", "", errors.WithStack(err) } if updated.Status.DownloadURL != "" { - return updated.Status.DownloadURL, nil + return updated.Status.DownloadURL, updated.Status.CaCert, nil } } } @@ -109,8 +110,10 @@ func download( w io.Writer, insecureSkipTLSVerify bool, caCertFile string, + caCertByteString string, ) error { var caPool *x509.CertPool + var err error if len(caCertFile) > 0 { caCert, err := os.ReadFile(caCertFile) if err != nil { @@ -125,6 +128,16 @@ func download( } caPool.AppendCertsFromPEM(caCert) } + if len(caCertByteString) > 0 { + // bundle the passed in cert with the system cert pool + // if it's available, otherwise create a new pool just + // for this. + caPool, err = x509.SystemCertPool() + if err != nil { + caPool = x509.NewCertPool() + } + caPool.AppendCertsFromPEM([]byte(caCertByteString)) + } defaultTransport := http.DefaultTransport.(*http.Transport) // same settings as the default transport diff --git a/pkg/controller/download_request_controller.go b/pkg/controller/download_request_controller.go index bd95658952..484f4b92ca 100644 --- a/pkg/controller/download_request_controller.go +++ b/pkg/controller/download_request_controller.go @@ -34,6 +34,7 @@ import ( "github.com/vmware-tanzu/velero/pkg/itemoperationmap" "github.com/vmware-tanzu/velero/pkg/persistence" "github.com/vmware-tanzu/velero/pkg/plugin/clientmgmt" + "github.com/vmware-tanzu/velero/pkg/plugin/velero" "github.com/vmware-tanzu/velero/pkg/util/kube" ) @@ -209,6 +210,8 @@ func (r *downloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ return ctrl.Result{}, errors.WithStack(err) } + downloadRequest.Status.CaCert = location.Spec.Config[velero.CaCertKey] + downloadRequest.Status.Phase = velerov1api.DownloadRequestPhaseProcessed // Update the expiration again to extend the time we wait (the TTL) to start after successfully processing the URL. diff --git a/pkg/plugin/velero/object_store.go b/pkg/plugin/velero/object_store.go index 29082e704b..a2056c8b7d 100644 --- a/pkg/plugin/velero/object_store.go +++ b/pkg/plugin/velero/object_store.go @@ -21,6 +21,8 @@ import ( "time" ) +const CaCertKey = "caCert" + // ObjectStore exposes basic object-storage operations required // by Velero. type ObjectStore interface {