Skip to content

Commit

Permalink
resolve conflict
Browse files Browse the repository at this point in the history
Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
  • Loading branch information
Lyndon-Li committed Oct 17, 2022
2 parents ecbc5d3 + c0430b8 commit 154f8de
Show file tree
Hide file tree
Showing 43 changed files with 205 additions and 195 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/5429-reasonerjt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Skip the exclusion check for additional resources returned by BIA
1 change: 1 addition & 0 deletions changelogs/unreleased/5441-sseago
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
moved RIA execute input/output structs back to velero package
2 changes: 1 addition & 1 deletion pkg/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ func (kb *kubernetesBackupper) BackupWithResolvers(log logrus.FieldLogger,
}

func (kb *kubernetesBackupper) backupItem(log logrus.FieldLogger, gr schema.GroupResource, itemBackupper *itemBackupper, unstructured *unstructured.Unstructured, preferredGVR schema.GroupVersionResource) bool {
backedUpItem, err := itemBackupper.backupItem(log, unstructured, gr, preferredGVR)
backedUpItem, err := itemBackupper.backupItem(log, unstructured, gr, preferredGVR, false)
if aggregate, ok := err.(kubeerrs.Aggregate); ok {
log.WithField("name", unstructured.GetName()).Infof("%d errors encountered backup up item", len(aggregate.Errors()))
// log each error separately so we get error location info in the log, and an
Expand Down
71 changes: 41 additions & 30 deletions pkg/backup/item_backupper.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"strings"
"time"

"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

"github.com/pkg/errors"
"github.com/sirupsen/logrus"
corev1api "k8s.io/api/core/v1"
Expand All @@ -47,6 +49,11 @@ import (
"github.com/vmware-tanzu/velero/pkg/volume"
)

const (
mustIncludeAdditionalItemAnnotation = "backup.velero.io/must-include-additional-items"
excludeFromBackupLabel = "velero.io/exclude-from-backup"
)

// itemBackupper can back up individual items to a tar writer.
type itemBackupper struct {
backupRequest *Request
Expand All @@ -61,16 +68,11 @@ type itemBackupper struct {
snapshotLocationVolumeSnapshotters map[string]vsv1.VolumeSnapshotter
}

const (
// veleroExcludeFromBackupLabel labeled item should be exclude by velero in backup job.
veleroExcludeFromBackupLabel = "velero.io/exclude-from-backup"
)

// backupItem backs up an individual item to tarWriter. The item may be excluded based on the
// namespaces IncludesExcludes list.
// In addition to the error return, backupItem also returns a bool indicating whether the item
// was actually backed up.
func (ib *itemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstructured, groupResource schema.GroupResource, preferredGVR schema.GroupVersionResource) (bool, error) {
func (ib *itemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstructured, groupResource schema.GroupResource, preferredGVR schema.GroupVersionResource, mustInclude bool) (bool, error) {
metadata, err := meta.Accessor(obj)
if err != nil {
return false, err
Expand All @@ -83,28 +85,30 @@ func (ib *itemBackupper) backupItem(logger logrus.FieldLogger, obj runtime.Unstr
log = log.WithField("resource", groupResource.String())
log = log.WithField("namespace", namespace)

if metadata.GetLabels()[veleroExcludeFromBackupLabel] == "true" {
log.Infof("Excluding item because it has label %s=true", veleroExcludeFromBackupLabel)
return false, nil
}

// NOTE: we have to re-check namespace & resource includes/excludes because it's possible that
// backupItem can be invoked by a custom action.
if namespace != "" && !ib.backupRequest.NamespaceIncludesExcludes.ShouldInclude(namespace) {
log.Info("Excluding item because namespace is excluded")
return false, nil
}

// NOTE: we specifically allow namespaces to be backed up even if IncludeClusterResources is
// false.
if namespace == "" && groupResource != kuberesource.Namespaces && ib.backupRequest.Spec.IncludeClusterResources != nil && !*ib.backupRequest.Spec.IncludeClusterResources {
log.Info("Excluding item because resource is cluster-scoped and backup.spec.includeClusterResources is false")
return false, nil
}
if mustInclude {
log.Infof("Skipping the exclusion checks for this resource")
} else {
if metadata.GetLabels()[excludeFromBackupLabel] == "true" {
log.Infof("Excluding item because it has label %s=true", excludeFromBackupLabel)
return false, nil
}
// NOTE: we have to re-check namespace & resource includes/excludes because it's possible that
// backupItem can be invoked by a custom action.
if namespace != "" && !ib.backupRequest.NamespaceIncludesExcludes.ShouldInclude(namespace) {
log.Info("Excluding item because namespace is excluded")
return false, nil
}
// NOTE: we specifically allow namespaces to be backed up even if IncludeClusterResources is
// false.
if namespace == "" && groupResource != kuberesource.Namespaces && ib.backupRequest.Spec.IncludeClusterResources != nil && !*ib.backupRequest.Spec.IncludeClusterResources {
log.Info("Excluding item because resource is cluster-scoped and backup.spec.includeClusterResources is false")
return false, nil
}

if !ib.backupRequest.ResourceIncludesExcludes.ShouldInclude(groupResource.String()) {
log.Info("Excluding item because resource is excluded")
return false, nil
if !ib.backupRequest.ResourceIncludesExcludes.ShouldInclude(groupResource.String()) {
log.Info("Excluding item because resource is excluded")
return false, nil
}
}

if metadata.GetDeletionTimestamp() != nil {
Expand Down Expand Up @@ -320,7 +324,8 @@ func (ib *itemBackupper) executeActions(
if err != nil {
return nil, errors.Wrapf(err, "error executing custom action (groupResource=%s, namespace=%s, name=%s)", groupResource.String(), namespace, name)
}
obj = updatedItem
u := &unstructured.Unstructured{Object: updatedItem.UnstructuredContent()}
mustInclude := u.GetAnnotations()[mustIncludeAdditionalItemAnnotation] == "true"

for _, additionalItem := range additionalItemIdentifiers {
gvr, resource, err := ib.discoveryHelper.ResourceFor(additionalItem.GroupResource.WithVersion(""))
Expand All @@ -334,6 +339,7 @@ func (ib *itemBackupper) executeActions(
}

item, err := client.Get(additionalItem.Name, metav1.GetOptions{})

if apierrors.IsNotFound(err) {
log.WithFields(logrus.Fields{
"groupResource": additionalItem.GroupResource,
Expand All @@ -346,12 +352,17 @@ func (ib *itemBackupper) executeActions(
return nil, errors.WithStack(err)
}

if _, err = ib.backupItem(log, item, gvr.GroupResource(), gvr); err != nil {
if _, err = ib.backupItem(log, item, gvr.GroupResource(), gvr, mustInclude); err != nil {
return nil, err
}
}
// remove the annotation as it's for communication between BIA and velero server,
// we don't want the resource be restored with this annotation.
if _, ok := u.GetAnnotations()[mustIncludeAdditionalItemAnnotation]; ok {
delete(u.GetAnnotations(), mustIncludeAdditionalItemAnnotation)
}
obj = u
}

return obj, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func (r RestartableRestoreItemAction) AppliesTo() (velero.ResourceSelector, erro
}

// Execute restarts the plugin's process if needed, then delegates the call.
func (r *RestartableRestoreItemAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) {
func (r *RestartableRestoreItemAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
delegate, err := r.getDelegate()
if err != nil {
return nil, err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"github.com/vmware-tanzu/velero/pkg/plugin/framework/common"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
mocks "github.com/vmware-tanzu/velero/pkg/plugin/velero/mocks/restoreitemaction/v1"
riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
)

func TestRestartableGetRestoreItemAction(t *testing.T) {
Expand Down Expand Up @@ -108,13 +107,13 @@ func TestRestartableRestoreItemActionDelegatedFunctions(t *testing.T) {
},
}

input := &riav1.RestoreItemActionExecuteInput{
input := &velero.RestoreItemActionExecuteInput{
Item: pv,
ItemFromBackup: pv,
Restore: new(v1.Restore),
}

output := &riav1.RestoreItemActionExecuteOutput{
output := &velero.RestoreItemActionExecuteOutput{
UpdatedItem: &unstructured.Unstructured{
Object: map[string]interface{}{
"color": "green",
Expand Down
4 changes: 2 additions & 2 deletions pkg/plugin/framework/restore_item_action_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (c *RestoreItemActionGRPCClient) AppliesTo() (velero.ResourceSelector, erro
}, nil
}

func (c *RestoreItemActionGRPCClient) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) {
func (c *RestoreItemActionGRPCClient) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
itemJSON, err := json.Marshal(input.Item.UnstructuredContent())
if err != nil {
return nil, errors.WithStack(err)
Expand Down Expand Up @@ -120,7 +120,7 @@ func (c *RestoreItemActionGRPCClient) Execute(input *riav1.RestoreItemActionExec
additionalItems = append(additionalItems, newItem)
}

return &riav1.RestoreItemActionExecuteOutput{
return &velero.RestoreItemActionExecuteOutput{
UpdatedItem: &updatedItem,
AdditionalItems: additionalItems,
SkipRestore: res.SkipRestore,
Expand Down
2 changes: 1 addition & 1 deletion pkg/plugin/framework/restore_item_action_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func (s *RestoreItemActionGRPCServer) Execute(ctx context.Context, req *proto.Re
return nil, common.NewGRPCError(errors.WithStack(err))
}

executeOutput, err := impl.Execute(&riav1.RestoreItemActionExecuteInput{
executeOutput, err := impl.Execute(&velero.RestoreItemActionExecuteInput{
Item: &item,
ItemFromBackup: &itemFromBackup,
Restore: &restoreObj,
Expand Down

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

62 changes: 62 additions & 0 deletions pkg/plugin/velero/restore_item_action_shared.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Copyright the Velero contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package velero

import (
"k8s.io/apimachinery/pkg/runtime"

api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
)

// RestoreItemActionExecuteInput contains the input parameters for the ItemAction's Execute function.
type RestoreItemActionExecuteInput struct {
// Item is the item being restored. It is likely different from the pristine backed up version
// (metadata reset, changed by various restore item action plugins, etc.).
Item runtime.Unstructured
// ItemFromBackup is the item taken from the pristine backed up version of resource.
ItemFromBackup runtime.Unstructured
// Restore is the representation of the restore resource processed by Velero.
Restore *api.Restore
}

// RestoreItemActionExecuteOutput contains the output variables for the ItemAction's Execution function.
type RestoreItemActionExecuteOutput struct {
// UpdatedItem is the item being restored mutated by ItemAction.
UpdatedItem runtime.Unstructured

// AdditionalItems is a list of additional related items that should
// be restored.
AdditionalItems []ResourceIdentifier

// SkipRestore tells velero to stop executing further actions
// on this item, and skip the restore step. When this field's
// value is true, AdditionalItems will be ignored.
SkipRestore bool
}

// NewRestoreItemActionExecuteOutput creates a new RestoreItemActionExecuteOutput
func NewRestoreItemActionExecuteOutput(item runtime.Unstructured) *RestoreItemActionExecuteOutput {
return &RestoreItemActionExecuteOutput{
UpdatedItem: item,
}
}

// WithoutRestore returns SkipRestore for RestoreItemActionExecuteOutput
func (r *RestoreItemActionExecuteOutput) WithoutRestore() *RestoreItemActionExecuteOutput {
r.SkipRestore = true
return r
}
44 changes: 1 addition & 43 deletions pkg/plugin/velero/restoreitemaction/v1/restore_item_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ limitations under the License.
package v1

import (
"k8s.io/apimachinery/pkg/runtime"

api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
)

Expand All @@ -36,44 +33,5 @@ type RestoreItemAction interface {
// related items that should be restored, a warning (which will be logged but will not prevent
// the item from being restored) or error (which will be logged and will prevent the item
// from being restored) if applicable.
Execute(input *RestoreItemActionExecuteInput) (*RestoreItemActionExecuteOutput, error)
}

// RestoreItemActionExecuteInput contains the input parameters for the ItemAction's Execute function.
type RestoreItemActionExecuteInput struct {
// Item is the item being restored. It is likely different from the pristine backed up version
// (metadata reset, changed by various restore item action plugins, etc.).
Item runtime.Unstructured
// ItemFromBackup is the item taken from the pristine backed up version of resource.
ItemFromBackup runtime.Unstructured
// Restore is the representation of the restore resource processed by Velero.
Restore *api.Restore
}

// RestoreItemActionExecuteOutput contains the output variables for the ItemAction's Execution function.
type RestoreItemActionExecuteOutput struct {
// UpdatedItem is the item being restored mutated by ItemAction.
UpdatedItem runtime.Unstructured

// AdditionalItems is a list of additional related items that should
// be restored.
AdditionalItems []velero.ResourceIdentifier

// SkipRestore tells velero to stop executing further actions
// on this item, and skip the restore step. When this field's
// value is true, AdditionalItems will be ignored.
SkipRestore bool
}

// NewRestoreItemActionExecuteOutput creates a new RestoreItemActionExecuteOutput
func NewRestoreItemActionExecuteOutput(item runtime.Unstructured) *RestoreItemActionExecuteOutput {
return &RestoreItemActionExecuteOutput{
UpdatedItem: item,
}
}

// WithoutRestore returns SkipRestore for RestoreItemActionExecuteOutput
func (r *RestoreItemActionExecuteOutput) WithoutRestore() *RestoreItemActionExecuteOutput {
r.SkipRestore = true
return r
Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error)
}
7 changes: 3 additions & 4 deletions pkg/restore/add_pv_from_pvc_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (

"github.com/vmware-tanzu/velero/pkg/kuberesource"
"github.com/vmware-tanzu/velero/pkg/plugin/velero"
riav1 "github.com/vmware-tanzu/velero/pkg/plugin/velero/restoreitemaction/v1"
)

type AddPVFromPVCAction struct {
Expand All @@ -41,7 +40,7 @@ func (a *AddPVFromPVCAction) AppliesTo() (velero.ResourceSelector, error) {
}, nil
}

func (a *AddPVFromPVCAction) Execute(input *riav1.RestoreItemActionExecuteInput) (*riav1.RestoreItemActionExecuteOutput, error) {
func (a *AddPVFromPVCAction) Execute(input *velero.RestoreItemActionExecuteInput) (*velero.RestoreItemActionExecuteOutput, error) {
a.logger.Info("Executing AddPVFromPVCAction")

// use input.ItemFromBackup because we need to look at status fields, which have already been
Expand All @@ -54,7 +53,7 @@ func (a *AddPVFromPVCAction) Execute(input *riav1.RestoreItemActionExecuteInput)
// TODO: consolidate this logic in a helper function to share with backup_pv_action.go
if pvc.Status.Phase != corev1api.ClaimBound || pvc.Spec.VolumeName == "" {
a.logger.Info("PVC is not bound or its volume name is empty")
return &riav1.RestoreItemActionExecuteOutput{
return &velero.RestoreItemActionExecuteOutput{
UpdatedItem: input.Item,
}, nil
}
Expand All @@ -65,7 +64,7 @@ func (a *AddPVFromPVCAction) Execute(input *riav1.RestoreItemActionExecuteInput)
}

a.logger.Infof("Adding PV %s as an additional item to restore", pvc.Spec.VolumeName)
return &riav1.RestoreItemActionExecuteOutput{
return &velero.RestoreItemActionExecuteOutput{
UpdatedItem: input.Item,
AdditionalItems: []velero.ResourceIdentifier{pv},
}, nil
Expand Down
Loading

0 comments on commit 154f8de

Please sign in to comment.