diff --git a/changelogs/unreleased/6497-blackpiglet b/changelogs/unreleased/6497-blackpiglet new file mode 100644 index 00000000000..30337ae92bf --- /dev/null +++ b/changelogs/unreleased/6497-blackpiglet @@ -0,0 +1 @@ +Remove dependency of the legacy client code from pkg/cmd directory part 2 \ No newline at end of file diff --git a/pkg/client/factory_test.go b/pkg/client/factory_test.go index e96b2b04498..547be6bff60 100644 --- a/pkg/client/factory_test.go +++ b/pkg/client/factory_test.go @@ -141,6 +141,10 @@ func TestFactory(t *testing.T) { kubebuilderClient, e := f.KubebuilderClient() assert.Contains(t, e.Error(), fmt.Sprintf("Get \"%s/api?timeout=", test.expectedHost)) assert.Nil(t, kubebuilderClient) + + kbClientWithWatch, e := f.KubebuilderWatchClient() + assert.Contains(t, e.Error(), fmt.Sprintf("Get \"%s/api?timeout=", test.expectedHost)) + assert.Nil(t, kbClientWithWatch) }) } } diff --git a/pkg/cmd/cli/backup/download_test.go b/pkg/cmd/cli/backup/download_test.go index 3a28b73f76e..a709a814b8b 100644 --- a/pkg/cmd/cli/backup/download_test.go +++ b/pkg/cmd/cli/backup/download_test.go @@ -27,14 +27,12 @@ import ( flag "github.com/spf13/pflag" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "sigs.k8s.io/controller-runtime/pkg/client/fake" "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/generated/clientset/versioned/scheme" + velerotest "github.com/vmware-tanzu/velero/pkg/test" veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec" - - factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks" ) func TestNewDownloadCommand(t *testing.T) { @@ -42,7 +40,7 @@ func TestNewDownloadCommand(t *testing.T) { f := &factorymocks.Factory{} backupName := "backup-1" - kbclient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build() + kbclient := velerotest.NewFakeControllerRuntimeClient(t) 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()) diff --git a/pkg/cmd/cli/backup/get.go b/pkg/cmd/cli/backup/get.go index f5ccc07e108..159fac30dd1 100644 --- a/pkg/cmd/cli/backup/get.go +++ b/pkg/cmd/cli/backup/get.go @@ -21,6 +21,8 @@ import ( "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + kbclient "sigs.k8s.io/controller-runtime/pkg/client" api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/client" @@ -38,19 +40,24 @@ func NewGetCommand(f client.Factory, use string) *cobra.Command { err := output.ValidateFlags(c) cmd.CheckError(err) - veleroClient, err := f.Client() + kbClient, err := f.KubebuilderClient() cmd.CheckError(err) - var backups *api.BackupList + backups := new(api.BackupList) if len(args) > 0 { - backups = new(api.BackupList) for _, name := range args { - backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(context.TODO(), name, metav1.GetOptions{}) + backup := new(api.Backup) + err := kbClient.Get(context.TODO(), kbclient.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, &kbclient.ListOptions{ + LabelSelector: parsedSelector, + Namespace: f.Namespace(), + }) cmd.CheckError(err) } diff --git a/pkg/cmd/cli/backup/get_test.go b/pkg/cmd/cli/backup/get_test.go index fbbeb91913d..6c9b8bb5f79 100644 --- a/pkg/cmd/cli/backup/get_test.go +++ b/pkg/cmd/cli/backup/get_test.go @@ -17,6 +17,7 @@ limitations under the License. package backup import ( + "context" "fmt" "os" "os/exec" @@ -24,15 +25,14 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + kbclient "sigs.k8s.io/controller-runtime/pkg/client" + "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" + velerotest "github.com/vmware-tanzu/velero/pkg/test" 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 TestNewGetCommand(t *testing.T) { @@ -41,18 +41,16 @@ func TestNewGetCommand(t *testing.T) { // create a factory f := &factorymocks.Factory{} - backups := &velerov1mocks.BackupInterface{} - veleroV1 := &velerov1mocks.VeleroV1Interface{} - client := &versionedmocks.Interface{} - bk := &velerov1api.Backup{} - bkList := &velerov1api.BackupList{} + client := velerotest.NewFakeControllerRuntimeClient(t) - 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) - client.On("VeleroV1").Return(veleroV1, nil) - f.On("Client").Return(client, nil) - f.On("Namespace").Return(mock.Anything) + for _, backupName := range args { + backup := builder.ForBackup(cmdtest.VeleroNameSpace, backupName).ObjectMeta(builder.WithLabels("abc", "abc")).Result() + err := client.Create(context.Background(), backup, &kbclient.CreateOptions{}) + require.NoError(t, err) + } + + f.On("KubebuilderClient").Return(client, nil) + f.On("Namespace").Return(cmdtest.VeleroNameSpace) // create command c := NewGetCommand(f, "velero backup get") @@ -69,6 +67,29 @@ func TestNewGetCommand(t *testing.T) { cmd := exec.Command(os.Args[0], []string{"-test.run=TestNewGetCommand"}...) cmd.Env = append(os.Environ(), fmt.Sprintf("%s=1", cmdtest.CaptureFlag)) stdout, _, err := veleroexec.RunCommand(cmd) + require.NoError(t, err) + + if err == nil { + output := strings.Split(stdout, "\n") + i := 0 + for _, line := range output { + if strings.Contains(line, "New") { + i++ + } + } + assert.Equal(t, len(args), i) + return + } + + d := NewGetCommand(f, "velero backup get") + c.SetArgs([]string{"-l", "abc=abc"}) + e = d.Execute() + assert.NoError(t, e) + + cmd = exec.Command(os.Args[0], []string{"-test.run=TestNewGetCommand"}...) + cmd.Env = append(os.Environ(), fmt.Sprintf("%s=1", cmdtest.CaptureFlag)) + stdout, _, err = veleroexec.RunCommand(cmd) + require.NoError(t, err) if err == nil { output := strings.Split(stdout, "\n") @@ -81,5 +102,4 @@ func TestNewGetCommand(t *testing.T) { assert.Equal(t, len(args), i) return } - t.Fatalf("process ran with err %v, want backups by get()", err) } diff --git a/pkg/cmd/cli/backup/logs.go b/pkg/cmd/cli/backup/logs.go index 95c2387a315..2f2e58fed2b 100644 --- a/pkg/cmd/cli/backup/logs.go +++ b/pkg/cmd/cli/backup/logs.go @@ -24,7 +24,7 @@ import ( "github.com/spf13/cobra" apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + kbclient "sigs.k8s.io/controller-runtime/pkg/client" velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/client" @@ -49,13 +49,11 @@ func NewLogsCommand(f client.Factory) *cobra.Command { Run: func(c *cobra.Command, args []string) { backupName := args[0] - veleroClient, err := f.Client() - cmd.CheckError(err) - kbClient, err := f.KubebuilderClient() cmd.CheckError(err) - backup, err := veleroClient.VeleroV1().Backups(f.Namespace()).Get(context.TODO(), backupName, metav1.GetOptions{}) + backup := new(velerov1api.Backup) + err = kbClient.Get(context.TODO(), kbclient.ObjectKey{Namespace: f.Namespace(), Name: backupName}, backup) if apierrors.IsNotFound(err) { cmd.Exit("Backup %q does not exist.", backupName) } else if err != nil { diff --git a/pkg/cmd/cli/backup/logs_test.go b/pkg/cmd/cli/backup/logs_test.go index d4b98b8847e..b4b400021c8 100644 --- a/pkg/cmd/cli/backup/logs_test.go +++ b/pkg/cmd/cli/backup/logs_test.go @@ -17,21 +17,20 @@ limitations under the License. package backup import ( + "context" "fmt" "os" "os/exec" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "sigs.k8s.io/controller-runtime/pkg/client/fake" + "github.com/stretchr/testify/require" + 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" factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks" 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" - 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" ) @@ -41,20 +40,13 @@ func TestNewLogsCommand(t *testing.T) { // create a factory f := &factorymocks.Factory{} - backups := &velerov1mocks.BackupInterface{} - veleroV1 := &velerov1mocks.VeleroV1Interface{} - client := &versionedmocks.Interface{} - bk := &velerov1api.Backup{} - bkList := &velerov1api.BackupList{} - kbclient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build() + kbClient := velerotest.NewFakeControllerRuntimeClient(t) + backup := builder.ForBackup(cmdtest.VeleroNameSpace, backupName).Result() + err := kbClient.Create(context.Background(), backup, &kbclient.CreateOptions{}) + require.NoError(t, err) - 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) - 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("Namespace").Return(cmdtest.VeleroNameSpace) + f.On("KubebuilderClient").Return(kbClient, nil) c := NewLogsCommand(f) assert.Equal(t, "Get backup logs", c.Short) diff --git a/pkg/cmd/cli/backuplocation/create_test.go b/pkg/cmd/cli/backuplocation/create_test.go index 34293fb889c..dc2cb1aae06 100644 --- a/pkg/cmd/cli/backuplocation/create_test.go +++ b/pkg/cmd/cli/backuplocation/create_test.go @@ -29,16 +29,9 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - veleroflag "github.com/vmware-tanzu/velero/pkg/cmd/util/flag" - "github.com/vmware-tanzu/velero/pkg/test" - - "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" - 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" + veleroflag "github.com/vmware-tanzu/velero/pkg/cmd/util/flag" + velerotest "github.com/vmware-tanzu/velero/pkg/test" ) func TestBuildBackupStorageLocationSetsNamespace(t *testing.T) { @@ -149,16 +142,7 @@ func TestCreateCommand_Run(t *testing.T) { args := []string{name, "arg2"} - backups := &velerov1mocks.BackupInterface{} - veleroV1 := &velerov1mocks.VeleroV1Interface{} - client := &versionedmocks.Interface{} - bk := &velerov1api.Backup{} - kbclient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build() - - 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) + kbclient := velerotest.NewFakeControllerRuntimeClient(t) f.On("Namespace").Return(mock.Anything) f.On("KubebuilderClient").Return(kbclient, nil) @@ -179,7 +163,7 @@ func TestCreateCommand_Run(t *testing.T) { assert.Equal(t, backupSyncPeriod, o.BackupSyncPeriod.String()) assert.Equal(t, validationFrequency, o.ValidationFrequency.String()) assert.Equal(t, true, reflect.DeepEqual(bslConfig, o.Config)) - assert.Equal(t, true, test.CompareSlice(strings.Split(labels, ","), strings.Split(o.Labels.String(), ","))) + assert.Equal(t, true, velerotest.CompareSlice(strings.Split(labels, ","), strings.Split(o.Labels.String(), ","))) assert.Equal(t, caCertFile, o.CACertFile) assert.Equal(t, accessMode, o.AccessMode.String()) diff --git a/pkg/cmd/cli/backuplocation/set_test.go b/pkg/cmd/cli/backuplocation/set_test.go index d97327126c7..b57f6a3208b 100644 --- a/pkg/cmd/cli/backuplocation/set_test.go +++ b/pkg/cmd/cli/backuplocation/set_test.go @@ -27,16 +27,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" + factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks" cmdtest "github.com/vmware-tanzu/velero/pkg/cmd/test" veleroflag "github.com/vmware-tanzu/velero/pkg/cmd/util/flag" - - "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" - 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" + velerotest "github.com/vmware-tanzu/velero/pkg/test" veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec" ) @@ -44,16 +38,9 @@ func TestNewSetCommand(t *testing.T) { backupName := "arg2" // create a config for factory f := &factorymocks.Factory{} - backups := &velerov1mocks.BackupInterface{} - veleroV1 := &velerov1mocks.VeleroV1Interface{} - client := &versionedmocks.Interface{} - bk := &velerov1api.Backup{} - kbclient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build() - - 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) + + kbclient := velerotest.NewFakeControllerRuntimeClient(t) + f.On("Namespace").Return(mock.Anything) f.On("KubebuilderClient").Return(kbclient, nil) @@ -97,16 +84,9 @@ func TestSetCommand_Execute(t *testing.T) { if os.Getenv(cmdtest.CaptureFlag) == "1" { // create a config for factory f := &factorymocks.Factory{} - backups := &velerov1mocks.BackupInterface{} - veleroV1 := &velerov1mocks.VeleroV1Interface{} - client := &versionedmocks.Interface{} - bk := &velerov1api.Backup{} - kbclient := fake.NewClientBuilder().WithScheme(scheme.Scheme).Build() - - 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) + + kbclient := velerotest.NewFakeControllerRuntimeClient(t) + f.On("Namespace").Return(mock.Anything) f.On("KubebuilderClient").Return(kbclient, nil) diff --git a/pkg/cmd/cli/restore/create.go b/pkg/cmd/cli/restore/create.go index 44db8eb8e1d..39219a53ff2 100644 --- a/pkg/cmd/cli/restore/create.go +++ b/pkg/cmd/cli/restore/create.go @@ -26,16 +26,17 @@ import ( "github.com/spf13/cobra" "github.com/spf13/pflag" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" + kbclient "sigs.k8s.io/controller-runtime/pkg/client" api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/client" "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/boolptr" + "github.com/vmware-tanzu/velero/pkg/util/kube" ) func NewCreateCommand(f client.Factory, use string) *cobra.Command { @@ -93,8 +94,7 @@ type CreateOptions struct { Wait bool AllowPartiallyFailed flag.OptionalBool ItemOperationTimeout time.Duration - - client veleroclient.Interface + client kbclient.WithWatch } func NewCreateOptions() *CreateOptions { @@ -153,7 +153,7 @@ func (o *CreateOptions) Complete(args []string, f client.Factory) error { o.RestoreName = fmt.Sprintf("%s-%s", sourceName, time.Now().Format("20060102150405")) } - client, err := f.Client() + client, err := f.KubebuilderWatchClient() if err != nil { return err } @@ -186,15 +186,20 @@ func (o *CreateOptions) Validate(c *cobra.Command, args []string, f client.Facto switch { case o.BackupName != "": - if _, err := o.client.VeleroV1().Backups(f.Namespace()).Get(context.TODO(), o.BackupName, metav1.GetOptions{}); err != nil { + backup := new(api.Backup) + if err := o.client.Get(context.TODO(), kbclient.ObjectKey{Namespace: f.Namespace(), Name: o.BackupName}, backup); err != nil { return err } case o.ScheduleName != "": - backupItems, err := o.client.VeleroV1().Backups(f.Namespace()).List(context.TODO(), metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", api.ScheduleNameLabel, o.ScheduleName)}) + backupList := new(api.BackupList) + err := o.client.List(context.TODO(), backupList, &kbclient.ListOptions{ + LabelSelector: labels.SelectorFromSet(map[string]string{api.ScheduleNameLabel: o.ScheduleName}), + Namespace: f.Namespace(), + }) if err != nil { return err } - if len(backupItems.Items) == 0 { + if len(backupList.Items) == 0 { return errors.Errorf("No backups found for the schedule %s", o.ScheduleName) } } @@ -248,14 +253,18 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error { // PartiallyFailed backup for the provided schedule, and use that specific backup // to restore from. if o.ScheduleName != "" && boolptr.IsSetToTrue(o.AllowPartiallyFailed.Value) { - backups, err := o.client.VeleroV1().Backups(f.Namespace()).List(context.TODO(), metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", api.ScheduleNameLabel, o.ScheduleName)}) + backupList := new(api.BackupList) + err := o.client.List(context.TODO(), backupList, &kbclient.ListOptions{ + LabelSelector: labels.SelectorFromSet(map[string]string{api.ScheduleNameLabel: o.ScheduleName}), + Namespace: f.Namespace(), + }) if err != nil { return err } // if we find a Completed or PartiallyFailed backup for the schedule, restore specifically from that backup. If we don't // find one, proceed as-is -- the Velero server will handle validation. - if backup := mostRecentBackup(backups.Items, api.BackupPhaseCompleted, api.BackupPhasePartiallyFailed); backup != nil { + if backup := mostRecentBackup(backupList.Items, api.BackupPhaseCompleted, api.BackupPhasePartiallyFailed); backup != nil { // TODO(sk): this is kind of a hack -- we should revisit this and probably // move this logic to the server side or otherwise solve this problem. o.BackupName = backup.Name @@ -299,7 +308,6 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error { return err } - var restoreInformer cache.SharedIndexInformer var updates chan *api.Restore if o.Wait { stop := make(chan struct{}) @@ -307,7 +315,12 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error { updates = make(chan *api.Restore) - restoreInformer = v1.NewRestoreInformer(o.client, f.Namespace(), 0, nil) + lw := kube.InternalLW{ + Client: o.client, + Namespace: f.Namespace(), + ObjectList: new(api.RestoreList), + } + restoreInformer := cache.NewSharedInformer(&lw, &api.Restore{}, time.Second) restoreInformer.AddEventHandler( cache.FilteringResourceEventHandler{ @@ -339,7 +352,7 @@ func (o *CreateOptions) Run(c *cobra.Command, f client.Factory) error { go restoreInformer.Run(stop) } - restore, err := o.client.VeleroV1().Restores(restore.Namespace).Create(context.TODO(), restore, metav1.CreateOptions{}) + err := o.client.Create(context.TODO(), restore, &kbclient.CreateOptions{}) if err != nil { return err } diff --git a/pkg/cmd/cli/restore/create_test.go b/pkg/cmd/cli/restore/create_test.go new file mode 100644 index 00000000000..fb6ebd83238 --- /dev/null +++ b/pkg/cmd/cli/restore/create_test.go @@ -0,0 +1,145 @@ +/* +Copyright 2020 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 restore + +import ( + "testing" + "time" + + "github.com/spf13/pflag" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + 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" + factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks" + cmdtest "github.com/vmware-tanzu/velero/pkg/cmd/test" + velerotest "github.com/vmware-tanzu/velero/pkg/test" +) + +func TestIsResourcePolicyValid(t *testing.T) { + require.True(t, isResourcePolicyValid(string(velerov1api.PolicyTypeNone))) + require.True(t, isResourcePolicyValid(string(velerov1api.PolicyTypeUpdate))) + require.False(t, isResourcePolicyValid("")) +} + +func TestMostRecentBackup(t *testing.T) { + backups := []velerov1api.Backup{ + *builder.ForBackup(cmdtest.VeleroNameSpace, "backup0").StartTimestamp(time.Now().Add(3 * time.Second)).Phase(velerov1api.BackupPhaseDeleting).Result(), + *builder.ForBackup(cmdtest.VeleroNameSpace, "backup1").StartTimestamp(time.Now().Add(time.Second)).Phase(velerov1api.BackupPhaseCompleted).Result(), + *builder.ForBackup(cmdtest.VeleroNameSpace, "backup2").StartTimestamp(time.Now().Add(2 * time.Second)).Phase(velerov1api.BackupPhasePartiallyFailed).Result(), + } + + expectedBackup := builder.ForBackup(cmdtest.VeleroNameSpace, "backup2").StartTimestamp(time.Now().Add(2 * time.Second)).Phase(velerov1api.BackupPhasePartiallyFailed).Result() + + resultBackup := mostRecentBackup(backups, velerov1api.BackupPhaseCompleted, velerov1api.BackupPhasePartiallyFailed) + + require.Equal(t, expectedBackup.Name, resultBackup.Name) +} + +func TestCreateCommand(t *testing.T) { + name := "nameToBeCreated" + 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{} + + // create command + cmd := NewCreateCommand(f, "") + require.Equal(t, "Create a restore", cmd.Short) + + backupName := "backup1" + scheduleName := "schedule1" + restoreVolumes := "true" + preserveNodePorts := "true" + labels := "c=foo,b=woo" + includeNamespaces := "app1,app2" + excludeNamespaces := "pod1,pod2,pod3" + existingResourcePolicy := "none" + includeResources := "sc,sts" + excludeResources := "job" + statusIncludeResources := "sc,sts" + statusExcludeResources := "job" + namespaceMappings := "a:b" + selector := "foo=bar" + includeClusterResources := "true" + allowPartiallyFailed := "true" + itemOperationTimeout := "10m0s" + + flags := new(pflag.FlagSet) + o := NewCreateOptions() + o.BindFlags(flags) + + flags.Parse([]string{"--from-backup", backupName}) + flags.Parse([]string{"--from-schedule", scheduleName}) + flags.Parse([]string{"--restore-volumes", restoreVolumes}) + flags.Parse([]string{"--preserve-nodeports", preserveNodePorts}) + flags.Parse([]string{"--labels", labels}) + flags.Parse([]string{"--existing-resource-policy", existingResourcePolicy}) + flags.Parse([]string{"--include-namespaces", includeNamespaces}) + flags.Parse([]string{"--exclude-namespaces", excludeNamespaces}) + flags.Parse([]string{"--include-resources", includeResources}) + flags.Parse([]string{"--exclude-resources", excludeResources}) + flags.Parse([]string{"--status-include-resources", statusIncludeResources}) + flags.Parse([]string{"--status-exclude-resources", statusExcludeResources}) + flags.Parse([]string{"--namespace-mappings", namespaceMappings}) + flags.Parse([]string{"--selector", selector}) + flags.Parse([]string{"--include-cluster-resources", includeClusterResources}) + flags.Parse([]string{"--allow-partially-failed", allowPartiallyFailed}) + flags.Parse([]string{"--item-operation-timeout", itemOperationTimeout}) + + client := velerotest.NewFakeControllerRuntimeClient(t).(kbclient.WithWatch) + + f.On("Namespace").Return(mock.Anything) + f.On("KubebuilderWatchClient").Return(client, nil) + + //Complete + e := o.Complete(args, f) + require.NoError(t, e) + + //Validate + e = o.Validate(cmd, args, f) + require.Contains(t, e.Error(), "either a backup or schedule must be specified, but not both") + + //cmd + e = o.Run(cmd, f) + require.NoError(t, e) + + require.Equal(t, backupName, o.BackupName) + require.Equal(t, scheduleName, o.ScheduleName) + require.Equal(t, restoreVolumes, o.RestoreVolumes.String()) + require.Equal(t, preserveNodePorts, o.PreserveNodePorts.String()) + require.Equal(t, labels, o.Labels.String()) + require.Equal(t, includeNamespaces, o.IncludeNamespaces.String()) + require.Equal(t, excludeNamespaces, o.ExcludeNamespaces.String()) + require.Equal(t, existingResourcePolicy, o.ExistingResourcePolicy) + require.Equal(t, includeResources, o.IncludeResources.String()) + require.Equal(t, excludeResources, o.ExcludeResources.String()) + + require.Equal(t, statusIncludeResources, o.StatusIncludeResources.String()) + require.Equal(t, statusExcludeResources, o.StatusExcludeResources.String()) + require.Equal(t, namespaceMappings, o.NamespaceMappings.String()) + require.Equal(t, selector, o.Selector.String()) + require.Equal(t, includeClusterResources, o.IncludeClusterResources.String()) + require.Equal(t, allowPartiallyFailed, o.AllowPartiallyFailed.String()) + require.Equal(t, itemOperationTimeout, o.ItemOperationTimeout.String()) + + }) +} diff --git a/pkg/cmd/cli/restore/restore_test.go b/pkg/cmd/cli/restore/restore_test.go new file mode 100644 index 00000000000..85f4b662a5e --- /dev/null +++ b/pkg/cmd/cli/restore/restore_test.go @@ -0,0 +1,34 @@ +/* +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 restore + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + factorymocks "github.com/vmware-tanzu/velero/pkg/client/mocks" +) + +func TestNewRestoreCommand(t *testing.T) { + // create a factory + f := &factorymocks.Factory{} + + // create command + cmd := NewCommand(f) + assert.Equal(t, "Work with restores", cmd.Short) +}