Skip to content

Commit 53e1022

Browse files
authored
Fix dirty node publish enforcement
This commit changes Trident to deny new CSI ControllerPublishVolume calls for CO nodes that have potentially unclean attachment states.
1 parent 4700174 commit 53e1022

File tree

9 files changed

+150
-31
lines changed

9 files changed

+150
-31
lines changed

storage_drivers/ontap/ontap_asa.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2024 NetApp, Inc. All Rights Reserved.
1+
// Copyright 2025 NetApp, Inc. All Rights Reserved.
22

33
package ontap
44

@@ -1323,6 +1323,10 @@ func (d *ASAStorageDriver) CanEnablePublishEnforcement() bool {
13231323
return true
13241324
}
13251325

1326+
func (d *ASAStorageDriver) HealVolumePublishEnforcement(ctx context.Context, volume *storage.Volume) bool {
1327+
return HealSANPublishEnforcement(ctx, d, volume)
1328+
}
1329+
13261330
// CreateASALUNInternalID creates a string in the format /svm/<svm_name>/lun/<lun_name>
13271331
func (d *ASAStorageDriver) CreateASALUNInternalID(svm, name string) string {
13281332
return fmt.Sprintf("/svm/%s/lun/%s", svm, name)

storage_drivers/ontap/ontap_asa_nvme.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,6 +1479,10 @@ func (d *ASANVMeStorageDriver) CanEnablePublishEnforcement() bool {
14791479
return true
14801480
}
14811481

1482+
func (d *ASANVMeStorageDriver) HealVolumePublishEnforcement(ctx context.Context, volume *storage.Volume) bool {
1483+
return HealSANPublishEnforcement(ctx, d, volume)
1484+
}
1485+
14821486
// CreateASANVMeNamespaceInternalID creates a string in the format /svm/<svm_name>/<namespace_name>
14831487
func (d *ASANVMeStorageDriver) CreateASANVMeNamespaceInternalID(svm, name string) string {
14841488
return fmt.Sprintf("/svm/%s/namespace/%s", svm, name)

storage_drivers/ontap/ontap_common.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4576,6 +4576,33 @@ func EnableSANPublishEnforcement(
45764576
return nil
45774577
}
45784578

4579+
// HealSANPublishEnforcement is a no-op for ONTAP-SAN volumes because ONTAP-SAN already properly sets
4580+
// the LUN mappings during publish/unpublish,
4581+
// operations. This function is implemented to satisfy interface assertions on the drivers.
4582+
func HealSANPublishEnforcement(_ context.Context, _ storage.Driver, _ *storage.Volume) bool {
4583+
return false
4584+
}
4585+
4586+
// HealNASPublishEnforcement checks if publish enforcement should be enabled on the given NAS volume
4587+
// and updates the volume config accordingly. It returns true if the volume config was updated.
4588+
func HealNASPublishEnforcement(ctx context.Context, driver storage.Driver, volume *storage.Volume) bool {
4589+
var updated bool
4590+
// Check if publish enforcement is already set.
4591+
if volume.Config.AccessInfo.PublishEnforcement {
4592+
// If publish enforcement is already enabled on the volume, nothing to do.
4593+
return updated
4594+
}
4595+
4596+
policy := volume.Config.ExportPolicy
4597+
driverConfig := driver.GetCommonConfig(ctx)
4598+
if policy == getEmptyExportPolicyName(*driverConfig.StoragePrefix) ||
4599+
policy == volume.Config.InternalName {
4600+
volume.Config.AccessInfo.PublishEnforcement = true
4601+
updated = true
4602+
}
4603+
return updated
4604+
}
4605+
45794606
func ValidateStoragePrefixEconomy(storagePrefix string) error {
45804607
// Ensure storage prefix is compatible with ONTAP
45814608
matched, err := regexp.MatchString(`^$|^[a-zA-Z0-9_.-]*$`, storagePrefix)

storage_drivers/ontap/ontap_common_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/netapp/trident/storage"
3030
sa "github.com/netapp/trident/storage_attribute"
3131
drivers "github.com/netapp/trident/storage_drivers"
32+
fakeDriver "github.com/netapp/trident/storage_drivers/fake"
3233
"github.com/netapp/trident/storage_drivers/ontap/api"
3334
"github.com/netapp/trident/storage_drivers/ontap/api/azgo"
3435
"github.com/netapp/trident/storage_drivers/ontap/api/rest/client/networking"
@@ -10370,3 +10371,102 @@ func TestCleanupFailedCloneFlexVol(t *testing.T) {
1037010371
})
1037110372
}
1037210373
}
10374+
10375+
func TestHealNASPublishEnforcement(t *testing.T) {
10376+
tt := map[string]struct {
10377+
makeDriver func() storage.Driver
10378+
volume *storage.Volume
10379+
assertBool assert.BoolAssertionFunc
10380+
}{
10381+
"enables publish enforcement when policy is the same as internal name": {
10382+
makeDriver: func() storage.Driver {
10383+
config := drivers.FakeStorageDriverConfig{
10384+
CommonStorageDriverConfig: &drivers.CommonStorageDriverConfig{
10385+
StorageDriverName: "fakeDriver",
10386+
StoragePrefix: convert.ToPtr("fake_"),
10387+
},
10388+
}
10389+
return fakeDriver.NewFakeStorageDriver(ctx, config)
10390+
},
10391+
volume: &storage.Volume{
10392+
Config: &storage.VolumeConfig{
10393+
InternalName: "pvc-test-name",
10394+
ExportPolicy: "pvc-test-name",
10395+
AccessInfo: tridentmodels.VolumeAccessInfo{
10396+
PublishEnforcement: false,
10397+
},
10398+
},
10399+
},
10400+
assertBool: assert.True,
10401+
},
10402+
"enables publish enforcement when policy is the empty export policy": {
10403+
makeDriver: func() storage.Driver {
10404+
config := drivers.FakeStorageDriverConfig{
10405+
CommonStorageDriverConfig: &drivers.CommonStorageDriverConfig{
10406+
StorageDriverName: "fakeDriver",
10407+
StoragePrefix: convert.ToPtr("fake_"),
10408+
},
10409+
}
10410+
return fakeDriver.NewFakeStorageDriver(ctx, config)
10411+
},
10412+
volume: &storage.Volume{
10413+
Config: &storage.VolumeConfig{
10414+
InternalName: "pvc-test-name",
10415+
ExportPolicy: getEmptyExportPolicyName("fake_"),
10416+
AccessInfo: tridentmodels.VolumeAccessInfo{
10417+
PublishEnforcement: false,
10418+
},
10419+
},
10420+
},
10421+
assertBool: assert.True,
10422+
},
10423+
"does not enable publish enforcement when policy is not empty and policy is not the same as the volume": {
10424+
makeDriver: func() storage.Driver {
10425+
config := drivers.FakeStorageDriverConfig{
10426+
CommonStorageDriverConfig: &drivers.CommonStorageDriverConfig{
10427+
StorageDriverName: "fakeDriver",
10428+
StoragePrefix: convert.ToPtr("fake_"),
10429+
},
10430+
}
10431+
return fakeDriver.NewFakeStorageDriver(ctx, config)
10432+
},
10433+
volume: &storage.Volume{
10434+
Config: &storage.VolumeConfig{
10435+
InternalName: "pvc-test-name",
10436+
ExportPolicy: "trident-export-policy",
10437+
AccessInfo: tridentmodels.VolumeAccessInfo{
10438+
PublishEnforcement: false,
10439+
},
10440+
},
10441+
},
10442+
assertBool: assert.False,
10443+
},
10444+
"does not update if publish enforcement is alread set": {
10445+
makeDriver: func() storage.Driver {
10446+
config := drivers.FakeStorageDriverConfig{
10447+
CommonStorageDriverConfig: &drivers.CommonStorageDriverConfig{
10448+
StorageDriverName: "fakeDriver",
10449+
StoragePrefix: convert.ToPtr("fake_"),
10450+
},
10451+
}
10452+
return fakeDriver.NewFakeStorageDriver(ctx, config)
10453+
},
10454+
volume: &storage.Volume{
10455+
Config: &storage.VolumeConfig{
10456+
InternalName: "pvc-test-name",
10457+
ExportPolicy: "trident-export-policy",
10458+
AccessInfo: tridentmodels.VolumeAccessInfo{
10459+
PublishEnforcement: true,
10460+
},
10461+
},
10462+
},
10463+
assertBool: assert.False,
10464+
},
10465+
}
10466+
10467+
for name, fixture := range tt {
10468+
t.Run(name, func(t *testing.T) {
10469+
fixture.assertBool(t, HealNASPublishEnforcement(ctx, fixture.makeDriver(), fixture.volume))
10470+
})
10471+
}
10472+
}

storage_drivers/ontap/ontap_nas.go

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1991,19 +1991,5 @@ func (d *NASStorageDriver) CanEnablePublishEnforcement() bool {
19911991
func (d *NASStorageDriver) HealVolumePublishEnforcement(
19921992
ctx context.Context, vol *storage.Volume,
19931993
) bool {
1994-
var updated bool
1995-
// Check of publish enforcment is already set
1996-
if vol.Config.AccessInfo.PublishEnforcement {
1997-
// If publish enforcement is already enabled on the volume, nothing to do.
1998-
return updated
1999-
}
2000-
2001-
policy := vol.Config.ExportPolicy
2002-
driverConfig := d.GetCommonConfig(ctx)
2003-
if policy == getEmptyExportPolicyName(*driverConfig.StoragePrefix) ||
2004-
policy == vol.Config.InternalName {
2005-
vol.Config.AccessInfo.PublishEnforcement = true
2006-
updated = true
2007-
}
2008-
return updated
1994+
return HealNASPublishEnforcement(ctx, d, vol)
20091995
}

storage_drivers/ontap/ontap_nas_qtree.go

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2789,19 +2789,5 @@ func (d *NASQtreeStorageDriver) CanEnablePublishEnforcement() bool {
27892789
func (d *NASQtreeStorageDriver) HealVolumePublishEnforcement(
27902790
ctx context.Context, vol *storage.Volume,
27912791
) bool {
2792-
var updated bool
2793-
// Check of publish enforcment is already set
2794-
if vol.Config.AccessInfo.PublishEnforcement {
2795-
// If publish enforcement is already enabled on the volume, nothing to do.
2796-
return updated
2797-
}
2798-
2799-
policy := vol.Config.ExportPolicy
2800-
driverConfig := d.GetCommonConfig(ctx)
2801-
if policy == getEmptyExportPolicyName(*driverConfig.StoragePrefix) ||
2802-
policy == vol.Config.InternalName {
2803-
vol.Config.AccessInfo.PublishEnforcement = true
2804-
updated = true
2805-
}
2806-
return updated
2792+
return HealNASPublishEnforcement(ctx, d, vol)
28072793
}

storage_drivers/ontap/ontap_san.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1807,3 +1807,7 @@ func (d *SANStorageDriver) EnablePublishEnforcement(ctx context.Context, volume
18071807
func (d *SANStorageDriver) CanEnablePublishEnforcement() bool {
18081808
return true
18091809
}
1810+
1811+
func (d *SANStorageDriver) HealVolumePublishEnforcement(ctx context.Context, volume *storage.Volume) bool {
1812+
return HealSANPublishEnforcement(ctx, d, volume)
1813+
}

storage_drivers/ontap/ontap_san_economy.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2809,6 +2809,10 @@ func (d *SANEconomyStorageDriver) CanEnablePublishEnforcement() bool {
28092809
return true
28102810
}
28112811

2812+
func (d *SANEconomyStorageDriver) HealVolumePublishEnforcement(ctx context.Context, volume *storage.Volume) bool {
2813+
return HealSANPublishEnforcement(ctx, d, volume)
2814+
}
2815+
28122816
// ParseLunInternalID parses the passed string which is in the format /svm/<svm_name>/flexvol/<flexvol_name>/lun/<lun_name>
28132817
// and returns svm, flexvol and LUN name.
28142818
func (d SANEconomyStorageDriver) ParseLunInternalID(internalId string) (svm, flexvol, lun string, err error) {

storage_drivers/ontap/ontap_san_nvme.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,3 +1833,7 @@ func (d *NVMeStorageDriver) EnablePublishEnforcement(_ context.Context, volume *
18331833
func (d *NVMeStorageDriver) CanEnablePublishEnforcement() bool {
18341834
return true
18351835
}
1836+
1837+
func (d *NVMeStorageDriver) HealVolumePublishEnforcement(ctx context.Context, volume *storage.Volume) bool {
1838+
return HealSANPublishEnforcement(ctx, d, volume)
1839+
}

0 commit comments

Comments
 (0)