diff --git a/go.mod b/go.mod index bf00c8c6..7f46f87e 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/spf13/cobra v0.0.6 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.4.0 - github.com/vmware-tanzu/astrolabe v0.1.2-0.20201008235446-3a8d26a2c1bf + github.com/vmware-tanzu/astrolabe v0.1.2-0.20201114003729-394c01f13c75 github.com/vmware-tanzu/velero v1.5.1 k8s.io/api v0.18.4 k8s.io/apiextensions-apiserver v0.18.4 diff --git a/go.sum b/go.sum index 9a16ce76..756d212f 100644 --- a/go.sum +++ b/go.sum @@ -787,8 +787,8 @@ github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vishvananda/netlink v1.0.0/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= -github.com/vmware-tanzu/astrolabe v0.1.2-0.20201008235446-3a8d26a2c1bf h1:JCXrID2CiNOdEo9TN3Dae3EfcYCENv9i/YjXK7fDruo= -github.com/vmware-tanzu/astrolabe v0.1.2-0.20201008235446-3a8d26a2c1bf/go.mod h1:Af9uI95FSmiaKAiyUFa21rvFAeU195hIv7dMK3XnRag= +github.com/vmware-tanzu/astrolabe v0.1.2-0.20201114003729-394c01f13c75 h1:Us8oETgxuHdH+PAyzre0p3pWqFNsaO0v5yVpU2TwkT0= +github.com/vmware-tanzu/astrolabe v0.1.2-0.20201114003729-394c01f13c75/go.mod h1:Af9uI95FSmiaKAiyUFa21rvFAeU195hIv7dMK3XnRag= github.com/vmware-tanzu/velero v1.5.1 h1:PMcPfrhv91AfO/NPIWJDVUEql+DUixPnTjg+LTV95yI= github.com/vmware-tanzu/velero v1.5.1/go.mod h1:SIyHunlEyLVeKjWR34rv0mLeNVsH5wiR/EmQuUEo1/k= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= diff --git a/pkg/backupdriver/backup_driver_controller_base.go b/pkg/backupdriver/backup_driver_controller_base.go index a1defd1c..dc531791 100644 --- a/pkg/backupdriver/backup_driver_controller_base.go +++ b/pkg/backupdriver/backup_driver_controller_base.go @@ -20,6 +20,9 @@ import ( "context" "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/backuprepository" "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/constants" + "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/utils" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/client-go/informers/core/v1" "strings" "time" @@ -108,11 +111,14 @@ type backupDriverController struct { // Upload queue uploadQueue workqueue.RateLimitingInterface - // Snapshot queue + // Secret queue + secretQueue workqueue.RateLimitingInterface + + // DeleteSnapshot queue deleteSnapshotQueue workqueue.RateLimitingInterface - // Snapshot Lister + // DeleteSnapshot Lister deleteSnapshotLister backupdriverlisters.DeleteSnapshotLister - // Snapshot Synced + // DeleteSnapshot Synced deleteSnapshotSynced cache.InformerSynced // Map supervisor cluster snapshot CRs to guest cluster snapshot CRs @@ -168,8 +174,10 @@ func NewBackupDriverController( deleteSnapshotQueue := workqueue.NewNamedRateLimitingQueue(rateLimiter, "backup-driver-delete-snapshot-queue") uploadQueue := workqueue.NewNamedRateLimitingQueue(rateLimiter, "backup-driver-upload-queue") svcSnapshotQueue := workqueue.NewNamedRateLimitingQueue(rateLimiter, "backup-driver-svc-snapshot-queue") + secretQueue := workqueue.NewNamedRateLimitingQueue(rateLimiter, "backup-driver-secret-queue") var svcSnapshotMap map[string]string + var secretInformer v1.SecretInformer // Configure supervisor cluster queues and caches in the guest // We watch supervisor snapshot CRs for the upload status. If local mode is set, we do not have to watch for upload status @@ -179,6 +187,10 @@ func NewBackupDriverController( cacheSyncs = append(cacheSyncs, svcSnapshotInformer.Informer().HasSynced) + } else { + // Watch for Secret Changes only in Supervisor/Vanilla setup. + secretInformer = informerFactory.Core().V1().Secrets() + cacheSyncs = append(cacheSyncs, secretInformer.Informer().HasSynced) } ctrl := &backupDriverController{ @@ -204,6 +216,7 @@ func NewBackupDriverController( deleteSnapshotLister: deleteSnapshotInformer.Lister(), uploadQueue: uploadQueue, svcSnapshotQueue: svcSnapshotQueue, + secretQueue: secretQueue, cacheSyncs: cacheSyncs, svcSnapshotMap: svcSnapshotMap, } @@ -275,8 +288,8 @@ func NewBackupDriverController( resyncPeriod, ) - // Configure supervisor cluster informers in the guest if svcKubeConfig != nil { + // Configure supervisor cluster informers in the guest svcSnapshotInformer := svcBackupdriverInformerFactory.Backupdriver().V1alpha1().Snapshots() svcSnapshotInformer.Informer().AddEventHandlerWithResyncPeriod( cache.ResourceEventHandlerFuncs{ @@ -286,7 +299,18 @@ func NewBackupDriverController( }, resyncPeriod) } - + // Configure secret informer in Supervisor and Vanilla setup only. + if secretInformer != nil { + secretInformer.Informer().AddEventHandlerWithResyncPeriod( + cache.FilteringResourceEventHandler{ + FilterFunc: utils.GetVcConfigSecretFilterFunc(logger), + Handler: cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { ctrl.enqueueSecret(obj) }, + UpdateFunc: func(oldObj, newObj interface{}) { ctrl.enqueueSecret(newObj) }, + }, + }, + constants.DefaultSecretResyncPeriod) + } return ctrl } @@ -314,6 +338,7 @@ func (ctrl *backupDriverController) Run( defer ctrl.deleteSnapshotQueue.ShutDown() defer ctrl.uploadQueue.ShutDown() defer ctrl.svcSnapshotQueue.ShutDown() + defer ctrl.secretQueue.ShutDown() ctrl.logger.Infof("Starting backup driver controller") defer ctrl.logger.Infof("Shutting down backup driver controller") @@ -339,12 +364,71 @@ func (ctrl *backupDriverController) Run( if ctrl.svcKubeConfig != nil { go wait.Until(ctrl.svcSnapshotWorker, 0, stopCh) + } else { + go wait.Until(ctrl.secretWorker, 0, stopCh) } } <-stopCh } +func (ctrl *backupDriverController) secretWorker() { + ctrl.logger.Infof("secretWorker: Enter secretWorker") + + key, quit := ctrl.secretQueue.Get() + if quit { + return + } + defer ctrl.secretQueue.Done(key) + + if err := ctrl.syncSecretByKey(key.(string)); err != nil { + ctrl.secretQueue.AddRateLimited(key) + } else { + ctrl.secretQueue.Forget(key) + } +} + +func (ctrl *backupDriverController) syncSecretByKey(key string) error { + ctrl.logger.Infof("syncSecretByKey: Started Secret processing %s", key) + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + ctrl.logger.Errorf("Split meta namespace key of secret %s failed: %v", key, err) + return err + } + // Retrieve the latest Secret. + params := make(map[string]interface{}) + err = utils.RetrieveVcConfigSecret(params, nil, ctrl.logger) + if err != nil { + ctrl.logger.Errorf("Failed to retrieve the latest vc config secret") + return err + } + ctrl.logger.Infof("Successfully retrieved latest vSphere VC credentials.") + err = ctrl.snapManager.ReloadSnapshotManagerIvdPetmConfig(params) + if err != nil { + ctrl.logger.Errorf("Secret %s/%s Reload failed, err: %v", namespace, name, err) + return err + } + ctrl.logger.Infof("Successfully processed updates in vc configuration.") + return nil +} + +func (ctrl *backupDriverController) enqueueSecret(obj interface{}) { + // Beware of "xxx deleted" events + if unknown, ok := obj.(cache.DeletedFinalStateUnknown); ok && unknown.Obj != nil { + obj = unknown.Obj + } + if secretItem, ok := obj.(*corev1.Secret); ok { + ctrl.logger.Infof("enqueueSecret on update: %s", secretItem.Name) + objName, err := cache.DeletionHandlingMetaNamespaceKeyFunc(secretItem) + if err != nil { + ctrl.logger.Errorf("failed to get key from object: %v, %v", err, secretItem) + return + } + ctrl.logger.Infof("enqueueSecret: enqueued %q for sync", objName) + ctrl.secretQueue.Add(objName) + } +} + // snapshotWorker is the main worker for snapshot request. func (ctrl *backupDriverController) snapshotWorker() { ctrl.logger.Infof("snapshotWorker: Enter snapshotWorker") diff --git a/pkg/cmd/backupdriver/cli/server/server.go b/pkg/cmd/backupdriver/cli/server/server.go index d8287f21..95738825 100644 --- a/pkg/cmd/backupdriver/cli/server/server.go +++ b/pkg/cmd/backupdriver/cli/server/server.go @@ -19,6 +19,7 @@ package server import ( "context" "fmt" + server2 "github.com/vmware-tanzu/astrolabe/pkg/server" "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/constants" "log" "net/http" @@ -30,7 +31,6 @@ import ( "time" "github.com/vmware-tanzu/astrolabe/pkg/astrolabe" - server2 "github.com/vmware-tanzu/astrolabe/pkg/server" "k8s.io/client-go/util/workqueue" "github.com/pkg/errors" @@ -82,8 +82,8 @@ func NewCommand(f client.Factory) *cobra.Command { kubeConfig: "", resyncPeriod: constants.ResyncPeriod, workers: cmd.DefaultBackupWorkers, - retryIntervalStart: cmd.DefaultRetryIntervalStart, - retryIntervalMax: cmd.DefaultRetryIntervalMax, + retryIntervalStart: constants.DefaultRetryIntervalStart, + retryIntervalMax: constants.DefaultRetryIntervalMax, } ) diff --git a/pkg/cmd/constants.go b/pkg/cmd/constants.go index 561de0bb..e0328ef0 100644 --- a/pkg/cmd/constants.go +++ b/pkg/cmd/constants.go @@ -16,8 +16,6 @@ limitations under the License. package cmd -import "time" - const ( // the port where prometheus metrics are exposed DefaultMetricsAddress = ":8085" @@ -30,7 +28,5 @@ const ( DefaultInsecureFlag bool = true DefaultVCConfigFromSecret bool = true - DefaultBackupWorkers = 1 - DefaultRetryIntervalStart = time.Second - DefaultRetryIntervalMax = 5 * time.Minute + DefaultBackupWorkers = 1 ) diff --git a/pkg/cmd/datamgr/cli/server/server.go b/pkg/cmd/datamgr/cli/server/server.go index 2cf1293c..29dcc822 100644 --- a/pkg/cmd/datamgr/cli/server/server.go +++ b/pkg/cmd/datamgr/cli/server/server.go @@ -19,6 +19,8 @@ package server import ( "context" "fmt" + "github.com/vmware-tanzu/astrolabe/pkg/common/vsphere" + server2 "github.com/vmware-tanzu/astrolabe/pkg/server" "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/constants" "log" "net/http" @@ -30,8 +32,6 @@ import ( "time" "github.com/vmware-tanzu/astrolabe/pkg/astrolabe" - "github.com/vmware-tanzu/astrolabe/pkg/ivd" - astrolabeServer "github.com/vmware-tanzu/astrolabe/pkg/server" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -156,6 +156,7 @@ type server struct { dataMover *dataMover.DataMover snapManager *snapshotmgr.SnapshotManager externalDataMgr bool + vcConfigSecret bool } func (s *server) run() error { @@ -188,27 +189,27 @@ func getVCConfigParams(config serverConfig, params map[string]interface{}, logge if config.vCenter == "" { return errors.New("getVCConfigParams: parameter vcenter-address not provided") } - params[ivd.HostVcParamKey] = config.vCenter + params[vsphere.HostVcParamKey] = config.vCenter if config.user == "" { return errors.New("getVCConfigParams: parameter vcenter-user not provided") } - params[ivd.UserVcParamKey] = config.user + params[vsphere.UserVcParamKey] = config.user passwd := os.Getenv("VC_PASSWORD") if passwd == "" { logger.Warnf("getVCConfigParams: Environment variable VC_PASSWORD not set or empty") } - params[ivd.PasswordVcParamKey] = passwd + params[vsphere.PasswordVcParamKey] = passwd if config.clusterId == "" { return errors.New("getVCConfigParams: parameter vcenter-user not provided") } - params[ivd.ClusterVcParamKey] = config.clusterId + params[vsphere.ClusterVcParamKey] = config.clusterId // Below vc configuration params are optional - params[ivd.PortVcParamKey] = config.port - params[ivd.InsecureFlagVcParamKey] = strconv.FormatBool(config.insecureFlag) + params[vsphere.PortVcParamKey] = config.port + params[vsphere.InsecureFlagVcParamKey] = strconv.FormatBool(config.insecureFlag) return nil } @@ -244,7 +245,7 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s return nil, err } - logger.Infof("VC configuration provided by user for :%s", ivdParams[ivd.HostVcParamKey]) + logger.Infof("VC configuration provided by user for :%s", ivdParams[vsphere.HostVcParamKey]) } snapshotMgrConfig := make(map[string]string) @@ -259,7 +260,7 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s } s3RepoParams := make(map[string]interface{}) - configInfo := astrolabeServer.NewConfigInfo(peConfigs, s3Config) + configInfo := server2.NewConfigInfo(peConfigs, s3Config) snapshotMgr, err := snapshotmgr.NewSnapshotManagerFromConfig(configInfo, s3RepoParams, snapshotMgrConfig, clientConfig, logger) if err != nil { @@ -296,6 +297,7 @@ func newServer(f client.Factory, config serverConfig, logger *logrus.Logger) (*s dataMover: clusterDataMover, snapManager: snapshotMgr, externalDataMgr: externalDataMgr, + vcConfigSecret: config.vcConfigFromSecret, } return s, nil } @@ -354,6 +356,21 @@ func (s *server) runControllers() error { os.Getenv("NODE_NAME"), ) + if !s.externalDataMgr && s.vcConfigSecret { + s.logger.Infof("Watching for vc config secret changes.") + vcConfigController := controller.NewVcConfigController( + s.logger, + s.kubeInformerFactory.Core().V1().Secrets(), + s.dataMover, + s.snapManager, + ) + wg.Add(1) + go func() { + defer wg.Done() + vcConfigController.Run(s.ctx, 1) + }() + } + wg.Add(1) go func() { defer wg.Done() diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 2ac1d4bd..ba9ec11a 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -37,6 +37,8 @@ const ( const ( // Duration after which Reflector resyncs CRs and calls UpdateFunc on each of the existing CRs. ResyncPeriod = 30 * time.Second + + DefaultSecretResyncPeriod = 5 * time.Minute ) // configuration constants for the volume snapshot plugin @@ -135,8 +137,8 @@ const ( // feature flog constants const ( - VSphereLocalModeFlag = "local-mode" - VSphereLocalModeFeature = "EnableLocalMode" + VSphereLocalModeFlag = "local-mode" + VSphereLocalModeFeature = "EnableLocalMode" ) const ( @@ -308,3 +310,8 @@ const ( ImageContainerComponent = "Container" ImageVersionComponent = "Version" ) + +const ( + DefaultRetryIntervalStart = time.Second + DefaultRetryIntervalMax = 5 * time.Minute +) diff --git a/pkg/controller/vc_config_controller.go b/pkg/controller/vc_config_controller.go new file mode 100644 index 00000000..c82be1f4 --- /dev/null +++ b/pkg/controller/vc_config_controller.go @@ -0,0 +1,109 @@ +package controller + +import ( + "github.com/sirupsen/logrus" + "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/constants" + "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/dataMover" + "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/snapshotmgr" + "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/utils" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/client-go/informers/core/v1" + "k8s.io/client-go/tools/cache" + "time" +) + +type vcConfigController struct { + *genericController + dataMover *dataMover.DataMover + snapMgr *snapshotmgr.SnapshotManager +} + +func NewVcConfigController( + logger logrus.FieldLogger, + secretInformer v1.SecretInformer, + dataMover *dataMover.DataMover, + snapMgr *snapshotmgr.SnapshotManager, +) Interface { + v := &vcConfigController{ + genericController: newGenericController("vc-config", logger), + dataMover: dataMover, + snapMgr: snapMgr, + } + v.syncHandler = v.processVcConfigSecretItem + v.retryHandler = v.exponentialBackoffHandler + v.cacheSyncWaiters = append( + v.cacheSyncWaiters, + secretInformer.Informer().HasSynced, + ) + + secretInformer.Informer().AddEventHandlerWithResyncPeriod( + cache.FilteringResourceEventHandler{ + FilterFunc: utils.GetVcConfigSecretFilterFunc(logger), + Handler: cache.ResourceEventHandlerFuncs{ + AddFunc: func(obj interface{}) { v.enqueueVcConfigSecret(obj) }, + UpdateFunc: func(oldObj, newObj interface{}) { v.enqueueVcConfigSecret(newObj) }, + }, + }, + constants.DefaultSecretResyncPeriod) + return v +} + +func (v *vcConfigController) enqueueVcConfigSecret(obj interface{}) { + // Beware of "xxx deleted" events + if unknown, ok := obj.(cache.DeletedFinalStateUnknown); ok && unknown.Obj != nil { + obj = unknown.Obj + } + if secretItem, ok := obj.(*corev1.Secret); ok { + v.logger.Infof("enqueueSecret on update: %s", secretItem.Name) + objName, err := cache.DeletionHandlingMetaNamespaceKeyFunc(secretItem) + if err != nil { + v.logger.Errorf("failed to get key from object: %v, %v", err, secretItem) + return + } + v.logger.Infof("enqueueVcConfigSecret: enqueued %q for sync", objName) + v.enqueue(obj) + } +} + +func (v *vcConfigController) processVcConfigSecretItem(key string) error { + log := v.logger.WithField("key", key) + log.Info("Running processVcConfigSecretItem") + + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + log.WithError(err).Error("Failed to split the key of queue item") + return nil + } + // Retrieve the latest Secret. + ivdParams := make(map[string]interface{}) + err = utils.RetrieveVcConfigSecret(ivdParams, nil, v.logger) + if err != nil { + v.logger.Errorf("Failed to retrieve the latest vc config secret") + return err + } + v.logger.Infof("Successfully retrieved latest vSphere VC credentials.") + if v.dataMover != nil { + err = v.dataMover.ReloadDataMoverIvdPetmConfig(ivdParams) + if err != nil { + v.logger.Errorf("Secret %s/%s Reload on DataMover failed, err: %v", namespace, name, err) + return err + } + } + if v.snapMgr != nil { + err = v.snapMgr.ReloadSnapshotManagerIvdPetmConfig(ivdParams) + if err != nil { + v.logger.Errorf("Secret %s/%s Reload on Snapshot Manager failed, err: %v", namespace, name, err) + return err + } + } + + v.logger.Infof("Successfully processed updates in vc configuration.") + return nil +} + +func (v *vcConfigController) exponentialBackoffHandler(key string) error { + v.logger.Info("Running exponentialBackoffHandler") + v.logger.Infof("Re-adding failed secret processing to the queue") + v.queue.AddAfter(key, time.Duration(1)*time.Minute) + return nil +} diff --git a/pkg/dataMover/data_mover.go b/pkg/dataMover/data_mover.go index 5992b0a5..1ed23ce3 100644 --- a/pkg/dataMover/data_mover.go +++ b/pkg/dataMover/data_mover.go @@ -21,6 +21,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/vmware-tanzu/astrolabe/pkg/astrolabe" + "github.com/vmware-tanzu/astrolabe/pkg/common/vsphere" "github.com/vmware-tanzu/astrolabe/pkg/ivd" "github.com/vmware-tanzu/astrolabe/pkg/s3repository" backupdriverv1 "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/apis/backupdriver/v1alpha1" @@ -33,11 +34,12 @@ type DataMover struct { logger logrus.FieldLogger ivdPETM *ivd.IVDProtectedEntityTypeManager inProgressCancelMap *sync.Map + reloadConfigLock *sync.Mutex } func NewDataMoverFromCluster(params map[string]interface{}, logger logrus.FieldLogger) (*DataMover, error) { // Retrieve VC configuration from the cluster only of it has not been passed by the caller - if _, ok := params[ivd.HostVcParamKey]; !ok { + if _, ok := params[vsphere.HostVcParamKey]; !ok { err := utils.RetrieveVcConfigSecret(params, nil, logger) if err != nil { @@ -58,10 +60,12 @@ func NewDataMoverFromCluster(params map[string]interface{}, logger logrus.FieldL logger.Infof("DataMover: Get ivdPETM from the params map") var syncMap sync.Map + var mut sync.Mutex dataMover := DataMover{ logger: logger, ivdPETM: ivdPETM, inProgressCancelMap: &syncMap, + reloadConfigLock: &mut, } logger.Infof("DataMover is initialized") @@ -69,6 +73,8 @@ func NewDataMoverFromCluster(params map[string]interface{}, logger logrus.FieldL } func (this *DataMover) CopyToRepo(peID astrolabe.ProtectedEntityID) (astrolabe.ProtectedEntityID, error) { + this.reloadConfigLock.Lock() + defer this.reloadConfigLock.Unlock() var s3PETM *s3repository.ProtectedEntityTypeManager logger := this.logger s3PETM, err := utils.GetDefaultS3PETM(logger) @@ -80,6 +86,8 @@ func (this *DataMover) CopyToRepo(peID astrolabe.ProtectedEntityID) (astrolabe.P } func (this *DataMover) CopyToRepoWithBackupRepository(peID astrolabe.ProtectedEntityID, backupRepository *backupdriverv1.BackupRepository) (astrolabe.ProtectedEntityID, error) { + this.reloadConfigLock.Lock() + defer this.reloadConfigLock.Unlock() var s3PETM *s3repository.ProtectedEntityTypeManager logger := this.logger s3PETM, err := backuprepository.GetRepositoryFromBackupRepository(backupRepository, logger) @@ -118,6 +126,8 @@ func (this *DataMover) copyToRepo(peID astrolabe.ProtectedEntityID, s3PETM *s3re } func (this *DataMover) CopyFromRepo(peID astrolabe.ProtectedEntityID, targetPEID astrolabe.ProtectedEntityID, options astrolabe.CopyCreateOptions) (astrolabe.ProtectedEntityID, error) { + this.reloadConfigLock.Lock() + defer this.reloadConfigLock.Unlock() var s3PETM *s3repository.ProtectedEntityTypeManager logger := this.logger s3PETM, err := utils.GetDefaultS3PETM(logger) @@ -129,6 +139,8 @@ func (this *DataMover) CopyFromRepo(peID astrolabe.ProtectedEntityID, targetPEID } func (this *DataMover) CopyFromRepoWithBackupRepository(peID astrolabe.ProtectedEntityID, targetPEID astrolabe.ProtectedEntityID, backupRepository *backupdriverv1.BackupRepository, options astrolabe.CopyCreateOptions) (astrolabe.ProtectedEntityID, error) { + this.reloadConfigLock.Lock() + defer this.reloadConfigLock.Unlock() var s3PETM *s3repository.ProtectedEntityTypeManager logger := this.logger s3PETM, err := backuprepository.GetRepositoryFromBackupRepository(backupRepository, logger) @@ -224,3 +236,15 @@ func (this *DataMover) UnregisterOngoingUpload(peID astrolabe.ProtectedEntityID) log.Infof("Unregistered from on-going upload map.") } } + +func (this *DataMover) ReloadDataMoverIvdPetmConfig(params map[string]interface{}) error { + this.reloadConfigLock.Lock() + defer this.reloadConfigLock.Unlock() + this.logger.Infof("DataMover Config Reload initiated.") + err := this.ivdPETM.ReloadConfig(context.TODO(), params) + if err != nil { + this.logger.Infof("Failed to reload IVD PE Type Manager config associated with DataMover") + return err + } + return nil +} diff --git a/pkg/snapshotmgr/data_manager_protected_entity_type_manager.go b/pkg/snapshotmgr/data_manager_protected_entity_type_manager.go index c6e595ac..78351263 100644 --- a/pkg/snapshotmgr/data_manager_protected_entity_type_manager.go +++ b/pkg/snapshotmgr/data_manager_protected_entity_type_manager.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/vmware-tanzu/astrolabe/pkg/ivd" ) import "github.com/vmware-tanzu/astrolabe/pkg/astrolabe" @@ -52,3 +54,17 @@ func (this DataManagerProtectedEntityTypeManager) CopyFromInfo(ctx context.Conte fmt.Println("CopyFromInfo called") return nil, nil } + +func (this DataManagerProtectedEntityTypeManager) ReloadDmIvdPetm(ctx context.Context, ivdParams map[string]interface{}, logger logrus.FieldLogger) error { + logger.Infof("ReloadDmIvdPetm called") + ivdProtectedEntityTypeManager, ok := this.ProtectedEntityTypeManager.(*ivd.IVDProtectedEntityTypeManager) + if ok { + err := ivdProtectedEntityTypeManager.ReloadConfig(context.TODO(), ivdParams) + if err != nil { + return errors.Wrapf(err, "Failed to Reload IVD Config in datapetm.") + } + logger.Debug("Successfully processed ReloadDmIvdPetm") + return nil + } + return nil +} diff --git a/pkg/snapshotmgr/snapshot_manager.go b/pkg/snapshotmgr/snapshot_manager.go index 38dff795..662385b9 100644 --- a/pkg/snapshotmgr/snapshot_manager.go +++ b/pkg/snapshotmgr/snapshot_manager.go @@ -20,6 +20,7 @@ import ( "context" "encoding/base64" "fmt" + "github.com/vmware-tanzu/astrolabe/pkg/common/vsphere" "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/backuprepository" "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/constants" v1 "k8s.io/api/core/v1" @@ -33,7 +34,6 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/vmware-tanzu/astrolabe/pkg/astrolabe" - "github.com/vmware-tanzu/astrolabe/pkg/ivd" astrolabe_pvc "github.com/vmware-tanzu/astrolabe/pkg/pvc" "github.com/vmware-tanzu/astrolabe/pkg/server" backupdriverv1 "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/apis/backupdriver/v1alpha1" @@ -72,15 +72,15 @@ func NewSnapshotManagerFromCluster(params map[string]interface{}, config map[str s3RepoParams["s3Url"] = params["s3Url"] } - _, isVcHostExist := params[ivd.HostVcParamKey] + _, isVcHostExist := params[vsphere.HostVcParamKey] if isVcHostExist { - ivdParams[ivd.HostVcParamKey] = params[ivd.HostVcParamKey] - ivdParams[ivd.UserVcParamKey] = params[ivd.UserVcParamKey] - ivdParams[ivd.PasswordVcParamKey] = params[ivd.PasswordVcParamKey] - ivdParams[ivd.PortVcParamKey] = params[ivd.PortVcParamKey] - ivdParams[ivd.DatacenterVcParamKey] = params[ivd.DatacenterVcParamKey] - ivdParams[ivd.InsecureFlagVcParamKey] = params[ivd.InsecureFlagVcParamKey] - ivdParams[ivd.ClusterVcParamKey] = params[ivd.ClusterVcParamKey] + ivdParams[vsphere.HostVcParamKey] = params[vsphere.HostVcParamKey] + ivdParams[vsphere.UserVcParamKey] = params[vsphere.UserVcParamKey] + ivdParams[vsphere.PasswordVcParamKey] = params[vsphere.PasswordVcParamKey] + ivdParams[vsphere.PortVcParamKey] = params[vsphere.PortVcParamKey] + ivdParams[vsphere.DatacenterVcParamKey] = params[vsphere.DatacenterVcParamKey] + ivdParams[vsphere.InsecureFlagVcParamKey] = params[vsphere.InsecureFlagVcParamKey] + ivdParams[vsphere.ClusterVcParamKey] = params[vsphere.ClusterVcParamKey] } peConfigs := make(map[string]map[string]interface{}) @@ -111,7 +111,7 @@ func NewSnapshotManagerFromConfig(configInfo server.ConfigInfo, s3RepoParams map // An empty ivd map must be passed to use the IVD // TODO - Move this code out to the caller - this assumes we always want IVD if ivdParams, ok := configInfo.PEConfigs["ivd"]; ok { - if _, ok := ivdParams[ivd.HostVcParamKey]; !ok { + if _, ok := ivdParams[vsphere.HostVcParamKey]; !ok { err := utils.RetrieveVcConfigSecret(ivdParams, k8sRestConfig, logger) if err != nil { logger.WithError(err).Errorf("Could not retrieve vsphere credential from k8s secret") @@ -135,7 +135,6 @@ func NewSnapshotManagerFromConfig(configInfo server.ConfigInfo, s3RepoParams map config: config, Pem: dpem, clusterFlavor: clusterFlavor, - //s3PETM: s3PETM, } logger.Infof("SnapshotManager is initialized with the configuration: %v", config) // if so, check whether there is any specification about remote storage location in config @@ -779,6 +778,24 @@ func (this *SnapshotManager) CreateVolumeFromSnapshotWithMetadata(peID astrolabe return pe.GetID(), err } +func (this *SnapshotManager) ReloadSnapshotManagerIvdPetmConfig(ivdParams map[string]interface{}) error { + + petm := this.Pem.GetProtectedEntityTypeManager("ivd") + if petm == nil { + return errors.New("Failed to retrieve IVD Protected Type Manager from Snapshot Manager") + } + dmPetm, ok := petm.(DataManagerProtectedEntityTypeManager) + if ok { + this.Debugf("Found DataManagerProtectedEntityTypeManager during snapshot IVD Petm Reload") + err := dmPetm.ReloadDmIvdPetm(context.TODO(), ivdParams, this.FieldLogger) + if err != nil { + return errors.Wrapf(err, "Failed to Reload IVD Config in SnapshotManager.") + } + return nil + } + return errors.New("Failed to find ivd petm associated with snapshot manager.") +} + func uploadCRNameForSnapshotPEID(snapshotPEID astrolabe.ProtectedEntityID) (string, error) { if !snapshotPEID.HasSnapshot() { return "", errors.New(fmt.Sprintf("snapshotPEID %s does not have a snapshot ID", snapshotPEID.String())) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index e88b872c..929ee3a6 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -45,12 +45,12 @@ import ( "github.com/vmware-tanzu/astrolabe/pkg/ivd" "github.com/vmware-tanzu/astrolabe/pkg/s3repository" pluginv1api "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/apis/datamover/v1alpha1" - pluginv1client "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/generated/clientset/versioned/typed/datamover/v1alpha1" plugin_clientset "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/generated/clientset/versioned" - k8serrors "k8s.io/apimachinery/pkg/api/errors" + pluginv1client "github.com/vmware-tanzu/velero-plugin-for-vsphere/pkg/generated/clientset/versioned/typed/datamover/v1alpha1" v1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" "github.com/vmware-tanzu/velero/pkg/generated/clientset/versioned" k8sv1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" @@ -320,7 +320,7 @@ func GetIVDPETMFromParamsMap(params map[string]interface{}, logger logrus.FieldL URLBase: "VOID_URL", } - ivdPETM, err := ivd.NewIVDProtectedEntityTypeManagerFromConfig(params, s3Config, logger) + ivdPETM, err := ivd.NewIVDProtectedEntityTypeManager(params, s3Config, logger) if err != nil { logger.WithError(err).Errorf("Error at creating new IVD PETM from vc params: %v, s3Config: %v", params, s3Config) @@ -964,3 +964,29 @@ func DeleteSvcSnapshot(svcSnapshotName string, gcSnapshotName string, gcSnapshot return nil } +func GetVcConfigSecretFilterFunc(logger logrus.FieldLogger) func(obj interface{}) bool { + config, err := rest.InClusterConfig() + if err != nil { + logger.WithError(err).Errorf("Failed to get k8s inClusterConfig") + return nil + } + var ns string + // Get the cluster flavor + clusterFlavor, err := GetClusterFlavor(config) + if clusterFlavor == constants.Supervisor { + ns = constants.VCSecretNsSupervisor + } else if clusterFlavor == constants.VSphere { + ns = constants.VCSecretNs + } + return func(obj interface{}) bool { + switch obj.(type) { + case *k8sv1.Secret: + incomingSecret := obj.(*k8sv1.Secret) + return incomingSecret.Namespace == ns && + incomingSecret.Name == constants.VCSecret + default: + logger.Debugf("Unrecognized object type found during filtering, ignoring") + } + return false + } +}