Merge pull request #6469 from blackpiglet/6190_fix

Remove dependency of the legacy client code from pkg/cmd directory part 1
This commit is contained in:
lyndon
2023-07-14 17:15:56 +08:00
committed by GitHub
22 changed files with 330 additions and 255 deletions

View File

@@ -22,13 +22,11 @@ import (
"strings"
"time"
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeerrs "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/tools/cache"
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/builder"
@@ -36,9 +34,8 @@ import (
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/util/flag"
"github.com/vmware-tanzu/velero/pkg/cmd/util/output"
veleroclient "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
v1 "github.com/vmware-tanzu/velero/pkg/generated/informers/externalversions/velero/v1"
"github.com/vmware-tanzu/velero/pkg/util/collections"
"github.com/vmware-tanzu/velero/pkg/util/kube"
)
func NewCreateCommand(f client.Factory, use string) *cobra.Command {
@@ -107,7 +104,7 @@ type CreateOptions struct {
CSISnapshotTimeout time.Duration
ItemOperationTimeout time.Duration
ResPoliciesConfigmap string
client veleroclient.Interface
client kbclient.WithWatch
}
func NewCreateOptions() *CreateOptions {
@@ -171,7 +168,7 @@ func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Facto
return err
}
client, err := f.KubebuilderClient()
client, err := f.KubebuilderWatchClient()
if err != nil {
return err
}
@@ -203,7 +200,8 @@ func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Facto
}
for _, loc := range o.SnapshotLocations {
if _, err := o.client.VeleroV1().VolumeSnapshotLocations(f.Namespace()).Get(context.TODO(), loc, metav1.GetOptions{}); err != nil {
snapshotLocation := new(velerov1api.VolumeSnapshotLocation)
if err := o.client.Get(context.TODO(), kbclient.ObjectKey{Namespace: f.Namespace(), Name: loc}, snapshotLocation); err != nil {
return err
}
}
@@ -216,7 +214,7 @@ func (o *CreateOptions) Complete(args []string, f client.Factory) error {
if len(args) > 0 {
o.Name = args[0]
}
client, err := f.Client()
client, err := f.KubebuilderWatchClient()
if err != nil {
return err
}
@@ -238,7 +236,6 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
fmt.Println("Creating backup from schedule, all other filters are ignored.")
}
var backupInformer cache.SharedIndexInformer
var updates chan *velerov1api.Backup
if o.Wait {
stop := make(chan struct{})
@@ -246,12 +243,17 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
updates = make(chan *velerov1api.Backup)
backupInformer = v1.NewBackupInformer(o.client, f.Namespace(), 0, nil)
lw := kube.InternalLW{
Client: o.client,
Namespace: f.Namespace(),
ObjectList: new(velerov1api.BackupList),
}
backupInformer := cache.NewSharedInformer(&lw, &velerov1api.Backup{}, time.Second)
backupInformer.AddEventHandler(
cache.FilteringResourceEventHandler{
FilterFunc: func(obj interface{}) bool {
backup, ok := obj.(*velerov1api.Backup)
if !ok {
return false
}
@@ -275,10 +277,11 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error {
},
},
)
go backupInformer.Run(stop)
}
_, err = o.client.VeleroV1().Backups(backup.Namespace).Create(context.TODO(), backup, metav1.CreateOptions{})
err = o.client.Create(context.TODO(), backup, &kbclient.CreateOptions{})
if err != nil {
return err
}
@@ -341,7 +344,8 @@ func (o *CreateOptions) BuildBackup(namespace string) (*velerov1api.Backup, erro
var backupBuilder *builder.BackupBuilder
if o.FromSchedule != "" {
schedule, err := o.client.VeleroV1().Schedules(namespace).Get(context.TODO(), o.FromSchedule, metav1.GetOptions{})
schedule := new(velerov1api.Schedule)
err := o.client.Get(context.TODO(), kbclient.ObjectKey{Namespace: namespace, Name: o.FromSchedule}, schedule)
if err != nil {
return nil, err
}

View File

@@ -23,24 +23,21 @@ import (
"testing"
"time"
flag "github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
flag "github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/runtime"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/builder"
clientfake "sigs.k8s.io/controller-runtime/pkg/client/fake"
factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks"
cmdtest "github.com/vmware-tanzu/velero/pkg/cmd/test"
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/fake"
versionedmocks "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/mocks"
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
velerov1mocks "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1/mocks"
"github.com/vmware-tanzu/velero/pkg/test"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
)
func TestCreateOptions_BuildBackup(t *testing.T) {
@@ -77,27 +74,31 @@ func TestCreateOptions_BuildBackup(t *testing.T) {
func TestCreateOptions_BuildBackupFromSchedule(t *testing.T) {
o := NewCreateOptions()
o.FromSchedule = "test"
o.client = fake.NewSimpleClientset()
scheme := runtime.NewScheme()
err := velerov1api.AddToScheme(scheme)
require.NoError(t, err)
o.client = velerotest.NewFakeControllerRuntimeClient(t).(controllerclient.WithWatch)
t.Run("inexistent schedule", func(t *testing.T) {
_, err := o.BuildBackup(cmdtest.VeleroNameSpace)
assert.Error(t, err)
require.Error(t, err)
})
expectedBackupSpec := builder.ForBackup("test", cmdtest.VeleroNameSpace).IncludedNamespaces("test").Result().Spec
schedule := builder.ForSchedule(cmdtest.VeleroNameSpace, "test").Template(expectedBackupSpec).ObjectMeta(builder.WithLabels("velero.io/test", "true"), builder.WithAnnotations("velero.io/test", "true")).Result()
o.client.VeleroV1().Schedules(cmdtest.VeleroNameSpace).Create(context.TODO(), schedule, metav1.CreateOptions{})
o.client.Create(context.TODO(), schedule, &kbclient.CreateOptions{})
t.Run("existing schedule", func(t *testing.T) {
backup, err := o.BuildBackup(cmdtest.VeleroNameSpace)
assert.NoError(t, err)
require.NoError(t, err)
assert.Equal(t, expectedBackupSpec, backup.Spec)
assert.Equal(t, map[string]string{
require.Equal(t, expectedBackupSpec, backup.Spec)
require.Equal(t, map[string]string{
"velero.io/test": "true",
velerov1api.ScheduleNameLabel: "test",
}, backup.GetLabels())
assert.Equal(t, map[string]string{
require.Equal(t, map[string]string{
"velero.io/test": "true",
}, backup.GetAnnotations())
})
@@ -145,6 +146,7 @@ func TestCreateCommand(t *testing.T) {
args := []string{name}
t.Run("create a backup create command with full options except fromSchedule and wait, then run by create option", func(t *testing.T) {
// create a factory
f := &factorymocks.Factory{}
@@ -203,81 +205,68 @@ func TestCreateCommand(t *testing.T) {
flags.Parse([]string{"--data-mover", dataMover})
//flags.Parse([]string{"--wait"})
backups := &velerov1mocks.BackupInterface{}
veleroV1 := &velerov1mocks.VeleroV1Interface{}
client := &versionedmocks.Interface{}
bk := &velerov1api.Backup{}
backups.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(bk, nil)
veleroV1.On("Backups", mock.Anything).Return(backups, nil)
client.On("VeleroV1").Return(veleroV1, nil)
f.On("Client").Return(client, nil)
client := velerotest.NewFakeControllerRuntimeClient(t).(kbclient.WithWatch)
f.On("Namespace").Return(mock.Anything)
f.On("KubebuilderClient").Return(nil, nil)
f.On("KubebuilderWatchClient").Return(client, nil)
//Complete
e := o.Complete(args, f)
assert.NoError(t, e)
require.NoError(t, e)
//Validate
e = o.Validate(cmd, args, f)
assert.Contains(t, e.Error(), "include-resources, exclude-resources and include-cluster-resources are old filter parameters")
assert.Contains(t, e.Error(), "include-cluster-scoped-resources, exclude-cluster-scoped-resources, include-namespace-scoped-resources and exclude-namespace-scoped-resources are new filter parameters.\nThey cannot be used together")
require.Contains(t, e.Error(), "include-resources, exclude-resources and include-cluster-resources are old filter parameters")
require.Contains(t, e.Error(), "include-cluster-scoped-resources, exclude-cluster-scoped-resources, include-namespace-scoped-resources and exclude-namespace-scoped-resources are new filter parameters.\nThey cannot be used together")
//cmd
e = o.Run(cmd, f)
assert.NoError(t, e)
require.NoError(t, e)
//Execute
cmd.SetArgs([]string{"bk-name-exe"})
e = cmd.Execute()
assert.NoError(t, e)
require.NoError(t, e)
// verify all options are set as expected
assert.Equal(t, name, o.Name)
assert.Equal(t, includeNamespaces, o.IncludeNamespaces.String())
assert.Equal(t, excludeNamespaces, o.ExcludeNamespaces.String())
assert.Equal(t, includeResources, o.IncludeResources.String())
assert.Equal(t, excludeResources, o.ExcludeResources.String())
assert.Equal(t, includeClusterScopedResources, o.IncludeClusterScopedResources.String())
assert.Equal(t, excludeClusterScopedResources, o.ExcludeClusterScopedResources.String())
assert.Equal(t, includeNamespaceScopedResources, o.IncludeNamespaceScopedResources.String())
assert.Equal(t, excludeNamespaceScopedResources, o.ExcludeNamespaceScopedResources.String())
assert.Equal(t, true, test.CompareSlice(strings.Split(labels, ","), strings.Split(o.Labels.String(), ",")))
assert.Equal(t, storageLocation, o.StorageLocation)
assert.Equal(t, snapshotLocations, strings.Split(o.SnapshotLocations[0], ",")[0])
assert.Equal(t, selector, o.Selector.String())
assert.Equal(t, orderedResources, o.OrderedResources)
assert.Equal(t, csiSnapshotTimeout, o.CSISnapshotTimeout.String())
assert.Equal(t, itemOperationTimeout, o.ItemOperationTimeout.String())
assert.Equal(t, snapshotVolumes, o.SnapshotVolumes.String())
assert.Equal(t, snapshotMoveData, o.SnapshotMoveData.String())
assert.Equal(t, includeClusterResources, o.IncludeClusterResources.String())
assert.Equal(t, defaultVolumesToFsBackup, o.DefaultVolumesToFsBackup.String())
assert.Equal(t, resPoliciesConfigmap, o.ResPoliciesConfigmap)
assert.Equal(t, dataMover, o.DataMover)
require.Equal(t, name, o.Name)
require.Equal(t, includeNamespaces, o.IncludeNamespaces.String())
require.Equal(t, excludeNamespaces, o.ExcludeNamespaces.String())
require.Equal(t, includeResources, o.IncludeResources.String())
require.Equal(t, excludeResources, o.ExcludeResources.String())
require.Equal(t, includeClusterScopedResources, o.IncludeClusterScopedResources.String())
require.Equal(t, excludeClusterScopedResources, o.ExcludeClusterScopedResources.String())
require.Equal(t, includeNamespaceScopedResources, o.IncludeNamespaceScopedResources.String())
require.Equal(t, excludeNamespaceScopedResources, o.ExcludeNamespaceScopedResources.String())
require.Equal(t, true, test.CompareSlice(strings.Split(labels, ","), strings.Split(o.Labels.String(), ",")))
require.Equal(t, storageLocation, o.StorageLocation)
require.Equal(t, snapshotLocations, strings.Split(o.SnapshotLocations[0], ",")[0])
require.Equal(t, selector, o.Selector.String())
require.Equal(t, orderedResources, o.OrderedResources)
require.Equal(t, csiSnapshotTimeout, o.CSISnapshotTimeout.String())
require.Equal(t, itemOperationTimeout, o.ItemOperationTimeout.String())
require.Equal(t, snapshotVolumes, o.SnapshotVolumes.String())
require.Equal(t, snapshotMoveData, o.SnapshotMoveData.String())
require.Equal(t, includeClusterResources, o.IncludeClusterResources.String())
require.Equal(t, defaultVolumesToFsBackup, o.DefaultVolumesToFsBackup.String())
require.Equal(t, resPoliciesConfigmap, o.ResPoliciesConfigmap)
require.Equal(t, dataMover, o.DataMover)
//assert.Equal(t, true, o.Wait)
// verify oldAndNewFilterParametersUsedTogether
mix := o.oldAndNewFilterParametersUsedTogether()
assert.Equal(t, true, mix)
require.Equal(t, true, mix)
})
t.Run("create a backup create command with specific storage-location setting", func(t *testing.T) {
bsl := "bsl-1"
// create a factory
f := &factorymocks.Factory{}
cmd := NewCreateCommand(f, "")
backups := &velerov1mocks.BackupInterface{}
veleroV1 := &velerov1mocks.VeleroV1Interface{}
client := &versionedmocks.Interface{}
kbclient := clientfake.NewClientBuilder().WithScheme(scheme.Scheme).Build()
kbclient := velerotest.NewFakeControllerRuntimeClient(t).(kbclient.WithWatch)
bk := &velerov1api.Backup{}
backups.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(bk, nil)
veleroV1.On("Backups", mock.Anything).Return(backups, nil)
client.On("VeleroV1").Return(veleroV1, nil)
f.On("Client").Return(client, nil)
f.On("Namespace").Return(mock.Anything)
f.On("KubebuilderClient").Return(kbclient, nil)
f.On("KubebuilderWatchClient").Return(kbclient, nil)
flags := new(flag.FlagSet)
o := NewCreateOptions()
@@ -301,18 +290,14 @@ func TestCreateCommand(t *testing.T) {
// create a factory
f := &factorymocks.Factory{}
cmd := NewCreateCommand(f, "")
vsls := &velerov1mocks.VolumeSnapshotLocationInterface{}
veleroV1 := &velerov1mocks.VeleroV1Interface{}
client := &versionedmocks.Interface{}
kbclient := clientfake.NewClientBuilder().WithScheme(scheme.Scheme).Build()
kbclient := velerotest.NewFakeControllerRuntimeClient(t).(kbclient.WithWatch)
vsl := &velerov1api.VolumeSnapshotLocation{}
vsls.On("Get", mock.Anything, mock.Anything, mock.Anything).Return(vsl, nil)
veleroV1.On("VolumeSnapshotLocations", mock.Anything).Return(vsls, nil)
client.On("VeleroV1").Return(veleroV1, nil)
f.On("Client").Return(client, nil)
f.On("Namespace").Return(mock.Anything)
f.On("KubebuilderClient").Return(kbclient, nil)
vsl := builder.ForVolumeSnapshotLocation(cmdtest.VeleroNameSpace, vslName).Result()
kbclient.Create(cmd.Context(), vsl, &controllerclient.CreateOptions{})
f.On("Namespace").Return(cmdtest.VeleroNameSpace)
f.On("KubebuilderWatchClient").Return(kbclient, nil)
flags := new(flag.FlagSet)
o := NewCreateOptions()
@@ -343,22 +328,13 @@ func TestCreateCommand(t *testing.T) {
fromSchedule := "schedule-name-1"
flags.Parse([]string{"--from-schedule", fromSchedule})
backups := &velerov1mocks.BackupInterface{}
bk := &velerov1api.Backup{}
schedules := &velerov1mocks.ScheduleInterface{}
veleroV1 := &velerov1mocks.VeleroV1Interface{}
client := &versionedmocks.Interface{}
kbclient := clientfake.NewClientBuilder().WithScheme(scheme.Scheme).Build()
sd := &velerov1api.Schedule{}
kbclient := velerotest.NewFakeControllerRuntimeClient(t).(kbclient.WithWatch)
backups.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(bk, nil)
veleroV1.On("Backups", mock.Anything).Return(backups, nil)
schedules.On("Get", mock.Anything, mock.Anything, mock.Anything).Return(sd, nil)
veleroV1.On("Schedules", mock.Anything).Return(schedules, nil)
client.On("VeleroV1").Return(veleroV1, nil)
f.On("Client").Return(client, nil)
f.On("Namespace").Return(mock.Anything)
f.On("KubebuilderClient").Return(kbclient, nil)
schedule := builder.ForSchedule(cmdtest.VeleroNameSpace, fromSchedule).Result()
kbclient.Create(context.Background(), schedule, &controllerclient.CreateOptions{})
f.On("Namespace").Return(cmdtest.VeleroNameSpace)
f.On("KubebuilderWatchClient").Return(kbclient, nil)
e := o.Complete(args, f)
assert.NoError(t, e)

View File

@@ -25,12 +25,14 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
kubeerrs "k8s.io/apimachinery/pkg/util/errors"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/backup"
"github.com/vmware-tanzu/velero/pkg/builder"
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/cli"
"github.com/vmware-tanzu/velero/pkg/label"
)
// NewDeleteCommand creates a new command that deletes a backup.
@@ -82,7 +84,8 @@ func Run(o *cli.DeleteOptions) error {
switch {
case len(o.Names) > 0:
for _, name := range o.Names {
backup, err := o.Client.VeleroV1().Backups(o.Namespace).Get(context.TODO(), name, metav1.GetOptions{})
backup := new(velerov1api.Backup)
err := o.Client.Get(context.TODO(), controllerclient.ObjectKey{Namespace: o.Namespace, Name: name}, backup)
if err != nil {
errs = append(errs, errors.WithStack(err))
continue
@@ -91,17 +94,22 @@ func Run(o *cli.DeleteOptions) error {
backups = append(backups, backup)
}
default:
selector := labels.Everything().String()
selector := labels.Everything()
if o.Selector.LabelSelector != nil {
selector = o.Selector.String()
convertedSelector, err := metav1.LabelSelectorAsSelector(o.Selector.LabelSelector)
if err != nil {
return errors.WithStack(err)
}
selector = convertedSelector
}
res, err := o.Client.VeleroV1().Backups(o.Namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: selector})
backupList := new(velerov1api.BackupList)
err := o.Client.List(context.TODO(), backupList, &controllerclient.ListOptions{LabelSelector: selector, Namespace: o.Namespace})
if err != nil {
return errors.WithStack(err)
}
for i := range res.Items {
backups = append(backups, &res.Items[i])
for i := range backupList.Items {
backups = append(backups, &backupList.Items[i])
}
}
@@ -112,9 +120,11 @@ func Run(o *cli.DeleteOptions) error {
// create a backup deletion request for each
for _, b := range backups {
deleteRequest := backup.NewDeleteBackupRequest(b.Name, string(b.UID))
deleteRequest := builder.ForDeleteBackupRequest(o.Namespace, "").BackupName(b.Name).
ObjectMeta(builder.WithLabels(velerov1api.BackupNameLabel, label.GetValidName(b.Name),
velerov1api.BackupUIDLabel, string(b.UID)), builder.WithGenerateName(b.Name+"-")).Result()
if _, err := o.Client.VeleroV1().DeleteBackupRequests(o.Namespace).Create(context.TODO(), deleteRequest, metav1.CreateOptions{}); err != nil {
if err := o.Client.Create(context.TODO(), deleteRequest, &controllerclient.CreateOptions{}); err != nil {
errs = append(errs, err)
continue
}

View File

@@ -17,68 +17,60 @@ limitations under the License.
package backup
import (
"context"
"fmt"
"os"
"os/exec"
"testing"
flag "github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/builder"
factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks"
"github.com/vmware-tanzu/velero/pkg/cmd/cli"
cmdtest "github.com/vmware-tanzu/velero/pkg/cmd/test"
versionedmocks "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/mocks"
velerov1mocks "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1/mocks"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec"
)
func TestDeleteCommand(t *testing.T) {
backupName := "backup-name-1"
backup1 := "backup-name-1"
backup2 := "backup-name-2"
// create a factory
f := &factorymocks.Factory{}
deleteBackupRequest := &velerov1mocks.DeleteBackupRequestInterface{}
backups := &velerov1mocks.BackupInterface{}
veleroV1 := &velerov1mocks.VeleroV1Interface{}
client := &versionedmocks.Interface{}
bk := &velerov1api.Backup{}
dbr := &velerov1api.DeleteBackupRequest{}
backups.On("Get", mock.Anything, mock.Anything, mock.Anything).Return(bk, nil)
deleteBackupRequest.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(dbr, nil)
veleroV1.On("DeleteBackupRequests", mock.Anything).Return(deleteBackupRequest, nil)
veleroV1.On("Backups", mock.Anything).Return(backups, nil)
client.On("VeleroV1").Return(veleroV1, nil)
f.On("Client").Return(client, nil)
f.On("Namespace").Return(mock.Anything)
client := velerotest.NewFakeControllerRuntimeClient(t)
client.Create(context.Background(), builder.ForBackup(cmdtest.VeleroNameSpace, backup1).Result(), &controllerclient.CreateOptions{})
client.Create(context.Background(), builder.ForBackup("default", backup2).Result(), &controllerclient.CreateOptions{})
f.On("KubebuilderClient").Return(client, nil)
f.On("Namespace").Return(cmdtest.VeleroNameSpace)
// create command
c := NewDeleteCommand(f, "velero backup delete")
c.SetArgs([]string{backupName})
assert.Equal(t, "Delete backups", c.Short)
c.SetArgs([]string{backup1, backup2})
require.Equal(t, "Delete backups", c.Short)
o := cli.NewDeleteOptions("backup")
flags := new(flag.FlagSet)
o.BindFlags(flags)
flags.Parse([]string{"--confirm"})
args := []string{"bk1", "bk2"}
args := []string{backup1, backup2}
bk.Name = backupName
e := o.Complete(f, args)
assert.Equal(t, e, nil)
require.Equal(t, nil, e)
e = o.Validate(c, f, args)
assert.Equal(t, e, nil)
require.Equal(t, nil, e)
e = Run(o)
assert.Equal(t, e, nil)
Run(o)
e = c.Execute()
assert.Equal(t, e, nil)
require.Equal(t, nil, e)
if os.Getenv(cmdtest.CaptureFlag) == "1" {
return
@@ -87,10 +79,7 @@ func TestDeleteCommand(t *testing.T) {
cmd := exec.Command(os.Args[0], []string{"-test.run=TestDeleteCommand"}...)
cmd.Env = append(os.Environ(), fmt.Sprintf("%s=1", cmdtest.CaptureFlag))
stdout, _, err := veleroexec.RunCommand(cmd)
if err == nil {
assert.Contains(t, stdout, fmt.Sprintf("Request to delete backup \"%s\" submitted successfully.", backupName))
return
if err != nil {
require.Contains(t, stdout, fmt.Sprintf("backups.velero.io \"%s\" not found.", backup2))
}
t.Fatalf("process ran with err %v, want backups by get()", err)
}

View File

@@ -21,14 +21,14 @@ import (
"fmt"
"os"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v4/apis/volumesnapshot/v1"
snapshotv1client "github.com/kubernetes-csi/external-snapshotter/client/v4/clientset/versioned"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
pkgbackup "github.com/vmware-tanzu/velero/pkg/backup"
"github.com/vmware-tanzu/velero/pkg/client"
"github.com/vmware-tanzu/velero/pkg/cmd"
"github.com/vmware-tanzu/velero/pkg/cmd/util/output"
@@ -54,9 +54,6 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
Use: use + " [NAME1] [NAME2] [NAME...]",
Short: "Describe backups",
Run: func(c *cobra.Command, args []string) {
veleroClient, err := f.Client()
cmd.CheckError(err)
kbClient, err := f.KubebuilderClient()
cmd.CheckError(err)
@@ -64,29 +61,37 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
cmd.CheckError(fmt.Errorf("invalid output format '%s'. valid value are 'plaintext, json'", outputFormat))
}
var backups *velerov1api.BackupList
backups := new(velerov1api.BackupList)
if len(args) > 0 {
backups = new(velerov1api.BackupList)
for _, name := range args {
backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(context.TODO(), name, metav1.GetOptions{})
backup := new(velerov1api.Backup)
err := kbClient.Get(context.TODO(), controllerclient.ObjectKey{Namespace: f.Namespace(), Name: name}, backup)
cmd.CheckError(err)
backups.Items = append(backups.Items, *backup)
}
} else {
backups, err = veleroClient.VeleroV1().Backups(f.Namespace()).List(context.TODO(), listOptions)
parsedSelector, err := labels.Parse(listOptions.LabelSelector)
cmd.CheckError(err)
err = kbClient.List(context.TODO(), backups, &controllerclient.ListOptions{LabelSelector: parsedSelector, Namespace: f.Namespace()})
cmd.CheckError(err)
}
first := true
for i, backup := range backups.Items {
deleteRequestListOptions := pkgbackup.NewDeleteBackupRequestListOptions(backup.Name, string(backup.UID))
deleteRequestList, err := veleroClient.VeleroV1().DeleteBackupRequests(f.Namespace()).List(context.TODO(), deleteRequestListOptions)
deleteRequestList := new(velerov1api.DeleteBackupRequestList)
err := kbClient.List(context.TODO(), deleteRequestList, &controllerclient.ListOptions{
Namespace: f.Namespace(),
LabelSelector: labels.SelectorFromSet(map[string]string{velerov1api.BackupNameLabel: label.GetValidName(backup.Name), velerov1api.BackupUIDLabel: string(backup.UID)}),
})
if err != nil {
fmt.Fprintf(os.Stderr, "error getting DeleteBackupRequests for backup %s: %v\n", backup.Name, err)
}
opts := label.NewListOptionsForBackup(backup.Name)
podVolumeBackupList, err := veleroClient.VeleroV1().PodVolumeBackups(f.Namespace()).List(context.TODO(), opts)
podVolumeBackupList := new(velerov1api.PodVolumeBackupList)
err = kbClient.List(context.TODO(), podVolumeBackupList, &controllerclient.ListOptions{
Namespace: f.Namespace(),
LabelSelector: labels.SelectorFromSet(map[string]string{velerov1api.BackupNameLabel: label.GetValidName(backup.Name)}),
})
if err != nil {
fmt.Fprintf(os.Stderr, "error getting PodVolumeBackups for backup %s: %v\n", backup.Name, err)
}
@@ -101,6 +106,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
csiClient, err = snapshotv1client.NewForConfig(clientConfig)
cmd.CheckError(err)
opts := label.NewListOptionsForBackup(backup.Name)
vscList, err = csiClient.SnapshotV1().VolumeSnapshotContents().List(context.TODO(), opts)
if err != nil {
fmt.Fprintf(os.Stderr, "error getting VolumeSnapshotContent objects for backup %s: %v\n", backup.Name, err)
@@ -110,10 +116,10 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
// structured output only applies to a single backup in case of OOM
// To describe the list of backups in structured format, users could iterate over the list and describe backup one after another.
if len(backups.Items) == 1 && outputFormat != "plaintext" {
s := output.DescribeBackupInSF(context.Background(), kbClient, &backups.Items[i], deleteRequestList.Items, podVolumeBackupList.Items, vscList.Items, details, veleroClient, insecureSkipTLSVerify, caCertFile, outputFormat)
s := output.DescribeBackupInSF(context.Background(), kbClient, &backups.Items[i], deleteRequestList.Items, podVolumeBackupList.Items, vscList.Items, details, insecureSkipTLSVerify, caCertFile, outputFormat)
fmt.Print(s)
} else {
s := output.DescribeBackup(context.Background(), kbClient, &backups.Items[i], deleteRequestList.Items, podVolumeBackupList.Items, vscList.Items, details, veleroClient, insecureSkipTLSVerify, caCertFile)
s := output.DescribeBackup(context.Background(), kbClient, &backups.Items[i], deleteRequestList.Items, podVolumeBackupList.Items, vscList.Items, details, insecureSkipTLSVerify, caCertFile)
if first {
first = false
fmt.Print(s)

View File

@@ -17,55 +17,37 @@ limitations under the License.
package backup
import (
"context"
"fmt"
"os"
"os/exec"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"k8s.io/client-go/rest"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/builder"
factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks"
cmdtest "github.com/vmware-tanzu/velero/pkg/cmd/test"
"github.com/vmware-tanzu/velero/pkg/features"
versionedmocks "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/mocks"
velerov1mocks "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1/mocks"
"github.com/vmware-tanzu/velero/pkg/test"
veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec"
)
func TestNewDescribeCommand(t *testing.T) {
// create a factory
f := &factorymocks.Factory{}
backups := &velerov1mocks.BackupInterface{}
veleroV1 := &velerov1mocks.VeleroV1Interface{}
client := &versionedmocks.Interface{}
clientConfig := rest.Config{}
deleteBackupRequest := &velerov1mocks.DeleteBackupRequestInterface{}
bk := &velerov1api.Backup{}
bkList := &velerov1api.BackupList{}
deleteBackupRequestList := &velerov1api.DeleteBackupRequestList{}
podVolumeBackups := &velerov1mocks.PodVolumeBackupInterface{}
podVolumeBackupList := &velerov1api.PodVolumeBackupList{}
backupName := "bk-describe-1"
bk.Name = backupName
testBackup := builder.ForBackup(cmdtest.VeleroNameSpace, backupName).Result()
clientConfig := rest.Config{}
kbClient := test.NewFakeControllerRuntimeClient(t)
kbClient.Create(context.Background(), testBackup, &controllerclient.CreateOptions{})
backups.On("List", mock.Anything, mock.Anything).Return(bkList, nil)
backups.On("Get", mock.Anything, mock.Anything, mock.Anything).Return(bk, nil)
veleroV1.On("Backups", mock.Anything).Return(backups, nil)
deleteBackupRequest.On("List", mock.Anything, mock.Anything).Return(deleteBackupRequestList, nil)
veleroV1.On("DeleteBackupRequests", mock.Anything).Return(deleteBackupRequest, nil)
podVolumeBackups.On("List", mock.Anything, mock.Anything).Return(podVolumeBackupList, nil)
veleroV1.On("PodVolumeBackups", mock.Anything, mock.Anything).Return(podVolumeBackups, nil)
client.On("VeleroV1").Return(veleroV1, nil)
f.On("ClientConfig").Return(&clientConfig, nil)
f.On("Client").Return(client, nil)
f.On("Namespace").Return(mock.Anything)
f.On("KubebuilderClient").Return(nil, nil)
f.On("Namespace").Return(cmdtest.VeleroNameSpace)
f.On("KubebuilderClient").Return(kbClient, nil)
// create command
c := NewDescribeCommand(f, "velero backup describe")
@@ -74,7 +56,7 @@ func TestNewDescribeCommand(t *testing.T) {
features.NewFeatureFlagSet("EnableCSI")
defer features.NewFeatureFlagSet()
c.SetArgs([]string{"bk1"})
c.SetArgs([]string{backupName})
e := c.Execute()
assert.NoError(t, e)

View File

@@ -26,7 +26,7 @@ import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/client"
@@ -84,10 +84,11 @@ func (o *DownloadOptions) BindFlags(flags *pflag.FlagSet) {
}
func (o *DownloadOptions) Validate(c *cobra.Command, args []string, f client.Factory) error {
veleroClient, err := f.Client()
kbClient, err := f.KubebuilderClient()
cmd.CheckError(err)
if _, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(context.TODO(), o.Name, metav1.GetOptions{}); err != nil {
backup := new(velerov1api.Backup)
if err := kbClient.Get(context.TODO(), controllerclient.ObjectKey{Namespace: f.Namespace(), Name: o.Name}, backup); err != nil {
return err
}

View File

@@ -17,6 +17,7 @@ limitations under the License.
package backup
import (
"context"
"fmt"
"os"
"os/exec"
@@ -25,35 +26,29 @@ import (
flag "github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"github.com/vmware-tanzu/velero/pkg/builder"
cmdtest "github.com/vmware-tanzu/velero/pkg/cmd/test"
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks"
versionedmocks "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/mocks"
velerov1mocks "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1/mocks"
)
func TestNewDownloadCommand(t *testing.T) {
// create a factory
f := &factorymocks.Factory{}
backups := &velerov1mocks.BackupInterface{}
veleroV1 := &velerov1mocks.VeleroV1Interface{}
client := &versionedmocks.Interface{}
bk := &velerov1api.Backup{}
backupName := "backup-1"
kbclient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build()
err := kbclient.Create(context.Background(), builder.ForBackup(cmdtest.VeleroNameSpace, backupName).Result())
require.NoError(t, err)
err = kbclient.Create(context.Background(), builder.ForBackup(cmdtest.VeleroNameSpace, "bk-to-be-download").Result())
require.NoError(t, err)
backups.On("Get", mock.Anything, mock.Anything, mock.Anything).Return(bk, nil)
veleroV1.On("Backups", mock.Anything).Return(backups, nil)
client.On("VeleroV1").Return(veleroV1, nil)
f.On("Client").Return(client, nil)
f.On("Namespace").Return(mock.Anything)
f.On("Namespace").Return(cmdtest.VeleroNameSpace)
f.On("KubebuilderClient").Return(kbclient, nil)
// create command
@@ -78,7 +73,6 @@ func TestNewDownloadCommand(t *testing.T) {
flags.Parse([]string{fmt.Sprintf("--insecure-skip-tls-verify=%s", strconv.FormatBool(insecureSkipTlsVerify))})
flags.Parse([]string{"--cacert", cacert})
backupName := "backup-1"
args := []string{backupName, "arg2"}
e := o.Complete(args)
@@ -105,7 +99,7 @@ func TestNewDownloadCommand(t *testing.T) {
_, stderr, err := veleroexec.RunCommand(cmd)
if err != nil {
assert.Contains(t, stderr, "download request download url timeout")
require.Contains(t, stderr, "download request download url timeout")
return
}
t.Fatalf("process ran with err %v, want backup delete successfully", err)

View File

@@ -26,14 +26,11 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks"
"github.com/vmware-tanzu/velero/pkg/cmd/cli"
cmdtest "github.com/vmware-tanzu/velero/pkg/cmd/test"
versionedmocks "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/mocks"
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec"
)
@@ -41,9 +38,7 @@ func TestNewDeleteCommand(t *testing.T) {
// create a factory
f := &factorymocks.Factory{}
client := &versionedmocks.Interface{}
kbclient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build()
f.On("Client").Return(client, nil)
kbclient := velerotest.NewFakeControllerRuntimeClient(t)
f.On("Namespace").Return(mock.Anything)
f.On("KubebuilderClient").Return(kbclient, nil)
@@ -86,9 +81,7 @@ func TestDeleteFunctions(t *testing.T) {
//t.Run("create the other create command with fromSchedule option for Run() other branches", func(t *testing.T) {
// create a factory
f := &factorymocks.Factory{}
client := &versionedmocks.Interface{}
kbclient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build()
f.On("Client").Return(client, nil)
kbclient := velerotest.NewFakeControllerRuntimeClient(t)
f.On("Namespace").Return(mock.Anything)
f.On("KubebuilderClient").Return(kbclient, nil)

View File

@@ -24,11 +24,10 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks"
cmdtest "github.com/vmware-tanzu/velero/pkg/cmd/test"
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec"
)
@@ -36,7 +35,7 @@ func TestNewGetCommand(t *testing.T) {
bkList := []string{"b1", "b2"}
f := &factorymocks.Factory{}
kbclient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build()
kbclient := velerotest.NewFakeControllerRuntimeClient(t)
f.On("Namespace").Return(mock.Anything)
f.On("KubebuilderClient").Return(kbclient, nil)

View File

@@ -25,16 +25,16 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/pflag"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/vmware-tanzu/velero/pkg/client"
clientset "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
)
// DeleteOptions contains parameters used for deleting a restore.
type DeleteOptions struct {
*SelectOptions
Confirm bool
Client clientset.Interface
Client controllerclient.Client
Namespace string
}
@@ -47,7 +47,7 @@ func NewDeleteOptions(singularTypeName string) *DeleteOptions {
// Complete fills in the correct values for all the options.
func (o *DeleteOptions) Complete(f client.Factory, args []string) error {
o.Namespace = f.Namespace()
client, err := f.Client()
client, err := f.KubebuilderClient()
if err != nil {
return err
}

View File

@@ -25,6 +25,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
kubeerrs "k8s.io/apimachinery/pkg/util/errors"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/client"
@@ -76,7 +77,8 @@ func Run(o *cli.DeleteOptions) error {
switch {
case len(o.Names) > 0:
for _, name := range o.Names {
restore, err := o.Client.VeleroV1().Restores(o.Namespace).Get(context.TODO(), name, metav1.GetOptions{})
restore := new(velerov1api.Restore)
err := o.Client.Get(context.TODO(), controllerclient.ObjectKey{Namespace: o.Namespace, Name: name}, restore)
if err != nil {
errs = append(errs, errors.WithStack(err))
continue
@@ -84,27 +86,39 @@ func Run(o *cli.DeleteOptions) error {
restores = append(restores, restore)
}
default:
selector := labels.Everything().String()
selector := labels.Everything()
if o.Selector.LabelSelector != nil {
selector = o.Selector.String()
convertedSelector, err := metav1.LabelSelectorAsSelector(o.Selector.LabelSelector)
if err != nil {
return errors.WithStack(err)
}
selector = convertedSelector
}
res, err := o.Client.VeleroV1().Restores(o.Namespace).List(context.TODO(), metav1.ListOptions{
restoreList := new(velerov1api.RestoreList)
err := o.Client.List(context.TODO(), restoreList, &controllerclient.ListOptions{
Namespace: o.Namespace,
LabelSelector: selector,
})
if err != nil {
errs = append(errs, errors.WithStack(err))
}
for i := range res.Items {
restores = append(restores, &res.Items[i])
for i := range restoreList.Items {
restores = append(restores, &restoreList.Items[i])
}
}
if len(errs) > 0 {
fmt.Println("errs: ", errs)
return kubeerrs.NewAggregate(errs)
}
if len(restores) == 0 {
fmt.Println("No restores found")
return nil
}
for _, r := range restores {
err := o.Client.VeleroV1().Restores(r.Namespace).Delete(context.TODO(), r.Name, metav1.DeleteOptions{})
err := o.Client.Delete(context.TODO(), r, &controllerclient.DeleteOptions{})
if err != nil {
errs = append(errs, errors.WithStack(err))
continue

View File

@@ -75,7 +75,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
fmt.Fprintf(os.Stderr, "error getting PodVolumeRestores for restore %s: %v\n", restore.Name, err)
}
s := output.DescribeRestore(context.Background(), kbClient, &restores.Items[i], podvolumeRestoreList.Items, details, veleroClient, insecureSkipTLSVerify, caCertFile)
s := output.DescribeRestore(context.Background(), kbClient, &restores.Items[i], podvolumeRestoreList.Items, details, insecureSkipTLSVerify, caCertFile)
if first {
first = false
fmt.Print(s)

View File

@@ -25,6 +25,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
kubeerrs "k8s.io/apimachinery/pkg/util/errors"
controllerclient "sigs.k8s.io/controller-runtime/pkg/client"
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/client"
@@ -76,7 +77,8 @@ func Run(o *cli.DeleteOptions) error {
switch {
case len(o.Names) > 0:
for _, name := range o.Names {
schedule, err := o.Client.VeleroV1().Schedules(o.Namespace).Get(context.TODO(), name, metav1.GetOptions{})
schedule := new(velerov1api.Schedule)
err := o.Client.Get(context.TODO(), controllerclient.ObjectKey{Namespace: o.Namespace, Name: name}, schedule)
if err != nil {
errs = append(errs, errors.WithStack(err))
continue
@@ -84,19 +86,25 @@ func Run(o *cli.DeleteOptions) error {
schedules = append(schedules, schedule)
}
default:
selector := labels.Everything().String()
selector := labels.Everything()
if o.Selector.LabelSelector != nil {
selector = o.Selector.String()
convertedSelector, err := metav1.LabelSelectorAsSelector(o.Selector.LabelSelector)
if err != nil {
return errors.WithStack(err)
}
selector = convertedSelector
}
res, err := o.Client.VeleroV1().Schedules(o.Namespace).List(context.TODO(), metav1.ListOptions{
scheduleList := new(velerov1api.ScheduleList)
err := o.Client.List(context.TODO(), scheduleList, &controllerclient.ListOptions{
Namespace: o.Namespace,
LabelSelector: selector,
})
if err != nil {
errs = append(errs, errors.WithStack(err))
}
for i := range res.Items {
schedules = append(schedules, &res.Items[i])
for i := range scheduleList.Items {
schedules = append(schedules, &scheduleList.Items[i])
}
}
if len(schedules) == 0 {
@@ -105,7 +113,7 @@ func Run(o *cli.DeleteOptions) error {
}
for _, s := range schedules {
err := o.Client.VeleroV1().Schedules(s.Namespace).Delete(context.TODO(), s.Name, metav1.DeleteOptions{})
err := o.Client.Delete(context.TODO(), s, &controllerclient.DeleteOptions{})
if err != nil {
errs = append(errs, errors.WithStack(err))
continue

View File

@@ -25,12 +25,11 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/builder"
"github.com/vmware-tanzu/velero/pkg/buildinfo"
"github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/scheme"
velerotest "github.com/vmware-tanzu/velero/pkg/test"
)
func TestPrintVersion(t *testing.T) {
@@ -83,7 +82,7 @@ func TestPrintVersion(t *testing.T) {
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
var (
kbClient = fake.NewClientBuilder().WithScheme(scheme.Scheme).Build()
kbClient = velerotest.NewFakeControllerRuntimeClient(t)
serverStatusGetter = new(mockServerStatusGetter)
buf = new(bytes.Buffer)
)