From ed67907122882785e98d1f8072152a25cce260cd Mon Sep 17 00:00:00 2001 From: Oded Viner Date: Sun, 12 Jan 2025 14:51:21 +0200 Subject: [PATCH] Adjust Node Label Conditions Based on Full Label Name on strechcluster Signed-off-by: Oded Viner --- api/v1/topologymap.go | 28 ++++++++++++++----- controllers/storagecluster/topology_test.go | 26 +++++++++++++++++ .../ocs-operator/api/v4/v1/topologymap.go | 17 +++++++++++ .../ocs-operator/api/v4/v1/topologymap.go | 17 +++++++++++ 4 files changed, 81 insertions(+), 7 deletions(-) diff --git a/api/v1/topologymap.go b/api/v1/topologymap.go index 63c008d2f5..d0c26b7f99 100644 --- a/api/v1/topologymap.go +++ b/api/v1/topologymap.go @@ -17,7 +17,8 @@ limitations under the License. package v1 import ( - "strings" + corev1 "k8s.io/api/core/v1" + "github.com/red-hat-storage/ocs-operator/v4/controllers/defaults" ) // NewNodeTopologyMap returns an initialized NodeTopologyMap @@ -61,18 +62,31 @@ func (m *NodeTopologyMap) Add(topologyKey string, value string) { m.Labels[topologyKey] = append(m.Labels[topologyKey], value) } -// GetKeyValues returns a node label matching the topologyKey and all values -// for that label across all storage nodes +// GetKeyValues returns a node label matching the supported topologyKey and all values +// for that label across all storage nodes. func (m *NodeTopologyMap) GetKeyValues(topologyKey string) (string, []string) { values := []string{} + // Supported failure domain labels + supportedLabels := map[string]string{ + "rack": defaults.RackTopologyKey, + "hostname": "kubernetes.io/hostname", + "zone": corev1.LabelZoneFailureDomainStable, + } + + // Get the specific label based on the topologyKey + expectedLabel, exists := supportedLabels[topologyKey] + if !exists { + return "", values // Return empty if the topologyKey is unsupported + } + + // Match the expected label and fetch the values for label, labelValues := range m.Labels { - if strings.Contains(label, topologyKey) { - topologyKey = label + if label == expectedLabel { values = labelValues - break + return label, values } } - return topologyKey, values + return "", values // Return empty if no match is found } diff --git a/controllers/storagecluster/topology_test.go b/controllers/storagecluster/topology_test.go index 81c09e4118..97aba900b5 100644 --- a/controllers/storagecluster/topology_test.go +++ b/controllers/storagecluster/topology_test.go @@ -3,6 +3,7 @@ package storagecluster import ( "context" "fmt" + "reflect" "testing" "github.com/stretchr/testify/assert" @@ -992,3 +993,28 @@ func TestDeterminePlacementRack(t *testing.T) { assert.Equalf(t, tc.expectedRack, actual, "[%s]: failed to get correct placement rack", tc.label) } } + +func TestGetKeyValuesStretchCluster(t *testing.T) { + // Create a new NodeTopologyMap + nodeTopologyMap := ocsv1.NewNodeTopologyMap() + + // Add valid and invalid labels + nodeTopologyMap.Add(corev1.LabelZoneFailureDomainStable, "zone1") + nodeTopologyMap.Add(corev1.LabelZoneFailureDomainStable, "zone2") + nodeTopologyMap.Add("topology.kubernetes.io/zone-principal", "zone-principal1") + + // Call the method + topologyKey, values := nodeTopologyMap.GetKeyValuesStrechCluster() + + // Expected values + expectedKey := corev1.LabelZoneFailureDomainStable + expectedValues := []string{"zone1", "zone2"} + + // Validate topologyKey + assert.Equal(t, expectedKey, topologyKey, "Mismatch in topologyKey") + + // Validate values using reflect.DeepEqual + if !reflect.DeepEqual(values, expectedValues) { + t.Errorf("Expected values: %v, got: %v", expectedValues, values) + } +} diff --git a/metrics/vendor/github.com/red-hat-storage/ocs-operator/api/v4/v1/topologymap.go b/metrics/vendor/github.com/red-hat-storage/ocs-operator/api/v4/v1/topologymap.go index 63c008d2f5..16db677b89 100644 --- a/metrics/vendor/github.com/red-hat-storage/ocs-operator/api/v4/v1/topologymap.go +++ b/metrics/vendor/github.com/red-hat-storage/ocs-operator/api/v4/v1/topologymap.go @@ -17,6 +17,7 @@ limitations under the License. package v1 import ( + corev1 "k8s.io/api/core/v1" "strings" ) @@ -76,3 +77,19 @@ func (m *NodeTopologyMap) GetKeyValues(topologyKey string) (string, []string) { return topologyKey, values } + +// GetKeyValuesStrechCluster returns the topologyKey (a node label matching the failure domain) +// and all associated values for the StretchCluster across all storage nodes. +func (m *NodeTopologyMap) GetKeyValuesStrechCluster() (string, []string) { + values := []string{} + topologyKey := "" + for label, labelValues := range m.Labels { + if label == corev1.LabelZoneFailureDomainStable { + topologyKey = label + values = labelValues + break + } + } + + return topologyKey, values +} diff --git a/vendor/github.com/red-hat-storage/ocs-operator/api/v4/v1/topologymap.go b/vendor/github.com/red-hat-storage/ocs-operator/api/v4/v1/topologymap.go index 63c008d2f5..16db677b89 100644 --- a/vendor/github.com/red-hat-storage/ocs-operator/api/v4/v1/topologymap.go +++ b/vendor/github.com/red-hat-storage/ocs-operator/api/v4/v1/topologymap.go @@ -17,6 +17,7 @@ limitations under the License. package v1 import ( + corev1 "k8s.io/api/core/v1" "strings" ) @@ -76,3 +77,19 @@ func (m *NodeTopologyMap) GetKeyValues(topologyKey string) (string, []string) { return topologyKey, values } + +// GetKeyValuesStrechCluster returns the topologyKey (a node label matching the failure domain) +// and all associated values for the StretchCluster across all storage nodes. +func (m *NodeTopologyMap) GetKeyValuesStrechCluster() (string, []string) { + values := []string{} + topologyKey := "" + for label, labelValues := range m.Labels { + if label == corev1.LabelZoneFailureDomainStable { + topologyKey = label + values = labelValues + break + } + } + + return topologyKey, values +}