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

kubeovn / kube-ovn / 15767155797

19 Jun 2025 10:17PM UTC coverage: 21.626% (+0.02%) from 21.602%
15767155797

Pull #5380

github

SkalaNetworks
fix(slr): deleting old entries from ipmapping to avoid clogging loadbalancer

Signed-off-by: SkalaNetworks <contact@skala.network>
Pull Request #5380: fix(slr): deleting old entries from ipmapping to avoid clogging loadbalancer

25 of 28 new or added lines in 1 file covered. (89.29%)

1 existing line in 1 file now uncovered.

10456 of 48350 relevant lines covered (21.63%)

0.25 hits per line

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

73.56
/pkg/ovs/ovn-nb-load_balancer.go
1
package ovs
2

3
import (
4
        "context"
5
        "fmt"
6
        "maps"
7
        "net"
8
        "slices"
9
        "sort"
10
        "strconv"
11
        "strings"
12

13
        "github.com/ovn-org/libovsdb/model"
14
        "github.com/ovn-org/libovsdb/ovsdb"
15
        "k8s.io/klog/v2"
16

17
        ovsclient "github.com/kubeovn/kube-ovn/pkg/ovsdb/client"
18
        "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb"
19
)
20

21
// CreateLoadBalancer create loadbalancer
22
func (c *OVNNbClient) CreateLoadBalancer(lbName, protocol, selectFields string) error {
1✔
23
        var (
1✔
24
                exist bool
1✔
25
                err   error
1✔
26
        )
1✔
27

1✔
28
        if exist, err = c.LoadBalancerExists(lbName); err != nil {
2✔
29
                klog.Errorf("failed to get lb: %v", err)
1✔
30
                return err
1✔
31
        }
1✔
32
        // found, ignore
33
        if exist {
2✔
34
                return nil
1✔
35
        }
1✔
36

37
        var (
1✔
38
                ops []ovsdb.Operation
1✔
39
                lb  *ovnnb.LoadBalancer
1✔
40
        )
1✔
41

1✔
42
        lb = &ovnnb.LoadBalancer{
1✔
43
                UUID:     ovsclient.NamedUUID(),
1✔
44
                Name:     lbName,
1✔
45
                Protocol: &protocol,
1✔
46
        }
1✔
47

1✔
48
        if len(selectFields) != 0 {
2✔
49
                lb.SelectionFields = []string{selectFields}
1✔
50
        }
1✔
51

52
        if ops, err = c.Create(lb); err != nil {
1✔
53
                klog.Error(err)
×
54
                return fmt.Errorf("generate operations for creating load balancer %s: %w", lbName, err)
×
55
        }
×
56

57
        if err = c.Transact("lb-add", ops); err != nil {
1✔
58
                klog.Error(err)
×
59
                return fmt.Errorf("create load balancer %s: %w", lbName, err)
×
60
        }
×
61
        return nil
1✔
62
}
63

64
// UpdateLoadBalancer update load balancer
65
func (c *OVNNbClient) UpdateLoadBalancer(lb *ovnnb.LoadBalancer, fields ...any) error {
1✔
66
        var (
1✔
67
                ops []ovsdb.Operation
1✔
68
                err error
1✔
69
        )
1✔
70

1✔
71
        if ops, err = c.ovsDbClient.Where(lb).Update(lb, fields...); err != nil {
1✔
72
                klog.Error(err)
×
73
                return fmt.Errorf("generate operations for updating load balancer %s: %w", lb.Name, err)
×
74
        }
×
75

76
        if err = c.Transact("lb-update", ops); err != nil {
1✔
77
                klog.Error(err)
×
78
                return fmt.Errorf("update load balancer %s: %w", lb.Name, err)
×
79
        }
×
80
        return nil
1✔
81
}
82

83
// LoadBalancerAddVips adds or updates a vip
84
func (c *OVNNbClient) LoadBalancerAddVip(lbName, vip string, backends ...string) error {
1✔
85
        var (
1✔
86
                ops []ovsdb.Operation
1✔
87
                err error
1✔
88
        )
1✔
89

1✔
90
        if _, err = c.GetLoadBalancer(lbName, false); err != nil {
2✔
91
                klog.Errorf("failed to get lb health check: %v", err)
1✔
92
                return err
1✔
93
        }
1✔
94

95
        sort.Strings(backends)
1✔
96
        if ops, err = c.LoadBalancerOp(
1✔
97
                lbName,
1✔
98
                func(lb *ovnnb.LoadBalancer) []model.Mutation {
2✔
99
                        var (
1✔
100
                                mutations = make([]model.Mutation, 0, 2)
1✔
101
                                value     = strings.Join(backends, ",")
1✔
102
                        )
1✔
103

1✔
104
                        if len(lb.Vips) != 0 {
2✔
105
                                if lb.Vips[vip] == value {
1✔
106
                                        return nil
×
107
                                }
×
108
                                mutations = append(
1✔
109
                                        mutations,
1✔
110
                                        model.Mutation{
1✔
111
                                                Field:   &lb.Vips,
1✔
112
                                                Value:   map[string]string{vip: lb.Vips[vip]},
1✔
113
                                                Mutator: ovsdb.MutateOperationDelete,
1✔
114
                                        },
1✔
115
                                )
1✔
116
                        }
117
                        mutations = append(
1✔
118
                                mutations,
1✔
119
                                model.Mutation{
1✔
120
                                        Field:   &lb.Vips,
1✔
121
                                        Value:   map[string]string{vip: value},
1✔
122
                                        Mutator: ovsdb.MutateOperationInsert,
1✔
123
                                },
1✔
124
                        )
1✔
125
                        return mutations
1✔
126
                },
127
        ); err != nil {
×
128
                return fmt.Errorf("failed to generate operations when adding vip %s with backends %v to load balancers %s: %w", vip, backends, lbName, err)
×
129
        }
×
130

131
        if ops != nil {
2✔
132
                if err = c.Transact("lb-add", ops); err != nil {
1✔
133
                        klog.Error(err)
×
134
                        return fmt.Errorf("failed to add vip %s with backends %v to load balancers %s: %w", vip, backends, lbName, err)
×
135
                }
×
136
        }
137
        return nil
1✔
138
}
139

140
// LoadBalancerDeleteVip deletes load balancer vip
141
func (c *OVNNbClient) LoadBalancerDeleteVip(lbName, vipEndpoint string, ignoreHealthCheck bool) error {
1✔
142
        var (
1✔
143
                ops  []ovsdb.Operation
1✔
144
                lb   *ovnnb.LoadBalancer
1✔
145
                lbhc *ovnnb.LoadBalancerHealthCheck
1✔
146
                err  error
1✔
147
        )
1✔
148

1✔
149
        lb, lbhc, err = c.GetLoadBalancerHealthCheck(lbName, vipEndpoint, true)
1✔
150
        if err != nil {
2✔
151
                klog.Errorf("failed to get lb health check: %v", err)
1✔
152
                return err
1✔
153
        }
1✔
154
        if !ignoreHealthCheck && lbhc != nil {
2✔
155
                klog.Infof("clean health check for lb %s with vip %s", lbName, vipEndpoint)
1✔
156
                // delete ip port mapping
1✔
157
                if err = c.LoadBalancerDeleteIPPortMapping(lbName, vipEndpoint); err != nil {
1✔
158
                        klog.Errorf("failed to delete lb ip port mapping: %v", err)
×
159
                        return err
×
160
                }
×
161
                if err = c.LoadBalancerDeleteHealthCheck(lbName, lbhc.UUID); err != nil {
1✔
162
                        klog.Errorf("failed to delete lb health check: %v", err)
×
163
                        return err
×
164
                }
×
165
        }
166
        if lb == nil || len(lb.Vips) == 0 {
2✔
167
                return nil
1✔
168
        }
1✔
169
        if _, ok := lb.Vips[vipEndpoint]; !ok {
2✔
170
                return nil
1✔
171
        }
1✔
172

173
        ops, err = c.LoadBalancerOp(
1✔
174
                lbName,
1✔
175
                func(lb *ovnnb.LoadBalancer) []model.Mutation {
2✔
176
                        return []model.Mutation{
1✔
177
                                {
1✔
178
                                        Field:   &lb.Vips,
1✔
179
                                        Value:   map[string]string{vipEndpoint: lb.Vips[vipEndpoint]},
1✔
180
                                        Mutator: ovsdb.MutateOperationDelete,
1✔
181
                                },
1✔
182
                        }
1✔
183
                },
1✔
184
        )
185
        if err != nil {
1✔
186
                klog.Error(err)
×
187
                return fmt.Errorf("failed to generate operations when deleting vip %s from load balancers %s: %w", vipEndpoint, lbName, err)
×
188
        }
×
189
        if len(ops) == 0 {
1✔
190
                return nil
×
191
        }
×
192

193
        if err = c.Transact("lb-add", ops); err != nil {
1✔
194
                klog.Error(err)
×
195
                return fmt.Errorf("failed to delete vip %s from load balancers %s: %w", vipEndpoint, lbName, err)
×
196
        }
×
197
        return nil
1✔
198
}
199

200
// SetLoadBalancerAffinityTimeout sets the LB's affinity timeout in seconds
201
func (c *OVNNbClient) SetLoadBalancerAffinityTimeout(lbName string, timeout int) error {
1✔
202
        var (
1✔
203
                options map[string]string
1✔
204
                lb      *ovnnb.LoadBalancer
1✔
205
                value   string
1✔
206
                err     error
1✔
207
        )
1✔
208

1✔
209
        if lb, err = c.GetLoadBalancer(lbName, false); err != nil {
2✔
210
                klog.Errorf("failed to get lb: %v", err)
1✔
211
                return err
1✔
212
        }
1✔
213

214
        if value = strconv.Itoa(timeout); len(lb.Options) != 0 && lb.Options["affinity_timeout"] == value {
2✔
215
                return nil
1✔
216
        }
1✔
217

218
        options = make(map[string]string, len(lb.Options)+1)
1✔
219
        maps.Copy(options, lb.Options)
1✔
220
        options["affinity_timeout"] = value
1✔
221

1✔
222
        lb.Options = options
1✔
223
        if err = c.UpdateLoadBalancer(lb, &lb.Options); err != nil {
1✔
224
                klog.Error(err)
×
225
                return fmt.Errorf("failed to set affinity timeout of lb %s to %d: %w", lbName, timeout, err)
×
226
        }
×
227
        return nil
1✔
228
}
229

230
// SetLoadBalancerPreferLocalBackend sets the LB's affinity timeout in seconds
231
func (c *OVNNbClient) SetLoadBalancerPreferLocalBackend(lbName string, preferLocalBackend bool) error {
×
232
        var (
×
233
                options map[string]string
×
234
                lb      *ovnnb.LoadBalancer
×
235
                value   string
×
236
                err     error
×
237
        )
×
238

×
239
        if lb, err = c.GetLoadBalancer(lbName, false); err != nil {
×
240
                klog.Errorf("failed to get lb: %v", err)
×
241
                return err
×
242
        }
×
243

244
        if preferLocalBackend {
×
245
                value = "true"
×
246
        } else {
×
247
                value = "false"
×
248
        }
×
249
        if len(lb.Options) != 0 && lb.Options["prefer_local_backend"] == value {
×
250
                return nil
×
251
        }
×
252

253
        options = make(map[string]string, len(lb.Options)+1)
×
254
        maps.Copy(options, lb.Options)
×
255
        options["prefer_local_backend"] = value
×
256

×
257
        lb.Options = options
×
258
        if err = c.UpdateLoadBalancer(lb, &lb.Options); err != nil {
×
259
                klog.Error(err)
×
260
                return fmt.Errorf("failed to set prefer local backend of lb %s to %s: %w", lbName, value, err)
×
261
        }
×
262
        return nil
×
263
}
264

265
// DeleteLoadBalancers delete several loadbalancer once
266
func (c *OVNNbClient) DeleteLoadBalancers(filter func(lb *ovnnb.LoadBalancer) bool) error {
1✔
267
        var (
1✔
268
                ops []ovsdb.Operation
1✔
269
                err error
1✔
270
        )
1✔
271

1✔
272
        if ops, err = c.ovsDbClient.WhereCache(
1✔
273
                func(lb *ovnnb.LoadBalancer) bool {
2✔
274
                        if filter != nil {
2✔
275
                                return filter(lb)
1✔
276
                        }
1✔
277
                        return true
×
278
                },
279
        ).Delete(); err != nil {
×
280
                klog.Error(err)
×
281
                return fmt.Errorf("generate operations for delete load balancers: %w", err)
×
282
        }
×
283

284
        if err = c.Transact("lb-del", ops); err != nil {
1✔
285
                klog.Errorf("failed to del lbs: %v", err)
×
286
                return fmt.Errorf("delete load balancers : %w", err)
×
287
        }
×
288
        return nil
1✔
289
}
290

291
// DeleteLoadBalancer delete loadbalancer
292
func (c *OVNNbClient) DeleteLoadBalancer(lbName string) error {
1✔
293
        var (
1✔
294
                ops []ovsdb.Operation
1✔
295
                err error
1✔
296
        )
1✔
297

1✔
298
        ops, err = c.DeleteLoadBalancerOp(lbName)
1✔
299
        if err != nil {
1✔
300
                klog.Errorf("failed to get delete lb op: %v", err)
×
301
                return err
×
302
        }
×
303

304
        if err = c.Transact("lb-del", ops); err != nil {
1✔
305
                klog.Errorf("failed to del lb: %v", err)
×
306
                return fmt.Errorf("delete load balancer %s: %w", lbName, err)
×
307
        }
×
308
        return nil
1✔
309
}
310

311
// GetLoadBalancer get load balancer by name,
312
// it is because of lack name index that does't use OVNNbClient.Get
313
func (c *OVNNbClient) GetLoadBalancer(lbName string, ignoreNotFound bool) (*ovnnb.LoadBalancer, error) {
1✔
314
        ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
1✔
315
        defer cancel()
1✔
316

1✔
317
        var (
1✔
318
                lbList []ovnnb.LoadBalancer
1✔
319
                err    error
1✔
320
        )
1✔
321

1✔
322
        lbList = make([]ovnnb.LoadBalancer, 0)
1✔
323
        if err = c.ovsDbClient.WhereCache(
1✔
324
                func(lb *ovnnb.LoadBalancer) bool {
2✔
325
                        return lb.Name == lbName
1✔
326
                },
1✔
327
        ).List(ctx, &lbList); err != nil {
×
328
                klog.Error(err)
×
329
                return nil, fmt.Errorf("failed to list load balancer %q: %w", lbName, err)
×
330
        }
×
331

332
        switch {
1✔
333
        // not found
334
        case len(lbList) == 0:
1✔
335
                if ignoreNotFound {
2✔
336
                        return nil, nil
1✔
337
                }
1✔
338
                return nil, fmt.Errorf("not found load balancer %q", lbName)
1✔
339
        case len(lbList) > 1:
1✔
340
                return nil, fmt.Errorf("more than one load balancer with same name %q", lbName)
1✔
341
        default:
1✔
342
                // #nosec G602
1✔
343
                return &lbList[0], nil
1✔
344
        }
345
}
346

347
func (c *OVNNbClient) LoadBalancerExists(lbName string) (bool, error) {
1✔
348
        lrp, err := c.GetLoadBalancer(lbName, true)
1✔
349
        return lrp != nil, err
1✔
350
}
1✔
351

352
// ListLoadBalancers list all load balancers
353
func (c *OVNNbClient) ListLoadBalancers(filter func(lb *ovnnb.LoadBalancer) bool) ([]ovnnb.LoadBalancer, error) {
1✔
354
        ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
1✔
355
        defer cancel()
1✔
356

1✔
357
        var (
1✔
358
                lbList []ovnnb.LoadBalancer
1✔
359
                err    error
1✔
360
        )
1✔
361

1✔
362
        lbList = make([]ovnnb.LoadBalancer, 0)
1✔
363
        if err = c.ovsDbClient.WhereCache(
1✔
364
                func(lb *ovnnb.LoadBalancer) bool {
2✔
365
                        if filter != nil {
2✔
366
                                return filter(lb)
1✔
367
                        }
1✔
368

369
                        return true
1✔
370
                },
371
        ).List(ctx, &lbList); err != nil {
×
372
                klog.Error(err)
×
373
                return nil, fmt.Errorf("failed to list load balancer: %w", err)
×
374
        }
×
375
        return lbList, nil
1✔
376
}
377

378
func (c *OVNNbClient) LoadBalancerOp(lbName string, mutationsFunc ...func(lb *ovnnb.LoadBalancer) []model.Mutation) ([]ovsdb.Operation, error) {
1✔
379
        var (
1✔
380
                mutations []model.Mutation
1✔
381
                ops       []ovsdb.Operation
1✔
382
                lb        *ovnnb.LoadBalancer
1✔
383
                err       error
1✔
384
        )
1✔
385

1✔
386
        if lb, err = c.GetLoadBalancer(lbName, false); err != nil {
2✔
387
                klog.Error(err)
1✔
388
                return nil, err
1✔
389
        }
1✔
390

391
        if len(mutationsFunc) == 0 {
2✔
392
                return nil, nil
1✔
393
        }
1✔
394

395
        mutations = make([]model.Mutation, 0, len(mutationsFunc))
1✔
396
        for _, f := range mutationsFunc {
2✔
397
                if mutation := f(lb); mutation != nil {
2✔
398
                        mutations = append(mutations, mutation...)
1✔
399
                }
1✔
400
        }
401
        if len(mutations) == 0 {
2✔
402
                return nil, nil
1✔
403
        }
1✔
404

405
        if ops, err = c.ovsDbClient.Where(lb).Mutate(lb, mutations...); err != nil {
1✔
406
                klog.Error(err)
×
407
                return nil, fmt.Errorf("generate operations for mutating load balancer %s: %w", lb.Name, err)
×
408
        }
×
409
        return ops, nil
1✔
410
}
411

412
// DeleteLoadBalancerOp create operation which delete load balancer
413
func (c *OVNNbClient) DeleteLoadBalancerOp(lbName string) ([]ovsdb.Operation, error) {
1✔
414
        var (
1✔
415
                ops []ovsdb.Operation
1✔
416
                lb  *ovnnb.LoadBalancer
1✔
417
                err error
1✔
418
        )
1✔
419

1✔
420
        if lb, err = c.GetLoadBalancer(lbName, true); err != nil {
2✔
421
                klog.Error(err)
1✔
422
                return nil, err
1✔
423
        }
1✔
424
        // not found, skip
425
        if lb == nil {
2✔
426
                return nil, nil
1✔
427
        }
1✔
428

429
        if ops, err = c.Where(lb).Delete(); err != nil {
1✔
430
                klog.Error(err)
×
431
                return nil, err
×
432
        }
×
433
        return ops, nil
1✔
434
}
435

436
// LoadBalancerAddIPPortMapping add load balancer ip port mapping
437
func (c *OVNNbClient) LoadBalancerAddIPPortMapping(lbName, vipEndpoint string, mappings map[string]string) error {
1✔
438
        if len(mappings) == 0 {
2✔
439
                return nil
1✔
440
        }
1✔
441

442
        var (
1✔
443
                ops []ovsdb.Operation
1✔
444
                err error
1✔
445
        )
1✔
446

1✔
447
        if ops, err = c.LoadBalancerOp(
1✔
448
                lbName,
1✔
449
                func(lb *ovnnb.LoadBalancer) []model.Mutation {
2✔
450
                        return []model.Mutation{
1✔
451
                                {
1✔
452
                                        Field:   &lb.IPPortMappings,
1✔
453
                                        Value:   mappings,
1✔
454
                                        Mutator: ovsdb.MutateOperationInsert,
1✔
455
                                },
1✔
456
                        }
1✔
457
                },
1✔
458
        ); err != nil {
×
459
                klog.Error(err)
×
460
                return fmt.Errorf("failed to generate operations when adding ip port mapping with vip %v to load balancers %s: %w", vipEndpoint, lbName, err)
×
461
        }
×
462

463
        if err = c.Transact("lb-add", ops); err != nil {
1✔
464
                klog.Error(err)
×
465
                return fmt.Errorf("failed to add ip port mapping with vip %v to load balancers %s: %w", vipEndpoint, lbName, err)
×
466
        }
×
467
        return nil
1✔
468
}
469

470
// LoadBalancerDeleteIPPortMapping delete load balancer ip port mapping
471
func (c *OVNNbClient) LoadBalancerDeleteIPPortMapping(lbName, vipEndpoint string) error {
1✔
472
        var (
1✔
473
                ops      []ovsdb.Operation
1✔
474
                lb       *ovnnb.LoadBalancer
1✔
475
                mappings map[string]string
1✔
476
                vip      string
1✔
477
                err      error
1✔
478
        )
1✔
479

1✔
480
        if lb, err = c.GetLoadBalancer(lbName, true); err != nil {
1✔
481
                klog.Errorf("failed to get lb health check: %v", err)
×
482
                return err
×
483
        }
×
484

485
        if lb == nil {
1✔
486
                klog.Infof("lb %s already deleted", lbName)
×
487
                return nil
×
488
        }
×
489
        if len(lb.IPPortMappings) == 0 {
2✔
490
                klog.Infof("lb %s has no ip port mapping", lbName)
1✔
491
                return nil
1✔
492
        }
1✔
493

494
        if vip, _, err = net.SplitHostPort(vipEndpoint); err != nil {
1✔
495
                err := fmt.Errorf("failed to split host port: %w", err)
×
496
                klog.Error(err)
×
497
                return err
×
498
        }
×
499

500
        mappings = lb.IPPortMappings
1✔
501
        for portIP, portMapVip := range lb.IPPortMappings {
2✔
502
                splits := strings.Split(portMapVip, ":")
1✔
503
                if len(splits) == 2 && splits[1] == vip {
1✔
504
                        delete(mappings, portIP)
×
505
                }
×
506
        }
507

508
        if ops, err = c.LoadBalancerOp(
1✔
509
                lbName,
1✔
510
                func(lb *ovnnb.LoadBalancer) []model.Mutation {
2✔
511
                        return []model.Mutation{
1✔
512
                                {
1✔
513
                                        Field:   &lb.IPPortMappings,
1✔
514
                                        Value:   mappings,
1✔
515
                                        Mutator: ovsdb.MutateOperationDelete,
1✔
516
                                },
1✔
517
                        }
1✔
518
                },
1✔
519
        ); err != nil {
×
520
                klog.Error(err)
×
521
                return fmt.Errorf("failed to generate operations when deleting ip port mapping %s from load balancers %s: %w", vipEndpoint, lbName, err)
×
522
        }
×
523
        if len(ops) == 0 {
1✔
524
                return nil
×
525
        }
×
526
        if err = c.Transact("lb-del", ops); err != nil {
1✔
527
                return fmt.Errorf("failed to delete ip port mappings %s from load balancer %s: %w", vipEndpoint, lbName, err)
×
528
        }
×
529
        return nil
1✔
530
}
531

532
// LoadBalancerUpdateIPPortMapping update load balancer ip port mapping
533
func (c *OVNNbClient) LoadBalancerUpdateIPPortMapping(lbName, vipEndpoint string, ipPortMappings map[string]string) error {
1✔
534
        ops, err := c.LoadBalancerOp(
1✔
535
                lbName,
1✔
536
                func(lb *ovnnb.LoadBalancer) []model.Mutation {
2✔
537
                        // Delete from the IPPortMappings any outdated mapping
1✔
538
                        mappingToDelete := make(map[string]string)
1✔
539
                        for portIP, portMapVip := range lb.IPPortMappings {
2✔
540
                                if _, ok := ipPortMappings[portIP]; !ok {
2✔
541
                                        mappingToDelete[portIP] = portMapVip
1✔
542
                                }
1✔
543
                        }
544

545
                        if len(mappingToDelete) > 0 {
2✔
546
                                klog.Infof("deleting outdated entry from ipportmapping %v", mappingToDelete)
1✔
547
                        }
1✔
548

549
                        return []model.Mutation{
1✔
550
                                {
1✔
551
                                        Field:   &lb.IPPortMappings,
1✔
552
                                        Value:   mappingToDelete,
1✔
553
                                        Mutator: ovsdb.MutateOperationDelete,
1✔
554
                                },
1✔
555
                                {
1✔
556
                                        Field:   &lb.IPPortMappings,
1✔
557
                                        Value:   ipPortMappings,
1✔
558
                                        Mutator: ovsdb.MutateOperationInsert,
1✔
559
                                },
1✔
560
                        }
1✔
561
                },
562
        )
563
        if err != nil {
1✔
NEW
564
                return fmt.Errorf("failed to generate operations when adding ip port mapping with vip %v to load balancers %s: %w", vipEndpoint, lbName, err)
×
NEW
565
        }
×
566
        if err = c.Transact("lb-add", ops); err != nil {
1✔
NEW
567
                return fmt.Errorf("failed to add ip port mapping with vip %v to load balancers %s: %w", vipEndpoint, lbName, err)
×
UNCOV
568
        }
×
569
        return nil
1✔
570
}
571

572
// LoadBalancerAddHealthCheck adds health check
573
func (c *OVNNbClient) LoadBalancerAddHealthCheck(lbName, vipEndpoint string, ignoreHealthCheck bool, ipPortMapping, externals map[string]string) error {
1✔
574
        klog.Infof("lb %s health check use ip port mapping %v", lbName, ipPortMapping)
1✔
575
        if err := c.LoadBalancerUpdateIPPortMapping(lbName, vipEndpoint, ipPortMapping); err != nil {
1✔
576
                klog.Errorf("failed to update lb ip port mapping: %v", err)
×
577
                return err
×
578
        }
×
579
        if !ignoreHealthCheck {
2✔
580
                klog.Infof("add health check for lb %s with vip %s and health check vip maps %v", lbName, vipEndpoint, ipPortMapping)
1✔
581
                if err := c.AddLoadBalancerHealthCheck(lbName, vipEndpoint, externals); err != nil {
1✔
582
                        klog.Errorf("failed to create lb health check: %v", err)
×
583
                        return err
×
584
                }
×
585
        }
586
        return nil
1✔
587
}
588

589
// LoadBalancerDeleteHealthCheck delete load balancer health check
590
func (c *OVNNbClient) LoadBalancerDeleteHealthCheck(lbName, uuid string) error {
1✔
591
        var (
1✔
592
                ops []ovsdb.Operation
1✔
593
                lb  *ovnnb.LoadBalancer
1✔
594
                err error
1✔
595
        )
1✔
596

1✔
597
        if lb, err = c.GetLoadBalancer(lbName, false); err != nil {
2✔
598
                klog.Errorf("failed to get lb: %v", err)
1✔
599
                return err
1✔
600
        }
1✔
601

602
        if slices.Contains(lb.HealthCheck, uuid) {
2✔
603
                ops, err = c.LoadBalancerOp(
1✔
604
                        lbName,
1✔
605
                        func(lb *ovnnb.LoadBalancer) []model.Mutation {
2✔
606
                                return []model.Mutation{
1✔
607
                                        {
1✔
608
                                                Field:   &lb.HealthCheck,
1✔
609
                                                Value:   []string{uuid},
1✔
610
                                                Mutator: ovsdb.MutateOperationDelete,
1✔
611
                                        },
1✔
612
                                }
1✔
613
                        },
1✔
614
                )
615
                if err != nil {
1✔
616
                        return fmt.Errorf("failed to generate operations when deleting health check %s from load balancers %s: %w", uuid, lbName, err)
×
617
                }
×
618
                if len(ops) == 0 {
1✔
619
                        return nil
×
620
                }
×
621
                if err = c.Transact("lb-hc-del", ops); err != nil {
1✔
622
                        return fmt.Errorf("failed to delete health check %s from load balancers %s: %w", uuid, lbName, err)
×
623
                }
×
624
        }
625

626
        return nil
1✔
627
}
628

629
// LoadBalancerUpdateHealthCheckOp create operations add to or delete health check from it
630
func (c *OVNNbClient) LoadBalancerUpdateHealthCheckOp(lbName string, lbhcUUIDs []string, op ovsdb.Mutator) ([]ovsdb.Operation, error) {
1✔
631
        if len(lbhcUUIDs) == 0 {
2✔
632
                return nil, nil
1✔
633
        }
1✔
634

635
        return c.LoadBalancerOp(
1✔
636
                lbName,
1✔
637
                func(lb *ovnnb.LoadBalancer) []model.Mutation {
2✔
638
                        return []model.Mutation{
1✔
639
                                {
1✔
640
                                        Field:   &lb.HealthCheck,
1✔
641
                                        Value:   lbhcUUIDs,
1✔
642
                                        Mutator: op,
1✔
643
                                },
1✔
644
                        }
1✔
645
                },
1✔
646
        )
647
}
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

© 2025 Coveralls, Inc