Skip to content

Commit 6ef8f93

Browse files
committed
fix: ignore the case when updating tags
1 parent cd39757 commit 6ef8f93

File tree

5 files changed

+103
-29
lines changed

5 files changed

+103
-29
lines changed

staging/src/k8s.io/legacy-cloud-providers/azure/azure_loadbalancer.go

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2139,7 +2139,6 @@ func shouldReleaseExistingOwnedPublicIP(existingPip *network.PublicIPAddress, lb
21392139

21402140
// ensurePIPTagged ensures the public IP of the service is tagged as configured
21412141
func (az *Cloud) ensurePIPTagged(service *v1.Service, pip *network.PublicIPAddress) bool {
2142-
changed := false
21432142
configTags := parseTags(az.Tags)
21442143
annotationTags := make(map[string]*string)
21452144
if _, ok := service.Annotations[ServiceAnnotationAzurePIPTags]; ok {
@@ -2162,12 +2161,10 @@ func (az *Cloud) ensurePIPTagged(service *v1.Service, pip *network.PublicIPAddre
21622161
if serviceNames != nil {
21632162
configTags[serviceTagKey] = serviceNames
21642163
}
2165-
for k, v := range configTags {
2166-
if vv, ok := pip.Tags[k]; !ok || !strings.EqualFold(to.String(v), to.String(vv)) {
2167-
pip.Tags[k] = v
2168-
changed = true
2169-
}
2170-
}
2164+
2165+
tags, changed := reconcileTags(pip.Tags, configTags)
2166+
pip.Tags = tags
2167+
21712168
return changed
21722169
}
21732170

@@ -2728,38 +2725,32 @@ func unbindServiceFromPIP(pip *network.PublicIPAddress, serviceName string) erro
27282725

27292726
// ensureLoadBalancerTagged ensures every load balancer in the resource group is tagged as configured
27302727
func (az *Cloud) ensureLoadBalancerTagged(lb *network.LoadBalancer) bool {
2731-
changed := false
27322728
if az.Tags == "" {
27332729
return false
27342730
}
27352731
tags := parseTags(az.Tags)
27362732
if lb.Tags == nil {
27372733
lb.Tags = make(map[string]*string)
27382734
}
2739-
for k, v := range tags {
2740-
if vv, ok := lb.Tags[k]; !ok || !strings.EqualFold(to.String(v), to.String(vv)) {
2741-
lb.Tags[k] = v
2742-
changed = true
2743-
}
2744-
}
2735+
2736+
tags, changed := reconcileTags(lb.Tags, tags)
2737+
lb.Tags = tags
2738+
27452739
return changed
27462740
}
27472741

27482742
// ensureSecurityGroupTagged ensures the security group is tagged as configured
27492743
func (az *Cloud) ensureSecurityGroupTagged(sg *network.SecurityGroup) bool {
2750-
changed := false
27512744
if az.Tags == "" {
27522745
return false
27532746
}
27542747
tags := parseTags(az.Tags)
27552748
if sg.Tags == nil {
27562749
sg.Tags = make(map[string]*string)
27572750
}
2758-
for k, v := range tags {
2759-
if vv, ok := sg.Tags[k]; !ok || !strings.EqualFold(to.String(v), to.String(vv)) {
2760-
sg.Tags[k] = v
2761-
changed = true
2762-
}
2763-
}
2751+
2752+
tags, changed := reconcileTags(sg.Tags, tags)
2753+
sg.Tags = tags
2754+
27642755
return changed
27652756
}

staging/src/k8s.io/legacy-cloud-providers/azure/azure_loadbalancer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3784,7 +3784,7 @@ func TestEnsurePIPTagged(t *testing.T) {
37843784
service := v1.Service{
37853785
ObjectMeta: metav1.ObjectMeta{
37863786
Annotations: map[string]string{
3787-
ServiceAnnotationAzurePIPTags: "a=b,c=d,e=,=f,ghi",
3787+
ServiceAnnotationAzurePIPTags: "A=b,c=d,e=,=f,ghi",
37883788
},
37893789
},
37903790
}

staging/src/k8s.io/legacy-cloud-providers/azure/azure_routes.go

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -541,16 +541,13 @@ func (az *Cloud) ensureRouteTableTagged(rt *network.RouteTable) (map[string]*str
541541
if az.Tags == "" {
542542
return nil, false
543543
}
544-
changed := false
545544
tags := parseTags(az.Tags)
546545
if rt.Tags == nil {
547546
rt.Tags = make(map[string]*string)
548547
}
549-
for k, v := range tags {
550-
if vv, ok := rt.Tags[k]; !ok || !strings.EqualFold(to.String(v), to.String(vv)) {
551-
rt.Tags[k] = v
552-
changed = true
553-
}
554-
}
548+
549+
tags, changed := reconcileTags(rt.Tags, tags)
550+
rt.Tags = tags
551+
555552
return rt.Tags, changed
556553
}

staging/src/k8s.io/legacy-cloud-providers/azure/azure_utils.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,28 @@ func parseTags(tags string) map[string]*string {
138138
}
139139
return formatted
140140
}
141+
142+
func findKeyInMapCaseInsensitive(targetMap map[string]*string, key string) (bool, string) {
143+
for k := range targetMap {
144+
if strings.EqualFold(k, key) {
145+
return true, k
146+
}
147+
}
148+
149+
return false, ""
150+
}
151+
152+
func reconcileTags(currentTagsOnResource, newTags map[string]*string) (reconciledTags map[string]*string, changed bool) {
153+
for k, v := range newTags {
154+
found, key := findKeyInMapCaseInsensitive(currentTagsOnResource, k)
155+
if !found {
156+
currentTagsOnResource[k] = v
157+
changed = true
158+
} else if !strings.EqualFold(to.String(v), to.String(currentTagsOnResource[key])) {
159+
currentTagsOnResource[key] = v
160+
changed = true
161+
}
162+
}
163+
164+
return currentTagsOnResource, changed
165+
}

staging/src/k8s.io/legacy-cloud-providers/azure/azure_utils_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"testing"
2424
"time"
2525

26+
"github.com/Azure/go-autorest/autorest/to"
2627
"github.com/stretchr/testify/assert"
2728
)
2829

@@ -152,3 +153,63 @@ func TestConvertTagsToMap(t *testing.T) {
152153
}
153154
}
154155
}
156+
157+
func TestReconcileTags(t *testing.T) {
158+
for _, testCase := range []struct {
159+
description string
160+
currentTagsOnResource, newTags, expectedTags map[string]*string
161+
expectedChanged bool
162+
}{
163+
{
164+
description: "reconcileTags should add missing tags and update existing tags",
165+
currentTagsOnResource: map[string]*string{
166+
"a": to.StringPtr("b"),
167+
},
168+
newTags: map[string]*string{
169+
"a": to.StringPtr("c"),
170+
"b": to.StringPtr("d"),
171+
},
172+
expectedTags: map[string]*string{
173+
"a": to.StringPtr("c"),
174+
"b": to.StringPtr("d"),
175+
},
176+
expectedChanged: true,
177+
},
178+
{
179+
description: "reconcileTags should ignore the case of keys when comparing",
180+
currentTagsOnResource: map[string]*string{
181+
"A": to.StringPtr("b"),
182+
"c": to.StringPtr("d"),
183+
},
184+
newTags: map[string]*string{
185+
"a": to.StringPtr("b"),
186+
"C": to.StringPtr("d"),
187+
},
188+
expectedTags: map[string]*string{
189+
"A": to.StringPtr("b"),
190+
"c": to.StringPtr("d"),
191+
},
192+
},
193+
{
194+
description: "reconcileTags should ignore the case of values when comparing",
195+
currentTagsOnResource: map[string]*string{
196+
"A": to.StringPtr("b"),
197+
"c": to.StringPtr("d"),
198+
},
199+
newTags: map[string]*string{
200+
"a": to.StringPtr("B"),
201+
"C": to.StringPtr("D"),
202+
},
203+
expectedTags: map[string]*string{
204+
"A": to.StringPtr("b"),
205+
"c": to.StringPtr("d"),
206+
},
207+
},
208+
} {
209+
t.Run(testCase.description, func(t *testing.T) {
210+
tags, changed := reconcileTags(testCase.currentTagsOnResource, testCase.newTags)
211+
assert.Equal(t, testCase.expectedChanged, changed)
212+
assert.Equal(t, testCase.expectedTags, tags)
213+
})
214+
}
215+
}

0 commit comments

Comments
 (0)