Skip to content

Commit

Permalink
feat: Add http.Header to CreateSignedURL method in ObjectStore interface
Browse files Browse the repository at this point in the history
Signed-off-by: Itamar Perez <[email protected]>
  • Loading branch information
esomore committed Jul 17, 2024
1 parent 55e0278 commit 16052cb
Show file tree
Hide file tree
Showing 14 changed files with 70 additions and 42 deletions.
2 changes: 1 addition & 1 deletion pkg/controller/download_request_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (r *downloadRequestReconciler) Reconcile(ctx context.Context, req ctrl.Requ
_ = r.restoreItemOperationsMap.UpdateForRestore(backupStore, downloadRequest.Spec.Target.Name)
}

if downloadRequest.Status.DownloadURL, err = backupStore.GetDownloadURL(downloadRequest.Spec.Target); err != nil {
if downloadRequest.Status.DownloadURL, _, err = backupStore.GetDownloadURL(downloadRequest.Spec.Target); err != nil {
log.Warnf("fail to get Backup metadata file's download URL %s, retry later: %s", downloadRequest.Spec.Target, err)
return ctrl.Result{}, errors.WithStack(err)
}
Expand Down
9 changes: 5 additions & 4 deletions pkg/persistence/in_memory_object_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"bytes"
"errors"
"io"
"net/http"
"strings"
"time"
)
Expand Down Expand Up @@ -152,18 +153,18 @@ func (o *inMemoryObjectStore) DeleteObject(bucket, key string) error {
return nil
}

func (o *inMemoryObjectStore) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) {
func (o *inMemoryObjectStore) CreateSignedURL(bucket, key string, ttl time.Duration) (string, http.Header, error) {
bucketData, ok := o.Data[bucket]
if !ok {
return "", errors.New("bucket not found")
return "", http.Header{}, errors.New("bucket not found")
}

_, ok = bucketData[key]
if !ok {
return "", errors.New("key not found")
return "", http.Header{}, errors.New("key not found")
}

return "a-url", nil
return "a-url", http.Header{}, nil
}

//
Expand Down
13 changes: 6 additions & 7 deletions pkg/persistence/mocks/backup_store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions pkg/persistence/mocks/object_store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions pkg/persistence/object_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"compress/gzip"
"encoding/json"
"io"
"net/http"
"strings"
"time"

Expand Down Expand Up @@ -92,7 +93,7 @@ type BackupStore interface {
DeleteRestore(name string) error
GetRestoredResourceList(name string) (map[string][]string, error)

GetDownloadURL(target velerov1api.DownloadTarget) (string, error)
GetDownloadURL(target velerov1api.DownloadTarget) (string, http.Header, error)
}

// DownloadURLTTL is how long a download URL is valid for.
Expand Down Expand Up @@ -615,7 +616,7 @@ func (s *objectBackupStore) PutBackupContents(backup string, backupContents io.R
return seekAndPutObject(s.objectStore, s.bucket, s.layout.getBackupContentsKey(backup), backupContents)
}

func (s *objectBackupStore) GetDownloadURL(target velerov1api.DownloadTarget) (string, error) {
func (s *objectBackupStore) GetDownloadURL(target velerov1api.DownloadTarget) (string, http.Header, error) {
switch target.Kind {
case velerov1api.DownloadTargetKindBackupContents:
return s.objectStore.CreateSignedURL(s.bucket, s.layout.getBackupContentsKey(target.Name), DownloadURLTTL)
Expand Down Expand Up @@ -646,7 +647,7 @@ func (s *objectBackupStore) GetDownloadURL(target velerov1api.DownloadTarget) (s
case velerov1api.DownloadTargetKindRestoreVolumeInfo:
return s.objectStore.CreateSignedURL(s.bucket, s.layout.getRestoreVolumeInfoKey(target.Name), DownloadURLTTL)
default:
return "", errors.Errorf("unsupported download target kind %q", target.Kind)
return "", http.Header{}, errors.Errorf("unsupported download target kind %q", target.Kind)
}
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/persistence/object_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ func TestGetDownloadURL(t *testing.T) {
t.Run(string(kind), func(t *testing.T) {
require.NoError(t, harness.objectStore.PutObject("test-bucket", expectedKey, newStringReadSeeker("foo")))

url, err := harness.GetDownloadURL(velerov1api.DownloadTarget{Kind: kind, Name: test.targetName})
url, _, err := harness.GetDownloadURL(velerov1api.DownloadTarget{Kind: kind, Name: test.targetName})
require.NoError(t, err)
assert.Equal(t, "a-url", url)
})
Expand Down
5 changes: 3 additions & 2 deletions pkg/plugin/clientmgmt/restartable_object_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package clientmgmt

import (
"io"
"net/http"
"time"

"github.com/pkg/errors"
Expand Down Expand Up @@ -167,10 +168,10 @@ func (r *restartableObjectStore) DeleteObject(bucket string, key string) error {
}

// CreateSignedURL restarts the plugin's process if needed, then delegates the call.
func (r *restartableObjectStore) CreateSignedURL(bucket string, key string, ttl time.Duration) (string, error) {
func (r *restartableObjectStore) CreateSignedURL(bucket string, key string, ttl time.Duration) (string, http.Header, error) {
delegate, err := r.getDelegate()
if err != nil {
return "", err
return "", http.Header{}, err
}
return delegate.CreateSignedURL(bucket, key, ttl)
}
5 changes: 3 additions & 2 deletions pkg/plugin/clientmgmt/restartable_object_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package clientmgmt

import (
"io"
"net/http"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -231,8 +232,8 @@ func TestRestartableObjectStoreDelegatedFunctions(t *testing.T) {
restartabletest.RestartableDelegateTest{
Function: "CreateSignedURL",
Inputs: []interface{}{"bucket", "key", 30 * time.Minute},
ExpectedErrorOutputs: []interface{}{"", errors.Errorf("reset error")},
ExpectedDelegateOutputs: []interface{}{"signedURL", errors.Errorf("delegate error")},
ExpectedErrorOutputs: []interface{}{"", http.Header{}, errors.Errorf("reset error")},
ExpectedDelegateOutputs: []interface{}{"signedURL", http.Header{}, errors.Errorf("delegate error")},
},
)
}
7 changes: 4 additions & 3 deletions pkg/plugin/framework/object_store_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package framework

import (
"io"
"net/http"
"time"

"github.com/pkg/errors"
Expand Down Expand Up @@ -206,7 +207,7 @@ func (c *ObjectStoreGRPCClient) DeleteObject(bucket, key string) error {
}

// CreateSignedURL creates a pre-signed URL for the given bucket and key that expires after ttl.
func (c *ObjectStoreGRPCClient) CreateSignedURL(bucket, key string, ttl time.Duration) (string, error) {
func (c *ObjectStoreGRPCClient) CreateSignedURL(bucket, key string, ttl time.Duration) (string, http.Header, error) {
req := &proto.CreateSignedURLRequest{
Plugin: c.Plugin,
Bucket: bucket,
Expand All @@ -216,8 +217,8 @@ func (c *ObjectStoreGRPCClient) CreateSignedURL(bucket, key string, ttl time.Dur

res, err := c.grpcClient.CreateSignedURL(context.Background(), req)
if err != nil {
return "", common.FromGRPCError(err)
return "", http.Header{}, common.FromGRPCError(err)
}

return res.Url, nil
return res.Url, res.Headers, nil
}
4 changes: 2 additions & 2 deletions pkg/plugin/framework/object_store_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,10 +264,10 @@ func (s *ObjectStoreGRPCServer) CreateSignedURL(ctx context.Context, req *proto.
return nil, common.NewGRPCError(err)
}

url, err := impl.CreateSignedURL(req.Bucket, req.Key, time.Duration(req.Ttl))
url, headers, err := impl.CreateSignedURL(req.Bucket, req.Key, time.Duration(req.Ttl))
if err != nil {
return nil, common.NewGRPCError(err)
}

return &proto.CreateSignedURLResponse{Url: url}, nil
return &proto.CreateSignedURLResponse{Url: url, Headers: headers}, nil
}
7 changes: 5 additions & 2 deletions pkg/plugin/generated/ObjectStore.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion pkg/plugin/proto/ObjectStore.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ message ListObjectsResponse {

message DeleteObjectRequest {
string plugin = 1;
string bucket = 2;
string bucket = 2;
string key = 3;
}

Expand All @@ -66,8 +66,13 @@ message CreateSignedURLRequest {
int64 ttl = 4;
}

message HeaderValues {
repeated string values = 1;
}

message CreateSignedURLResponse {
string url = 1;
map<string, HeaderValues> headers = 2;
}

message ObjectStoreInitRequest {
Expand Down
27 changes: 19 additions & 8 deletions pkg/plugin/velero/mocks/object_store.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pkg/plugin/velero/object_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package velero

import (
"io"
"net/http"
"time"
)

Expand Down Expand Up @@ -61,5 +62,5 @@ type ObjectStore interface {
DeleteObject(bucket, key string) error

// CreateSignedURL creates a pre-signed URL for the given bucket and key that expires after ttl.
CreateSignedURL(bucket, key string, ttl time.Duration) (string, error)
CreateSignedURL(bucket, key string, ttl time.Duration) (string, http.Header, error)
}

0 comments on commit 16052cb

Please sign in to comment.