add cli for create/view restore resource policies (#9966)

Added CLI for creating restore resource policies, and view
the resource policies associated with resource if present.
Only list the name of the configmap for now.

Signed-off-by: Adam Zhang <adam.zhang@broadcom.com>
This commit is contained in:
Adam Zhang
2026-07-10 10:56:56 +08:00
committed by GitHub
parent d2342532f4
commit c1cd00ff07
4 changed files with 66 additions and 1 deletions
@@ -0,0 +1 @@
Fix issue #9937, add CLI support for restore filters via resource policy
+21 -1
View File
@@ -32,6 +32,7 @@ import (
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/vmware-tanzu/velero/internal/resourcemodifiers"
"github.com/vmware-tanzu/velero/internal/resourcepolicies"
api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
@@ -61,7 +62,13 @@ func NewCreateCommand(f client.Factory, use string) *cobra.Command {
velero restore create --from-schedule schedule-1 --allow-partially-failed
# Create a restore for only persistentvolumeclaims and persistentvolumes within a backup.
velero restore create --from-backup backup-2 --include-resources persistentvolumeclaims,persistentvolumes`,
velero restore create --from-backup backup-2 --include-resources persistentvolumeclaims,persistentvolumes
Notes:
- Global filters (--include-resources, --selector, etc.) apply to all included namespaces
- Namespace-scoped filters defined in --resource-policies-configmap refine global filters for matching namespaces (globally excluded kinds cannot be re-included)
- Fine-grained global filter policies defined in --resource-policies-configmap refine global filters for cluster-scoped resources
- Use 'velero restore describe' to view the referenced resource policies ConfigMap after restore creation`,
Args: cobra.MaximumNArgs(1),
Run: func(c *cobra.Command, args []string) {
cmd.CheckError(o.Complete(args, f))
@@ -100,6 +107,7 @@ type CreateOptions struct {
AllowPartiallyFailed flag.OptionalBool
ItemOperationTimeout time.Duration
ResourceModifierConfigMap string
ResourcePoliciesConfigMap string
WriteSparseFiles flag.OptionalBool
ParallelFilesDownload int
client kbclient.WithWatch
@@ -154,6 +162,8 @@ func (o *CreateOptions) BindFlags(flags *pflag.FlagSet) {
flags.StringVar(&o.ResourceModifierConfigMap, "resource-modifier-configmap", "", "Reference to the resource modifier configmap that restore will use")
flags.StringVar(&o.ResourcePoliciesConfigMap, "resource-policies-configmap", "", "Reference to the ConfigMap containing restore resource filter policies")
f = flags.VarPF(&o.WriteSparseFiles, "write-sparse-files", "", "Whether to write sparse files during restoring volumes")
f.NoOptDefVal = cmd.TRUE
@@ -310,6 +320,15 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
}
}
var resPolicies *corev1api.TypedLocalObjectReference
if o.ResourcePoliciesConfigMap != "" {
resPolicies = &corev1api.TypedLocalObjectReference{
Kind: resourcepolicies.ConfigmapRefType,
Name: o.ResourcePoliciesConfigMap,
}
}
restore := &api.Restore{
ObjectMeta: metav1.ObjectMeta{
Namespace: f.Namespace(),
@@ -332,6 +351,7 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
PreserveNodePorts: o.PreserveNodePorts.Value,
IncludeClusterResources: o.IncludeClusterResources.Value,
ResourceModifier: resModifiers,
ResourcePolicy: resPolicies,
ItemOperationTimeout: metav1.Duration{
Duration: o.ItemOperationTimeout,
},
+39
View File
@@ -77,6 +77,8 @@ func TestCreateCommand(t *testing.T) {
includeClusterResources := "true"
allowPartiallyFailed := "true"
itemOperationTimeout := "10m0s"
resourceModifierConfigMap := "modifier-cm"
ResourcePoliciesConfigMap := "policies-cm"
writeSparseFiles := "true"
parallel := 2
flags := new(pflag.FlagSet)
@@ -101,6 +103,8 @@ func TestCreateCommand(t *testing.T) {
flags.Parse([]string{"--include-cluster-resources", includeClusterResources})
flags.Parse([]string{"--allow-partially-failed", allowPartiallyFailed})
flags.Parse([]string{"--item-operation-timeout", itemOperationTimeout})
flags.Parse([]string{"--resource-modifier-configmap", resourceModifierConfigMap})
flags.Parse([]string{"--resource-policies-configmap", ResourcePoliciesConfigMap})
flags.Parse([]string{"--write-sparse-files", writeSparseFiles})
flags.Parse([]string{"--parallel-files-download", "2"})
client := velerotest.NewFakeControllerRuntimeClient(t).(kbclient.WithWatch)
@@ -139,6 +143,8 @@ func TestCreateCommand(t *testing.T) {
require.Equal(t, includeClusterResources, o.IncludeClusterResources.String())
require.Equal(t, allowPartiallyFailed, o.AllowPartiallyFailed.String())
require.Equal(t, itemOperationTimeout, o.ItemOperationTimeout.String())
require.Equal(t, resourceModifierConfigMap, o.ResourceModifierConfigMap)
require.Equal(t, ResourcePoliciesConfigMap, o.ResourcePoliciesConfigMap)
require.Equal(t, writeSparseFiles, o.WriteSparseFiles.String())
require.Equal(t, parallel, o.ParallelFilesDownload)
})
@@ -189,4 +195,37 @@ func TestCreateCommand(t *testing.T) {
err := o.Validate(c, []string{}, f)
require.Equal(t, "backups.velero.io \"not-exist\" not found", err.Error())
})
t.Run("create a restore with resource policies configmap", func(t *testing.T) {
f := &factorymocks.Factory{}
c := NewCreateCommand(f, "")
require.Equal(t, "Create a restore", c.Short)
flags := new(pflag.FlagSet)
o := NewCreateOptions()
o.BindFlags(flags)
backupName := "backup-with-policies"
ResourcePoliciesConfigMap := "test-policies-cm"
flags.Parse([]string{"--from-backup", backupName})
flags.Parse([]string{"--resource-policies-configmap", ResourcePoliciesConfigMap})
kbclient := velerotest.NewFakeControllerRuntimeClient(t).(kbclient.WithWatch)
backup := builder.ForBackup(cmdtest.VeleroNameSpace, backupName).Phase(velerov1api.BackupPhaseCompleted).Result()
require.NoError(t, kbclient.Create(t.Context(), backup, &controllerclient.CreateOptions{}))
f.On("Namespace").Return(cmdtest.VeleroNameSpace)
f.On("KubebuilderWatchClient").Return(kbclient, nil)
require.NoError(t, o.Complete(args, f))
require.NoError(t, o.Validate(c, []string{}, f))
require.NoError(t, o.Run(c, f))
// Verify the created restore object
createdRestore := &velerov1api.Restore{}
err := kbclient.Get(t.Context(), controllerclient.ObjectKey{Namespace: cmdtest.VeleroNameSpace, Name: name}, createdRestore)
require.NoError(t, err)
require.NotNil(t, createdRestore.Spec.ResourcePolicy)
require.Equal(t, "configmap", createdRestore.Spec.ResourcePolicy.Kind)
require.Equal(t, ResourcePoliciesConfigMap, createdRestore.Spec.ResourcePolicy.Name)
})
}
+5
View File
@@ -219,6 +219,11 @@ func DescribeRestore(
DescribeResourceModifier(d, restore.Spec.ResourceModifier)
}
if restore.Spec.ResourcePolicy != nil {
d.Println()
DescribeResourcePolicies(d, restore.Spec.ResourcePolicy)
}
describeUploaderConfigForRestore(d, restore.Spec)
d.Println()