Skip to content

Commit 5804bdd

Browse files
authored
Merge pull request #1358 from YaoZengzeng/se
prevent deletion of addresses that are already occupied by other objects
2 parents 09e9e8f + 82e0dce commit 5804bdd

File tree

4 files changed

+140
-1
lines changed

4 files changed

+140
-1
lines changed

pkg/controller/workload/cache/service_cache.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,18 @@ func (s *serviceCache) AddOrUpdateService(svc *workloadapi.Service) {
7272
func (s *serviceCache) DeleteService(resourceName string) {
7373
s.mutex.Lock()
7474
defer s.mutex.Unlock()
75+
76+
svc, ok := s.servicesByResourceName[resourceName]
77+
if !ok {
78+
return
79+
}
80+
81+
for _, addr := range svc.GetAddresses() {
82+
addrStr, _ := netip.AddrFromSlice(addr.GetAddress())
83+
networkAddress := composeNetworkAddress(addr.GetNetwork(), addrStr)
84+
s.deleteAddr(networkAddress, svc)
85+
}
86+
7587
delete(s.servicesByResourceName, resourceName)
7688
}
7789

@@ -91,3 +103,13 @@ func (s *serviceCache) GetService(resourceName string) *workloadapi.Service {
91103
defer s.mutex.RUnlock()
92104
return s.servicesByResourceName[resourceName]
93105
}
106+
107+
func (s *serviceCache) deleteAddr(addr NetworkAddress, svc *workloadapi.Service) {
108+
if service, ok := s.servicesByAddr[addr]; ok {
109+
if service.GetNamespace() == svc.GetNamespace() && service.GetName() == svc.GetName() {
110+
// NOTE: If the associated service is updated, we can no longer delete it.
111+
// Ref: https://github.com/kmesh-net/kmesh/issues/1352
112+
delete(s.servicesByAddr, addr)
113+
}
114+
}
115+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright The Kmesh Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at:
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package cache
18+
19+
import (
20+
"net/netip"
21+
"testing"
22+
23+
"github.com/stretchr/testify/assert"
24+
25+
"kmesh.net/kmesh/api/v2/workloadapi"
26+
"kmesh.net/kmesh/pkg/controller/workload/common"
27+
)
28+
29+
func TestAddOrUpdateService(t *testing.T) {
30+
cache := NewServiceCache()
31+
32+
svc1 := common.CreateFakeService("svc1", "10.240.10.1", "", nil)
33+
34+
cache.AddOrUpdateService(svc1)
35+
36+
name := svc1.ResourceName()
37+
38+
assert.Equal(t, svc1, cache.GetService(name))
39+
assert.Equal(t, svc1, cache.GetServiceByAddr(NetworkAddress{Address: netip.MustParseAddr("10.240.10.1")}))
40+
}
41+
42+
func TestDeleteService(t *testing.T) {
43+
t.Run("normal delete", func(t *testing.T) {
44+
cache := NewServiceCache()
45+
46+
svc1 := common.CreateFakeService("svc1", "10.240.10.1", "", nil)
47+
48+
cache.AddOrUpdateService(svc1)
49+
50+
name := svc1.ResourceName()
51+
assert.Equal(t, svc1, cache.GetService(name))
52+
53+
cache.DeleteService(name)
54+
assert.Equal(t, (*workloadapi.Service)(nil), cache.GetService(name))
55+
assert.Equal(t, (*workloadapi.Service)(nil), cache.GetServiceByAddr(NetworkAddress{Address: netip.MustParseAddr("10.240.10.1")}))
56+
})
57+
58+
t.Run("address override", func(t *testing.T) {
59+
cache := NewServiceCache()
60+
61+
svc1 := common.CreateFakeService("svc1", "10.240.10.1", "", nil)
62+
cache.AddOrUpdateService(svc1)
63+
64+
// Both svc1 and svc2 point to address "10.240.10.1"
65+
svc2 := common.CreateFakeService("svc2", "10.240.10.1", "", nil)
66+
cache.AddOrUpdateService(svc2)
67+
68+
name1 := svc1.ResourceName()
69+
name2 := svc2.ResourceName()
70+
71+
assert.Equal(t, svc1, cache.GetService(name1))
72+
assert.Equal(t, svc2, cache.GetService(name2))
73+
74+
// Delete svc1
75+
cache.DeleteService(name1)
76+
// Address "10.240.10.1" has been overwritten by svc2, so it will not be deleted
77+
assert.Equal(t, svc2, cache.GetServiceByAddr(NetworkAddress{Address: netip.MustParseAddr("10.240.10.1")}))
78+
})
79+
}

pkg/controller/workload/cache/workload_cache.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func (w *cache) DeleteWorkload(uid string) {
9898
for _, ip := range workload.Addresses {
9999
addr, _ := netip.AddrFromSlice(ip)
100100
networkAddress := composeNetworkAddress(workload.Network, addr)
101-
delete(w.byAddr, networkAddress)
101+
w.deleteAddr(networkAddress, uid)
102102
}
103103

104104
delete(w.byUid, uid)
@@ -115,3 +115,13 @@ func (w *cache) List() []*workloadapi.Workload {
115115

116116
return out
117117
}
118+
119+
func (w *cache) deleteAddr(addr NetworkAddress, uid string) {
120+
if workload, ok := w.byAddr[addr]; ok {
121+
if workload.Uid == uid {
122+
// NOTE: If the uid is updated, it means that a new object occupies this address and we can no longer delete it.
123+
// Ref: https://github.com/kmesh-net/kmesh/issues/1352
124+
delete(w.byAddr, addr)
125+
}
126+
}
127+
}

pkg/controller/workload/cache/workload_cache_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,32 @@ func TestDeleteWorkload(t *testing.T) {
134134
assert.Equal(t, (*workloadapi.Workload)(nil), w.byAddr[NetworkAddress{Network: "ut-net", Address: addr1}])
135135
assert.Equal(t, (*workloadapi.Workload)(nil), w.byAddr[NetworkAddress{Network: "ut-net", Address: addr2}])
136136
})
137+
138+
t.Run("address override", func(t *testing.T) {
139+
w := NewWorkloadCache()
140+
Addresses := []string{
141+
"192.168.224.22",
142+
"1.2.3.4",
143+
}
144+
workload := common.CreateFakeWorkload("192.168.224.22", "", common.WithWorkloadBasicInfo("ut-workload", "123456", "ut-net"), common.WithAddresses(Addresses))
145+
w.AddOrUpdateWorkload(workload)
146+
147+
// Both workload2 and workload point to address "192.168.224.22"
148+
workload2 := common.CreateFakeWorkload("192.168.224.22", "", common.WithWorkloadBasicInfo("ut-workload-2", "abcdefg", "ut-net"))
149+
w.AddOrUpdateWorkload(workload2)
150+
151+
assert.Equal(t, workload, w.byUid["123456"])
152+
assert.Equal(t, workload2, w.byUid["abcdefg"])
153+
154+
w.DeleteWorkload("123456")
155+
assert.Equal(t, (*workloadapi.Workload)(nil), w.byUid["123456"])
156+
157+
addr0 := netip.MustParseAddr(Addresses[0])
158+
addr1 := netip.MustParseAddr(Addresses[1])
159+
160+
// Address "192.168.224.22" has been overwritten by workload2, so it will not be deleted
161+
assert.Equal(t, workload2, w.byAddr[NetworkAddress{Network: "ut-net", Address: addr0}])
162+
// Address "1.2.3.4" still points to workload, so it will be deleted.
163+
assert.Equal(t, (*workloadapi.Workload)(nil), w.byAddr[NetworkAddress{Network: "ut-net", Address: addr1}])
164+
})
137165
}

0 commit comments

Comments
 (0)