Remove dependency of the legacy client code from pkg/cmd directory.

Signed-off-by: Xun Jiang <jxun@vmware.com>
This commit is contained in:
Xun Jiang
2023-07-05 20:44:09 +08:00
parent e54a8af0ad
commit 89d3ad4864
22 changed files with 330 additions and 255 deletions

View File

@@ -0,0 +1 @@
Remove dependency of the legacy client code from pkg/cmd directory

View File

@@ -55,6 +55,10 @@ type Factory interface {
// types to its scheme. It uses the following priority to specify the cluster
// configuration: --kubeconfig flag, KUBECONFIG environment variable, in-cluster configuration.
KubebuilderClient() (kbclient.Client, error)
// KubebuilderWatchClient returns a client with watcher for the controller runtime framework.
// It adds Kubernetes and Velero types to its scheme. It uses the following priority to specify the cluster
// configuration: --kubeconfig flag, KUBECONFIG environment variable, in-cluster configuration.
KubebuilderWatchClient() (kbclient.WithWatch, error)
// SetBasename changes the basename for an already-constructed client.
// This is useful for generating clients that require a different user-agent string below the root `velero`
// command, such as the server subcommand.
@@ -182,6 +186,39 @@ func (f *factory) KubebuilderClient() (kbclient.Client, error) {
return kubebuilderClient, nil
}
func (f *factory) KubebuilderWatchClient() (kbclient.WithWatch, error) {
clientConfig, err := f.ClientConfig()
if err != nil {
return nil, err
}
scheme := runtime.NewScheme()
if err := velerov1api.AddToScheme(scheme); err != nil {
return nil, err
}
if err := velerov2alpha1api.AddToScheme(scheme); err != nil {
return nil, err
}
if err := k8scheme.AddToScheme(scheme); err != nil {
return nil, err
}
if err := apiextv1beta1.AddToScheme(scheme); err != nil {
return nil, err
}
if err := apiextv1.AddToScheme(scheme); err != nil {
return nil, err
}
kubebuilderWatchClient, err := kbclient.NewWithWatch(clientConfig, kbclient.Options{
Scheme: scheme,
})
if err != nil {
return nil, err
}
return kubebuilderWatchClient, nil
}
func (f *factory) SetBasename(name string) {
f.baseName = name
}

View File

@@ -157,6 +157,32 @@ func (_m *Factory) KubebuilderClient() (pkgclient.Client, error) {
return r0, r1
}
// KubebuilderWatchClient provides a mock function with given fields:
func (_m *Factory) KubebuilderWatchClient() (pkgclient.WithWatch, error) {
ret := _m.Called()
var r0 pkgclient.WithWatch
var r1 error
if rf, ok := ret.Get(0).(func() (pkgclient.WithWatch, error)); ok {
return rf()
}
if rf, ok := ret.Get(0).(func() pkgclient.WithWatch); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(pkgclient.WithWatch)
}
}
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Namespace provides a mock function with given fields:
func (_m *Factory) Namespace() string {
ret := _m.Called()

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)
)

View File

@@ -36,7 +36,6 @@ import (
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/cmd/util/downloadrequest"
"github.com/vmware-tanzu/velero/pkg/features"
clientset "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
"github.com/vmware-tanzu/velero/pkg/itemoperation"
"github.com/vmware-tanzu/velero/pkg/util/collections"
@@ -53,7 +52,6 @@ func DescribeBackup(
podVolumeBackups []velerov1api.PodVolumeBackup,
volumeSnapshotContents []snapshotv1api.VolumeSnapshotContent,
details bool,
veleroClient clientset.Interface,
insecureSkipTLSVerify bool,
caCertFile string,
) string {
@@ -106,7 +104,7 @@ func DescribeBackup(
DescribeBackupSpec(d, backup.Spec)
d.Println()
DescribeBackupStatus(ctx, kbClient, d, backup, details, veleroClient, insecureSkipTLSVerify, caCertFile)
DescribeBackupStatus(ctx, kbClient, d, backup, details, insecureSkipTLSVerify, caCertFile)
if len(deleteRequests) > 0 {
d.Println()
@@ -300,7 +298,7 @@ func DescribeBackupSpec(d *Describer, spec velerov1api.BackupSpec) {
}
// DescribeBackupStatus describes a backup status in human-readable format.
func DescribeBackupStatus(ctx context.Context, kbClient kbclient.Client, d *Describer, backup *velerov1api.Backup, details bool, veleroClient clientset.Interface, insecureSkipTLSVerify bool, caCertPath string) {
func DescribeBackupStatus(ctx context.Context, kbClient kbclient.Client, d *Describer, backup *velerov1api.Backup, details bool, insecureSkipTLSVerify bool, caCertPath string) {
status := backup.Status
// Status.Version has been deprecated, use Status.FormatVersion

View File

@@ -33,7 +33,6 @@ import (
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/cmd/util/downloadrequest"
"github.com/vmware-tanzu/velero/pkg/features"
clientset "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
"github.com/vmware-tanzu/velero/pkg/util/results"
"github.com/vmware-tanzu/velero/pkg/volume"
)
@@ -47,7 +46,6 @@ func DescribeBackupInSF(
podVolumeBackups []velerov1api.PodVolumeBackup,
volumeSnapshotContents []snapshotv1api.VolumeSnapshotContent,
details bool,
veleroClient clientset.Interface,
insecureSkipTLSVerify bool,
caCertFile string,
outputFormat string,
@@ -70,7 +68,7 @@ func DescribeBackupInSF(
DescribeBackupSpecInSF(d, backup.Spec)
DescribeBackupStatusInSF(ctx, kbClient, d, backup, details, veleroClient, insecureSkipTLSVerify, caCertFile)
DescribeBackupStatusInSF(ctx, kbClient, d, backup, details, insecureSkipTLSVerify, caCertFile)
if len(deleteRequests) > 0 {
DescribeDeleteBackupRequestsInSF(d, deleteRequests)
@@ -236,7 +234,7 @@ func DescribeBackupSpecInSF(d *StructuredDescriber, spec velerov1api.BackupSpec)
}
// DescribeBackupStatusInSF describes a backup status in structured format.
func DescribeBackupStatusInSF(ctx context.Context, kbClient kbclient.Client, d *StructuredDescriber, backup *velerov1api.Backup, details bool, veleroClient clientset.Interface, insecureSkipTLSVerify bool, caCertPath string) {
func DescribeBackupStatusInSF(ctx context.Context, kbClient kbclient.Client, d *StructuredDescriber, backup *velerov1api.Backup, details bool, insecureSkipTLSVerify bool, caCertPath string) {
status := backup.Status
backupStatusInfo := make(map[string]interface{})

View File

@@ -31,12 +31,11 @@ import (
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
"github.com/vmware-tanzu/velero/pkg/cmd/util/downloadrequest"
clientset "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned"
"github.com/vmware-tanzu/velero/pkg/itemoperation"
"github.com/vmware-tanzu/velero/pkg/util/results"
)
func DescribeRestore(ctx context.Context, kbClient kbclient.Client, restore *velerov1api.Restore, podVolumeRestores []velerov1api.PodVolumeRestore, details bool, veleroClient clientset.Interface, insecureSkipTLSVerify bool, caCertFile string) string {
func DescribeRestore(ctx context.Context, kbClient kbclient.Client, restore *velerov1api.Restore, podVolumeRestores []velerov1api.PodVolumeRestore, details bool, insecureSkipTLSVerify bool, caCertFile string) string {
return Describe(func(d *Describer) {
d.DescribeMetadata(restore.ObjectMeta)

View File

@@ -0,0 +1,41 @@
/*
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 kube
import (
"context"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/watch"
kbclient "sigs.k8s.io/controller-runtime/pkg/client"
)
type InternalLW struct {
Client kbclient.WithWatch
Namespace string
ObjectList kbclient.ObjectList
}
func (lw *InternalLW) Watch(options metav1.ListOptions) (watch.Interface, error) {
return lw.Client.Watch(context.Background(), lw.ObjectList, &kbclient.ListOptions{Raw: &options, Namespace: lw.Namespace})
}
func (lw *InternalLW) List(options metav1.ListOptions) (runtime.Object, error) {
err := lw.Client.List(context.Background(), lw.ObjectList, &kbclient.ListOptions{Raw: &options, Namespace: lw.Namespace})
return lw.ObjectList, err
}