mirror of
https://github.com/vmware-tanzu/velero.git
synced 2025-12-23 06:15:21 +00:00
Merge pull request #9379 from Lyndon-Li/repo-static-info-provider
Some checks failed
Run the E2E test on kind / get-go-version (push) Failing after 1m6s
Run the E2E test on kind / build (push) Has been skipped
Run the E2E test on kind / setup-test-matrix (push) Successful in 2s
Run the E2E test on kind / run-e2e-test (push) Has been skipped
Main CI / get-go-version (push) Failing after 10s
Main CI / Build (push) Has been skipped
Close stale issues and PRs / stale (push) Successful in 13s
Trivy Nightly Scan / Trivy nightly scan (velero, main) (push) Failing after 7m58s
Trivy Nightly Scan / Trivy nightly scan (velero-plugin-for-aws, main) (push) Failing after 1m41s
Trivy Nightly Scan / Trivy nightly scan (velero-plugin-for-gcp, main) (push) Failing after 1m13s
Trivy Nightly Scan / Trivy nightly scan (velero-plugin-for-microsoft-azure, main) (push) Failing after 1m0s
Some checks failed
Run the E2E test on kind / get-go-version (push) Failing after 1m6s
Run the E2E test on kind / build (push) Has been skipped
Run the E2E test on kind / setup-test-matrix (push) Successful in 2s
Run the E2E test on kind / run-e2e-test (push) Has been skipped
Main CI / get-go-version (push) Failing after 10s
Main CI / Build (push) Has been skipped
Close stale issues and PRs / stale (push) Successful in 13s
Trivy Nightly Scan / Trivy nightly scan (velero, main) (push) Failing after 7m58s
Trivy Nightly Scan / Trivy nightly scan (velero-plugin-for-aws, main) (push) Failing after 1m41s
Trivy Nightly Scan / Trivy nightly scan (velero-plugin-for-gcp, main) (push) Failing after 1m13s
Trivy Nightly Scan / Trivy nightly scan (velero-plugin-for-microsoft-azure, main) (push) Failing after 1m0s
Repo provider interface refactor for repo static configuration
This commit is contained in:
1
changelogs/unreleased/9379-Lyndon-Li
Normal file
1
changelogs/unreleased/9379-Lyndon-Li
Normal file
@@ -0,0 +1 @@
|
||||
Refactor repo provider interface for static configuration
|
||||
@@ -60,7 +60,19 @@ type Manager interface {
|
||||
BatchForget(context.Context, *velerov1api.BackupRepository, []string) []error
|
||||
|
||||
// DefaultMaintenanceFrequency returns the default maintenance frequency from the specific repo
|
||||
DefaultMaintenanceFrequency(repo *velerov1api.BackupRepository) (time.Duration, error)
|
||||
DefaultMaintenanceFrequency(*velerov1api.BackupRepository) (time.Duration, error)
|
||||
|
||||
// ClientSideCacheLimit returns the max cache size required on client side
|
||||
ClientSideCacheLimit(*velerov1api.BackupRepository) (int64, error)
|
||||
}
|
||||
|
||||
// ConfigProvider defines the methods to get configurations of a backup repository
|
||||
type ConfigManager interface {
|
||||
// DefaultMaintenanceFrequency returns the default maintenance frequency from the specific repo
|
||||
DefaultMaintenanceFrequency(string) (time.Duration, error)
|
||||
|
||||
// ClientSideCacheLimit returns the max cache size required on client side
|
||||
ClientSideCacheLimit(string, map[string]string) (int64, error)
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
@@ -74,6 +86,11 @@ type manager struct {
|
||||
log logrus.FieldLogger
|
||||
}
|
||||
|
||||
type configManager struct {
|
||||
providers map[string]provider.ConfigProvider
|
||||
log logrus.FieldLogger
|
||||
}
|
||||
|
||||
// NewManager create a new repository manager.
|
||||
func NewManager(
|
||||
namespace string,
|
||||
@@ -101,6 +118,20 @@ func NewManager(
|
||||
return mgr
|
||||
}
|
||||
|
||||
// NewConfigManager create a new repository config manager.
|
||||
func NewConfigManager(
|
||||
log logrus.FieldLogger,
|
||||
) ConfigManager {
|
||||
mgr := &configManager{
|
||||
providers: map[string]provider.ConfigProvider{},
|
||||
log: log,
|
||||
}
|
||||
|
||||
mgr.providers[velerov1api.BackupRepositoryTypeKopia] = provider.NewUnifiedRepoConfigProvider(velerov1api.BackupRepositoryTypeKopia, mgr.log)
|
||||
|
||||
return mgr
|
||||
}
|
||||
|
||||
func (m *manager) InitRepo(repo *velerov1api.BackupRepository) error {
|
||||
m.repoLocker.LockExclusive(repo.Name)
|
||||
defer m.repoLocker.UnlockExclusive(repo.Name)
|
||||
@@ -227,12 +258,16 @@ func (m *manager) DefaultMaintenanceFrequency(repo *velerov1api.BackupRepository
|
||||
return 0, errors.WithStack(err)
|
||||
}
|
||||
|
||||
param, err := m.assembleRepoParam(repo)
|
||||
return prd.DefaultMaintenanceFrequency(), nil
|
||||
}
|
||||
|
||||
func (m *manager) ClientSideCacheLimit(repo *velerov1api.BackupRepository) (int64, error) {
|
||||
prd, err := m.getRepositoryProvider(repo)
|
||||
if err != nil {
|
||||
return 0, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return prd.DefaultMaintenanceFrequency(context.Background(), param), nil
|
||||
return prd.ClientSideCacheLimit(repo.Spec.RepositoryConfig), nil
|
||||
}
|
||||
|
||||
func (m *manager) getRepositoryProvider(repo *velerov1api.BackupRepository) (provider.Provider, error) {
|
||||
@@ -256,3 +291,30 @@ func (m *manager) assembleRepoParam(repo *velerov1api.BackupRepository) (provide
|
||||
BackupRepo: repo,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (cm *configManager) DefaultMaintenanceFrequency(repoType string) (time.Duration, error) {
|
||||
prd, err := cm.getRepositoryProvider(repoType)
|
||||
if err != nil {
|
||||
return 0, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return prd.DefaultMaintenanceFrequency(), nil
|
||||
}
|
||||
|
||||
func (cm *configManager) ClientSideCacheLimit(repoType string, repoOption map[string]string) (int64, error) {
|
||||
prd, err := cm.getRepositoryProvider(repoType)
|
||||
if err != nil {
|
||||
return 0, errors.WithStack(err)
|
||||
}
|
||||
|
||||
return prd.ClientSideCacheLimit(repoOption), nil
|
||||
}
|
||||
|
||||
func (cm *configManager) getRepositoryProvider(repoType string) (provider.ConfigProvider, error) {
|
||||
switch repoType {
|
||||
case velerov1api.BackupRepositoryTypeKopia:
|
||||
return cm.providers[velerov1api.BackupRepositoryTypeKopia], nil
|
||||
default:
|
||||
return nil, fmt.Errorf("failed to get provider for repository %s", repoType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,3 +47,20 @@ func TestGetRepositoryProvider(t *testing.T) {
|
||||
_, err = mgr.getRepositoryProvider(repo)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestGetRepositoryConfigProvider(t *testing.T) {
|
||||
mgr := NewConfigManager(nil).(*configManager)
|
||||
|
||||
// empty repository type
|
||||
_, err := mgr.getRepositoryProvider("")
|
||||
require.Error(t, err)
|
||||
|
||||
// valid repository type
|
||||
provider, err := mgr.getRepositoryProvider(velerov1.BackupRepositoryTypeKopia)
|
||||
require.NoError(t, err)
|
||||
assert.NotNil(t, provider)
|
||||
|
||||
// invalid repository type
|
||||
_, err = mgr.getRepositoryProvider(velerov1.BackupRepositoryTypeRestic)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
84
pkg/repository/mocks/ConfigManager.go
Normal file
84
pkg/repository/mocks/ConfigManager.go
Normal file
@@ -0,0 +1,84 @@
|
||||
// Code generated by mockery v2.53.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
time "time"
|
||||
)
|
||||
|
||||
// ConfigManager is an autogenerated mock type for the ConfigManager type
|
||||
type ConfigManager struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// ClientSideCacheLimit provides a mock function with given fields: repoType, repoOption
|
||||
func (_m *ConfigManager) ClientSideCacheLimit(repoType string, repoOption map[string]string) (int64, error) {
|
||||
ret := _m.Called(repoType, repoOption)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ClientSideCacheLimit")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(string, map[string]string) (int64, error)); ok {
|
||||
return rf(repoType, repoOption)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(string, map[string]string) int64); ok {
|
||||
r0 = rf(repoType, repoOption)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(string, map[string]string) error); ok {
|
||||
r1 = rf(repoType, repoOption)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// DefaultMaintenanceFrequency provides a mock function with given fields: repoType
|
||||
func (_m *ConfigManager) DefaultMaintenanceFrequency(repoType string) (time.Duration, error) {
|
||||
ret := _m.Called(repoType)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DefaultMaintenanceFrequency")
|
||||
}
|
||||
|
||||
var r0 time.Duration
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(string) (time.Duration, error)); ok {
|
||||
return rf(repoType)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(string) time.Duration); ok {
|
||||
r0 = rf(repoType)
|
||||
} else {
|
||||
r0 = ret.Get(0).(time.Duration)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(repoType)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// NewConfigManager creates a new instance of ConfigManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
// The first argument is typically a *testing.T value.
|
||||
func NewConfigManager(t interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}) *ConfigManager {
|
||||
mock := &ConfigManager{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.39.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.2. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
@@ -37,6 +37,34 @@ func (_m *Manager) BatchForget(_a0 context.Context, _a1 *v1.BackupRepository, _a
|
||||
return r0
|
||||
}
|
||||
|
||||
// ClientSideCacheLimit provides a mock function with given fields: _a0
|
||||
func (_m *Manager) ClientSideCacheLimit(_a0 *v1.BackupRepository) (int64, error) {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for ClientSideCacheLimit")
|
||||
}
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(*v1.BackupRepository) (int64, error)); ok {
|
||||
return rf(_a0)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(*v1.BackupRepository) int64); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(*v1.BackupRepository) error); ok {
|
||||
r1 = rf(_a0)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ConnectToRepo provides a mock function with given fields: repo
|
||||
func (_m *Manager) ConnectToRepo(repo *v1.BackupRepository) error {
|
||||
ret := _m.Called(repo)
|
||||
@@ -55,9 +83,9 @@ func (_m *Manager) ConnectToRepo(repo *v1.BackupRepository) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// DefaultMaintenanceFrequency provides a mock function with given fields: repo
|
||||
func (_m *Manager) DefaultMaintenanceFrequency(repo *v1.BackupRepository) (time.Duration, error) {
|
||||
ret := _m.Called(repo)
|
||||
// DefaultMaintenanceFrequency provides a mock function with given fields: _a0
|
||||
func (_m *Manager) DefaultMaintenanceFrequency(_a0 *v1.BackupRepository) (time.Duration, error) {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for DefaultMaintenanceFrequency")
|
||||
@@ -66,16 +94,16 @@ func (_m *Manager) DefaultMaintenanceFrequency(repo *v1.BackupRepository) (time.
|
||||
var r0 time.Duration
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(*v1.BackupRepository) (time.Duration, error)); ok {
|
||||
return rf(repo)
|
||||
return rf(_a0)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(*v1.BackupRepository) time.Duration); ok {
|
||||
r0 = rf(repo)
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
r0 = ret.Get(0).(time.Duration)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(*v1.BackupRepository) error); ok {
|
||||
r1 = rf(repo)
|
||||
r1 = rf(_a0)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ type RepoParam struct {
|
||||
|
||||
// Provider defines the methods to manipulate a backup repository
|
||||
type Provider interface {
|
||||
ConfigProvider
|
||||
|
||||
// InitRepo is to initialize a repository from a new storage place
|
||||
InitRepo(ctx context.Context, param RepoParam) error
|
||||
|
||||
@@ -60,7 +62,13 @@ type Provider interface {
|
||||
|
||||
// BatchForget is to delete a list of snapshots from the repository
|
||||
BatchForget(ctx context.Context, snapshotIDs []string, param RepoParam) []error
|
||||
|
||||
// DefaultMaintenanceFrequency returns the default frequency to run maintenance
|
||||
DefaultMaintenanceFrequency(ctx context.Context, param RepoParam) time.Duration
|
||||
}
|
||||
|
||||
// ConfigProvider defines the methods to get configurations of a backup repository
|
||||
type ConfigProvider interface {
|
||||
// DefaultMaintenanceFrequency returns the default frequency to run maintenance
|
||||
DefaultMaintenanceFrequency() time.Duration
|
||||
|
||||
// ClientSideCacheLimit returns the max cache size required on client side
|
||||
ClientSideCacheLimit(repoOption map[string]string) int64
|
||||
}
|
||||
|
||||
@@ -90,6 +90,10 @@ func (r *resticRepositoryProvider) BatchForget(ctx context.Context, snapshotIDs
|
||||
return errs
|
||||
}
|
||||
|
||||
func (r *resticRepositoryProvider) DefaultMaintenanceFrequency(ctx context.Context, param RepoParam) time.Duration {
|
||||
func (r *resticRepositoryProvider) DefaultMaintenanceFrequency() time.Duration {
|
||||
return r.svc.DefaultMaintenanceFrequency()
|
||||
}
|
||||
|
||||
func (r *resticRepositoryProvider) ClientSideCacheLimit(repoOption map[string]string) int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -46,6 +46,12 @@ type unifiedRepoProvider struct {
|
||||
log logrus.FieldLogger
|
||||
}
|
||||
|
||||
type unifiedRepoConfigProvider struct {
|
||||
repoService udmrepo.BackupRepoService
|
||||
repoBackend string
|
||||
log logrus.FieldLogger
|
||||
}
|
||||
|
||||
// this func is assigned to a package-level variable so it can be
|
||||
// replaced when unit-testing
|
||||
var getS3Credentials = repoconfig.GetS3Credentials
|
||||
@@ -86,9 +92,18 @@ func NewUnifiedRepoProvider(
|
||||
return &repo
|
||||
}
|
||||
|
||||
func GetUnifiedRepoClientSideCacheLimit(repoOption map[string]string, repoBackend string, log logrus.FieldLogger) int64 {
|
||||
repoService := createRepoService(repoBackend, log)
|
||||
return repoService.ClientSideCacheLimit(repoOption)
|
||||
func NewUnifiedRepoConfigProvider(
|
||||
repoBackend string,
|
||||
log logrus.FieldLogger,
|
||||
) ConfigProvider {
|
||||
repo := unifiedRepoConfigProvider{
|
||||
repoBackend: repoBackend,
|
||||
log: log,
|
||||
}
|
||||
|
||||
repo.repoService = createRepoService(repoBackend, log)
|
||||
|
||||
return &repo
|
||||
}
|
||||
|
||||
func (urp *unifiedRepoProvider) InitRepo(ctx context.Context, param RepoParam) error {
|
||||
@@ -375,10 +390,14 @@ func (urp *unifiedRepoProvider) BatchForget(ctx context.Context, snapshotIDs []s
|
||||
return errs
|
||||
}
|
||||
|
||||
func (urp *unifiedRepoProvider) DefaultMaintenanceFrequency(ctx context.Context, param RepoParam) time.Duration {
|
||||
func (urp *unifiedRepoProvider) DefaultMaintenanceFrequency() time.Duration {
|
||||
return urp.repoService.DefaultMaintenanceFrequency()
|
||||
}
|
||||
|
||||
func (urp *unifiedRepoProvider) ClientSideCacheLimit(repoOption map[string]string) int64 {
|
||||
return urp.repoService.ClientSideCacheLimit(repoOption)
|
||||
}
|
||||
|
||||
func (urp *unifiedRepoProvider) GetPassword(param any) (string, error) {
|
||||
_, ok := param.(RepoParam)
|
||||
if !ok {
|
||||
@@ -429,6 +448,14 @@ func (urp *unifiedRepoProvider) GetStoreOptions(param any) (map[string]string, e
|
||||
return storeOptions, nil
|
||||
}
|
||||
|
||||
func (urcp *unifiedRepoConfigProvider) DefaultMaintenanceFrequency() time.Duration {
|
||||
return urcp.repoService.DefaultMaintenanceFrequency()
|
||||
}
|
||||
|
||||
func (urcp *unifiedRepoConfigProvider) ClientSideCacheLimit(repoOption map[string]string) int64 {
|
||||
return urcp.repoService.ClientSideCacheLimit(repoOption)
|
||||
}
|
||||
|
||||
func getRepoPassword(secretStore credentials.SecretStore) (string, error) {
|
||||
if secretStore == nil {
|
||||
return "", errors.New("invalid credentials interface")
|
||||
|
||||
Reference in New Issue
Block a user