mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-03 11:45:20 +00:00
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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user