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

kubeovn / kube-ovn / 12275027635

11 Dec 2024 11:03AM UTC coverage: 21.899% (+3.2%) from 18.675%
12275027635

Pull #4800

github

changluyi
add e2e test script

Signed-off-by: clyi <clyi@alauda.io>
Pull Request #4800: pod should use mac and ips provider by multus firstly

0 of 21 new or added lines in 1 file covered. (0.0%)

32 existing lines in 2 files now uncovered.

10185 of 46508 relevant lines covered (21.9%)

0.25 hits per line

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

75.64
/pkg/ovs/ovn-nb-logical_router_route.go
1
package ovs
2

3
import (
4
        "context"
5
        "errors"
6
        "fmt"
7
        "slices"
8

9
        "github.com/ovn-org/libovsdb/client"
10
        "github.com/ovn-org/libovsdb/model"
11
        "github.com/ovn-org/libovsdb/ovsdb"
12
        "github.com/scylladb/go-set/strset"
13
        "k8s.io/klog/v2"
14
        "k8s.io/utils/ptr"
15

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

21
func (c *OVNNbClient) ListLogicalRouterStaticRoutesByOption(lrName, _, key, value string) ([]*ovnnb.LogicalRouterStaticRoute, error) {
1✔
22
        fnFilter := func(route *ovnnb.LogicalRouterStaticRoute) bool {
2✔
23
                if len(route.Options) != 0 {
2✔
24
                        if _, ok := route.Options[key]; ok {
2✔
25
                                return route.Options[key] == value
1✔
26
                        }
1✔
27
                }
28
                return false
1✔
29
        }
30
        return c.listLogicalRouterStaticRoutesByFilter(lrName, fnFilter)
1✔
31
}
32

33
// CreateLogicalRouterStaticRoutes create several logical router static route once
34
func (c *OVNNbClient) CreateLogicalRouterStaticRoutes(lrName string, routes ...*ovnnb.LogicalRouterStaticRoute) error {
1✔
35
        if len(routes) == 0 {
2✔
36
                return nil
1✔
37
        }
1✔
38

39
        models := make([]model.Model, 0, len(routes))
1✔
40
        routeUUIDs := make([]string, 0, len(routes))
1✔
41
        for _, route := range routes {
2✔
42
                if route != nil {
2✔
43
                        models = append(models, model.Model(route))
1✔
44
                        routeUUIDs = append(routeUUIDs, route.UUID)
1✔
45
                }
1✔
46
        }
47

48
        createRoutesOp, err := c.ovsDbClient.Create(models...)
1✔
49
        if err != nil {
1✔
50
                klog.Error(err)
×
51
                return fmt.Errorf("generate operations for creating static routes: %w", err)
×
52
        }
×
53

54
        routeAddOp, err := c.LogicalRouterUpdateStaticRouteOp(lrName, routeUUIDs, ovsdb.MutateOperationInsert)
1✔
55
        if err != nil {
2✔
56
                klog.Error(err)
1✔
57
                return fmt.Errorf("generate operations for adding static routes to logical router %s: %w", lrName, err)
1✔
58
        }
1✔
59

60
        ops := make([]ovsdb.Operation, 0, len(createRoutesOp)+len(routeAddOp))
1✔
61
        ops = append(ops, createRoutesOp...)
1✔
62
        ops = append(ops, routeAddOp...)
1✔
63

1✔
64
        if err = c.Transact("lr-routes-add", ops); err != nil {
1✔
65
                klog.Error(err)
×
66
                return fmt.Errorf("add static routes to %s: %w", lrName, err)
×
67
        }
×
68

69
        return nil
1✔
70
}
71

72
// AddLogicalRouterStaticRoute add a logical router static route
73
func (c *OVNNbClient) AddLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix string, bfdID *string, nexthops ...string) error {
1✔
74
        if len(policy) == 0 {
2✔
75
                policy = ovnnb.LogicalRouterStaticRoutePolicyDstIP
1✔
76
        }
1✔
77

78
        routes, err := c.ListLogicalRouterStaticRoutes(lrName, &routeTable, &policy, ipPrefix, nil)
1✔
79
        if err != nil {
2✔
80
                klog.Error(err)
1✔
81
                return err
1✔
82
        }
1✔
83

84
        existing := strset.New()
1✔
85
        var toDel []string
1✔
86
        for _, route := range routes {
2✔
87
                if slices.Contains(nexthops, route.Nexthop) {
2✔
88
                        existing.Add(route.Nexthop)
1✔
89
                } else {
2✔
90
                        if route.BFD != nil && bfdID != nil && *route.BFD != *bfdID {
1✔
91
                                continue
×
92
                        }
93
                        toDel = append(toDel, route.UUID)
1✔
94
                }
95
        }
96
        var toAdd []*ovnnb.LogicalRouterStaticRoute
1✔
97
        for _, nexthop := range nexthops {
2✔
98
                if !existing.Has(nexthop) {
2✔
99
                        route, err := c.newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, bfdID)
1✔
100
                        if err != nil {
1✔
101
                                klog.Error(err)
×
102
                                return err
×
103
                        }
×
104
                        toAdd = append(toAdd, route)
1✔
105
                }
106
        }
107
        klog.Infof("logical router %s del static routes: %v", lrName, toDel)
2✔
108
        ops, err := c.LogicalRouterUpdateStaticRouteOp(lrName, toDel, ovsdb.MutateOperationDelete)
1✔
109
        if err != nil {
1✔
110
                klog.Error(err)
1✔
111
                return fmt.Errorf("generate operations for removing static routes from logical router %s: %w", lrName, err)
1✔
112
        }
×
UNCOV
113
        if err = c.Transact("lr-route-del", ops); err != nil {
×
114
                klog.Error(err)
×
115
                return fmt.Errorf("failed to delete static routes from logical router %s: %w", lrName, err)
1✔
116
        }
×
UNCOV
117
        if err = c.CreateLogicalRouterStaticRoutes(lrName, toAdd...); err != nil {
×
118
                klog.Error(err)
×
119
                return fmt.Errorf("failed to add static routes to logical router %s: %w", lrName, err)
1✔
120
        }
×
UNCOV
121
        return nil
×
UNCOV
122
}
×
123

1✔
124
// UpdateLogicalRouterStaticRoute update logical router static route
125
func (c *OVNNbClient) UpdateLogicalRouterStaticRoute(route *ovnnb.LogicalRouterStaticRoute, fields ...interface{}) error {
126
        if route == nil {
127
                return errors.New("route is nil")
1✔
128
        }
2✔
129

1✔
130
        op, err := c.ovsDbClient.Where(route).Update(route, fields...)
1✔
131
        if err != nil {
132
                klog.Error(err)
1✔
133
                return fmt.Errorf("generate operations for updating logical router static route 'policy %s ip_prefix %s': %w", *route.Policy, route.IPPrefix, err)
1✔
134
        }
×
UNCOV
135

×
UNCOV
136
        if err = c.Transact("net-update", op); err != nil {
×
137
                klog.Error(err)
138
                return fmt.Errorf("update logical router static route 'policy %s ip_prefix %s': %w", *route.Policy, route.IPPrefix, err)
1✔
139
        }
×
UNCOV
140

×
UNCOV
141
        return nil
×
142
}
143

1✔
144
// DeleteLogicalRouterStaticRoute delete a logical router static route
145
func (c *OVNNbClient) DeleteLogicalRouterStaticRoute(lrName string, routeTable, policy *string, ipPrefix, nexthop string) error {
146
        if policy == nil || len(*policy) == 0 {
147
                policy = ptr.To(ovnnb.LogicalRouterStaticRoutePolicyDstIP)
1✔
148
        }
2✔
149

1✔
150
        lr, err := c.GetLogicalRouter(lrName, true)
1✔
151
        if lr == nil && err == nil {
152
                return nil
1✔
153
        }
2✔
154

1✔
155
        routes, err := c.ListLogicalRouterStaticRoutes(lrName, routeTable, policy, ipPrefix, nil)
1✔
156
        if err != nil {
157
                klog.Error(err)
1✔
158
                return err
1✔
159
        }
×
UNCOV
160

×
UNCOV
161
        // not found, skip
×
162
        if len(routes) == 0 {
163
                return nil
164
        }
2✔
165

1✔
166
        uuids := make([]string, 0, len(routes))
1✔
167
        for _, route := range routes {
168
                if nexthop == "" || route.Nexthop == nexthop {
1✔
169
                        uuids = append(uuids, route.UUID)
2✔
170
                }
2✔
171
        }
1✔
172

1✔
173
        // remove static route from logical router
174
        ops, err := c.LogicalRouterUpdateStaticRouteOp(lrName, uuids, ovsdb.MutateOperationDelete)
175
        if err != nil {
176
                klog.Error(err)
1✔
177
                return fmt.Errorf("generate operations for removing static routes %v from logical router %s: %w", uuids, lrName, err)
1✔
178
        }
×
UNCOV
179
        if err = c.Transact("lr-route-del", ops); err != nil {
×
180
                klog.Error(err)
×
181
                return fmt.Errorf("delete static routes %v from logical router %s: %w", uuids, lrName, err)
1✔
182
        }
×
UNCOV
183

×
UNCOV
184
        return nil
×
185
}
186

1✔
187
// DeleteLogicalRouterStaticRoute delete a logical router static route
188
func (c *OVNNbClient) DeleteLogicalRouterStaticRouteByUUID(lrName, uuid string) error {
189
        lr, err := c.GetLogicalRouter(lrName, true)
190
        if err != nil {
1✔
191
                return err
1✔
192
        }
1✔
193
        if lr == nil {
×
194
                return nil
×
195
        }
1✔
UNCOV
196

×
UNCOV
197
        // remove static route from logical router
×
198
        ops, err := c.LogicalRouterUpdateStaticRouteOp(lrName, []string{uuid}, ovsdb.MutateOperationDelete)
199
        if err != nil {
200
                klog.Error(err)
1✔
201
                return fmt.Errorf("generate operations for removing static route %s from logical router %s: %w", uuid, lrName, err)
1✔
202
        }
×
203
        if err = c.Transact("lr-route-del", ops); err != nil {
×
204
                klog.Error(err)
×
205
                return fmt.Errorf("delete static route %s from logical router %s: %w", uuid, lrName, err)
1✔
206
        }
×
UNCOV
207

×
208
        return nil
×
209
}
210

1✔
211
func (c *OVNNbClient) DeleteLogicalRouterStaticRouteByExternalIDs(lrName string, externalIDs map[string]string) error {
212
        lr, err := c.GetLogicalRouter(lrName, true)
213
        if err != nil {
1✔
214
                return err
1✔
215
        }
1✔
216
        if lr == nil {
×
217
                return nil
×
218
        }
1✔
UNCOV
219

×
220
        routes, err := c.ListLogicalRouterStaticRoutes(lrName, nil, nil, "", externalIDs)
×
221
        if err != nil {
222
                klog.Error(err)
1✔
223
                return err
1✔
224
        }
×
225
        if len(routes) == 0 {
×
226
                return nil
×
227
        }
2✔
228

1✔
229
        uuids := make([]string, 0, len(routes))
1✔
230
        for _, route := range routes {
231
                uuids = append(uuids, route.UUID)
1✔
232
        }
2✔
233

1✔
234
        // remove static route from logical router
1✔
235
        ops, err := c.LogicalRouterUpdateStaticRouteOp(lrName, uuids, ovsdb.MutateOperationDelete)
236
        if err != nil {
237
                klog.Error(err)
1✔
238
                return fmt.Errorf("generate operations for removing static routes %v from logical router %s: %w", uuids, lrName, err)
1✔
239
        }
×
240
        if err = c.Transact("lr-route-del", ops); err != nil {
×
241
                klog.Error(err)
×
242
                return fmt.Errorf("delete static routes %v from logical router %s: %w", uuids, lrName, err)
1✔
243
        }
×
UNCOV
244

×
245
        return nil
×
246
}
247

1✔
248
// ClearLogicalRouterStaticRoute clear static route from logical router once
249
func (c *OVNNbClient) ClearLogicalRouterStaticRoute(lrName string) error {
250
        lr, err := c.GetLogicalRouter(lrName, false)
251
        if err != nil {
1✔
252
                klog.Error(err)
1✔
253
                return fmt.Errorf("get logical router %s: %w", lrName, err)
2✔
254
        }
1✔
255

1✔
256
        // clear static route
1✔
257
        lr.StaticRoutes = nil
258
        ops, err := c.UpdateLogicalRouterOp(lr, &lr.StaticRoutes)
259
        if err != nil {
1✔
260
                klog.Error(err)
1✔
261
                return fmt.Errorf("generate operations for clear logical router %s static route: %w", lrName, err)
1✔
262
        }
×
UNCOV
263
        if err = c.Transact("lr-route-clear", ops); err != nil {
×
264
                klog.Error(err)
×
265
                return fmt.Errorf("clear logical router %s static routes: %w", lrName, err)
1✔
266
        }
×
UNCOV
267

×
UNCOV
268
        return nil
×
269
}
270

1✔
271
// GetLogicalRouterStaticRouteByUUID get logical router static route by UUID
272
func (c *OVNNbClient) GetLogicalRouterStaticRouteByUUID(uuid string) (*ovnnb.LogicalRouterStaticRoute, error) {
273
        ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
274
        defer cancel()
1✔
275

1✔
276
        route := &ovnnb.LogicalRouterStaticRoute{UUID: uuid}
1✔
277
        if err := c.Get(ctx, route); err != nil {
1✔
278
                klog.Error(err)
1✔
279
                return nil, err
1✔
280
        }
×
UNCOV
281

×
UNCOV
282
        return route, nil
×
283
}
284

1✔
285
// GetLogicalRouterStaticRoute get logical router static route by some attribute,
286
// a static route is uniquely identified by router(lrName), policy and ipPrefix when route is not ecmp
287
// a static route is uniquely identified by router(lrName), policy, ipPrefix and nexthop when route is ecmp
288
func (c *OVNNbClient) GetLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop string, ignoreNotFound bool) (*ovnnb.LogicalRouterStaticRoute, error) {
289
        // this is necessary because may exist same static route in different logical router
290
        if len(lrName) == 0 {
1✔
291
                return nil, errors.New("the logical router name is required")
1✔
292
        }
2✔
293

1✔
294
        fnFilter := func(route *ovnnb.LogicalRouterStaticRoute) bool {
1✔
295
                return route.RouteTable == routeTable && route.Policy != nil && *route.Policy == policy && route.IPPrefix == ipPrefix && route.Nexthop == nexthop
296
        }
2✔
297
        routeList, err := c.listLogicalRouterStaticRoutesByFilter(lrName, fnFilter)
1✔
298
        if err != nil {
1✔
299
                klog.Error(err)
1✔
300
                return nil, fmt.Errorf("get logical router %s static route 'policy %s ip_prefix %s nexthop %s': %w", lrName, policy, ipPrefix, nexthop, err)
2✔
301
        }
1✔
302

1✔
303
        // not found
1✔
304
        if len(routeList) == 0 {
305
                if ignoreNotFound {
306
                        return nil, nil
2✔
307
                }
2✔
308
                return nil, fmt.Errorf("not found logical router %s static route 'policy %s ip_prefix %s nexthop %s'", lrName, policy, ipPrefix, nexthop)
1✔
309
        }
1✔
310

1✔
311
        if len(routeList) > 1 {
312
                return nil, fmt.Errorf("more than one static route 'policy %s ip_prefix %s nexthop %s' in logical router %s", policy, ipPrefix, nexthop, lrName)
313
        }
2✔
314

1✔
315
        return routeList[0], nil
1✔
316
}
317

1✔
318
// ListLogicalRouterStaticRoutes list route which match the given externalIDs
319
func (c *OVNNbClient) ListLogicalRouterStaticRoutes(lrName string, routeTable, policy *string, ipPrefix string, externalIDs map[string]string) ([]*ovnnb.LogicalRouterStaticRoute, error) {
320
        fnFilter := func(route *ovnnb.LogicalRouterStaticRoute) bool {
321
                if len(route.ExternalIDs) < len(externalIDs) {
1✔
322
                        return false
2✔
323
                }
2✔
324

1✔
325
                if len(route.ExternalIDs) != 0 {
1✔
326
                        for k, v := range externalIDs {
327
                                // if only key exist but not value in externalIDs, we should include this route,
2✔
328
                                // it's equal to shell command `ovn-nbctl --columns=xx find logical_router_static_route external_ids:key!=\"\"`
2✔
329
                                if len(v) == 0 {
1✔
330
                                        if len(route.ExternalIDs[k]) == 0 {
1✔
331
                                                return false
2✔
332
                                        }
2✔
333
                                } else {
1✔
334
                                        if route.ExternalIDs[k] != v {
1✔
335
                                                return false
1✔
336
                                        }
2✔
337
                                }
1✔
338
                        }
1✔
339
                }
340

341
                if routeTable != nil && route.RouteTable != *routeTable {
342
                        return false
343
                }
2✔
344
                if policy != nil {
1✔
345
                        if route.Policy != nil {
1✔
346
                                if *route.Policy != *policy {
2✔
347
                                        return false
2✔
348
                                }
2✔
349
                        } else if *policy != ovnnb.LogicalRouterStaticRoutePolicyDstIP {
1✔
350
                                return false
1✔
351
                        }
×
UNCOV
352
                }
×
UNCOV
353
                if ipPrefix != "" && route.IPPrefix != ipPrefix {
×
354
                        return false
355
                }
2✔
356

1✔
357
                return true
1✔
358
        }
359

1✔
360
        return c.listLogicalRouterStaticRoutesByFilter(lrName, fnFilter)
361
}
362

1✔
363
func (c *OVNNbClient) LogicalRouterStaticRouteExists(lrName, routeTable, policy, ipPrefix, nexthop string) (bool, error) {
364
        route, err := c.GetLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop, true)
365
        return route != nil, err
1✔
366
}
1✔
367

1✔
368
// newLogicalRouterStaticRoute return logical router static route with basic information
1✔
369
func (c *OVNNbClient) newLogicalRouterStaticRoute(lrName, routeTable, policy, ipPrefix, nexthop string, bfdID *string, options ...func(route *ovnnb.LogicalRouterStaticRoute)) (*ovnnb.LogicalRouterStaticRoute, error) {
370
        if len(lrName) == 0 {
371
                return nil, errors.New("the logical router name is required")
1✔
372
        }
2✔
373

1✔
374
        if len(policy) == 0 {
1✔
375
                policy = ovnnb.LogicalRouterStaticRoutePolicyDstIP
376
        }
2✔
377

1✔
378
        exists, err := c.LogicalRouterStaticRouteExists(lrName, routeTable, policy, ipPrefix, nexthop)
1✔
379
        if err != nil {
380
                klog.Error(err)
1✔
381
                return nil, fmt.Errorf("get logical router %s route: %w", lrName, err)
1✔
382
        }
×
UNCOV
383

×
UNCOV
384
        // found, ignore
×
385
        if exists {
386
                return nil, nil
387
        }
2✔
388

1✔
389
        route := &ovnnb.LogicalRouterStaticRoute{
1✔
390
                UUID:       ovsclient.NamedUUID(),
391
                Policy:     &policy,
1✔
392
                IPPrefix:   ipPrefix,
1✔
393
                Nexthop:    nexthop,
1✔
394
                RouteTable: routeTable,
1✔
395
        }
1✔
396
        for _, option := range options {
1✔
397
                option(route)
1✔
398
        }
1✔
399

2✔
400
        if bfdID != nil {
1✔
401
                route.BFD = bfdID
1✔
402
                if route.Options == nil {
403
                        route.Options = make(map[string]string)
2✔
404
                }
1✔
405
                route.Options[util.StaticRouteBfdEcmp] = "true"
2✔
406
        }
1✔
407
        return route, nil
1✔
408
}
1✔
409

410
func (c *OVNNbClient) listLogicalRouterStaticRoutesByFilter(lrName string, filter func(route *ovnnb.LogicalRouterStaticRoute) bool) ([]*ovnnb.LogicalRouterStaticRoute, error) {
1✔
411
        lr, err := c.GetLogicalRouter(lrName, false)
412
        if err != nil {
413
                klog.Error(err)
1✔
414
                return nil, err
1✔
415
        }
2✔
416

1✔
417
        routeList := make([]*ovnnb.LogicalRouterStaticRoute, 0, len(lr.StaticRoutes))
1✔
418
        for _, uuid := range lr.StaticRoutes {
1✔
419
                route, err := c.GetLogicalRouterStaticRouteByUUID(uuid)
420
                if err != nil {
1✔
421
                        if errors.Is(err, client.ErrNotFound) {
2✔
422
                                continue
1✔
423
                        }
1✔
424
                        klog.Error(err)
×
425
                        return nil, err
×
426
                }
UNCOV
427
                if filter == nil || filter(route) {
×
UNCOV
428
                        routeList = append(routeList, route)
×
429
                }
430
        }
2✔
431

1✔
432
        return routeList, nil
1✔
433
}
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