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

kubeovn / kube-ovn / 16047898469

03 Jul 2025 10:22AM UTC coverage: 21.529% (-0.02%) from 21.545%
16047898469

Pull #5426

github

zhangzujian
fix setting LR option always_learn_from_arp_request

Signed-off-by: zhangzujian <zhangzujian.7@gmail.com>
Pull Request #5426: fix setting LR option always_learn_from_arp_request

1 of 26 new or added lines in 2 files covered. (3.85%)

5 existing lines in 3 files now uncovered.

10511 of 48823 relevant lines covered (21.53%)

0.25 hits per line

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

76.19
/pkg/ovs/ovn-nb-port_group.go
1
package ovs
2

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

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

16
        "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb"
17
)
18

19
func (c *OVNNbClient) CreatePortGroup(pgName string, externalIDs map[string]string) error {
1✔
20
        pg, err := c.GetPortGroup(pgName, true)
1✔
21
        if err != nil {
2✔
22
                klog.Error(err)
1✔
23
                return err
1✔
24
        }
1✔
25

26
        if pg != nil {
2✔
27
                if !maps.Equal(pg.ExternalIDs, externalIDs) {
2✔
28
                        pg.ExternalIDs = maps.Clone(externalIDs)
1✔
29
                        if err = c.UpdatePortGroup(pg, &pg.ExternalIDs); err != nil {
1✔
30
                                err = fmt.Errorf("failed to update port group %s external IDs: %w", pgName, err)
×
31
                                klog.Error(err)
×
32
                                return err
×
33
                        }
×
34
                }
35
                return nil
1✔
36
        }
37

38
        pg = &ovnnb.PortGroup{
1✔
39
                Name:        pgName,
1✔
40
                ExternalIDs: externalIDs,
1✔
41
        }
1✔
42

1✔
43
        ops, err := c.Create(pg)
1✔
44
        if err != nil {
1✔
45
                klog.Error(err)
×
46
                return fmt.Errorf("generate operations for creating port group %s: %w", pgName, err)
×
47
        }
×
48

49
        if err = c.Transact("pg-add", ops); err != nil {
2✔
50
                klog.Error(err)
1✔
51
                return fmt.Errorf("create port group %s: %w", pgName, err)
1✔
52
        }
1✔
53

54
        return nil
1✔
55
}
56

57
// PortGroupAddPorts add ports to port group
58
func (c *OVNNbClient) PortGroupAddPorts(pgName string, lspNames ...string) error {
1✔
59
        return c.PortGroupUpdatePorts(pgName, ovsdb.MutateOperationInsert, lspNames...)
1✔
60
}
1✔
61

62
// PortGroupRemovePorts remove ports from port group
63
func (c *OVNNbClient) PortGroupRemovePorts(pgName string, lspNames ...string) error {
1✔
64
        return c.PortGroupUpdatePorts(pgName, ovsdb.MutateOperationDelete, lspNames...)
1✔
65
}
1✔
66

67
func (c *OVNNbClient) PortGroupSetPorts(pgName string, ports []string) error {
1✔
68
        if pgName == "" {
2✔
69
                return errors.New("port group name is empty")
1✔
70
        }
1✔
71

72
        pg, err := c.GetPortGroup(pgName, false)
1✔
73
        if err != nil {
2✔
74
                klog.Error(err)
1✔
75
                return fmt.Errorf("get port group %s: %w", pgName, err)
1✔
76
        }
1✔
77

78
        expected := strset.NewWithSize(len(ports))
1✔
79
        for _, port := range ports {
2✔
80
                lsp, err := c.GetLogicalSwitchPort(port, true)
1✔
81
                if err != nil {
1✔
82
                        klog.Error(err)
×
83
                        return err
×
84
                }
×
85
                if lsp != nil {
2✔
86
                        expected.Add(lsp.UUID)
1✔
87
                }
1✔
88
        }
89

90
        existing := strset.New(pg.Ports...)
1✔
91
        toAdd := strset.Difference(expected, existing).List()
1✔
92
        toDel := strset.Difference(existing, expected).List()
1✔
93

1✔
94
        insertOps, err := c.portGroupUpdatePortOp(pgName, toAdd, ovsdb.MutateOperationInsert)
1✔
95
        if err != nil {
1✔
96
                klog.Error(err)
×
97
                return fmt.Errorf("failed generate operations for adding ports %v to port group %s: %w", toAdd, pgName, err)
×
98
        }
×
99
        deleteOps, err := c.portGroupUpdatePortOp(pgName, toDel, ovsdb.MutateOperationDelete)
1✔
100
        if err != nil {
1✔
101
                klog.Error(err)
×
102
                return fmt.Errorf("failed generate operations for deleting ports %v from port group %s: %w", toDel, pgName, err)
×
103
        }
×
104

105
        if err = c.Transact("pg-ports-update", append(insertOps, deleteOps...)); err != nil {
1✔
106
                klog.Error(err)
×
107
                return fmt.Errorf("port group %s set ports %v: %w", pgName, ports, err)
×
108
        }
×
109

110
        return nil
1✔
111
}
112

113
// UpdatePortGroup update port group
114
func (c *OVNNbClient) UpdatePortGroup(pg *ovnnb.PortGroup, fields ...any) error {
1✔
115
        op, err := c.Where(pg).Update(pg, fields...)
1✔
116
        if err != nil {
2✔
117
                klog.Error(err)
1✔
118
                return fmt.Errorf("generate operations for updating port group %s: %w", pg.Name, err)
1✔
119
        }
1✔
120

121
        if err = c.Transact("pg-update", op); err != nil {
1✔
122
                klog.Error(err)
×
123
                return fmt.Errorf("update port group %s: %w", pg.Name, err)
×
124
        }
×
125

126
        return nil
1✔
127
}
128

129
// PortGroupUpdatePorts add several ports to or from port group once
130
func (c *OVNNbClient) PortGroupUpdatePorts(pgName string, op ovsdb.Mutator, lspNames ...string) error {
1✔
131
        if len(lspNames) == 0 {
2✔
132
                return nil
1✔
133
        }
1✔
134

135
        lspUUIDs := make([]string, 0, len(lspNames))
1✔
136

1✔
137
        for _, lspName := range lspNames {
2✔
138
                lsp, err := c.GetLogicalSwitchPort(lspName, true)
1✔
139
                if err != nil {
1✔
140
                        klog.Error(err)
×
141
                        return err
×
142
                }
×
143

144
                // ignore non-existent object
145
                if lsp != nil {
2✔
146
                        lspUUIDs = append(lspUUIDs, lsp.UUID)
1✔
147
                }
1✔
148
        }
149

150
        ops, err := c.portGroupUpdatePortOp(pgName, lspUUIDs, op)
1✔
151
        if err != nil {
2✔
152
                klog.Error(err)
1✔
153
                return fmt.Errorf("generate operations for port group %s update ports %v: %w", pgName, lspNames, err)
1✔
154
        }
1✔
155

156
        if err := c.Transact("pg-ports-update", ops); err != nil {
1✔
157
                klog.Error(err)
×
158
                return fmt.Errorf("port group %s update ports %v: %w", pgName, lspNames, err)
×
159
        }
×
160

161
        return nil
1✔
162
}
163

164
func (c *OVNNbClient) DeletePortGroup(pgName ...string) error {
1✔
165
        delList := make([]*ovnnb.PortGroup, 0, len(pgName))
1✔
166
        for _, name := range pgName {
2✔
167
                // get port group
1✔
168
                pg, err := c.GetPortGroup(name, true)
1✔
169
                if err != nil {
1✔
170
                        return fmt.Errorf("get port group %s when delete: %w", name, err)
×
171
                }
×
172
                // not found, skip
173
                if pg == nil {
2✔
174
                        continue
1✔
175
                }
176
                delList = append(delList, pg)
1✔
177
        }
178
        if len(delList) == 0 {
2✔
179
                return nil
1✔
180
        }
1✔
181

182
        modelList := make([]model.Model, len(delList))
1✔
183
        for i, pg := range delList {
2✔
184
                modelList[i] = pg
1✔
185
        }
1✔
186
        op, err := c.Where(modelList...).Delete()
1✔
187
        if err != nil {
1✔
188
                return err
×
189
        }
×
190
        if err := c.Transact("pg-del", op); err != nil {
1✔
191
                klog.Error(err)
×
192
                return fmt.Errorf("delete port group %s: %w", pgName, err)
×
193
        }
×
194

195
        return nil
1✔
196
}
197

198
// GetPortGroup get port group by name
199
func (c *OVNNbClient) GetPortGroup(pgName string, ignoreNotFound bool) (*ovnnb.PortGroup, error) {
1✔
200
        if pgName == "" {
2✔
201
                return nil, errors.New("port group name is empty")
1✔
202
        }
1✔
203
        ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
1✔
204
        defer cancel()
1✔
205

1✔
206
        pg := &ovnnb.PortGroup{Name: pgName}
1✔
207
        if err := c.Get(ctx, pg); err != nil {
2✔
208
                if ignoreNotFound && errors.Is(err, client.ErrNotFound) {
2✔
209
                        return nil, nil
1✔
210
                }
1✔
211
                klog.Error(err)
1✔
212
                return nil, fmt.Errorf("get port group %s: %w", pgName, err)
1✔
213
        }
214

215
        return pg, nil
1✔
216
}
217

218
// ListPortGroups list port groups which match the given externalIDs,
219
// result should include all port groups when externalIDs is empty,
220
// result should include all port groups which externalIDs[key] is not empty when externalIDs[key] is ""
221
func (c *OVNNbClient) ListPortGroups(externalIDs map[string]string) ([]ovnnb.PortGroup, error) {
1✔
222
        ctx, cancel := context.WithTimeout(context.Background(), c.Timeout)
1✔
223
        defer cancel()
1✔
224

1✔
225
        var pgs []ovnnb.PortGroup
1✔
226
        if err := c.WhereCache(func(pg *ovnnb.PortGroup) bool {
2✔
227
                if len(externalIDs) != 0 && len(pg.ExternalIDs) < len(externalIDs) {
2✔
228
                        return false
1✔
229
                }
1✔
230

231
                if len(pg.ExternalIDs) != 0 {
2✔
232
                        for k, v := range externalIDs {
2✔
233
                                // if only key exist but not value in externalIDs, we should include this pg,
1✔
234
                                // it's equal to shell command `ovn-nbctl --columns=xx find port_group external_ids:key!=\"\"`
1✔
235
                                if len(v) == 0 {
2✔
236
                                        if len(pg.ExternalIDs[k]) == 0 {
2✔
237
                                                return false
1✔
238
                                        }
1✔
239
                                } else {
1✔
240
                                        if pg.ExternalIDs[k] != v {
1✔
UNCOV
241
                                                return false
×
UNCOV
242
                                        }
×
243
                                }
244
                        }
245
                }
246

247
                return true
1✔
248
        }).List(ctx, &pgs); err != nil {
×
249
                klog.Errorf("list logical switch ports: %v", err)
×
250
                return nil, err
×
251
        }
×
252

253
        return pgs, nil
1✔
254
}
255

256
func (c *OVNNbClient) PortGroupExists(pgName string) (bool, error) {
×
257
        lsp, err := c.GetPortGroup(pgName, true)
×
258
        return lsp != nil, err
×
259
}
×
260

261
// portGroupUpdatePortOp create operations add port to or delete port from port group
262
func (c *OVNNbClient) portGroupUpdatePortOp(pgName string, lspUUIDs []string, op ovsdb.Mutator) ([]ovsdb.Operation, error) {
1✔
263
        if len(lspUUIDs) == 0 {
2✔
264
                return nil, nil
1✔
265
        }
1✔
266

267
        mutation := func(pg *ovnnb.PortGroup) *model.Mutation {
2✔
268
                mutation := &model.Mutation{
1✔
269
                        Field:   &pg.Ports,
1✔
270
                        Value:   lspUUIDs,
1✔
271
                        Mutator: op,
1✔
272
                }
1✔
273

1✔
274
                return mutation
1✔
275
        }
1✔
276

277
        return c.portGroupOp(pgName, mutation)
1✔
278
}
279

280
// portGroupUpdateACLOp create operations add acl to or delete acl from port group
281
func (c *OVNNbClient) portGroupUpdateACLOp(pgName string, aclUUIDs []string, op ovsdb.Mutator) ([]ovsdb.Operation, error) {
1✔
282
        if len(aclUUIDs) == 0 {
2✔
283
                return nil, nil
1✔
284
        }
1✔
285

286
        mutation := func(pg *ovnnb.PortGroup) *model.Mutation {
2✔
287
                mutation := &model.Mutation{
1✔
288
                        Field:   &pg.ACLs,
1✔
289
                        Value:   aclUUIDs,
1✔
290
                        Mutator: op,
1✔
291
                }
1✔
292

1✔
293
                return mutation
1✔
294
        }
1✔
295

296
        return c.portGroupOp(pgName, mutation)
1✔
297
}
298

299
// portGroupOp create operations about port group
300
func (c *OVNNbClient) portGroupOp(pgName string, mutationsFunc ...func(pg *ovnnb.PortGroup) *model.Mutation) ([]ovsdb.Operation, error) {
1✔
301
        pg, err := c.GetPortGroup(pgName, false)
1✔
302
        if err != nil {
2✔
303
                klog.Error(err)
1✔
304
                return nil, fmt.Errorf("get port group %s: %w", pgName, err)
1✔
305
        }
1✔
306

307
        if len(mutationsFunc) == 0 {
2✔
308
                return nil, nil
1✔
309
        }
1✔
310

311
        mutations := make([]model.Mutation, 0, len(mutationsFunc))
1✔
312

1✔
313
        for _, f := range mutationsFunc {
2✔
314
                mutation := f(pg)
1✔
315

1✔
316
                if mutation != nil {
2✔
317
                        mutations = append(mutations, *mutation)
1✔
318
                }
1✔
319
        }
320

321
        ops, err := c.ovsDbClient.Where(pg).Mutate(pg, mutations...)
1✔
322
        if err != nil {
1✔
323
                klog.Error(err)
×
324
                return nil, fmt.Errorf("generate operations for mutating port group %s: %w", pgName, err)
×
325
        }
×
326

327
        return ops, nil
1✔
328
}
329

330
func (c *OVNNbClient) RemovePortFromPortGroups(portName string, portGroupNames ...string) error {
1✔
331
        lsp, err := c.GetLogicalSwitchPort(portName, true)
1✔
332
        if err != nil {
1✔
333
                klog.Error(err)
×
334
                return fmt.Errorf("failed to get logical switch port %s: %w", portName, err)
×
335
        }
×
336
        if lsp == nil {
1✔
337
                return nil
×
338
        }
×
339

340
        portGroups := make([]ovnnb.PortGroup, 0, len(portGroupNames))
1✔
341
        if len(portGroupNames) != 0 {
2✔
342
                for _, pgName := range portGroupNames {
2✔
343
                        pg, err := c.GetPortGroup(pgName, true)
1✔
344
                        if err != nil {
1✔
345
                                klog.Error(err)
×
346
                                return fmt.Errorf("failed to get port group %s: %w", pgName, err)
×
347
                        }
×
348
                        if pg != nil {
2✔
349
                                portGroups = append(portGroups, *pg)
1✔
350
                        }
1✔
351
                }
352
        } else if portGroups, err = c.ListPortGroups(nil); err != nil {
1✔
353
                klog.Error(err)
×
354
                return fmt.Errorf("failed to list port groups: %w", err)
×
355
        }
×
356

357
        var ops []ovsdb.Operation
1✔
358
        for _, pg := range portGroups {
2✔
359
                if !slices.Contains(pg.Ports, lsp.UUID) {
2✔
360
                        continue
1✔
361
                }
362

363
                op, err := c.portGroupUpdatePortOp(pg.Name, []string{lsp.UUID}, ovsdb.MutateOperationDelete)
1✔
364
                if err != nil {
1✔
365
                        klog.Error(err)
×
366
                        return fmt.Errorf("failed to generate operations for removing port %s from port group %s: %w", portName, pg.Name, err)
×
367
                }
×
368
                ops = append(ops, op...)
1✔
369
        }
370

371
        if err = c.Transact("pg-update", ops); err != nil {
1✔
372
                klog.Error(err)
×
373
                return fmt.Errorf("failed to remove port %s from all port groups: %w", portName, err)
×
374
        }
×
375

376
        return nil
1✔
377
}
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