5
5
from netapp_ontap import config
6
6
from netapp_ontap .error import NetAppRestError
7
7
from netapp_ontap .host_connection import HostConnection
8
+ from netapp_ontap .resources import NvmeNamespace
8
9
from netapp_ontap .resources import Svm
9
10
from netapp_ontap .resources import Volume
10
11
@@ -80,6 +81,32 @@ def create_svm(self, project_id: str, aggregate_name: str):
80
81
logger .error ("Error creating SVM: %s" , e )
81
82
exit (1 )
82
83
84
+ def delete_svm (self , svm_name : str ) -> bool :
85
+ """Deletes a Storage Virtual Machine (SVM) based on its name.
86
+
87
+ Args:
88
+ svm_name (str): The name of the SVM to delete
89
+
90
+ Returns:
91
+ bool: True if deleted successfully, False otherwise
92
+
93
+ Note:
94
+ All non-root volumes, NVMe namespaces, and other dependencies
95
+ must be deleted prior to deleting the SVM.
96
+ """
97
+ try :
98
+ # Find the SVM by name
99
+ svm = Svm ()
100
+ svm .get (name = svm_name )
101
+ logger .info ("Found SVM '%s' with UUID %s" , svm_name , svm .uuid )
102
+ svm .delete ()
103
+ logger .info ("SVM '%s' deletion initiated successfully" , svm_name )
104
+ return True
105
+
106
+ except Exception as e :
107
+ logger .error ("Failed to delete SVM '%s': %s" , svm_name , str (e ))
108
+ return False
109
+
83
110
def create_volume (
84
111
self , project_id : str , volume_size : str , aggregate_name : str
85
112
) -> str :
@@ -105,6 +132,41 @@ def create_volume(
105
132
logger .error ("Error creating Volume: %s" , e )
106
133
exit (1 )
107
134
135
+ def delete_volume (self , volume_name : str , force : bool = False ) -> bool :
136
+ """Deletes a volume based on volume name.
137
+
138
+ Args:
139
+ volume_name (str): The name of the volume to delete
140
+ force (bool): If True, attempts to delete even if volume has dependencies
141
+
142
+ Returns:
143
+ bool: True if deleted successfully, False otherwise
144
+
145
+ Raises:
146
+ Exception: If volume not found or deletion fails
147
+ """
148
+ try :
149
+ vol = Volume ()
150
+ vol .get (name = volume_name )
151
+
152
+ logger .info ("Found volume '%s'" , volume_name )
153
+
154
+ # Check if volume is online and has data
155
+ if hasattr (vol , "state" ) and vol .state == "online" :
156
+ logger .warning ("Volume '%s' is online" , volume_name )
157
+
158
+ if force :
159
+ vol .delete (allow_delete_while_mapped = True )
160
+ else :
161
+ vol .delete ()
162
+
163
+ logger .info ("Volume '%s' deletion initiated successfully" , volume_name )
164
+ return True
165
+
166
+ except Exception as e :
167
+ logger .error ("Failed to delete volume '%s': %s" , volume_name , str (e ))
168
+ return False
169
+
108
170
def check_if_svm_exists (self , project_id ):
109
171
svm_name = self ._svm_name (project_id )
110
172
@@ -114,6 +176,31 @@ def check_if_svm_exists(self, project_id):
114
176
except NetAppRestError :
115
177
return False
116
178
179
+ def mapped_namespaces (self , svm_name , volume_name ):
180
+ if not config .CONNECTION :
181
+ return
182
+
183
+ ns_list = NvmeNamespace .get_collection (
184
+ query = f"svm.name={ svm_name } &location.volume.name={ volume_name } " ,
185
+ fields = "uuid,name,status.mapped" ,
186
+ )
187
+ return ns_list
188
+
189
+ def cleanup_project (self , project_id : str ) -> dict [str , bool ]:
190
+ """Removes a Volume and SVM associated with a project.
191
+
192
+ Note: This method will delete the data if volume is still in use.
193
+ """
194
+ svm_name = self ._svm_name (project_id )
195
+ vol_name = self ._volume_name (project_id )
196
+ delete_vol_result = self .delete_volume (vol_name )
197
+ logger .debug ("Delete volume result: %s" , delete_vol_result )
198
+
199
+ delete_svm_result = self .delete_svm (svm_name )
200
+ logger .debug ("Delete SVM result: %s" , delete_svm_result )
201
+
202
+ return {"volume" : delete_vol_result , "svm" : delete_svm_result }
203
+
117
204
def _svm_name (self , project_id ):
118
205
return f"os-{ project_id } "
119
206
0 commit comments