@@ -17,9 +17,11 @@ import (
1717 . "github.com/netapp/trident/logging"
1818 confClients "github.com/netapp/trident/operator/controllers/configurator/clients"
1919 operatorV1 "github.com/netapp/trident/operator/crd/apis/netapp/v1"
20+ tridentV1 "github.com/netapp/trident/persistent_store/crd/apis/netapp/v1"
2021 sa "github.com/netapp/trident/storage_attribute"
2122 "github.com/netapp/trident/storage_drivers/ontap/awsapi"
2223 "github.com/netapp/trident/utils"
24+ "github.com/netapp/trident/utils/errors"
2325)
2426
2527const (
@@ -60,8 +62,8 @@ type SVM struct {
6062 ManagementLIF string `json:"managementLIF"`
6163}
6264
63- // NewFsxnInstance creates a new instance of the AWS struct and populates it with the provided CRs and client
64- func NewFsxnInstance (
65+ // NewFSxNInstance creates a new instance of the AWS struct and populates it with the provided CRs and client
66+ func NewFSxNInstance (
6567 torcCR * operatorV1.TridentOrchestrator , configuratorCR * operatorV1.TridentConfigurator ,
6668 client confClients.ConfiguratorClientInterface ,
6769) (* AWS , error ) {
@@ -70,7 +72,7 @@ func NewFsxnInstance(
7072 }
7173
7274 if configuratorCR == nil {
73- return nil , fmt .Errorf ("empty AWSFsxN configurator CR" )
75+ return nil , fmt .Errorf ("empty AWS FSxN configurator CR" )
7476 }
7577
7678 if client == nil {
@@ -117,33 +119,39 @@ func (aws *AWS) Validate() error {
117119 aws .AwsClient = api
118120
119121 for key , fsxnInstance := range aws .SVMs {
120- if err := aws .processFsxnInstance (context .Background (), key , fsxnInstance ); err != nil {
122+ if err := aws .processFSxNInstance (context .Background (), key , fsxnInstance ); err != nil {
121123 return err
122124 }
123125 }
124126
125127 return nil
126128}
127129
128- // processFsxnInstance processes the auto-backend configuration for the FSxN instance.
130+ // processFSxNInstance processes the auto-backend configuration for the FSxN instance.
129131// It creates the SVM if it does not exist and creates the secret for the SVM.
130- func (aws * AWS ) processFsxnInstance (ctx context.Context , key int , svm SVM ) error {
132+ func (aws * AWS ) processFSxNInstance (ctx context.Context , key int , svm SVM ) error {
131133 var (
132- svmName string
133- secretName string
134- secretARN string
135- svmExists bool
134+ svmName string
135+ secretName string
136+ secretARN string
137+ svmExists bool
138+ ErrStatusCode = "StatusCode: 400"
136139 )
137140 svmName = svm .SvmName
138141 if svmName == "" {
139142 svmName = fmt .Sprintf (SvmNamePattern , svm .FsxnID )
143+ svm .SvmName = svmName
140144 }
141145 _ , err := aws .AwsClient .GetFilesystemByID (ctx , svm .FsxnID )
142- if err != nil {
146+ if errors .IsNotFoundError (err ) || (err != nil && strings .Contains (err .Error (), ErrStatusCode )) {
147+ err = aws .cleanUpFSxNRelatedObjects (svm , svm .Protocols )
148+ if err != nil {
149+ Log ().Error (err )
150+ }
143151 return fmt .Errorf ("error occurred while getting fsxn id: %v : %v" , svm .FsxnID , err )
144152 }
145153 Log ().Debugf ("Filesystem ID: %s exists" , svm .FsxnID )
146- secretName = fmt . Sprintf ( TridentSecretPattern , strings . TrimPrefix ( svmName , "trident-" ) )
154+ secretName = getAWSSecretName ( svmName )
147155 // Get the secret if it already exists or create a new one
148156 secret , _ := aws .AwsClient .GetSecret (ctx , secretName )
149157 if secret != nil {
@@ -245,7 +253,7 @@ func (aws *AWS) Create() ([]string, error) {
245253 )
246254 for _ , svm := range aws .SVMs {
247255 for _ , protocol := range svm .Protocols {
248- backendName = getFsxnBackendName (svm .FsxnID , protocol )
256+ backendName = getFSxNBackendName (svm .FsxnID , protocol )
249257 backendYAML := getFsxnTBCYaml (svm , aws .TridentNamespace , backendName , protocol )
250258 if err := aws .ConfClient .CreateOrPatchObject (confClients .OBackend , backendName ,
251259 aws .TridentNamespace , backendYAML ); err != nil {
@@ -262,7 +270,7 @@ func (aws *AWS) CreateStorageClass() error {
262270 var driver string
263271 for _ , svm := range aws .SVMs {
264272 for _ , protocol := range svm .Protocols {
265- name := getFsxnStorageClassName (svm .FsxnID , protocol )
273+ name := getFSxNStorageClassName (svm .FsxnID , protocol )
266274 if protocol == sa .NFS {
267275 driver = config .OntapNASStorageDriverName
268276 } else if protocol == sa .ISCSI {
@@ -290,12 +298,95 @@ func (aws *AWS) GetCloudProvider() string {
290298 return k8sclient .CloudProviderAWS
291299}
292300
293- // getFsxnTBCYaml returns the FsxN Trident backend config name
294- func getFsxnBackendName (fsxnId , protocolType string ) string {
301+ // DeleteBackend deletes the backend if the FSxN instance is deleted
302+ func (aws * AWS ) DeleteBackend (request map [string ]interface {}) error {
303+ protocols := request ["protocols" ].([]string )
304+ fsxnId := request ["FSxNID" ].(string )
305+ for _ , protocol := range protocols {
306+ backendName := getFSxNBackendName (fsxnId , protocol )
307+ if err := aws .ConfClient .DeleteObject (confClients .OBackend , backendName , aws .TridentNamespace ); err != nil {
308+ return fmt .Errorf ("error occurred while deleting backend: %w" , err )
309+ }
310+ }
311+ return nil
312+ }
313+
314+ // DeleteStorageClass deletes the storage class if the FSxN instance is deleted
315+ func (aws * AWS ) DeleteStorageClass (request map [string ]interface {}) error {
316+ protocols := request ["protocols" ].([]string )
317+ fsxnId := request ["FSxNID" ].(string )
318+ for _ , protocol := range protocols {
319+ name := getFSxNStorageClassName (fsxnId , protocol )
320+ if err := aws .ConfClient .DeleteObject (confClients .OStorageClass , name , aws .TridentNamespace ); err != nil {
321+ return fmt .Errorf ("error occurred while deleting storage class: %w" , err )
322+ }
323+ }
324+ return nil
325+ }
326+
327+ // DeleteSnapshotClass deletes the snapshot class if the FSxN instance is deleted
328+ func (aws * AWS ) DeleteSnapshotClass () error {
329+ tbcList , err := aws .ConfClient .ListObjects (confClients .OBackend , "" )
330+ if err != nil {
331+ return fmt .Errorf ("error occurred while listing TBC objects: %w" , err )
332+ }
333+ if len (tbcList .(* tridentV1.TridentBackendList ).Items ) == 0 {
334+ if err := aws .ConfClient .DeleteObject (confClients .OSnapshotClass , NetAppSnapshotClassName , "" ); err != nil {
335+ return fmt .Errorf ("error occurred while deleting snapshot class: %w" , err )
336+ }
337+ }
338+
339+ return nil
340+ }
341+
342+ // cleanUpFSxNRelatedObjects cleans up the FSxN instance related objects like storage class, backend, and AWS secret
343+ func (aws * AWS ) cleanUpFSxNRelatedObjects (svm SVM , protocols []string ) (err error ) {
344+ cleanupRequest := map [string ]interface {}{
345+ "FSxNID" : svm .FsxnID ,
346+ "protocols" : protocols ,
347+ }
348+
349+ // Delete the storage class
350+ if deleteErr := aws .DeleteStorageClass (cleanupRequest ); err != nil {
351+ err = fmt .Errorf ("failed to delete VolumeSnapshotClass: %w" , deleteErr )
352+ }
353+
354+ // Delete the backend
355+ if deleteErr := aws .DeleteBackend (cleanupRequest ); err != nil {
356+ err = fmt .Errorf ("failed to delete backend: %w" , deleteErr )
357+ }
358+
359+ // Delete the AWS secret
360+ if deleteErr := deleteSecret (context .Background (), aws , getAWSSecretName (svm .SvmName )); err != nil {
361+ err = fmt .Errorf ("failed to delete AWS secret: %w" , deleteErr )
362+ }
363+
364+ // Delete the VolumeSnapshotClass if no backend is present
365+ if deleteErr := aws .DeleteSnapshotClass (); err != nil {
366+ err = fmt .Errorf ("failed to delete VolumeSnapshotClass: %w" , deleteErr )
367+ }
368+
369+ return
370+ }
371+
372+ func deleteSecret (ctx context.Context , aws * AWS , secretName string ) error {
373+ if err := aws .AwsClient .DeleteSecret (ctx , secretName ); err != nil {
374+ return fmt .Errorf ("error occurred while deleting secret: %w" , err )
375+ }
376+ return nil
377+ }
378+
379+ // getFSxNBackendName returns the FsxN Trident backend config name
380+ func getFSxNBackendName (fsxnId , protocolType string ) string {
295381 return fmt .Sprintf (BackendNamePattern , fsxnId , protocolType )
296382}
297383
298- // getFsxnStorageClassName returns the storage class name for the FSxN backend
299- func getFsxnStorageClassName (fsxnId , protocolType string ) string {
384+ // getFSxNStorageClassName returns the storage class name for the FSxN backend
385+ func getFSxNStorageClassName (fsxnId , protocolType string ) string {
300386 return fmt .Sprintf (StorageClassNamePattern , fsxnId , protocolType )
301387}
388+
389+ // getAWSSecretName returns the AWS secret name for the FSxN backend
390+ func getAWSSecretName (svmName string ) string {
391+ return fmt .Sprintf (TridentSecretPattern , strings .TrimPrefix (svmName , "trident-" ))
392+ }
0 commit comments