Skip to content

Commit

Permalink
Add support for custom zone labels
Browse files Browse the repository at this point in the history
  • Loading branch information
tdawe committed Nov 29, 2024
1 parent 21d69bb commit 22b5607
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 6 deletions.
7 changes: 4 additions & 3 deletions service/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,12 @@ func (s *service) CreateVolume(
var volumeTopology []*csi.Topology
systemSegments := map[string]string{} // topology segments matching requested system for a volume

// Handle Zone topology, which happens when node is annotated with "Zone" label
// Handle Zone topology, which happens when node is annotated with a matching zone label
if len(zoneTargetMap) != 0 && accessibility != nil && len(accessibility.GetPreferred()) > 0 {
for _, topo := range accessibility.GetPreferred() {
for topoLabel, zoneName := range topo.Segments {
if strings.HasPrefix(topoLabel, "zone."+Name) {
Log.Infof("Zoning based on label %s", s.opts.zoneLabelKey)
if strings.HasPrefix(topoLabel, s.opts.zoneLabelKey) {
zoneTarget, ok := zoneTargetMap[ZoneName(zoneName)]
if !ok {
Log.Infof("no zone target for %s", zoneTarget)
Expand All @@ -241,7 +242,7 @@ func (s *service) CreateVolume(
continue
}

systemSegments["zone."+Name] = zoneName
systemSegments[s.opts.zoneLabelKey] = zoneName
volumeTopology = append(volumeTopology, &csi.Topology{
Segments: systemSegments,
})
Expand Down
2 changes: 2 additions & 0 deletions service/features/array-config/multi_az
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"systemID": "14dbbf5617523654",
"zone": {
"name": "zoneA",
"labelKey": "zone.csi-vxflexos.dellemc.com",
"protectionDomains": [
{
"name": "mocksystem",
Expand All @@ -27,6 +28,7 @@
"systemID": "15dbbf5617523655",
"zone": {
"name": "zoneB",
"labelKey": "zone.csi-vxflexos.dellemc.com",
"protectionDomains": [
{
"name": "mocksystem",
Expand Down
7 changes: 4 additions & 3 deletions service/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -758,8 +758,9 @@ func (s *service) NodeGetInfo(
// csi-vxflexos.dellemc.com/<systemID>: <provisionerName>
Log.Infof("Arrays: %+v", s.opts.arrays)
topology := map[string]string{}
if zone, ok := labels["zone."+Name]; ok {
topology["zone."+Name] = zone

if zone, ok := labels[s.opts.zoneLabelKey]; ok {
topology[s.opts.zoneLabelKey] = zone
}

for _, array := range s.opts.arrays {
Expand All @@ -772,7 +773,7 @@ func (s *service) NodeGetInfo(
topology[Name+"/"+array.SystemID+"-nfs"] = "true"
}

if zone, ok := topology["zone."+Name]; ok {
if zone, ok := topology[s.opts.zoneLabelKey]; ok {
if zone == string(array.AvailabilityZone.Name) {
// Add only the secret values with the correct zone.
nodeID, _ := GetNodeUID(ctx, s)
Expand Down
27 changes: 27 additions & 0 deletions service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ type (
// AvailabilityZone provides a mapping between cluster zones labels and storage systems
type AvailabilityZone struct {
Name ZoneName `json:"name"`
LabelKey string `json:"labelKey"`
ProtectionDomains []ProtectionDomain `json:"protectionDomains"`
}

Expand Down Expand Up @@ -186,6 +187,7 @@ type Opts struct {
IsQuotaEnabled bool // allow driver to enable quota limits for NFS volumes
ExternalAccess string // used for adding extra IP/IP range to the NFS export
KubeNodeName string
zoneLabelKey string
}

type service struct {
Expand Down Expand Up @@ -417,6 +419,13 @@ func (s *service) BeforeServe(
return err
}

// if custom zoning is being used, find the common label from the array secret
opts.zoneLabelKey, err = getZoneKeyLabelFromSecret(opts.arrays)
if err != nil {
Log.Warnf("unable to get zone key from secret: %s", err.Error())
return err
}

if err = s.ProcessMapSecretChange(); err != nil {
Log.Warnf("unable to configure dynamic configMap secret change detection : %s", err.Error())
return err
Expand Down Expand Up @@ -1873,3 +1882,21 @@ func ParseInt64FromContext(ctx context.Context, key string) (int64, error) {
func lookupEnv(ctx context.Context, key string) (string, bool) {
return csictx.LookupEnv(ctx, key)
}

func getZoneKeyLabelFromSecret(arrays map[string]*ArrayConnectionData) (string, error) {
zoneKeyLabel := ""

for _, array := range arrays {
if array.AvailabilityZone != nil {
if zoneKeyLabel == "" {
// Assumes that the key parameter is not empty
zoneKeyLabel = array.AvailabilityZone.LabelKey
} else if zoneKeyLabel != array.AvailabilityZone.LabelKey {
Log.Warnf("array %s zone key %s does not match %s", array.SystemID, array.AvailabilityZone.LabelKey, zoneKeyLabel)
return "", fmt.Errorf("array %s zone key %s does not match %s", array.SystemID, array.AvailabilityZone.LabelKey, zoneKeyLabel)
}
}
}

return zoneKeyLabel, nil
}
64 changes: 64 additions & 0 deletions service/service_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,70 @@ func TestGetIPAddressByInterface(t *testing.T) {
}
}

func TestGetZoneKeyLabelFromSecret(t *testing.T) {
tests := []struct {
name string
arrays map[string]*ArrayConnectionData
expectedLabel string
expectedErr error
}{
{
name: "Empty array connection data",
arrays: map[string]*ArrayConnectionData{},
expectedLabel: "",
expectedErr: nil,
},
{
name: "Array connection data with same zone label keys",
arrays: map[string]*ArrayConnectionData{
"array1": {
AvailabilityZone: &AvailabilityZone{
Name: "zone1",
LabelKey: "custom-zone.io/area",
},
},
"array2": {
AvailabilityZone: &AvailabilityZone{
Name: "zone2",
LabelKey: "custom-zone.io/area",
},
},
},
expectedLabel: "custom-zone.io/area",
expectedErr: nil,
},
{
name: "Array connection data with different label keys",
arrays: map[string]*ArrayConnectionData{
"array1": {
SystemID: "system-1",
AvailabilityZone: &AvailabilityZone{
Name: "zone1",
LabelKey: "custom-zone-1.io/area",
},
},
"array2": {
SystemID: "system-2",
AvailabilityZone: &AvailabilityZone{
Name: "zone2",
LabelKey: "custom-zone-2.io/area",
},
},
},
expectedLabel: "",
expectedErr: fmt.Errorf("array system-2 zone key custom-zone-2.io/area does not match custom-zone-1.io/area"),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
label, err := getZoneKeyLabelFromSecret(tt.arrays)
assert.Equal(t, err, tt.expectedErr)
assert.Equal(t, label, tt.expectedLabel)
})
}
}

func TestFindNetworkInterfaceIPs(t *testing.T) {
tests := []struct {
name string
Expand Down
4 changes: 4 additions & 0 deletions service/step_defs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4250,6 +4250,10 @@ func (f *feature) iUseConfig(filename string) error {
}
}

f.service.opts.zoneLabelKey, err = getZoneKeyLabelFromSecret(f.service.opts.arrays)
if err != nil {
return fmt.Errorf("get zone key label from secret: %s", err.Error())
}
fmt.Printf("****************************************************** s.opts.arrays %v\n", f.service.opts.arrays)
f.service.systemProbeAll(context.Background())
f.adminClient = f.service.adminClients[arrayID]
Expand Down

0 comments on commit 22b5607

Please sign in to comment.