mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-01-03 11:45:20 +00:00
1
changelogs/unreleased/6394-qiuming-best
Normal file
1
changelogs/unreleased/6394-qiuming-best
Normal file
@@ -0,0 +1 @@
|
||||
Add UT for pkg/discovery
|
||||
@@ -206,7 +206,7 @@ func (r *DataUploadReconciler) runCancelableDataUpload(ctx context.Context, du *
|
||||
OnProgress: r.OnDataUploadProgress,
|
||||
}
|
||||
|
||||
fsBackup, err := r.dataPathMgr.CreateFileSystemBR(du.Name, dataUploadDownloadRequestor, ctx, r.client, du.Namespace, callbacks, log) // VAE
|
||||
fsBackup, err := r.dataPathMgr.CreateFileSystemBR(du.Name, dataUploadDownloadRequestor, ctx, r.client, du.Namespace, callbacks, log)
|
||||
if err != nil {
|
||||
if err == datapath.ConcurrentLimitExceed {
|
||||
log.Info("runCancelableDataUpload is concurrent limited")
|
||||
|
||||
@@ -18,13 +18,20 @@ package discovery
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/version"
|
||||
"k8s.io/client-go/discovery/fake"
|
||||
clientgotesting "k8s.io/client-go/testing"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
discoverymocks "github.com/vmware-tanzu/velero/pkg/discovery/mocks"
|
||||
"github.com/vmware-tanzu/velero/pkg/features"
|
||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/logging"
|
||||
)
|
||||
@@ -197,5 +204,462 @@ func TestRefreshServerPreferredResources(t *testing.T) {
|
||||
assert.Equal(t, test.resourceList, resources)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestHelper_ResourceFor(t *testing.T) {
|
||||
fakeDiscoveryClient := &fake.FakeDiscovery{
|
||||
Fake: &clientgotesting.Fake{},
|
||||
}
|
||||
fakeDiscoveryClient.Resources = []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "pods",
|
||||
Kind: "Pod",
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Verbs: []string{"create", "get", "list"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
h := &helper{
|
||||
discoveryClient: fakeDiscoveryClient,
|
||||
lock: sync.RWMutex{},
|
||||
mapper: nil,
|
||||
resources: fakeDiscoveryClient.Resources,
|
||||
resourcesMap: make(map[schema.GroupVersionResource]metav1.APIResource),
|
||||
serverVersion: &version.Info{Major: "1", Minor: "22", GitVersion: "v1.22.1"},
|
||||
}
|
||||
|
||||
for _, resourceList := range h.resources {
|
||||
for _, resource := range resourceList.APIResources {
|
||||
gvr := schema.GroupVersionResource{
|
||||
Group: resource.Group,
|
||||
Version: resource.Version,
|
||||
Resource: resource.Name,
|
||||
}
|
||||
h.resourcesMap[gvr] = resource
|
||||
}
|
||||
}
|
||||
pvGVR := schema.GroupVersionResource{
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Resource: "pods",
|
||||
}
|
||||
h.mapper = &velerotest.FakeMapper{Resources: map[schema.GroupVersionResource]schema.GroupVersionResource{pvGVR: pvGVR}}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
err string
|
||||
input *schema.GroupVersionResource
|
||||
isNotFoundRes bool
|
||||
expectedGVR *schema.GroupVersionResource
|
||||
expectedAPIResource *metav1.APIResource
|
||||
}{
|
||||
{
|
||||
name: "Found resource",
|
||||
input: &schema.GroupVersionResource{
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Resource: "pods",
|
||||
},
|
||||
expectedAPIResource: &metav1.APIResource{
|
||||
Name: "pods",
|
||||
Kind: "Pod",
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Verbs: []string{"create", "get", "list"},
|
||||
},
|
||||
expectedGVR: &schema.GroupVersionResource{
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Resource: "pods",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Error to found resource",
|
||||
input: &schema.GroupVersionResource{
|
||||
Group: "",
|
||||
Version: "v2",
|
||||
Resource: "pods",
|
||||
},
|
||||
err: "invalid resource",
|
||||
expectedGVR: &schema.GroupVersionResource{},
|
||||
expectedAPIResource: &metav1.APIResource{},
|
||||
},
|
||||
{
|
||||
name: "Error to found api resource",
|
||||
input: &schema.GroupVersionResource{
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Resource: "pods",
|
||||
},
|
||||
isNotFoundRes: true,
|
||||
err: "APIResource not found for GroupVersionResource",
|
||||
expectedGVR: &schema.GroupVersionResource{},
|
||||
expectedAPIResource: &metav1.APIResource{},
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.isNotFoundRes {
|
||||
h.resourcesMap = nil
|
||||
}
|
||||
gvr, apiResource, err := h.ResourceFor(*tc.input)
|
||||
if tc.err == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.Contains(t, err.Error(), tc.err)
|
||||
}
|
||||
assert.Equal(t, *tc.expectedGVR, gvr)
|
||||
assert.Equal(t, *tc.expectedAPIResource, apiResource)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelper_KindFor(t *testing.T) {
|
||||
fakeDiscoveryClient := &fake.FakeDiscovery{
|
||||
Fake: &clientgotesting.Fake{},
|
||||
}
|
||||
fakeDiscoveryClient.Resources = []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "pods",
|
||||
Kind: "Pod",
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Verbs: []string{"create", "get", "list"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
pvGVK := schema.GroupVersionKind{
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Kind: "Deployment",
|
||||
}
|
||||
pvAPIRes := metav1.APIResource{
|
||||
Name: "deployments",
|
||||
Kind: "Deployment",
|
||||
Group: "apps",
|
||||
Version: "v1",
|
||||
Verbs: []string{"create", "get", "list"},
|
||||
}
|
||||
|
||||
h := &helper{
|
||||
discoveryClient: fakeDiscoveryClient,
|
||||
lock: sync.RWMutex{},
|
||||
resources: fakeDiscoveryClient.Resources,
|
||||
resourcesMap: make(map[schema.GroupVersionResource]metav1.APIResource),
|
||||
serverVersion: &version.Info{Major: "1", Minor: "22", GitVersion: "v1.22.1"},
|
||||
}
|
||||
|
||||
h.kindMap = map[schema.GroupVersionKind]metav1.APIResource{pvGVK: pvAPIRes}
|
||||
h.mapper = &velerotest.FakeMapper{KindToPluralResource: map[schema.GroupVersionKind]schema.GroupVersionResource{}}
|
||||
for _, resourceList := range h.resources {
|
||||
for _, resource := range resourceList.APIResources {
|
||||
gvr := schema.GroupVersionResource{
|
||||
Group: resource.Group,
|
||||
Version: resource.Version,
|
||||
Resource: resource.Name,
|
||||
}
|
||||
h.resourcesMap[gvr] = resource
|
||||
}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
err string
|
||||
input *schema.GroupVersionKind
|
||||
isNotFoundRes bool
|
||||
expectedGVR *schema.GroupVersionResource
|
||||
expectedAPIResource *metav1.APIResource
|
||||
}{
|
||||
{
|
||||
name: "Found resource",
|
||||
input: &schema.GroupVersionKind{
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
expectedAPIResource: &metav1.APIResource{
|
||||
Name: "deployments",
|
||||
Kind: "Deployment",
|
||||
Group: "apps",
|
||||
Version: "v1",
|
||||
Verbs: []string{"create", "get", "list"},
|
||||
},
|
||||
expectedGVR: &schema.GroupVersionResource{
|
||||
Group: "apps",
|
||||
Version: "v1",
|
||||
Resource: "deployments",
|
||||
},
|
||||
}, {
|
||||
name: "Not found resource",
|
||||
input: &schema.GroupVersionKind{
|
||||
Group: "",
|
||||
Version: "v2",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
expectedAPIResource: &metav1.APIResource{},
|
||||
expectedGVR: &schema.GroupVersionResource{},
|
||||
err: "no matches for kind",
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
gvr, apiResource, err := h.KindFor(*tc.input)
|
||||
if tc.err == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.Contains(t, err.Error(), tc.err)
|
||||
}
|
||||
assert.Equal(t, *tc.expectedGVR, gvr)
|
||||
assert.Equal(t, *tc.expectedAPIResource, apiResource)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelper_Refresh(t *testing.T) {
|
||||
testCases := []struct {
|
||||
description string
|
||||
features string
|
||||
groupResources []*metav1.APIResourceList
|
||||
serverGroups []*metav1.APIGroup
|
||||
expectedErr error
|
||||
expectedResource metav1.APIResource
|
||||
}{
|
||||
{
|
||||
description: "Default case - Resource found",
|
||||
groupResources: []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "pods",
|
||||
Kind: "Pod",
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Verbs: []string{"get", "list", "create"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
serverGroups: []*metav1.APIGroup{
|
||||
{
|
||||
Name: "group1",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{
|
||||
GroupVersion: "v1",
|
||||
Version: "v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: nil,
|
||||
expectedResource: metav1.APIResource{
|
||||
Name: "pods",
|
||||
Kind: "Pod",
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Verbs: []string{"get", "list", "create"},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "Feature flag enabled - ServerGroupsAndResources",
|
||||
features: velerov1api.APIGroupVersionsFeatureFlag,
|
||||
groupResources: []*metav1.APIResourceList{},
|
||||
serverGroups: []*metav1.APIGroup{
|
||||
{
|
||||
Name: "group1",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{
|
||||
GroupVersion: "v1",
|
||||
Version: "v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedErr: nil,
|
||||
expectedResource: metav1.APIResource{
|
||||
Name: "pods",
|
||||
Kind: "Pod",
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Verbs: []string{"get", "list", "create"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
fakeDiscoveryClient := &fake.FakeDiscovery{
|
||||
Fake: &clientgotesting.Fake{},
|
||||
}
|
||||
fakeDiscoveryClient.Resources = []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "pods",
|
||||
Kind: "Pod",
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Verbs: []string{"create", "get", "list"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.description, func(t *testing.T) {
|
||||
h := &helper{
|
||||
lock: sync.RWMutex{},
|
||||
discoveryClient: fakeDiscoveryClient,
|
||||
logger: logrus.New(),
|
||||
}
|
||||
// Set feature flags
|
||||
if testCase.features != "" {
|
||||
features.Enable(testCase.features)
|
||||
}
|
||||
err := h.Refresh()
|
||||
assert.Equal(t, testCase.expectedErr, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelper_refreshServerPreferredResources(t *testing.T) {
|
||||
apiList := []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "pods",
|
||||
Kind: "Pod",
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Verbs: []string{"create", "get", "list"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
isGetResError bool
|
||||
}{
|
||||
{
|
||||
name: "success get preferred resources",
|
||||
},
|
||||
{
|
||||
name: "failed to get preferred resources",
|
||||
isGetResError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeClient := discoverymocks.NewServerResourcesInterface(t)
|
||||
|
||||
if tc.isGetResError {
|
||||
fakeClient.On("ServerPreferredResources").Return(nil, errors.New("Failed to discover preferred resources"))
|
||||
} else {
|
||||
fakeClient.On("ServerPreferredResources").Return(apiList, nil)
|
||||
}
|
||||
|
||||
resources, err := refreshServerPreferredResources(fakeClient, logrus.New())
|
||||
|
||||
if tc.isGetResError {
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, resources)
|
||||
} else {
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, resources)
|
||||
}
|
||||
|
||||
fakeClient.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelper_refreshServerGroupsAndResources(t *testing.T) {
|
||||
apiList := []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{
|
||||
Name: "pods",
|
||||
Kind: "Pod",
|
||||
Group: "",
|
||||
Version: "v1",
|
||||
Verbs: []string{"create", "get", "list"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
apiGroup := []*metav1.APIGroup{
|
||||
{
|
||||
Name: "group1",
|
||||
Versions: []metav1.GroupVersionForDiscovery{
|
||||
{
|
||||
GroupVersion: "v1",
|
||||
Version: "v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
isGetResError bool
|
||||
}{
|
||||
{
|
||||
name: "success get service groups and resouorces",
|
||||
},
|
||||
{
|
||||
name: "failed to service groups and resouorces",
|
||||
isGetResError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fakeClient := discoverymocks.NewServerResourcesInterface(t)
|
||||
|
||||
if tc.isGetResError {
|
||||
fakeClient.On("ServerGroupsAndResources").Return(nil, nil, errors.New("Failed to discover service groups and resouorces"))
|
||||
} else {
|
||||
fakeClient.On("ServerGroupsAndResources").Return(apiGroup, apiList, nil)
|
||||
}
|
||||
|
||||
serverGroups, serverResources, err := refreshServerGroupsAndResources(fakeClient, logrus.New())
|
||||
|
||||
if tc.isGetResError {
|
||||
assert.NotNil(t, err)
|
||||
assert.Nil(t, serverGroups)
|
||||
assert.Nil(t, serverResources)
|
||||
} else {
|
||||
assert.Nil(t, err)
|
||||
assert.NotNil(t, serverGroups)
|
||||
assert.NotNil(t, serverResources)
|
||||
}
|
||||
|
||||
fakeClient.AssertExpectations(t)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelper(t *testing.T) {
|
||||
fakeDiscoveryClient := &fake.FakeDiscovery{
|
||||
Fake: &clientgotesting.Fake{},
|
||||
}
|
||||
h, err := NewHelper(fakeDiscoveryClient, logrus.New())
|
||||
assert.Nil(t, err)
|
||||
// All below calls put together for the implementation are empty or just very simple, and just want to cover testing
|
||||
// If wanting to write unit tests for some functions could remove it and with writing new function alone
|
||||
h.Resources()
|
||||
h.APIGroups()
|
||||
h.ServerVersion()
|
||||
}
|
||||
|
||||
@@ -154,3 +154,84 @@ func NewHelper(t mockConstructorTestingTNewHelper) *Helper {
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
// serverResourcesInterface is an autogenerated mock type for the serverResourcesInterface type
|
||||
type serverResourcesInterface struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// ServerGroupsAndResources provides a mock function with given fields:
|
||||
func (_m *serverResourcesInterface) ServerGroupsAndResources() ([]*v1.APIGroup, []*v1.APIResourceList, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 []*v1.APIGroup
|
||||
var r1 []*v1.APIResourceList
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(0).(func() ([]*v1.APIGroup, []*v1.APIResourceList, error)); ok {
|
||||
return rf()
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func() []*v1.APIGroup); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*v1.APIGroup)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func() []*v1.APIResourceList); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
if ret.Get(1) != nil {
|
||||
r1 = ret.Get(1).([]*v1.APIResourceList)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(2).(func() error); ok {
|
||||
r2 = rf()
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// ServerPreferredResources provides a mock function with given fields:
|
||||
func (_m *serverResourcesInterface) ServerPreferredResources() ([]*v1.APIResourceList, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 []*v1.APIResourceList
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func() ([]*v1.APIResourceList, error)); ok {
|
||||
return rf()
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func() []*v1.APIResourceList); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*v1.APIResourceList)
|
||||
}
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTnewServerResourcesInterface interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewServerResourcesInterface creates a new instance of serverResourcesInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewServerResourcesInterface(t mockConstructorTestingTnewServerResourcesInterface) *serverResourcesInterface {
|
||||
mock := &serverResourcesInterface{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -19,13 +19,15 @@ package test
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
type FakeMapper struct {
|
||||
meta.RESTMapper
|
||||
AutoReturnResource bool
|
||||
Resources map[schema.GroupVersionResource]schema.GroupVersionResource
|
||||
AutoReturnResource bool
|
||||
Resources map[schema.GroupVersionResource]schema.GroupVersionResource
|
||||
KindToPluralResource map[schema.GroupVersionKind]schema.GroupVersionResource
|
||||
}
|
||||
|
||||
func (m *FakeMapper) ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error) {
|
||||
@@ -56,3 +58,36 @@ func (m *FakeMapper) ResourceFor(input schema.GroupVersionResource) (schema.Grou
|
||||
|
||||
return schema.GroupVersionResource{}, errors.Errorf("invalid resource %q", input.String())
|
||||
}
|
||||
|
||||
func (m *FakeMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*meta.RESTMapping, error) {
|
||||
potentialGVK := make([]schema.GroupVersionKind, 0)
|
||||
// Pick an appropriate version
|
||||
for _, version := range versions {
|
||||
if len(version) == 0 || version == runtime.APIVersionInternal {
|
||||
continue
|
||||
}
|
||||
currGVK := gk.WithVersion(version)
|
||||
if _, ok := m.KindToPluralResource[currGVK]; ok {
|
||||
potentialGVK = append(potentialGVK, currGVK)
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(potentialGVK) == 0 {
|
||||
return nil, &meta.NoKindMatchError{GroupKind: gk, SearchedVersions: versions}
|
||||
}
|
||||
|
||||
for _, gvk := range potentialGVK {
|
||||
//Ensure we have a REST mapping
|
||||
res, ok := m.KindToPluralResource[gvk]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
return &meta.RESTMapping{
|
||||
Resource: res,
|
||||
GroupVersionKind: gvk,
|
||||
Scope: meta.RESTScopeNamespace,
|
||||
}, nil
|
||||
}
|
||||
return nil, &meta.NoResourceMatchError{PartialResource: schema.GroupVersionResource{Group: gk.Group, Resource: gk.Kind}}
|
||||
}
|
||||
|
||||
@@ -268,12 +268,12 @@ func findPreviousSnapshotManifest(ctx context.Context, rep repo.Repository, sour
|
||||
for _, p := range man {
|
||||
log.Debugf("Found one snapshot %s, start time %v, incomplete %s, tags %v", p.ID, p.StartTime.ToTime(), p.IncompleteReason, p.Tags)
|
||||
|
||||
requestor, found := p.Tags[uploader.SnapshotRequestorTag]
|
||||
requester, found := p.Tags[uploader.SnapshotRequesterTag]
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
|
||||
if requestor != snapshotTags[uploader.SnapshotRequestorTag] {
|
||||
if requester != snapshotTags[uploader.SnapshotRequesterTag] {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -264,7 +264,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
Path: "/path/to/dir1",
|
||||
}
|
||||
snapshotTags := map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
}
|
||||
noLaterThan := fs.UTCTimestampFromTime(time.Now())
|
||||
@@ -299,7 +299,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
return []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value",
|
||||
"anotherCustomTag": "123",
|
||||
@@ -312,7 +312,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
expectedSnapshots: []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value",
|
||||
"anotherCustomTag": "123",
|
||||
@@ -330,7 +330,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
return []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value1",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -339,7 +339,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value2",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -351,7 +351,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
expectedSnapshots: []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value1",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -361,14 +361,14 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
// Snapshot with different requestor
|
||||
// Snapshot with different requester
|
||||
{
|
||||
name: "Snapshot with different requestor",
|
||||
name: "Snapshot with different requester",
|
||||
listSnapshotsFunc: func(ctx context.Context, rep repo.Repository, si snapshot.SourceInfo) ([]*snapshot.Manifest, error) {
|
||||
return []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user2",
|
||||
uploader.SnapshotRequesterTag: "user2",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value",
|
||||
"snapshotRequestor": "user2",
|
||||
@@ -387,7 +387,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
return []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader2",
|
||||
"otherTag": "value",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -406,7 +406,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
return []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -426,7 +426,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
return []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -446,7 +446,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
return []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value1",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -455,7 +455,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value2",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -466,7 +466,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
},
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value3",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -479,7 +479,7 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
expectedSnapshots: []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value3",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -490,14 +490,14 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
// Snapshot with manifest SnapshotRequestorTag not found
|
||||
// Snapshot with manifest SnapshotRequesterTag not found
|
||||
{
|
||||
name: "Snapshot with manifest SnapshotRequestorTag not found",
|
||||
name: "Snapshot with manifest SnapshotRequesterTag not found",
|
||||
listSnapshotsFunc: func(ctx context.Context, rep repo.Repository, si snapshot.SourceInfo) ([]*snapshot.Manifest, error) {
|
||||
return []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
"requestor": "user1",
|
||||
"requester": "user1",
|
||||
uploader.SnapshotUploaderTag: "uploader1",
|
||||
"otherTag": "value",
|
||||
"snapshotRequestor": "user1",
|
||||
@@ -510,14 +510,14 @@ func TestFindPreviousSnapshotManifest(t *testing.T) {
|
||||
expectedSnapshots: []*snapshot.Manifest{},
|
||||
expectedError: nil,
|
||||
},
|
||||
// Snapshot with manifest SnapshotRequestorTag not found
|
||||
// Snapshot with manifest SnapshotRequesterTag not found
|
||||
{
|
||||
name: "Snapshot with manifest SnapshotUploaderTag not found",
|
||||
listSnapshotsFunc: func(ctx context.Context, rep repo.Repository, si snapshot.SourceInfo) ([]*snapshot.Manifest, error) {
|
||||
return []*snapshot.Manifest{
|
||||
{
|
||||
Tags: map[string]string{
|
||||
uploader.SnapshotRequestorTag: "user1",
|
||||
uploader.SnapshotRequesterTag: "user1",
|
||||
"uploader": "uploader1",
|
||||
"otherTag": "value",
|
||||
"snapshotRequestor": "user1",
|
||||
|
||||
@@ -150,7 +150,7 @@ func (kp *kopiaProvider) RunBackup(
|
||||
if tags == nil {
|
||||
tags = make(map[string]string)
|
||||
}
|
||||
tags[uploader.SnapshotRequestorTag] = kp.requestorType
|
||||
tags[uploader.SnapshotRequesterTag] = kp.requestorType
|
||||
tags[uploader.SnapshotUploaderTag] = uploader.KopiaType
|
||||
|
||||
snapshotInfo, isSnapshotEmpty, err := BackupFunc(ctx, kpUploader, repoWriter, path, realSource, forceFull, parentSnapshot, tags, log)
|
||||
|
||||
@@ -65,7 +65,7 @@ func NewUploaderProvider(
|
||||
ctx context.Context,
|
||||
client client.Client,
|
||||
uploaderType string,
|
||||
requestorType string,
|
||||
requesterType string,
|
||||
repoIdentifier string,
|
||||
bsl *velerov1api.BackupStorageLocation,
|
||||
backupRepo *velerov1api.BackupRepository,
|
||||
@@ -73,15 +73,15 @@ func NewUploaderProvider(
|
||||
repoKeySelector *v1.SecretKeySelector,
|
||||
log logrus.FieldLogger,
|
||||
) (Provider, error) {
|
||||
if requestorType == "" {
|
||||
return nil, errors.New("requestor type is empty")
|
||||
if requesterType == "" {
|
||||
return nil, errors.New("requester type is empty")
|
||||
}
|
||||
|
||||
if credGetter.FromFile == nil {
|
||||
return nil, errors.New("uninitialized FileStore credentail is not supported")
|
||||
return nil, errors.New("uninitialized FileStore credential is not supported")
|
||||
}
|
||||
if uploaderType == uploader.KopiaType {
|
||||
return NewKopiaUploaderProvider(requestorType, ctx, credGetter, backupRepo, log)
|
||||
return NewKopiaUploaderProvider(requesterType, ctx, credGetter, backupRepo, log)
|
||||
} else {
|
||||
return NewResticUploaderProvider(repoIdentifier, bsl, credGetter, repoKeySelector, log)
|
||||
}
|
||||
|
||||
@@ -55,25 +55,25 @@ func TestNewUploaderProvider(t *testing.T) {
|
||||
Description: "When requestorType is empty, it should return an error",
|
||||
UploaderType: "kopia",
|
||||
RequestorType: "",
|
||||
ExpectedError: "requestor type is empty",
|
||||
ExpectedError: "requester type is empty",
|
||||
},
|
||||
{
|
||||
Description: "When FileStore credential is uninitialized, it should return an error",
|
||||
UploaderType: "kopia",
|
||||
RequestorType: "requestor",
|
||||
ExpectedError: "uninitialized FileStore credentail",
|
||||
RequestorType: "requester",
|
||||
ExpectedError: "uninitialized FileStore credential",
|
||||
},
|
||||
{
|
||||
Description: "When uploaderType is kopia, it should return a KopiaUploaderProvider",
|
||||
UploaderType: "kopia",
|
||||
RequestorType: "requestor",
|
||||
RequestorType: "requester",
|
||||
needFromFile: true,
|
||||
ExpectedError: "invalid credentials interface",
|
||||
},
|
||||
{
|
||||
Description: "When uploaderType is not kopia, it should return a ResticUploaderProvider",
|
||||
UploaderType: "restic",
|
||||
RequestorType: "requestor",
|
||||
RequestorType: "requester",
|
||||
needFromFile: true,
|
||||
ExpectedError: "",
|
||||
},
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
const (
|
||||
ResticType = "restic"
|
||||
KopiaType = "kopia"
|
||||
SnapshotRequestorTag = "snapshot-requestor"
|
||||
SnapshotRequesterTag = "snapshot-requester"
|
||||
SnapshotUploaderTag = "snapshot-uploader"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user