Define itemoperations.json format and update DownloadRequest API.

This is to support uploading async operation metadata to
object storage to support progress monitoring.

Signed-off-by: Scott Seago <sseago@redhat.com>
This commit is contained in:
Scott Seago
2023-01-09 17:56:01 -05:00
parent 722aead2fd
commit 70b4238013
13 changed files with 349 additions and 174 deletions

View File

@@ -24,6 +24,7 @@ import (
snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/itemoperation"
persistence "github.com/vmware-tanzu/velero/pkg/persistence"
volume "github.com/vmware-tanzu/velero/pkg/volume"
)
@@ -274,6 +275,34 @@ func (_m *BackupStore) PutRestoreResults(backup string, restore string, results
return r0
}
// PutRestoreItemOperations provides a mock function with given fields: backup, restore, restoreItemOperations
func (_m *BackupStore) PutRestoreItemOperations(backup string, restore string, restoreItemOperations io.Reader) error {
ret := _m.Called(backup, restore, restoreItemOperations)
var r0 error
if rf, ok := ret.Get(0).(func(string, string, io.Reader) error); ok {
r0 = rf(backup, restore, restoreItemOperations)
} else {
r0 = ret.Error(0)
}
return r0
}
// PutBackupItemOperations provides a mock function with given fields: backup, backupItemOperations
func (_m *BackupStore) PutBackupItemOperations(backup string, backupItemOperations io.Reader) error {
ret := _m.Called(backup, backupItemOperations)
var r0 error
if rf, ok := ret.Get(0).(func(string, io.Reader) error); ok {
r0 = rf(backup, backupItemOperations)
} else {
r0 = ret.Error(0)
}
return r0
}
func (_m *BackupStore) GetCSIVolumeSnapshots(backup string) ([]*snapshotv1api.VolumeSnapshot, error) {
panic("Not implemented")
return nil, nil
@@ -289,6 +318,12 @@ func (_m *BackupStore) GetCSIVolumeSnapshotClasses(backup string) ([]*snapshotv1
return nil, nil
}
func (_m *BackupStore) GetItemSnapshots(name string) ([]*volume.ItemSnapshot, error) {
func (_m *BackupStore) GetBackupItemOperations(name string) ([]*itemoperation.BackupOperation, error) {
panic("implement me")
return nil, nil
}
func (_m *BackupStore) GetRestoreItemOperations(name string) ([]*itemoperation.RestoreOperation, error) {
panic("implement me")
return nil, nil
}

View File

@@ -33,6 +33,7 @@ import (
"github.com/vmware-tanzu/velero/internal/credentials"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
"github.com/vmware-tanzu/velero/pkg/itemoperation"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
"github.com/vmware-tanzu/velero/pkg/volume"
)
@@ -44,7 +45,7 @@ type BackupInfo struct {
Log,
PodVolumeBackups,
VolumeSnapshots,
ItemSnapshots,
BackupItemOperations,
BackupResourceList,
CSIVolumeSnapshots,
CSIVolumeSnapshotContents,
@@ -59,8 +60,9 @@ type BackupStore interface {
ListBackups() ([]string, error)
PutBackup(info BackupInfo) error
PutBackupItemOperations(backup string, backupItemOperations io.Reader) error
GetBackupMetadata(name string) (*velerov1api.Backup, error)
GetItemSnapshots(name string) ([]*volume.ItemSnapshot, error)
GetBackupItemOperations(name string) ([]*itemoperation.BackupOperation, error)
GetBackupVolumeSnapshots(name string) ([]*volume.Snapshot, error)
GetPodVolumeBackups(name string) ([]*velerov1api.PodVolumeBackup, error)
GetBackupContents(name string) (io.ReadCloser, error)
@@ -75,6 +77,8 @@ type BackupStore interface {
PutRestoreLog(backup, restore string, log io.Reader) error
PutRestoreResults(backup, restore string, results io.Reader) error
PutRestoreItemOperations(backup, restore string, restoreItemOperations io.Reader) error
GetRestoreItemOperations(name string) ([]*itemoperation.RestoreOperation, error)
DeleteRestore(name string) error
GetDownloadURL(target velerov1api.DownloadTarget) (string, error)
@@ -256,7 +260,7 @@ func (s *objectBackupStore) PutBackup(info BackupInfo) error {
var backupObjs = map[string]io.Reader{
s.layout.getPodVolumeBackupsKey(info.Name): info.PodVolumeBackups,
s.layout.getBackupVolumeSnapshotsKey(info.Name): info.VolumeSnapshots,
s.layout.getItemSnapshotsKey(info.Name): info.ItemSnapshots,
s.layout.getBackupItemOperationsKey(info.Name): info.BackupItemOperations,
s.layout.getBackupResourceListKey(info.Name): info.BackupResourceList,
s.layout.getCSIVolumeSnapshotKey(info.Name): info.CSIVolumeSnapshots,
s.layout.getCSIVolumeSnapshotContentsKey(info.Name): info.CSIVolumeSnapshotContents,
@@ -329,11 +333,11 @@ func (s *objectBackupStore) GetBackupVolumeSnapshots(name string) ([]*volume.Sna
return volumeSnapshots, nil
}
func (s *objectBackupStore) GetItemSnapshots(name string) ([]*volume.ItemSnapshot, error) {
// if the itemsnapshots file doesn't exist, we don't want to return an error, since
// a legacy backup or a backup with no snapshots would not have this file, so check for
func (s *objectBackupStore) GetBackupItemOperations(name string) ([]*itemoperation.BackupOperation, error) {
// if the itemoperations file doesn't exist, we don't want to return an error, since
// a legacy backup or a backup with no async operations would not have this file, so check for
// its existence before attempting to get its contents.
res, err := tryGet(s.objectStore, s.bucket, s.layout.getItemSnapshotsKey(name))
res, err := tryGet(s.objectStore, s.bucket, s.layout.getBackupItemOperationsKey(name))
if err != nil {
return nil, err
}
@@ -342,12 +346,33 @@ func (s *objectBackupStore) GetItemSnapshots(name string) ([]*volume.ItemSnapsho
}
defer res.Close()
var itemSnapshots []*volume.ItemSnapshot
if err := decode(res, &itemSnapshots); err != nil {
var backupItemOperations []*itemoperation.BackupOperation
if err := decode(res, &backupItemOperations); err != nil {
return nil, err
}
return itemSnapshots, nil
return backupItemOperations, nil
}
func (s *objectBackupStore) GetRestoreItemOperations(name string) ([]*itemoperation.RestoreOperation, error) {
// if the itemoperations file doesn't exist, we don't want to return an error, since
// a legacy restore or a restore with no async operations would not have this file, so check for
// its existence before attempting to get its contents.
res, err := tryGet(s.objectStore, s.bucket, s.layout.getRestoreItemOperationsKey(name))
if err != nil {
return nil, err
}
if res == nil {
return nil, nil
}
defer res.Close()
var restoreItemOperations []*itemoperation.RestoreOperation
if err := decode(res, &restoreItemOperations); err != nil {
return nil, err
}
return restoreItemOperations, nil
}
// tryGet returns the object with the given key if it exists, nil if it does not exist,
@@ -510,6 +535,14 @@ func (s *objectBackupStore) PutRestoreResults(backup string, restore string, res
return s.objectStore.PutObject(s.bucket, s.layout.getRestoreResultsKey(restore), results)
}
func (s *objectBackupStore) PutRestoreItemOperations(backup string, restore string, restoreItemOperations io.Reader) error {
return seekAndPutObject(s.objectStore, s.bucket, s.layout.getRestoreItemOperationsKey(restore), restoreItemOperations)
}
func (s *objectBackupStore) PutBackupItemOperations(backup string, backupItemOperations io.Reader) error {
return seekAndPutObject(s.objectStore, s.bucket, s.layout.getBackupItemOperationsKey(backup), backupItemOperations)
}
func (s *objectBackupStore) GetDownloadURL(target velerov1api.DownloadTarget) (string, error) {
switch target.Kind {
case velerov1api.DownloadTargetKindBackupContents:
@@ -518,8 +551,10 @@ func (s *objectBackupStore) GetDownloadURL(target velerov1api.DownloadTarget) (s
return s.objectStore.CreateSignedURL(s.bucket, s.layout.getBackupLogKey(target.Name), DownloadURLTTL)
case velerov1api.DownloadTargetKindBackupVolumeSnapshots:
return s.objectStore.CreateSignedURL(s.bucket, s.layout.getBackupVolumeSnapshotsKey(target.Name), DownloadURLTTL)
case velerov1api.DownloadTargetKindBackupItemSnapshots:
return s.objectStore.CreateSignedURL(s.bucket, s.layout.getItemSnapshotsKey(target.Name), DownloadURLTTL)
case velerov1api.DownloadTargetKindBackupItemOperations:
return s.objectStore.CreateSignedURL(s.bucket, s.layout.getBackupItemOperationsKey(target.Name), DownloadURLTTL)
case velerov1api.DownloadTargetKindRestoreItemOperations:
return s.objectStore.CreateSignedURL(s.bucket, s.layout.getRestoreItemOperationsKey(target.Name), DownloadURLTTL)
case velerov1api.DownloadTargetKindBackupResourceList:
return s.objectStore.CreateSignedURL(s.bucket, s.layout.getBackupResourceListKey(target.Name), DownloadURLTTL)
case velerov1api.DownloadTargetKindRestoreLog:

View File

@@ -89,8 +89,8 @@ func (l *ObjectStoreLayout) getBackupVolumeSnapshotsKey(backup string) string {
return path.Join(l.subdirs["backups"], backup, fmt.Sprintf("%s-volumesnapshots.json.gz", backup))
}
func (l *ObjectStoreLayout) getItemSnapshotsKey(backup string) string {
return path.Join(l.subdirs["backups"], backup, fmt.Sprintf("%s-itemsnapshots.json.gz", backup))
func (l *ObjectStoreLayout) getBackupItemOperationsKey(backup string) string {
return path.Join(l.subdirs["backups"], backup, fmt.Sprintf("%s-itemoperations.json.gz", backup))
}
func (l *ObjectStoreLayout) getBackupResourceListKey(backup string) string {
@@ -105,6 +105,10 @@ func (l *ObjectStoreLayout) getRestoreResultsKey(restore string) string {
return path.Join(l.subdirs["restores"], restore, fmt.Sprintf("restore-%s-results.gz", restore))
}
func (l *ObjectStoreLayout) getRestoreItemOperationsKey(restore string) string {
return path.Join(l.subdirs["restores"], restore, fmt.Sprintf("restore-%s-itemoperations.json.gz", restore))
}
func (l *ObjectStoreLayout) getCSIVolumeSnapshotKey(backup string) string {
return path.Join(l.subdirs["backups"], backup, fmt.Sprintf("%s-csi-volumesnapshots.json.gz", backup))
}

View File

@@ -36,6 +36,7 @@ import (
"github.com/vmware-tanzu/velero/internal/credentials"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/builder"
"github.com/vmware-tanzu/velero/pkg/itemoperation"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
providermocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
@@ -216,98 +217,98 @@ func TestListBackups(t *testing.T) {
func TestPutBackup(t *testing.T) {
tests := []struct {
name string
prefix string
metadata io.Reader
contents io.Reader
log io.Reader
podVolumeBackup io.Reader
snapshots io.Reader
itemSnapshots io.Reader
resourceList io.Reader
expectedErr string
expectedKeys []string
name string
prefix string
metadata io.Reader
contents io.Reader
log io.Reader
podVolumeBackup io.Reader
snapshots io.Reader
backupItemOperations io.Reader
resourceList io.Reader
expectedErr string
expectedKeys []string
}{
{
name: "normal case",
metadata: newStringReadSeeker("metadata"),
contents: newStringReadSeeker("contents"),
log: newStringReadSeeker("log"),
podVolumeBackup: newStringReadSeeker("podVolumeBackup"),
snapshots: newStringReadSeeker("snapshots"),
itemSnapshots: newStringReadSeeker("itemSnapshots"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "",
name: "normal case",
metadata: newStringReadSeeker("metadata"),
contents: newStringReadSeeker("contents"),
log: newStringReadSeeker("log"),
podVolumeBackup: newStringReadSeeker("podVolumeBackup"),
snapshots: newStringReadSeeker("snapshots"),
backupItemOperations: newStringReadSeeker("backupItemOperations"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "",
expectedKeys: []string{
"backups/backup-1/velero-backup.json",
"backups/backup-1/backup-1.tar.gz",
"backups/backup-1/backup-1-logs.gz",
"backups/backup-1/backup-1-podvolumebackups.json.gz",
"backups/backup-1/backup-1-volumesnapshots.json.gz",
"backups/backup-1/backup-1-itemsnapshots.json.gz",
"backups/backup-1/backup-1-itemoperations.json.gz",
"backups/backup-1/backup-1-resource-list.json.gz",
},
},
{
name: "normal case with backup store prefix",
prefix: "prefix-1/",
metadata: newStringReadSeeker("metadata"),
contents: newStringReadSeeker("contents"),
log: newStringReadSeeker("log"),
podVolumeBackup: newStringReadSeeker("podVolumeBackup"),
snapshots: newStringReadSeeker("snapshots"),
itemSnapshots: newStringReadSeeker("itemSnapshots"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "",
name: "normal case with backup store prefix",
prefix: "prefix-1/",
metadata: newStringReadSeeker("metadata"),
contents: newStringReadSeeker("contents"),
log: newStringReadSeeker("log"),
podVolumeBackup: newStringReadSeeker("podVolumeBackup"),
snapshots: newStringReadSeeker("snapshots"),
backupItemOperations: newStringReadSeeker("backupItemOperations"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "",
expectedKeys: []string{
"prefix-1/backups/backup-1/velero-backup.json",
"prefix-1/backups/backup-1/backup-1.tar.gz",
"prefix-1/backups/backup-1/backup-1-logs.gz",
"prefix-1/backups/backup-1/backup-1-podvolumebackups.json.gz",
"prefix-1/backups/backup-1/backup-1-volumesnapshots.json.gz",
"prefix-1/backups/backup-1/backup-1-itemsnapshots.json.gz",
"prefix-1/backups/backup-1/backup-1-itemoperations.json.gz",
"prefix-1/backups/backup-1/backup-1-resource-list.json.gz",
},
},
{
name: "error on metadata upload does not upload data",
metadata: new(errorReader),
contents: newStringReadSeeker("contents"),
log: newStringReadSeeker("log"),
podVolumeBackup: newStringReadSeeker("podVolumeBackup"),
snapshots: newStringReadSeeker("snapshots"),
itemSnapshots: newStringReadSeeker("itemSnapshots"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "error readers return errors",
expectedKeys: []string{"backups/backup-1/backup-1-logs.gz"},
name: "error on metadata upload does not upload data",
metadata: new(errorReader),
contents: newStringReadSeeker("contents"),
log: newStringReadSeeker("log"),
podVolumeBackup: newStringReadSeeker("podVolumeBackup"),
snapshots: newStringReadSeeker("snapshots"),
backupItemOperations: newStringReadSeeker("backupItemOperations"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "error readers return errors",
expectedKeys: []string{"backups/backup-1/backup-1-logs.gz"},
},
{
name: "error on data upload deletes metadata",
metadata: newStringReadSeeker("metadata"),
contents: new(errorReader),
log: newStringReadSeeker("log"),
snapshots: newStringReadSeeker("snapshots"),
itemSnapshots: newStringReadSeeker("itemSnapshots"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "error readers return errors",
expectedKeys: []string{"backups/backup-1/backup-1-logs.gz"},
name: "error on data upload deletes metadata",
metadata: newStringReadSeeker("metadata"),
contents: new(errorReader),
log: newStringReadSeeker("log"),
snapshots: newStringReadSeeker("snapshots"),
backupItemOperations: newStringReadSeeker("backupItemOperations"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "error readers return errors",
expectedKeys: []string{"backups/backup-1/backup-1-logs.gz"},
},
{
name: "error on log upload is ok",
metadata: newStringReadSeeker("foo"),
contents: newStringReadSeeker("bar"),
log: new(errorReader),
podVolumeBackup: newStringReadSeeker("podVolumeBackup"),
snapshots: newStringReadSeeker("snapshots"),
itemSnapshots: newStringReadSeeker("itemSnapshots"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "",
name: "error on log upload is ok",
metadata: newStringReadSeeker("foo"),
contents: newStringReadSeeker("bar"),
log: new(errorReader),
podVolumeBackup: newStringReadSeeker("podVolumeBackup"),
snapshots: newStringReadSeeker("snapshots"),
backupItemOperations: newStringReadSeeker("backupItemOperations"),
resourceList: newStringReadSeeker("resourceList"),
expectedErr: "",
expectedKeys: []string{
"backups/backup-1/velero-backup.json",
"backups/backup-1/backup-1.tar.gz",
"backups/backup-1/backup-1-podvolumebackups.json.gz",
"backups/backup-1/backup-1-volumesnapshots.json.gz",
"backups/backup-1/backup-1-itemsnapshots.json.gz",
"backups/backup-1/backup-1-itemoperations.json.gz",
"backups/backup-1/backup-1-resource-list.json.gz",
},
},
@@ -335,14 +336,14 @@ func TestPutBackup(t *testing.T) {
harness := newObjectBackupStoreTestHarness("foo", tc.prefix)
backupInfo := BackupInfo{
Name: "backup-1",
Metadata: tc.metadata,
Contents: tc.contents,
Log: tc.log,
PodVolumeBackups: tc.podVolumeBackup,
VolumeSnapshots: tc.snapshots,
ItemSnapshots: tc.itemSnapshots,
BackupResourceList: tc.resourceList,
Name: "backup-1",
Metadata: tc.metadata,
Contents: tc.contents,
Log: tc.log,
PodVolumeBackups: tc.podVolumeBackup,
VolumeSnapshots: tc.snapshots,
BackupItemOperations: tc.backupItemOperations,
BackupResourceList: tc.resourceList,
}
err := harness.PutBackup(backupInfo)
@@ -442,30 +443,30 @@ func TestGetBackupVolumeSnapshots(t *testing.T) {
assert.EqualValues(t, snapshots, res)
}
func TestGetItemSnapshots(t *testing.T) {
func TestGetBackupItemOperations(t *testing.T) {
harness := newObjectBackupStoreTestHarness("test-bucket", "")
// volumesnapshots file not found should not error
// itemoperations file not found should not error
harness.objectStore.PutObject(harness.bucket, "backups/test-backup/velero-backup.json", newStringReadSeeker("foo"))
res, err := harness.GetItemSnapshots("test-backup")
res, err := harness.GetBackupItemOperations("test-backup")
assert.NoError(t, err)
assert.Nil(t, res)
// volumesnapshots file containing invalid data should error
harness.objectStore.PutObject(harness.bucket, "backups/test-backup/test-backup-itemsnapshots.json.gz", newStringReadSeeker("foo"))
res, err = harness.GetItemSnapshots("test-backup")
// itemoperations file containing invalid data should error
harness.objectStore.PutObject(harness.bucket, "backups/test-backup/test-backup-itemoperations.json.gz", newStringReadSeeker("foo"))
res, err = harness.GetBackupItemOperations("test-backup")
assert.NotNil(t, err)
// volumesnapshots file containing gzipped json data should return correctly
snapshots := []*volume.ItemSnapshot{
// itemoperations file containing gzipped json data should return correctly
operations := []*itemoperation.BackupOperation{
{
Spec: volume.ItemSnapshotSpec{
Spec: itemoperation.BackupOperationSpec{
BackupName: "test-backup",
ResourceIdentifier: "item-1",
},
},
{
Spec: volume.ItemSnapshotSpec{
Spec: itemoperation.BackupOperationSpec{
BackupName: "test-backup",
ResourceIdentifier: "item-2",
},
@@ -475,13 +476,13 @@ func TestGetItemSnapshots(t *testing.T) {
obj := new(bytes.Buffer)
gzw := gzip.NewWriter(obj)
require.NoError(t, json.NewEncoder(gzw).Encode(snapshots))
require.NoError(t, json.NewEncoder(gzw).Encode(operations))
require.NoError(t, gzw.Close())
require.NoError(t, harness.objectStore.PutObject(harness.bucket, "backups/test-backup/test-backup-itemsnapshots.json.gz", obj))
require.NoError(t, harness.objectStore.PutObject(harness.bucket, "backups/test-backup/test-backup-itemoperations.json.gz", obj))
res, err = harness.GetItemSnapshots("test-backup")
res, err = harness.GetBackupItemOperations("test-backup")
assert.NoError(t, err)
assert.EqualValues(t, snapshots, res)
assert.EqualValues(t, operations, res)
}
func TestGetBackupContents(t *testing.T) {
@@ -564,7 +565,7 @@ func TestGetDownloadURL(t *testing.T) {
velerov1api.DownloadTargetKindBackupContents: "backups/my-backup/my-backup.tar.gz",
velerov1api.DownloadTargetKindBackupLog: "backups/my-backup/my-backup-logs.gz",
velerov1api.DownloadTargetKindBackupVolumeSnapshots: "backups/my-backup/my-backup-volumesnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemSnapshots: "backups/my-backup/my-backup-itemsnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemOperations: "backups/my-backup/my-backup-itemoperations.json.gz",
velerov1api.DownloadTargetKindBackupResourceList: "backups/my-backup/my-backup-resource-list.json.gz",
},
},
@@ -576,7 +577,7 @@ func TestGetDownloadURL(t *testing.T) {
velerov1api.DownloadTargetKindBackupContents: "velero-backups/backups/my-backup/my-backup.tar.gz",
velerov1api.DownloadTargetKindBackupLog: "velero-backups/backups/my-backup/my-backup-logs.gz",
velerov1api.DownloadTargetKindBackupVolumeSnapshots: "velero-backups/backups/my-backup/my-backup-volumesnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemSnapshots: "velero-backups/backups/my-backup/my-backup-itemsnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemOperations: "velero-backups/backups/my-backup/my-backup-itemoperations.json.gz",
velerov1api.DownloadTargetKindBackupResourceList: "velero-backups/backups/my-backup/my-backup-resource-list.json.gz",
},
},
@@ -587,7 +588,7 @@ func TestGetDownloadURL(t *testing.T) {
velerov1api.DownloadTargetKindBackupContents: "backups/b-cool-20170913154901-20170913154902/b-cool-20170913154901-20170913154902.tar.gz",
velerov1api.DownloadTargetKindBackupLog: "backups/b-cool-20170913154901-20170913154902/b-cool-20170913154901-20170913154902-logs.gz",
velerov1api.DownloadTargetKindBackupVolumeSnapshots: "backups/b-cool-20170913154901-20170913154902/b-cool-20170913154901-20170913154902-volumesnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemSnapshots: "backups/b-cool-20170913154901-20170913154902/b-cool-20170913154901-20170913154902-itemsnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemOperations: "backups/b-cool-20170913154901-20170913154902/b-cool-20170913154901-20170913154902-itemoperations.json.gz",
velerov1api.DownloadTargetKindBackupResourceList: "backups/b-cool-20170913154901-20170913154902/b-cool-20170913154901-20170913154902-resource-list.json.gz",
},
},
@@ -598,7 +599,7 @@ func TestGetDownloadURL(t *testing.T) {
velerov1api.DownloadTargetKindBackupContents: "backups/my-backup-20170913154901/my-backup-20170913154901.tar.gz",
velerov1api.DownloadTargetKindBackupLog: "backups/my-backup-20170913154901/my-backup-20170913154901-logs.gz",
velerov1api.DownloadTargetKindBackupVolumeSnapshots: "backups/my-backup-20170913154901/my-backup-20170913154901-volumesnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemSnapshots: "backups/my-backup-20170913154901/my-backup-20170913154901-itemsnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemOperations: "backups/my-backup-20170913154901/my-backup-20170913154901-itemoperations.json.gz",
velerov1api.DownloadTargetKindBackupResourceList: "backups/my-backup-20170913154901/my-backup-20170913154901-resource-list.json.gz",
},
},
@@ -610,7 +611,7 @@ func TestGetDownloadURL(t *testing.T) {
velerov1api.DownloadTargetKindBackupContents: "velero-backups/backups/my-backup-20170913154901/my-backup-20170913154901.tar.gz",
velerov1api.DownloadTargetKindBackupLog: "velero-backups/backups/my-backup-20170913154901/my-backup-20170913154901-logs.gz",
velerov1api.DownloadTargetKindBackupVolumeSnapshots: "velero-backups/backups/my-backup-20170913154901/my-backup-20170913154901-volumesnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemSnapshots: "velero-backups/backups/my-backup-20170913154901/my-backup-20170913154901-itemsnapshots.json.gz",
velerov1api.DownloadTargetKindBackupItemOperations: "velero-backups/backups/my-backup-20170913154901/my-backup-20170913154901-itemoperations.json.gz",
velerov1api.DownloadTargetKindBackupResourceList: "velero-backups/backups/my-backup-20170913154901/my-backup-20170913154901-resource-list.json.gz",
},
},
@@ -618,8 +619,9 @@ func TestGetDownloadURL(t *testing.T) {
name: "restore",
targetName: "my-backup",
expectedKeyByKind: map[velerov1api.DownloadTargetKind]string{
velerov1api.DownloadTargetKindRestoreLog: "restores/my-backup/restore-my-backup-logs.gz",
velerov1api.DownloadTargetKindRestoreResults: "restores/my-backup/restore-my-backup-results.gz",
velerov1api.DownloadTargetKindRestoreLog: "restores/my-backup/restore-my-backup-logs.gz",
velerov1api.DownloadTargetKindRestoreResults: "restores/my-backup/restore-my-backup-results.gz",
velerov1api.DownloadTargetKindRestoreItemOperations: "restores/my-backup/restore-my-backup-itemoperations.json.gz",
},
},
{
@@ -627,16 +629,18 @@ func TestGetDownloadURL(t *testing.T) {
targetName: "my-backup",
prefix: "velero-backups/",
expectedKeyByKind: map[velerov1api.DownloadTargetKind]string{
velerov1api.DownloadTargetKindRestoreLog: "velero-backups/restores/my-backup/restore-my-backup-logs.gz",
velerov1api.DownloadTargetKindRestoreResults: "velero-backups/restores/my-backup/restore-my-backup-results.gz",
velerov1api.DownloadTargetKindRestoreLog: "velero-backups/restores/my-backup/restore-my-backup-logs.gz",
velerov1api.DownloadTargetKindRestoreResults: "velero-backups/restores/my-backup/restore-my-backup-results.gz",
velerov1api.DownloadTargetKindRestoreItemOperations: "velero-backups/restores/my-backup/restore-my-backup-itemoperations.json.gz",
},
},
{
name: "restore with multiple dashes",
targetName: "b-cool-20170913154901-20170913154902",
expectedKeyByKind: map[velerov1api.DownloadTargetKind]string{
velerov1api.DownloadTargetKindRestoreLog: "restores/b-cool-20170913154901-20170913154902/restore-b-cool-20170913154901-20170913154902-logs.gz",
velerov1api.DownloadTargetKindRestoreResults: "restores/b-cool-20170913154901-20170913154902/restore-b-cool-20170913154901-20170913154902-results.gz",
velerov1api.DownloadTargetKindRestoreLog: "restores/b-cool-20170913154901-20170913154902/restore-b-cool-20170913154901-20170913154902-logs.gz",
velerov1api.DownloadTargetKindRestoreResults: "restores/b-cool-20170913154901-20170913154902/restore-b-cool-20170913154901-20170913154902-results.gz",
velerov1api.DownloadTargetKindRestoreItemOperations: "restores/b-cool-20170913154901-20170913154902/restore-b-cool-20170913154901-20170913154902-itemoperations.json.gz",
},
},
}