diff --git a/pkg/reporting/app.go b/pkg/reporting/app.go index 5e3fc35049..96d4b3cacc 100644 --- a/pkg/reporting/app.go +++ b/pkg/reporting/app.go @@ -26,6 +26,7 @@ import ( "github.com/replicatedhq/kots/pkg/util" troubleshootpreflight "github.com/replicatedhq/troubleshoot/pkg/preflight" "github.com/segmentio/ksuid" + velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" veleroclientv1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1" helmrelease "helm.sh/helm/v3/pkg/release" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -272,15 +273,20 @@ func GetReportingInfo(appID string) *types.ReportingInfo { } if clientset != nil && veleroClient != nil { - report, err := getSnapshotReport(store.GetStore(), clientset, veleroClient, appID, r.ClusterID) + bsl, err := snapshot.FindBackupStoreLocation(context.TODO(), clientset, veleroClient, util.PodNamespace) if err != nil { - logger.Debugf("failed to get snapshot report: %v", err.Error()) + logger.Debugf("failed to find backup store location: %v", err.Error()) } else { - r.SnapshotProvider = report.Provider - r.SnapshotFullSchedule = report.FullSchedule - r.SnapshotFullTTL = report.FullTTL - r.SnapshotPartialSchedule = report.PartialSchedule - r.SnapshotPartialTTL = report.PartialTTL + report, err := getSnapshotReport(store.GetStore(), bsl, appID, r.ClusterID) + if err != nil { + logger.Debugf("failed to get snapshot report: %v", err.Error()) + } else { + r.SnapshotProvider = report.Provider + r.SnapshotFullSchedule = report.FullSchedule + r.SnapshotFullTTL = report.FullTTL + r.SnapshotPartialSchedule = report.PartialSchedule + r.SnapshotPartialTTL = report.PartialTTL + } } } @@ -362,13 +368,9 @@ func getGitOpsReport(clientset kubernetes.Interface, appID string, clusterID str return false, "" } -func getSnapshotReport(kotsStore store.Store, clientset kubernetes.Interface, veleroClient veleroclientv1.VeleroV1Interface, appID string, clusterID string) (*SnapshotReport, error) { +func getSnapshotReport(kotsStore store.Store, bsl *velerov1.BackupStorageLocation, appID string, clusterID string) (*SnapshotReport, error) { report := &SnapshotReport{} - bsl, err := snapshot.FindBackupStoreLocation(context.TODO(), clientset, veleroClient, util.PodNamespace) - if err != nil { - return nil, errors.Wrap(err, "failed to find backup store location") - } if bsl == nil { return nil, errors.New("no backup store location found") } diff --git a/pkg/reporting/app_test.go b/pkg/reporting/app_test.go index 60af007b4a..1053a869bf 100644 --- a/pkg/reporting/app_test.go +++ b/pkg/reporting/app_test.go @@ -11,13 +11,7 @@ import ( "github.com/replicatedhq/kots/pkg/store" mock_store "github.com/replicatedhq/kots/pkg/store/mock" velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" - velerofake "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/fake" - veleroclientv1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/fake" ) func Test_getSnapshotReport(t *testing.T) { @@ -28,30 +22,25 @@ func Test_getSnapshotReport(t *testing.T) { t.Setenv("POD_NAMESPACE", "default") testVeleroNamespace := "velero" - veleroNamespaceConfigmap := &corev1.ConfigMap{ + testBsl := &velerov1.BackupStorageLocation{ ObjectMeta: metav1.ObjectMeta{ - Name: "kotsadm-velero-namespace", - }, - Data: map[string]string{ - "veleroNamespace": testVeleroNamespace, - }, - } - veleroDeployment := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: "velero", + Name: "default", Namespace: testVeleroNamespace, }, + Spec: velerov1.BackupStorageLocationSpec{ + Provider: "aws", + Default: true, + }, } testAppID := "test-app-id" testClusterID := "test-cluster-id" type args struct { - kotsStore store.Store - clientset kubernetes.Interface - veleroClient veleroclientv1.VeleroV1Interface - appID string - clusterID string + kotsStore store.Store + bsl *velerov1.BackupStorageLocation + appID string + clusterID string } tests := []struct { name string @@ -64,10 +53,7 @@ func Test_getSnapshotReport(t *testing.T) { name: "happy path with schedule and ttl", args: args{ kotsStore: mockStore, - clientset: fake.NewSimpleClientset(veleroNamespaceConfigmap, veleroDeployment), - veleroClient: velerofake.NewSimpleClientset( - backupStorageLocationWithProvider(testVeleroNamespace, "aws"), - ).VeleroV1(), + bsl: testBsl, appID: testAppID, clusterID: testClusterID, }, @@ -97,10 +83,7 @@ func Test_getSnapshotReport(t *testing.T) { name: "happy path with default ttl only", args: args{ kotsStore: mockStore, - clientset: fake.NewSimpleClientset(veleroNamespaceConfigmap, veleroDeployment), - veleroClient: velerofake.NewSimpleClientset( - backupStorageLocationWithProvider(testVeleroNamespace, "aws"), - ).VeleroV1(), + bsl: testBsl, appID: testAppID, clusterID: testClusterID, }, @@ -129,11 +112,10 @@ func Test_getSnapshotReport(t *testing.T) { { name: "no backup storage location", args: args{ - kotsStore: mockStore, - clientset: fake.NewSimpleClientset(veleroNamespaceConfigmap, veleroDeployment), - veleroClient: velerofake.NewSimpleClientset().VeleroV1(), - appID: testAppID, - clusterID: testClusterID, + kotsStore: mockStore, + bsl: nil, + appID: testAppID, + clusterID: testClusterID, }, mockStoreExpectations: func() {}, wantErr: true, @@ -142,10 +124,7 @@ func Test_getSnapshotReport(t *testing.T) { name: "failed to list clusters", args: args{ kotsStore: mockStore, - clientset: fake.NewSimpleClientset(veleroNamespaceConfigmap, veleroDeployment), - veleroClient: velerofake.NewSimpleClientset( - backupStorageLocationWithProvider(testVeleroNamespace, "aws"), - ).VeleroV1(), + bsl: testBsl, appID: testAppID, clusterID: testClusterID, }, @@ -158,10 +137,7 @@ func Test_getSnapshotReport(t *testing.T) { name: "failed to get app", args: args{ kotsStore: mockStore, - clientset: fake.NewSimpleClientset(veleroNamespaceConfigmap, veleroDeployment), - veleroClient: velerofake.NewSimpleClientset( - backupStorageLocationWithProvider(testVeleroNamespace, "aws"), - ).VeleroV1(), + bsl: testBsl, appID: testAppID, clusterID: testClusterID, }, @@ -181,7 +157,7 @@ func Test_getSnapshotReport(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.mockStoreExpectations() - got, err := getSnapshotReport(tt.args.kotsStore, tt.args.clientset, tt.args.veleroClient, tt.args.appID, tt.args.clusterID) + got, err := getSnapshotReport(tt.args.kotsStore, tt.args.bsl, tt.args.appID, tt.args.clusterID) if (err != nil) != tt.wantErr { t.Errorf("getSnapshotReport() error = %v, wantErr %v", err, tt.wantErr) return @@ -192,16 +168,3 @@ func Test_getSnapshotReport(t *testing.T) { }) } } - -func backupStorageLocationWithProvider(namespace string, provider string) *velerov1.BackupStorageLocation { - return &velerov1.BackupStorageLocation{ - ObjectMeta: metav1.ObjectMeta{ - Name: "default", - Namespace: namespace, - }, - Spec: velerov1.BackupStorageLocationSpec{ - Provider: provider, - Default: true, - }, - } -} diff --git a/pkg/snapshot/store_test.go b/pkg/snapshot/store_test.go index 37dfe64137..5443527401 100644 --- a/pkg/snapshot/store_test.go +++ b/pkg/snapshot/store_test.go @@ -2,13 +2,19 @@ package snapshot import ( "context" + "reflect" "testing" "github.com/replicatedhq/kots/pkg/snapshot/types" "github.com/stretchr/testify/require" + velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + velerofake "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/fake" + veleroclientv1 "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned/typed/velero/v1" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/kubernetes/fake" testclient "k8s.io/client-go/kubernetes/fake" "k8s.io/utils/pointer" ) @@ -510,3 +516,85 @@ func Test_isMinioMigration(t *testing.T) { }) } } + +func TestFindBackupStoreLocation(t *testing.T) { + + testVeleroNamespace := "velero" + testBsl := &velerov1.BackupStorageLocation{ + ObjectMeta: metav1.ObjectMeta{ + Name: "default", + Namespace: testVeleroNamespace, + }, + Spec: velerov1.BackupStorageLocationSpec{ + Provider: "aws", + Default: true, + }, + } + veleroNamespaceConfigmap := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: "kotsadm-velero-namespace", + }, + Data: map[string]string{ + "veleroNamespace": testVeleroNamespace, + }, + } + veleroDeployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: "velero", + Namespace: testVeleroNamespace, + }, + } + + type args struct { + clientset kubernetes.Interface + veleroClient veleroclientv1.VeleroV1Interface + kotsadmNamespace string + } + tests := []struct { + name string + args args + want *velerov1.BackupStorageLocation + wantErr bool + }{ + { + name: "backup store location found", + args: args{ + clientset: fake.NewSimpleClientset(veleroNamespaceConfigmap, veleroDeployment), + veleroClient: velerofake.NewSimpleClientset(testBsl).VeleroV1(), + kotsadmNamespace: "default", + }, + want: testBsl, + }, + { + name: "return nil if no backup store location found", + args: args{ + clientset: fake.NewSimpleClientset(veleroNamespaceConfigmap, veleroDeployment), + veleroClient: velerofake.NewSimpleClientset().VeleroV1(), + kotsadmNamespace: "default", + }, + want: nil, + }, + { + name: "return nil if no velero deployment found", + args: args{ + clientset: fake.NewSimpleClientset(veleroNamespaceConfigmap), + veleroClient: velerofake.NewSimpleClientset(testBsl).VeleroV1(), + kotsadmNamespace: "default", + }, + want: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + got, err := FindBackupStoreLocation(ctx, tt.args.clientset, tt.args.veleroClient, tt.args.kotsadmNamespace) + if (err != nil) != tt.wantErr { + t.Errorf("FindBackupStoreLocation() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("FindBackupStoreLocation() = %v, want %v", got, tt.want) + } + }) + } +}