• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubeovn / kube-ovn / 20055545781

09 Dec 2025 07:31AM UTC coverage: 21.457% (-0.009%) from 21.466%
20055545781

push

github

zbb88888
ovn process skip non-ovn subnet (#6018)

Signed-off-by: zbb88888 <jmdxjsjgcxy@gmail.com>

0 of 12 new or added lines in 3 files covered. (0.0%)

2 existing lines in 1 file now uncovered.

10641 of 49592 relevant lines covered (21.46%)

0.25 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pkg/controller/vip.go
1
package controller
2

3
import (
4
        "context"
5
        "encoding/json"
6
        "errors"
7
        "fmt"
8
        "slices"
9
        "strings"
10

11
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
12
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13
        "k8s.io/apimachinery/pkg/types"
14
        "k8s.io/client-go/tools/cache"
15
        "k8s.io/klog/v2"
16
        "sigs.k8s.io/controller-runtime/pkg/client"
17
        "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
18

19
        kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
20
        "github.com/kubeovn/kube-ovn/pkg/ovs"
21
        "github.com/kubeovn/kube-ovn/pkg/util"
22
)
23

24
func (c *Controller) enqueueAddVirtualIP(obj any) {
×
25
        key := cache.MetaObjectToName(obj.(*kubeovnv1.Vip)).String()
×
26
        klog.Infof("enqueue add vip %s", key)
×
27
        c.addVirtualIPQueue.Add(key)
×
28
}
×
29

30
func (c *Controller) enqueueUpdateVirtualIP(oldObj, newObj any) {
×
31
        oldVip := oldObj.(*kubeovnv1.Vip)
×
32
        newVip := newObj.(*kubeovnv1.Vip)
×
33
        key := cache.MetaObjectToName(newVip).String()
×
34
        if !newVip.DeletionTimestamp.IsZero() ||
×
35
                oldVip.Spec.MacAddress != newVip.Spec.MacAddress ||
×
36
                oldVip.Spec.V4ip != newVip.Spec.V4ip ||
×
37
                oldVip.Spec.V6ip != newVip.Spec.V6ip {
×
38
                klog.Infof("enqueue update vip %s", key)
×
39
                c.updateVirtualIPQueue.Add(key)
×
40
        }
×
41
        if !slices.Equal(oldVip.Spec.Selector, newVip.Spec.Selector) {
×
42
                klog.Infof("enqueue update virtual parents for %s", key)
×
43
                c.updateVirtualParentsQueue.Add(key)
×
44
        }
×
45
}
46

47
func (c *Controller) enqueueDelVirtualIP(obj any) {
×
48
        var vip *kubeovnv1.Vip
×
49
        switch t := obj.(type) {
×
50
        case *kubeovnv1.Vip:
×
51
                vip = t
×
52
        case cache.DeletedFinalStateUnknown:
×
53
                v, ok := t.Obj.(*kubeovnv1.Vip)
×
54
                if !ok {
×
55
                        klog.Warningf("unexpected object type: %T", t.Obj)
×
56
                        return
×
57
                }
×
58
                vip = v
×
59
        default:
×
60
                klog.Warningf("unexpected type: %T", obj)
×
61
                return
×
62
        }
63

64
        key := cache.MetaObjectToName(vip).String()
×
65
        klog.Infof("enqueue del vip %s", key)
×
66
        c.delVirtualIPQueue.Add(vip)
×
67
}
68

69
func (c *Controller) handleAddVirtualIP(key string) error {
×
70
        cachedVip, err := c.virtualIpsLister.Get(key)
×
71
        if err != nil {
×
72
                if k8serrors.IsNotFound(err) {
×
73
                        return nil
×
74
                }
×
75
                klog.Error(err)
×
76
                return err
×
77
        }
78
        if cachedVip.Status.Mac != "" {
×
79
                // already ok
×
80
                return nil
×
81
        }
×
82
        klog.V(3).Infof("handle add vip %s", key)
×
83
        vip := cachedVip.DeepCopy()
×
84
        var sourceV4Ip, sourceV6Ip, v4ip, v6ip, mac, subnetName string
×
85
        subnetName = vip.Spec.Subnet
×
86
        if subnetName == "" {
×
87
                return fmt.Errorf("failed to create vip '%s', subnet should be set", key)
×
88
        }
×
89
        subnet, err := c.subnetsLister.Get(subnetName)
×
90
        if err != nil {
×
91
                klog.Errorf("failed to get subnet %s: %v", subnetName, err)
×
92
                return err
×
93
        }
×
94
        portName := ovs.PodNameToPortName(vip.Name, vip.Spec.Namespace, subnet.Spec.Provider)
×
95
        sourceV4Ip = vip.Spec.V4ip
×
96
        sourceV6Ip = vip.Spec.V6ip
×
97
        // v6 ip address can not use upper case
×
98
        if util.ContainsUppercase(vip.Spec.V6ip) {
×
99
                err := fmt.Errorf("vip %s v6 ip address %s can not contain upper case", vip.Name, vip.Spec.V6ip)
×
100
                klog.Error(err)
×
101
                return err
×
102
        }
×
103
        var macPointer *string
×
104
        ipStr := util.GetStringIP(sourceV4Ip, sourceV6Ip)
×
105
        if ipStr != "" || vip.Spec.MacAddress != "" {
×
106
                if vip.Spec.MacAddress != "" {
×
107
                        macPointer = &vip.Spec.MacAddress
×
108
                }
×
109
                v4ip, v6ip, mac, err = c.acquireStaticIPAddress(subnet.Name, vip.Name, portName, ipStr, macPointer)
×
110
        } else {
×
111
                // Random allocate
×
112
                v4ip, v6ip, mac, err = c.acquireIPAddress(subnet.Name, vip.Name, portName)
×
113
        }
×
114
        if err != nil {
×
115
                klog.Error(err)
×
116
                return err
×
117
        }
×
118
        if vip.Spec.Type == util.SwitchLBRuleVip {
×
119
                // create a lsp use subnet gw mac, and set it option as arp_proxy
×
120
                lrpName := fmt.Sprintf("%s-%s", subnet.Spec.Vpc, subnet.Name)
×
121
                klog.Infof("get logical router port %s", lrpName)
×
122
                lrp, err := c.OVNNbClient.GetLogicalRouterPort(lrpName, false)
×
123
                if err != nil {
×
124
                        klog.Errorf("failed to get lrp %s: %v", lrpName, err)
×
125
                        return err
×
126
                }
×
127
                if lrp.MAC == "" {
×
128
                        err = fmt.Errorf("logical router port %s should have mac", lrpName)
×
129
                        klog.Error(err)
×
130
                        return err
×
131
                }
×
132
                mac = lrp.MAC
×
133
                ipStr := util.GetStringIP(v4ip, v6ip)
×
134
                if err := c.OVNNbClient.CreateLogicalSwitchPort(subnet.Name, portName, ipStr, mac, vip.Name, vip.Spec.Namespace, false, "", "", false, nil, subnet.Spec.Vpc); err != nil {
×
135
                        err = fmt.Errorf("failed to create lsp %s: %w", portName, err)
×
136
                        klog.Error(err)
×
137
                        return err
×
138
                }
×
139
                if err := c.OVNNbClient.SetLogicalSwitchPortArpProxy(portName, true); err != nil {
×
140
                        err = fmt.Errorf("failed to enable lsp arp proxy for vip %s: %w", portName, err)
×
141
                        klog.Error(err)
×
142
                        return err
×
143
                }
×
144
        }
145

146
        if vip.Spec.Type == util.KubeHostVMVip {
×
147
                // k8s host network pod vm use vip for its nic ip
×
148
                klog.Infof("create lsp for host network pod vm nic ip %s", vip.Name)
×
149
                ipStr := util.GetStringIP(v4ip, v6ip)
×
150
                if err := c.OVNNbClient.CreateLogicalSwitchPort(subnet.Name, portName, ipStr, mac, vip.Name, vip.Spec.Namespace, false, "", "", false, nil, subnet.Spec.Vpc); err != nil {
×
151
                        err = fmt.Errorf("failed to create lsp %s: %w", portName, err)
×
152
                        klog.Error(err)
×
153
                        return err
×
154
                }
×
155
        }
156
        if err = c.createOrUpdateVipCR(key, vip.Spec.Namespace, subnet.Name, v4ip, v6ip, mac); err != nil {
×
157
                klog.Errorf("failed to create or update vip '%s', %v", vip.Name, err)
×
158
                return err
×
159
        }
×
160
        if vip.Spec.Type == util.KubeHostVMVip {
×
161
                // vm use the vip as its real ip
×
162
                klog.Infof("created host network pod vm ip %s", key)
×
163
                return nil
×
164
        }
×
165
        if err := c.handleUpdateVirtualParents(key); err != nil {
×
166
                err := fmt.Errorf("error syncing virtual parents for vip '%s': %s", key, err.Error())
×
167
                klog.Error(err)
×
168
                return err
×
169
        }
×
170
        return nil
×
171
}
172

173
func (c *Controller) handleUpdateVirtualIP(key string) error {
×
174
        cachedVip, err := c.virtualIpsLister.Get(key)
×
175
        if err != nil {
×
176
                if k8serrors.IsNotFound(err) {
×
177
                        return nil
×
178
                }
×
179
                klog.Error(err)
×
180
                return err
×
181
        }
182
        vip := cachedVip.DeepCopy()
×
183
        // should delete
×
184
        if !vip.DeletionTimestamp.IsZero() {
×
185
                if err = c.handleDelVipFinalizer(key); err != nil {
×
186
                        klog.Errorf("failed to handle vip finalizer %v", err)
×
187
                        return err
×
188
                }
×
189
                return nil
×
190
        }
191
        // v6 ip address can not use upper case
192
        if util.ContainsUppercase(vip.Spec.V6ip) {
×
193
                err := fmt.Errorf("vip %s v6 ip address %s can not contain upper case", vip.Name, vip.Spec.V6ip)
×
194
                klog.Error(err)
×
195
                return err
×
196
        }
×
197
        // not support change
198
        if vip.Status.Mac != "" && vip.Status.Mac != vip.Spec.MacAddress {
×
199
                err = errors.New("not support change mac of vip")
×
200
                klog.Errorf("%v", err)
×
201
                return err
×
202
        }
×
203
        if vip.Status.V4ip != "" && vip.Status.V4ip != vip.Spec.V4ip {
×
204
                err = errors.New("not support change v4 ip of vip")
×
205
                klog.Errorf("%v", err)
×
206
                return err
×
207
        }
×
208
        if vip.Status.V6ip != "" && vip.Status.V6ip != vip.Spec.V6ip {
×
209
                err = errors.New("not support change v6 ip of vip")
×
210
                klog.Errorf("%v", err)
×
211
                return err
×
212
        }
×
213
        // should update
214
        if vip.Status.Mac == "" {
×
215
                if err = c.createOrUpdateVipCR(key, vip.Spec.Namespace, vip.Spec.Subnet,
×
216
                        vip.Spec.V4ip, vip.Spec.V6ip, vip.Spec.MacAddress); err != nil {
×
217
                        klog.Error(err)
×
218
                        return err
×
219
                }
×
220
                ready := true
×
221
                if err = c.patchVipStatus(key, vip.Spec.V4ip, ready); err != nil {
×
222
                        klog.Error(err)
×
223
                        return err
×
224
                }
×
225
                if err = c.handleAddVipFinalizer(key); err != nil {
×
226
                        klog.Errorf("failed to handle vip finalizer %v", err)
×
227
                        return err
×
228
                }
×
229
        }
230
        return nil
×
231
}
232

233
func (c *Controller) handleDelVirtualIP(vip *kubeovnv1.Vip) error {
×
234
        klog.Infof("handle delete vip %s", vip.Name)
×
235
        // TODO:// clean vip in its parent port aap list
×
236
        if vip.Spec.Type != "" {
×
237
                subnet, err := c.subnetsLister.Get(vip.Spec.Subnet)
×
238
                if err != nil {
×
239
                        klog.Errorf("failed to get subnet %s: %v", vip.Spec.Subnet, err)
×
240
                        return err
×
241
                }
×
242
                portName := ovs.PodNameToPortName(vip.Name, vip.Spec.Namespace, subnet.Spec.Provider)
×
243
                klog.Infof("delete vip lsp %s", portName)
×
244
                if err := c.OVNNbClient.DeleteLogicalSwitchPort(portName); err != nil {
×
245
                        err = fmt.Errorf("failed to delete lsp %s: %w", vip.Name, err)
×
246
                        klog.Error(err)
×
247
                        return err
×
248
                }
×
249
        }
250
        // delete virtual ports
251
        if err := c.OVNNbClient.DeleteLogicalSwitchPort(vip.Name); err != nil {
×
252
                klog.Errorf("delete virtual logical switch port %s from logical switch %s: %v", vip.Name, vip.Spec.Subnet, err)
×
253
                return err
×
254
        }
×
255
        c.ipam.ReleaseAddressByPod(vip.Name, vip.Spec.Subnet)
×
256
        c.updateSubnetStatusQueue.Add(vip.Spec.Subnet)
×
257
        return nil
×
258
}
259

260
func (c *Controller) handleUpdateVirtualParents(key string) error {
×
261
        cachedVip, err := c.virtualIpsLister.Get(key)
×
262
        if err != nil {
×
263
                if k8serrors.IsNotFound(err) {
×
264
                        return nil
×
265
                }
×
266
                klog.Error(err)
×
267
                return err
×
268
        }
269
        if cachedVip.Spec.Type == util.KubeHostVMVip {
×
270
                // vm use the vip as its real ip
×
271
                klog.Infof("created host network pod vm ip %s", key)
×
272
                return nil
×
273
        }
×
274
        // only pods in the same namespace as vip are allowed to use aap
275
        if (cachedVip.Status.V4ip == "" && cachedVip.Status.V6ip == "") || cachedVip.Spec.Namespace == "" {
×
276
                return nil
×
277
        }
×
278

279
        // add new virtual port if not exist
280
        ipStr := util.GetStringIP(cachedVip.Status.V4ip, cachedVip.Status.V6ip)
×
281
        if err = c.OVNNbClient.CreateVirtualLogicalSwitchPort(cachedVip.Name, cachedVip.Spec.Subnet, ipStr); err != nil {
×
282
                klog.Errorf("create virtual port with vip %s from logical switch %s: %v", cachedVip.Name, cachedVip.Spec.Subnet, err)
×
283
                return err
×
284
        }
×
285

286
        // update virtual parents
287
        if cachedVip.Spec.Type == util.SwitchLBRuleVip {
×
288
                // switch lb rule vip no need to have virtual parents
×
289
                return nil
×
290
        }
×
291

292
        // vip cloud use selector to select pods as its virtual parents
293
        selectors := make(map[string]string)
×
294
        for _, v := range cachedVip.Spec.Selector {
×
295
                parts := strings.Split(strings.TrimSpace(v), ":")
×
296
                if len(parts) != 2 {
×
297
                        continue
×
298
                }
299
                selectors[strings.TrimSpace(parts[0])] = strings.TrimSpace(parts[1])
×
300
        }
301
        sel, _ := metav1.LabelSelectorAsSelector(&metav1.LabelSelector{MatchLabels: selectors})
×
302
        pods, err := c.podsLister.Pods(cachedVip.Spec.Namespace).List(sel)
×
303
        if err != nil {
×
304
                klog.Errorf("failed to list pods that meet selector requirements, %v", err)
×
305
                return err
×
306
        }
×
307

308
        var virtualParents []string
×
309
        for _, pod := range pods {
×
310
                if pod.Annotations == nil {
×
311
                        // pod has no annotations
×
312
                        continue
×
313
                }
314
                if aaps := strings.Split(pod.Annotations[util.AAPsAnnotation], ","); !slices.Contains(aaps, cachedVip.Name) {
×
315
                        continue
×
316
                }
317
                podName := c.getNameByPod(pod)
×
318
                podNets, err := c.getPodKubeovnNets(pod)
×
319
                if err != nil {
×
320
                        klog.Errorf("failed to get pod nets %v", err)
×
321
                }
×
322
                for _, podNet := range podNets {
×
NEW
323
                        // Skip non-OVN subnets that don't create OVN logical switch ports
×
NEW
324
                        if !isOvnSubnet(podNet.Subnet) {
×
NEW
325
                                continue
×
326
                        }
327

328
                        if podNet.Subnet.Name == cachedVip.Spec.Subnet {
×
329
                                portName := ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName)
×
330
                                virtualParents = append(virtualParents, portName)
×
331
                                key := cache.MetaObjectToName(pod).String()
×
332
                                klog.Infof("enqueue update pod security for %s", key)
×
333
                                c.updatePodSecurityQueue.Add(key)
×
334
                                break
×
335
                        }
336
                }
337
        }
338

339
        parents := strings.Join(virtualParents, ",")
×
340
        if err = c.OVNNbClient.SetVirtualLogicalSwitchPortVirtualParents(cachedVip.Name, parents); err != nil {
×
341
                klog.Errorf("set vip %s virtual parents %s: %v", cachedVip.Name, parents, err)
×
342
                return err
×
343
        }
×
344

345
        return nil
×
346
}
347

348
func (c *Controller) createOrUpdateVipCR(key, ns, subnet, v4ip, v6ip, mac string) error {
×
349
        vipCR, err := c.virtualIpsLister.Get(key)
×
350
        if err != nil {
×
351
                if k8serrors.IsNotFound(err) {
×
352
                        if _, err := c.config.KubeOvnClient.KubeovnV1().Vips().Create(context.Background(), &kubeovnv1.Vip{
×
353
                                ObjectMeta: metav1.ObjectMeta{
×
354
                                        Name: key,
×
355
                                        Labels: map[string]string{
×
356
                                                util.SubnetNameLabel: subnet,
×
357
                                                util.IPReservedLabel: "",
×
358
                                        },
×
359
                                        Namespace: ns,
×
360
                                },
×
361
                                Spec: kubeovnv1.VipSpec{
×
362
                                        Namespace:  ns,
×
363
                                        Subnet:     subnet,
×
364
                                        V4ip:       v4ip,
×
365
                                        V6ip:       v6ip,
×
366
                                        MacAddress: mac,
×
367
                                },
×
368
                        }, metav1.CreateOptions{}); err != nil {
×
369
                                err := fmt.Errorf("failed to create crd vip '%s', %w", key, err)
×
370
                                klog.Error(err)
×
371
                                return err
×
372
                        }
×
373
                } else {
×
374
                        err := fmt.Errorf("failed to get crd vip '%s', %w", key, err)
×
375
                        klog.Error(err)
×
376
                        return err
×
377
                }
×
378
        } else {
×
379
                vip := vipCR.DeepCopy()
×
380
                if vip.Status.Mac == "" && mac != "" {
×
381
                        // vip not support to update, just delete and create
×
382
                        vip.Spec.Namespace = ns
×
383
                        vip.Spec.V4ip = v4ip
×
384
                        vip.Spec.V6ip = v6ip
×
385
                        vip.Spec.MacAddress = mac
×
386

×
387
                        vip.Status.V4ip = v4ip
×
388
                        vip.Status.V6ip = v6ip
×
389
                        vip.Status.Mac = mac
×
390
                        vip.Status.Type = vip.Spec.Type
×
391
                        if _, err := c.config.KubeOvnClient.KubeovnV1().Vips().Update(context.Background(), vip, metav1.UpdateOptions{}); err != nil {
×
392
                                err := fmt.Errorf("failed to update vip '%s', %w", key, err)
×
393
                                klog.Error(err)
×
394
                                return err
×
395
                        }
×
396
                }
397
                var needUpdateLabel bool
×
398
                var op string
×
399
                if len(vip.Labels) == 0 {
×
400
                        op = "add"
×
401
                        vip.Labels = map[string]string{
×
402
                                util.SubnetNameLabel: subnet,
×
403
                                util.IPReservedLabel: "",
×
404
                        }
×
405
                        needUpdateLabel = true
×
406
                }
×
407
                if _, ok := vip.Labels[util.SubnetNameLabel]; !ok {
×
408
                        op = "add"
×
409
                        vip.Labels[util.SubnetNameLabel] = subnet
×
410
                        vip.Labels[util.IPReservedLabel] = ""
×
411
                        needUpdateLabel = true
×
412
                }
×
413
                if needUpdateLabel {
×
414
                        patchPayloadTemplate := `[{ "op": "%s", "path": "/metadata/labels", "value": %s }]`
×
415
                        raw, _ := json.Marshal(vip.Labels)
×
416
                        patchPayload := fmt.Sprintf(patchPayloadTemplate, op, raw)
×
417
                        if _, err := c.config.KubeOvnClient.KubeovnV1().Vips().Patch(context.Background(), vip.Name, types.JSONPatchType,
×
418
                                []byte(patchPayload), metav1.PatchOptions{}); err != nil {
×
419
                                klog.Errorf("failed to patch label for vip '%s', %v", vip.Name, err)
×
420
                                return err
×
421
                        }
×
422
                }
423
        }
424
        c.updateSubnetStatusQueue.Add(subnet)
×
425
        return nil
×
426
}
427

428
func (c *Controller) patchVipStatus(key, v4ip string, ready bool) error {
×
429
        oriVip, err := c.virtualIpsLister.Get(key)
×
430
        if err != nil {
×
431
                if k8serrors.IsNotFound(err) {
×
432
                        return nil
×
433
                }
×
434
                klog.Error(err)
×
435
                return err
×
436
        }
437
        vip := oriVip.DeepCopy()
×
438
        var changed bool
×
439

×
440
        if ready && v4ip != "" && vip.Status.V4ip != v4ip {
×
441
                vip.Status.V4ip = v4ip
×
442
                changed = true
×
443
        }
×
444

445
        if changed {
×
446
                if _, err = c.config.KubeOvnClient.KubeovnV1().Vips().Update(context.Background(), vip, metav1.UpdateOptions{}); err != nil {
×
447
                        klog.Errorf("failed to update status for vip '%s', %v", key, err)
×
448
                        return err
×
449
                }
×
450
        }
451
        return nil
×
452
}
453

454
func (c *Controller) podReuseVip(vipName, portName string, keepVIP bool) error {
×
455
        // when pod use static vip, label vip reserved for pod
×
456
        oriVip, err := c.virtualIpsLister.Get(vipName)
×
457
        if err != nil {
×
458
                if k8serrors.IsNotFound(err) {
×
459
                        return nil
×
460
                }
×
461
                klog.Error(err)
×
462
                return err
×
463
        }
464
        vip := oriVip.DeepCopy()
×
465
        if vip.Labels == nil {
×
466
                vip.Labels = map[string]string{}
×
467
        }
×
468
        var op string
×
469

×
470
        if vip.Labels[util.IPReservedLabel] != "" {
×
471
                if keepVIP && vip.Labels[util.IPReservedLabel] == portName {
×
472
                        return nil
×
473
                }
×
474
                return fmt.Errorf("vip '%s' is in use by pod %s", vip.Name, vip.Labels[util.IPReservedLabel])
×
475
        }
476
        op = "replace"
×
477
        vip.Labels[util.IPReservedLabel] = portName
×
478
        patchPayloadTemplate := `[{ "op": "%s", "path": "/metadata/labels", "value": %s }]`
×
479
        raw, _ := json.Marshal(vip.Labels)
×
480
        patchPayload := fmt.Sprintf(patchPayloadTemplate, op, raw)
×
481
        if _, err = c.config.KubeOvnClient.KubeovnV1().Vips().Patch(context.Background(), vip.Name, types.JSONPatchType, []byte(patchPayload), metav1.PatchOptions{}); err != nil {
×
482
                klog.Errorf("failed to patch label for vip '%s', %v", vip.Name, err)
×
483
                return err
×
484
        }
×
485
        c.ipam.ReleaseAddressByPod(vipName, vip.Spec.Subnet)
×
486
        c.updateSubnetStatusQueue.Add(vip.Spec.Subnet)
×
487
        return nil
×
488
}
489

490
func (c *Controller) releaseVip(key string) error {
×
491
        // clean vip label when pod delete
×
492
        oriVip, err := c.virtualIpsLister.Get(key)
×
493
        if err != nil {
×
494
                if k8serrors.IsNotFound(err) {
×
495
                        return nil
×
496
                }
×
497
                klog.Error(err)
×
498
                return err
×
499
        }
500
        vip := oriVip.DeepCopy()
×
501
        var needUpdateLabel bool
×
502
        var op string
×
503
        if vip.Labels[util.IPReservedLabel] == "" {
×
504
                return nil
×
505
        }
×
506
        op = "replace"
×
507
        vip.Labels[util.IPReservedLabel] = ""
×
508
        needUpdateLabel = true
×
509
        if needUpdateLabel {
×
510
                klog.V(3).Infof("clean reserved label from vip %s", key)
×
511
                patchPayloadTemplate := `[{ "op": "%s", "path": "/metadata/labels", "value": %s }]`
×
512
                raw, _ := json.Marshal(vip.Labels)
×
513
                patchPayload := fmt.Sprintf(patchPayloadTemplate, op, raw)
×
514
                if _, err := c.config.KubeOvnClient.KubeovnV1().Vips().Patch(context.Background(), vip.Name,
×
515
                        types.JSONPatchType, []byte(patchPayload), metav1.PatchOptions{}); err != nil {
×
516
                        klog.Errorf("failed to patch label for vip '%s', %v", vip.Name, err)
×
517
                        return err
×
518
                }
×
519
                mac := &vip.Status.Mac
×
520
                if vip.Status.Mac == "" {
×
521
                        mac = nil
×
522
                }
×
523
                if _, _, _, err = c.ipam.GetStaticAddress(key, vip.Name, vip.Status.V4ip, mac, vip.Spec.Subnet, false); err != nil {
×
524
                        klog.Errorf("failed to recover IPAM from vip CR %s: %v", vip.Name, err)
×
525
                }
×
526
                c.updateSubnetStatusQueue.Add(vip.Spec.Subnet)
×
527
        }
528
        return nil
×
529
}
530

531
func (c *Controller) handleAddVipFinalizer(key string) error {
×
532
        cachedVip, err := c.virtualIpsLister.Get(key)
×
533
        if err != nil {
×
534
                if k8serrors.IsNotFound(err) {
×
535
                        return nil
×
536
                }
×
537
                klog.Error(err)
×
538
                return err
×
539
        }
540
        if !cachedVip.DeletionTimestamp.IsZero() || len(cachedVip.GetFinalizers()) != 0 {
×
541
                return nil
×
542
        }
×
543
        newVip := cachedVip.DeepCopy()
×
544
        controllerutil.AddFinalizer(newVip, util.KubeOVNControllerFinalizer)
×
545
        patch, err := util.GenerateMergePatchPayload(cachedVip, newVip)
×
546
        if err != nil {
×
547
                klog.Errorf("failed to generate patch payload for ovn eip '%s', %v", cachedVip.Name, err)
×
548
                return err
×
549
        }
×
550
        if _, err := c.config.KubeOvnClient.KubeovnV1().Vips().Patch(context.Background(), cachedVip.Name,
×
551
                types.MergePatchType, patch, metav1.PatchOptions{}, ""); err != nil {
×
552
                if k8serrors.IsNotFound(err) {
×
553
                        return nil
×
554
                }
×
555
                klog.Errorf("failed to add finalizer for vip '%s', %v", cachedVip.Name, err)
×
556
                return err
×
557
        }
558
        return nil
×
559
}
560

561
func (c *Controller) handleDelVipFinalizer(key string) error {
×
562
        cachedVip, err := c.virtualIpsLister.Get(key)
×
563
        if err != nil {
×
564
                if k8serrors.IsNotFound(err) {
×
565
                        return nil
×
566
                }
×
567
                klog.Error(err)
×
568
                return err
×
569
        }
570
        if len(cachedVip.GetFinalizers()) == 0 {
×
571
                return nil
×
572
        }
×
573
        newVip := cachedVip.DeepCopy()
×
574
        controllerutil.RemoveFinalizer(newVip, util.KubeOVNControllerFinalizer)
×
575
        patch, err := util.GenerateMergePatchPayload(cachedVip, newVip)
×
576
        if err != nil {
×
577
                klog.Errorf("failed to generate patch payload for ovn eip '%s', %v", cachedVip.Name, err)
×
578
                return err
×
579
        }
×
580
        if _, err := c.config.KubeOvnClient.KubeovnV1().Vips().Patch(context.Background(), cachedVip.Name,
×
581
                types.MergePatchType, patch, metav1.PatchOptions{}, ""); err != nil {
×
582
                if k8serrors.IsNotFound(err) {
×
583
                        return nil
×
584
                }
×
585
                klog.Errorf("failed to remove finalizer from vip '%s', %v", cachedVip.Name, err)
×
586
                return err
×
587
        }
588
        return nil
×
589
}
590

591
func (c *Controller) syncVipFinalizer(cl client.Client) error {
×
592
        // migrate depreciated finalizer to new finalizer
×
593
        vips := &kubeovnv1.VipList{}
×
594
        return migrateFinalizers(cl, vips, func(i int) (client.Object, client.Object) {
×
595
                if i < 0 || i >= len(vips.Items) {
×
596
                        return nil, nil
×
597
                }
×
598
                return vips.Items[i].DeepCopy(), vips.Items[i].DeepCopy()
×
599
        })
600
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc