@@ -256,6 +256,71 @@ type pvcToSnapshotsMap struct {
256256 items map [namespacedName ]map [namespacedName ]struct {}
257257}
258258
259+ func (m * pvcToSnapshotsMap ) add (pvc , snapshot , namespace string ) {
260+ m .Lock ()
261+ defer m .Unlock ()
262+
263+ pvcKey := namespacedName {
264+ namespace : namespace ,
265+ name : pvc ,
266+ }
267+ if _ , ok := m .items [pvcKey ]; ! ok {
268+ m .items [pvcKey ] = make (map [namespacedName ]struct {})
269+ }
270+ snapKey := namespacedName {
271+ namespace : namespace ,
272+ name : snapshot ,
273+ }
274+ m.items [pvcKey ][snapKey ] = struct {}{}
275+ }
276+
277+ func (m * pvcToSnapshotsMap ) get (pvc , namespace string ) []string {
278+ m .RLock ()
279+ defer m .RUnlock ()
280+
281+ pvcKey := namespacedName {
282+ namespace : namespace ,
283+ name : pvc ,
284+ }
285+ snapMap , ok := m .items [pvcKey ]
286+ if ! ok {
287+ return []string {}
288+ }
289+
290+ snaps := make ([]string , 0 , len (snapMap ))
291+ for k := range snapMap {
292+ snaps = append (snaps , k .name )
293+ }
294+ return snaps
295+ }
296+
297+ func (m * pvcToSnapshotsMap ) delete (pvc , snapshot , namespace string ) {
298+ m .Lock ()
299+ defer m .Unlock ()
300+
301+ pvcKey := namespacedName {
302+ namespace : namespace ,
303+ name : pvc ,
304+ }
305+ snapMap , ok := m .items [pvcKey ]
306+ if ! ok {
307+ return
308+ }
309+
310+ snapKey := namespacedName {
311+ namespace : namespace ,
312+ name : snapshot ,
313+ }
314+ delete (snapMap , snapKey )
315+ if len (snapMap ) != 0 {
316+ m .items [pvcKey ] = snapMap
317+ return
318+ }
319+
320+ // delete pvc entry if no snapshots are present
321+ delete (m .items , pvcKey )
322+ }
323+
259324// K8sOrchestrator defines set of properties specific to K8s.
260325type K8sOrchestrator struct {
261326 supervisorFSS FSSConfigMapInfo
@@ -1968,6 +2033,74 @@ func nodeRemove(obj interface{}) {
19682033 k8sOrchestratorInstance .nodeIDToNameMap .remove (nodeMoID )
19692034}
19702035
2036+ func initPVCToSnapshotsMap (ctx context.Context , controllerClusterFlavor cnstypes.CnsClusterFlavor ) error {
2037+ log := logger .GetLogger (ctx )
2038+ // TODO: check if we need to check the FSS as well
2039+ if controllerClusterFlavor != cnstypes .CnsClusterFlavorWorkload {
2040+ // PVC to VolumeSnapshot cache is only required for WCP for now.
2041+ log .Info ("non WCP cluster detected. skipping initialising PVC to Snapshot cache." )
2042+ return nil
2043+ }
2044+
2045+ k8sOrchestratorInstance .pvcToSnapshotsMap = pvcToSnapshotsMap {
2046+ RWMutex : & sync.RWMutex {},
2047+ items : make (map [namespacedName ]map [namespacedName ]struct {}),
2048+ }
2049+ snapshotAdded := func (obj any ) {
2050+ snap , ok := obj .(* snapshotv1.VolumeSnapshot )
2051+ if ! ok || snap == nil {
2052+ log .Warnf ("unrecognized object %+v" , obj )
2053+ return
2054+ }
2055+
2056+ log .Infof ("snapshotAdded: snapshot=%v" , snap )
2057+ if snap .Spec .Source .PersistentVolumeClaimName == nil {
2058+ log .Warnf ("snapshot is not associated with any PVC. Ignoring it..." )
2059+ return
2060+ }
2061+
2062+ k8sOrchestratorInstance .pvcToSnapshotsMap .add (
2063+ * snap .Spec .Source .PersistentVolumeClaimName , snap .Name , snap .Namespace )
2064+ log .With ("pvc" , * snap .Spec .Source .PersistentVolumeClaimName ).With ("snapshot" , snap .Name ).
2065+ With ("namespace" , snap .Namespace ).Debug ("successfully added the snapshot to the cache" )
2066+ }
2067+ snapshotDeleted := func (obj any ) {
2068+ snap , ok := obj .(* snapshotv1.VolumeSnapshot )
2069+ if ! ok || snap == nil {
2070+ log .Warnf ("unrecognized object %+v" , obj )
2071+ return
2072+ }
2073+
2074+ log .Infof ("snapshotDeleted: snapshot=%v" , snap )
2075+ if snap .Spec .Source .PersistentVolumeClaimName == nil {
2076+ log .Warnf ("snapshot is not associated with any PVC. Ignoring it..." )
2077+ return
2078+ }
2079+
2080+ k8sOrchestratorInstance .pvcToSnapshotsMap .delete (
2081+ * snap .Spec .Source .PersistentVolumeClaimName , snap .Name , snap .Namespace )
2082+ log .With ("pvc" , * snap .Spec .Source .PersistentVolumeClaimName ).With ("snapshot" , snap .Name ).
2083+ With ("namespace" , snap .Namespace ).Debug ("successfully removed the snapshot from the cache" )
2084+ }
2085+
2086+ err := k8sOrchestratorInstance .informerManager .AddSnapshotListener (ctx ,
2087+ func (obj any ) {
2088+ snapshotAdded (obj )
2089+ },
2090+ func (oldObj , newObj any ) {
2091+ // TODO: implement or remove as we probably don't need to take any action
2092+ log .Info ("snapshotUpdated" )
2093+ },
2094+ func (obj any ) {
2095+ snapshotDeleted (obj )
2096+ })
2097+ if err != nil {
2098+ return logger .LogNewErrorf (log , "failed to listen on volumesnapshots. Error: %v" , err )
2099+ }
2100+
2101+ return nil
2102+ }
2103+
19712104// GetNodeIDtoNameMap returns a map containing the nodeID to node name
19722105func (c * K8sOrchestrator ) GetNodeIDtoNameMap (ctx context.Context ) map [string ]string {
19732106 return c .nodeIDToNameMap .items
@@ -2282,6 +2415,11 @@ func (c *K8sOrchestrator) GetPVCNamespacedNameByUID(uid string) (k8stypes.Namesp
22822415 return nsName , true
22832416}
22842417
2418+ // GetSnapshotsForPVC returns the names of the snapshots for the given PVC
2419+ func (c * K8sOrchestrator ) GetSnapshotsForPVC (ctx context.Context , pvc , namespace string ) []string {
2420+ return c .pvcToSnapshotsMap .get (pvc , namespace )
2421+ }
2422+
22852423// GetPVCDataSource Retrieves the VolumeSnapshot source when a PVC from VolumeSnapshot is being created.
22862424func GetPVCDataSource (ctx context.Context , claim * v1.PersistentVolumeClaim ) (* v1.ObjectReference , error ) {
22872425 var dataSource v1.ObjectReference
@@ -2309,98 +2447,3 @@ func GetPVCDataSource(ctx context.Context, claim *v1.PersistentVolumeClaim) (*v1
23092447 }
23102448 return & dataSource , nil
23112449}
2312-
2313- func initPVCToSnapshotsMap (ctx context.Context , controllerClusterFlavor cnstypes.CnsClusterFlavor ) error {
2314- log := logger .GetLogger (ctx )
2315- if controllerClusterFlavor != cnstypes .CnsClusterFlavorWorkload {
2316- // PVC to VolumeSnapshot cache is only required for WCP for now.
2317- log .Info ("non WCP cluster detected. skipping initialising PVC to Snapshot cache." )
2318- return nil
2319- }
2320-
2321- k8sOrchestratorInstance .pvcToSnapshotsMap = pvcToSnapshotsMap {
2322- RWMutex : & sync.RWMutex {},
2323- items : make (map [namespacedName ]map [namespacedName ]struct {}),
2324- }
2325-
2326- snapshotAdded := func (obj any ) {
2327- snap , ok := obj .(* snapshotv1.VolumeSnapshot )
2328- if ! ok || snap == nil {
2329- log .Warnf ("snapshotAdded: unrecognized object %+v" , obj )
2330- return
2331- }
2332-
2333- log .Infof ("snapshotAdded: snapshot=%v" , snap )
2334- if snap .Spec .Source .PersistentVolumeClaimName == nil {
2335- log .Warnf ("snapshotAdded: snapshot is not associated with any PVC. Ignoring it..." )
2336- return
2337- }
2338-
2339- k8sOrchestratorInstance .pvcToSnapshotsMap .Lock ()
2340- defer k8sOrchestratorInstance .pvcToSnapshotsMap .Unlock ()
2341-
2342- pvcName := namespacedName {
2343- namespace : snap .Namespace ,
2344- name : * snap .Spec .Source .PersistentVolumeClaimName ,
2345- }
2346- if _ , ok := k8sOrchestratorInstance .pvcToSnapshotsMap .items [pvcName ]; ! ok {
2347- k8sOrchestratorInstance .pvcToSnapshotsMap .items [pvcName ] = make (map [namespacedName ]struct {})
2348- }
2349- snapName := namespacedName {
2350- namespace : snap .Namespace ,
2351- name : snap .Name ,
2352- }
2353- k8sOrchestratorInstance .pvcToSnapshotsMap .items [pvcName ][snapName ] = struct {}{}
2354- log .With ("pvc" , pvcName ).With ("snapshot" , snapName ).Debug ("successfully added the snapshot to the cache" )
2355- }
2356-
2357- snapshotDeleted := func (obj any ) {
2358- snap , ok := obj .(* snapshotv1.VolumeSnapshot )
2359- if ! ok || snap == nil {
2360- log .Warnf ("snapshotDeleted: unrecognized object %+v" , obj )
2361- return
2362- }
2363-
2364- log .Infof ("snapshotDeleted: snapshot=%v" , snap )
2365- if snap .Spec .Source .PersistentVolumeClaimName == nil {
2366- log .Warnf ("snapshotDeleted: snapshot is not associated with any PVC. Ignoring it..." )
2367- return
2368- }
2369-
2370- k8sOrchestratorInstance .pvcToSnapshotsMap .Lock ()
2371- defer k8sOrchestratorInstance .pvcToSnapshotsMap .Unlock ()
2372-
2373- pvcName := namespacedName {
2374- namespace : snap .Namespace ,
2375- name : * snap .Spec .Source .PersistentVolumeClaimName ,
2376- }
2377- if _ , ok := k8sOrchestratorInstance .pvcToSnapshotsMap .items [pvcName ]; ! ok {
2378- log .Infof ("snapshotDeleted: associated PVC %s not found in the map. Ignoring the delete event..." , pvcName )
2379- return
2380- }
2381-
2382- snapName := namespacedName {
2383- namespace : snap .Namespace ,
2384- name : snap .Name ,
2385- }
2386- delete (k8sOrchestratorInstance .pvcToSnapshotsMap .items [pvcName ], snapName )
2387- log .With ("pvc" , pvcName ).With ("snapshot" , snapName ).Debug ("successfully removed the snapshot from the cache" )
2388- }
2389-
2390- err := k8sOrchestratorInstance .informerManager .AddSnapshotListener (ctx ,
2391- func (obj any ) {
2392- snapshotAdded (obj )
2393- },
2394- func (oldObj , newObj any ) {
2395- // TODO: implement
2396- log .Info ("snapshotUpdated" )
2397- },
2398- func (obj any ) {
2399- snapshotDeleted (obj )
2400- })
2401- if err != nil {
2402- return logger .LogNewErrorf (log , "failed to listen on volumesnapshots. Error: %v" , err )
2403- }
2404-
2405- return nil
2406- }
0 commit comments