@@ -286,37 +286,6 @@ func ensureExportPolicyExists(ctx context.Context, policyName string, clientAPI
286286 return clientAPI .ExportPolicyCreate (ctx , policyName )
287287}
288288
289- // publishShare ensures that the volume has the correct export policy applied.
290- func publishShare (
291- ctx context.Context , clientAPI api.OntapAPI , config * drivers.OntapStorageDriverConfig ,
292- publishInfo * tridentmodels.VolumePublishInfo , volumeName string ,
293- ModifyVolumeExportPolicy func (ctx context.Context , volumeName , policyName string ) error ,
294- ) error {
295- fields := LogFields {
296- "Method" : "publishFlexVolShare" ,
297- "Type" : "ontap_common" ,
298- "Share" : volumeName ,
299- }
300- Logd (ctx , config .StorageDriverName ,
301- config .DebugTraceFlags ["method" ]).WithFields (fields ).Trace (">>>> publishFlexVolShare" )
302- defer Logd (ctx , config .StorageDriverName ,
303- config .DebugTraceFlags ["method" ]).WithFields (fields ).Trace ("<<<< publishFlexVolShare" )
304-
305- if ! config .AutoExportPolicy || publishInfo .Unmanaged {
306- // Nothing to do if we're not configuring export policies automatically or volume is not managed
307- return nil
308- }
309-
310- if err := ensureNodeAccess (ctx , publishInfo , clientAPI , config ); err != nil {
311- return err
312- }
313-
314- // Update volume to use the correct export policy
315- policyName := getExportPolicyName (publishInfo .BackendUUID )
316- err := ModifyVolumeExportPolicy (ctx , volumeName , policyName )
317- return err
318- }
319-
320289func getExportPolicyName (backendUUID string ) string {
321290 return fmt .Sprintf ("trident-%s" , backendUUID )
322291}
@@ -369,6 +338,61 @@ func reconcileNASNodeAccess(
369338 return nil
370339}
371340
341+ // ensureNodeAccessForPolicy check to see if export policy exists and if not it will create it.
342+ // Add the desired rule(s) to the policy.
343+ func ensureNodeAccessForPolicy (
344+ ctx context.Context , targetNode * tridentmodels.Node , clientAPI api.OntapAPI ,
345+ config * drivers.OntapStorageDriverConfig , policyName string ,
346+ ) error {
347+ if exists , err := clientAPI .ExportPolicyExists (ctx , policyName ); err != nil {
348+ return err
349+ } else if ! exists {
350+ Logc (ctx ).WithField ("exportPolicy" , policyName ).Debug ("Export policy missing, will create it." )
351+
352+ if err = ensureExportPolicyExists (ctx , policyName , clientAPI ); err != nil {
353+ return err
354+ }
355+ }
356+
357+ desiredRules , err := network .FilterIPs (ctx , targetNode .IPs , config .AutoExportCIDRs )
358+ if err != nil {
359+ err = fmt .Errorf ("unable to determine desired export policy rules; %v" , err )
360+ Logc (ctx ).Error (err )
361+ return err
362+ }
363+
364+ // first grab all existing rules
365+ existingRules , err := clientAPI .ExportRuleList (ctx , policyName )
366+ if err != nil {
367+ // Could not list rules, just log it, no action required.
368+ Logc (ctx ).WithField ("error" , err ).Debug ("Export policy rules could not be listed." )
369+ }
370+
371+ for _ , desiredRule := range desiredRules {
372+
373+ // Loop through the existing rules one by one and compare to make sure we cover the scenario where the
374+ // existing rule is of format "10.193.112.26, 10.244.2.0" and the desired rule is format "10.193.112.26".
375+ // This can happen because of the difference in how ONTAP ZAPI and ONTAP REST creates export rule.
376+
377+ ruleFound := false
378+ for existingRule := range existingRules {
379+ if strings .Contains (existingRule , desiredRule ) {
380+ ruleFound = true
381+ break
382+ }
383+ }
384+
385+ // Rule does not exist, so create it
386+ if ! ruleFound {
387+ if err = clientAPI .ExportRuleCreate (ctx , policyName , desiredRule , config .NASType ); err != nil {
388+ return err
389+ }
390+ }
391+ }
392+
393+ return nil
394+ }
395+
372396func getDesiredExportPolicyRules (
373397 ctx context.Context , nodes []* tridentmodels.Node , config * drivers.OntapStorageDriverConfig ,
374398) ([]string , error ) {
@@ -3864,3 +3888,58 @@ func deleteAutomaticSnapshot(
38643888 }
38653889 }
38663890}
3891+
3892+ // removeExportPolicyRules takes an export policy name,
3893+ // retrieves its rules and matches the rules that exist to the IP addresses from the node.
3894+ // Any matched IP addresses will be removed from the export policy.
3895+ func removeExportPolicyRules (
3896+ ctx context.Context , exportPolicy string , publishInfo * tridentmodels.VolumePublishInfo , clientAPI api.OntapAPI ,
3897+ ) error {
3898+ var removeRuleIndexes []int
3899+
3900+ nodeIPRules := make (map [string ]struct {})
3901+ for _ , ip := range publishInfo .HostIP {
3902+ nodeIPRules [ip ] = struct {}{}
3903+ }
3904+ // Get export policy rules from given policy
3905+ allExportRules , err := clientAPI .ExportRuleList (ctx , exportPolicy )
3906+ if err != nil {
3907+ return err
3908+ }
3909+
3910+ // Match list of rules to rule index based on clientMatch address
3911+ // ONTAP expects the rule index to delete
3912+ for clientMatch , ruleIndex := range allExportRules {
3913+ // For the policy, match the node IP addresses to the clientMatch to remove the matched items.
3914+ // Example:
3915+ // trident_pvc_123 is attached to node1 and node2. The policy is being unpublished from node1.
3916+ // node1 IP addresses [1.1.1.0, 1.1.1.1] node2 IP addresses [2.2.2.0, 2.2.2.2].
3917+ // export policy "trident_pvc_123" should have the export rules:
3918+ // index 1: "1.1.1.0"
3919+ // index 2: "1.1.1.1"
3920+ // index 3: "2.2.2.0"
3921+ // index 4: "2.2.2.2"
3922+ // When the clientMatch is the same as the node IP that export rule index will be added to the list of
3923+ // indexes to be removed. For this example indexes 1 and 2 will be removed.
3924+
3925+ // Legacy export policies created via ZAPI will have multiple clientMatch IPs for a node in a single rule.
3926+ // index 1: "1.1.1.0, 1.1.1.1"
3927+ // index 2: "2.2.2.0, 2.2.2.2"
3928+ // For this example, index 1 will be removed.
3929+ for _ , singleClientMatch := range strings .Split (clientMatch , "," ) {
3930+ if _ , match := nodeIPRules [singleClientMatch ]; match {
3931+ removeRuleIndexes = append (removeRuleIndexes , ruleIndex )
3932+ }
3933+ }
3934+ }
3935+
3936+ // Attempt to remove node IP addresses from export policy rules
3937+ for _ , ruleIndex := range removeRuleIndexes {
3938+ if err = clientAPI .ExportRuleDestroy (ctx , exportPolicy , ruleIndex ); err != nil {
3939+ Logc (ctx ).WithError (err ).Error ("Error deleting export policy rule." )
3940+ return err
3941+ }
3942+ }
3943+
3944+ return nil
3945+ }
0 commit comments