Skip to content

Commit

Permalink
BackupItemAction v2 API implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Scott Seago <[email protected]>
  • Loading branch information
sseago committed Oct 17, 2022
1 parent c0430b8 commit 4a3b3be
Show file tree
Hide file tree
Showing 30 changed files with 2,664 additions and 149 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/5442-sseago
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BackupItemAction v2 API implementation
4 changes: 4 additions & 0 deletions hack/build-image/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ RUN apt-get update && apt-get install -y unzip
RUN wget --quiet https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/protoc-3.14.0-linux-x86_64.zip && \
unzip protoc-3.14.0-linux-x86_64.zip && \
mv bin/protoc /usr/bin/protoc && \
mv include/google /usr/include && \
chmod a+x /usr/include/google && \
chmod a+x /usr/include/google/protobuf && \
chmod a+r -R /usr/include/google && \
chmod +x /usr/bin/protoc
RUN go get github.com/golang/protobuf/[email protected]

Expand Down
2 changes: 1 addition & 1 deletion hack/update-2proto.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ HACK_DIR=$(dirname "${BASH_SOURCE}")
echo "Updating plugin proto"

echo protoc --version
protoc pkg/plugin/proto/*.proto --go_out=plugins=grpc:pkg/plugin/generated/ --go_opt=module=github.com/vmware-tanzu/velero/pkg/plugin/generated -I pkg/plugin/proto/
protoc pkg/plugin/proto/*.proto pkg/plugin/proto/*/*/*.proto --go_out=plugins=grpc:pkg/plugin/generated/ --go_opt=module=github.com/vmware-tanzu/velero/pkg/plugin/generated -I pkg/plugin/proto/ -I /usr/include

echo "Updating plugin proto - done!"
12 changes: 6 additions & 6 deletions pkg/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import (
velerov1client "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1"
"github.com/vmware-tanzu/velero/pkg/kuberesource"
"github.com/vmware-tanzu/velero/pkg/plugin/framework"
biav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
"github.com/vmware-tanzu/velero/pkg/podexec"
"github.com/vmware-tanzu/velero/pkg/podvolume"
Expand All @@ -63,9 +63,9 @@ const BackupFormatVersion = "1.1.0"
type Backupper interface {
// Backup takes a backup using the specification in the velerov1api.Backup and writes backup and log data
// to the given writers.
Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer, actions []biav1.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error
Backup(logger logrus.FieldLogger, backup *Request, backupFile io.Writer, actions []biav2.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error
BackupWithResolvers(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer,
backupItemActionResolver framework.BackupItemActionResolver, itemSnapshotterResolver framework.ItemSnapshotterResolver,
backupItemActionResolver framework.BackupItemActionResolverV2, itemSnapshotterResolver framework.ItemSnapshotterResolver,
volumeSnapshotterGetter VolumeSnapshotterGetter) error
}

Expand Down Expand Up @@ -174,8 +174,8 @@ type VolumeSnapshotterGetter interface {
// back up individual resources that don't prevent the backup from continuing to be processed) are logged
// to the backup log.
func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Request, backupFile io.Writer,
actions []biav1.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error {
backupItemActions := framework.NewBackupItemActionResolver(actions)
actions []biav2.BackupItemAction, volumeSnapshotterGetter VolumeSnapshotterGetter) error {
backupItemActions := framework.NewBackupItemActionResolverV2(actions)
itemSnapshotters := framework.NewItemSnapshotterResolver(nil)
return kb.BackupWithResolvers(log, backupRequest, backupFile, backupItemActions, itemSnapshotters,
volumeSnapshotterGetter)
Expand All @@ -184,7 +184,7 @@ func (kb *kubernetesBackupper) Backup(log logrus.FieldLogger, backupRequest *Req
func (kb *kubernetesBackupper) BackupWithResolvers(log logrus.FieldLogger,
backupRequest *Request,
backupFile io.Writer,
backupItemActionResolver framework.BackupItemActionResolver,
backupItemActionResolver framework.BackupItemActionResolverV2,
itemSnapshotterResolver framework.ItemSnapshotterResolver,
volumeSnapshotterGetter VolumeSnapshotterGetter) error {
gzippedData := gzip.NewWriter(backupFile)
Expand Down
109 changes: 67 additions & 42 deletions pkg/backup/backup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import (
"github.com/vmware-tanzu/velero/pkg/discovery"
"github.com/vmware-tanzu/velero/pkg/kuberesource"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
biav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v1"
biav2 "github.com/vmware-tanzu/velero/pkg/plugin/velero/backupitemaction/v2"
vsv1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/volumesnapshotter/v1"
"github.com/vmware-tanzu/velero/pkg/podvolume"
"github.com/vmware-tanzu/velero/pkg/test"
Expand Down Expand Up @@ -1139,23 +1139,32 @@ type recordResourcesAction struct {
ids []string
backups []velerov1.Backup
additionalItems []velero.ResourceIdentifier
operationID string
}

func (a *recordResourcesAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
func (a *recordResourcesAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
metadata, err := meta.Accessor(item)
if err != nil {
return item, a.additionalItems, err
return item, a.additionalItems, a.operationID, err
}
a.ids = append(a.ids, kubeutil.NamespaceAndName(metadata))
a.backups = append(a.backups, *backup)

return item, a.additionalItems, nil
return item, a.additionalItems, a.operationID, nil
}

func (a *recordResourcesAction) AppliesTo() (velero.ResourceSelector, error) {
return a.selector, nil
}

func (a *recordResourcesAction) Progress(operationID string, backup *velerov1.Backup) (velero.OperationProgress, error) {
return velero.OperationProgress{}, nil
}

func (a *recordResourcesAction) Cancel(operationID string, backup *velerov1.Backup) error {
return nil
}

func (a *recordResourcesAction) ForResource(resource string) *recordResourcesAction {
a.selector.IncludedResources = append(a.selector.IncludedResources, resource)
return a
Expand Down Expand Up @@ -1362,7 +1371,7 @@ func TestBackupActionsRunForCorrectItems(t *testing.T) {
h.addItems(t, resource)
}

actions := []biav1.BackupItemAction{}
actions := []biav2.BackupItemAction{}
for action := range tc.actions {
actions = append(actions, action)
}
Expand All @@ -1388,7 +1397,7 @@ func TestBackupWithInvalidActions(t *testing.T) {
name string
backup *velerov1.Backup
apiResources []*test.APIResource
actions []biav1.BackupItemAction
actions []biav2.BackupItemAction
}{
{
name: "action with invalid label selector results in an error",
Expand All @@ -1404,7 +1413,7 @@ func TestBackupWithInvalidActions(t *testing.T) {
builder.ForPersistentVolume("baz").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
new(recordResourcesAction).ForLabelSelector("=invalid-selector"),
},
},
Expand All @@ -1422,7 +1431,7 @@ func TestBackupWithInvalidActions(t *testing.T) {
builder.ForPersistentVolume("baz").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&appliesToErrorAction{},
},
},
Expand Down Expand Up @@ -1453,7 +1462,15 @@ func (a *appliesToErrorAction) AppliesTo() (velero.ResourceSelector, error) {
return velero.ResourceSelector{}, errors.New("error calling AppliesTo")
}

func (a *appliesToErrorAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
func (a *appliesToErrorAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
panic("not implemented")
}

func (a *appliesToErrorAction) Progress(operationID string, backup *velerov1.Backup) (velero.OperationProgress, error) {
panic("not implemented")
}

func (a *appliesToErrorAction) Cancel(operationID string, backup *velerov1.Backup) error {
panic("not implemented")
}

Expand All @@ -1466,16 +1483,16 @@ func TestBackupActionModifications(t *testing.T) {
// method modifies the item being passed in by calling the 'modify' function on it.
modifyingActionGetter := func(modify func(*unstructured.Unstructured)) *pluggableAction {
return &pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
obj, ok := item.(*unstructured.Unstructured)
if !ok {
return nil, nil, errors.Errorf("unexpected type %T", item)
return nil, nil, "", errors.Errorf("unexpected type %T", item)
}

res := obj.DeepCopy()
modify(res)

return res, nil, nil
return res, nil, "", nil
},
}
}
Expand All @@ -1484,7 +1501,7 @@ func TestBackupActionModifications(t *testing.T) {
name string
backup *velerov1.Backup
apiResources []*test.APIResource
actions []biav1.BackupItemAction
actions []biav2.BackupItemAction
want map[string]unstructuredObject
}{
{
Expand All @@ -1495,7 +1512,7 @@ func TestBackupActionModifications(t *testing.T) {
builder.ForPod("ns-1", "pod-1").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
modifyingActionGetter(func(item *unstructured.Unstructured) {
item.SetLabels(map[string]string{"updated": "true"})
}),
Expand All @@ -1512,7 +1529,7 @@ func TestBackupActionModifications(t *testing.T) {
builder.ForPod("ns-1", "pod-1").ObjectMeta(builder.WithLabels("should-be-removed", "true")).Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
modifyingActionGetter(func(item *unstructured.Unstructured) {
item.SetLabels(nil)
}),
Expand All @@ -1529,7 +1546,7 @@ func TestBackupActionModifications(t *testing.T) {
builder.ForPod("ns-1", "pod-1").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
modifyingActionGetter(func(item *unstructured.Unstructured) {
item.Object["spec"].(map[string]interface{})["nodeName"] = "foo"
}),
Expand All @@ -1547,7 +1564,7 @@ func TestBackupActionModifications(t *testing.T) {
builder.ForPod("ns-1", "pod-1").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
modifyingActionGetter(func(item *unstructured.Unstructured) {
item.SetName(item.GetName() + "-updated")
item.SetNamespace(item.GetNamespace() + "-updated")
Expand Down Expand Up @@ -1588,7 +1605,7 @@ func TestBackupActionAdditionalItems(t *testing.T) {
name string
backup *velerov1.Backup
apiResources []*test.APIResource
actions []biav1.BackupItemAction
actions []biav2.BackupItemAction
want []string
}{
{
Expand All @@ -1601,16 +1618,16 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPod("ns-3", "pod-3").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
selector: velero.ResourceSelector{IncludedNamespaces: []string{"ns-1"}},
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.Pods, Namespace: "ns-2", Name: "pod-2"},
{GroupResource: kuberesource.Pods, Namespace: "ns-3", Name: "pod-3"},
}

return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
Expand All @@ -1633,15 +1650,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPod("ns-3", "pod-3").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.Pods, Namespace: "ns-2", Name: "pod-2"},
{GroupResource: kuberesource.Pods, Namespace: "ns-3", Name: "pod-3"},
}

return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
Expand All @@ -1663,15 +1680,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPersistentVolume("pv-2").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"},
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-2"},
}

return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
Expand All @@ -1696,15 +1713,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPersistentVolume("pv-2").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"},
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-2"},
}

return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
Expand All @@ -1726,15 +1743,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPersistentVolume("pv-2").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"},
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-2"},
}

return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
Expand All @@ -1757,15 +1774,15 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPersistentVolume("pv-2").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-1"},
{GroupResource: kuberesource.PersistentVolumes, Name: "pv-2"},
}

return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
Expand All @@ -1787,16 +1804,16 @@ func TestBackupActionAdditionalItems(t *testing.T) {
builder.ForPod("ns-3", "pod-3").Result(),
),
},
actions: []biav1.BackupItemAction{
actions: []biav2.BackupItemAction{
&pluggableAction{
selector: velero.ResourceSelector{IncludedNamespaces: []string{"ns-1"}},
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
executeFunc: func(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
additionalItems := []velero.ResourceIdentifier{
{GroupResource: kuberesource.Pods, Namespace: "ns-4", Name: "pod-4"},
{GroupResource: kuberesource.Pods, Namespace: "ns-5", Name: "pod-5"},
}

return item, additionalItems, nil
return item, additionalItems, "", nil
},
},
},
Expand Down Expand Up @@ -2727,12 +2744,12 @@ func TestBackupWithRestic(t *testing.T) {
// function body at runtime.
type pluggableAction struct {
selector velero.ResourceSelector
executeFunc func(runtime.Unstructured, *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error)
executeFunc func(runtime.Unstructured, *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error)
}

func (a *pluggableAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, error) {
func (a *pluggableAction) Execute(item runtime.Unstructured, backup *velerov1.Backup) (runtime.Unstructured, []velero.ResourceIdentifier, string, error) {
if a.executeFunc == nil {
return item, nil, nil
return item, nil, "", nil
}

return a.executeFunc(item, backup)
Expand All @@ -2742,6 +2759,14 @@ func (a *pluggableAction) AppliesTo() (velero.ResourceSelector, error) {
return a.selector, nil
}

func (a *pluggableAction) Progress(operationID string, backup *velerov1.Backup) (velero.OperationProgress, error) {
return velero.OperationProgress{}, nil
}

func (a *pluggableAction) Cancel(operationID string, backup *velerov1.Backup) error {
return nil
}

type harness struct {
*test.APIServer
backupper *kubernetesBackupper
Expand Down
Loading

0 comments on commit 4a3b3be

Please sign in to comment.