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

kubeovn / kube-ovn / 17228354799

26 Aug 2025 04:55AM UTC coverage: 21.341% (-0.2%) from 21.508%
17228354799

push

github

oilbeater
handle delete final state unknown object in enqueue handler (#5649)

Signed-off-by: Mengxin Liu <liumengxinfly@gmail.com>

0 of 443 new or added lines in 27 files covered. (0.0%)

1 existing line in 1 file now uncovered.

10514 of 49267 relevant lines covered (21.34%)

0.25 hits per line

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

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

3
import (
4
        "fmt"
5
        "maps"
6
        "reflect"
7
        "slices"
8
        "strconv"
9
        "strings"
10
        "unicode"
11

12
        "github.com/scylladb/go-set/strset"
13
        corev1 "k8s.io/api/core/v1"
14
        netv1 "k8s.io/api/networking/v1"
15
        k8serrors "k8s.io/apimachinery/pkg/api/errors"
16
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
17
        "k8s.io/apimachinery/pkg/labels"
18
        utilruntime "k8s.io/apimachinery/pkg/util/runtime"
19
        "k8s.io/client-go/tools/cache"
20
        "k8s.io/klog/v2"
21
        "k8s.io/utils/set"
22

23
        kubeovnv1 "github.com/kubeovn/kube-ovn/pkg/apis/kubeovn/v1"
24
        "github.com/kubeovn/kube-ovn/pkg/ovs"
25
        "github.com/kubeovn/kube-ovn/pkg/ovsdb/ovnnb"
26
        "github.com/kubeovn/kube-ovn/pkg/util"
27
)
28

29
func (c *Controller) enqueueAddNp(obj any) {
×
30
        key := cache.MetaObjectToName(obj.(*netv1.NetworkPolicy)).String()
×
31
        klog.V(3).Infof("enqueue add network policy %s", key)
×
32
        c.updateNpQueue.Add(key)
×
33
}
×
34

35
func (c *Controller) enqueueDeleteNp(obj any) {
×
NEW
36
        var np *netv1.NetworkPolicy
×
NEW
37
        switch t := obj.(type) {
×
NEW
38
        case *netv1.NetworkPolicy:
×
NEW
39
                np = t
×
NEW
40
        case cache.DeletedFinalStateUnknown:
×
NEW
41
                n, ok := t.Obj.(*netv1.NetworkPolicy)
×
NEW
42
                if !ok {
×
NEW
43
                        klog.Warningf("unexpected object type: %T", t.Obj)
×
NEW
44
                        return
×
NEW
45
                }
×
NEW
46
                np = n
×
NEW
47
        default:
×
NEW
48
                klog.Warningf("unexpected type: %T", obj)
×
NEW
49
                return
×
50
        }
51

NEW
52
        key := cache.MetaObjectToName(np).String()
×
53
        klog.V(3).Infof("enqueue delete network policy %s", key)
×
54
        c.deleteNpQueue.Add(key)
×
55
}
56

57
func (c *Controller) enqueueUpdateNp(oldObj, newObj any) {
×
58
        oldNp := oldObj.(*netv1.NetworkPolicy)
×
59
        newNp := newObj.(*netv1.NetworkPolicy)
×
60
        if !reflect.DeepEqual(oldNp.Spec, newNp.Spec) ||
×
61
                !maps.Equal(oldNp.Annotations, newNp.Annotations) {
×
62
                key := cache.MetaObjectToName(newNp).String()
×
63
                klog.V(3).Infof("enqueue update np %s", key)
×
64
                c.updateNpQueue.Add(key)
×
65
        }
×
66
}
67

68
func (c *Controller) createAsForNetpol(ns, name, direction, asName string, addresses []string) error {
×
69
        if err := c.OVNNbClient.CreateAddressSet(asName, map[string]string{
×
70
                networkPolicyKey: fmt.Sprintf("%s/%s/%s", ns, name, direction),
×
71
        }); err != nil {
×
72
                klog.Errorf("failed to create ovn address set %s for np %s/%s: %v", asName, ns, name, err)
×
73
                return err
×
74
        }
×
75

76
        if err := c.OVNNbClient.AddressSetUpdateAddress(asName, addresses...); err != nil {
×
77
                klog.Errorf("failed to set addresses %q to address set %s: %v", strings.Join(addresses, ","), asName, err)
×
78
                return err
×
79
        }
×
80

81
        return nil
×
82
}
83

84
func (c *Controller) handleUpdateNp(key string) error {
×
85
        namespace, name, err := cache.SplitMetaNamespaceKey(key)
×
86
        if err != nil {
×
87
                utilruntime.HandleError(fmt.Errorf("invalid resource key: %s", key))
×
88
                return nil
×
89
        }
×
90

91
        c.npKeyMutex.LockKey(key)
×
92
        defer func() { _ = c.npKeyMutex.UnlockKey(key) }()
×
93
        klog.Infof("handle add/update network policy %s", key)
×
94

×
95
        np, err := c.npsLister.NetworkPolicies(namespace).Get(name)
×
96
        if err != nil {
×
97
                if k8serrors.IsNotFound(err) {
×
98
                        return nil
×
99
                }
×
100
                klog.Error(err)
×
101
                return err
×
102
        }
103

104
        defer func() {
×
105
                if err != nil {
×
106
                        c.recorder.Eventf(np, corev1.EventTypeWarning, "CreateACLFailed", err.Error())
×
107
                }
×
108
        }()
109

110
        logEnable := np.Annotations[util.NetworkPolicyLogAnnotation] == "true"
×
111

×
112
        var logActions []string
×
113
        if np.Annotations[util.ACLActionsLogAnnotation] != "" {
×
114
                logActions = strings.Split(np.Annotations[util.ACLActionsLogAnnotation], ",")
×
115
        } else {
×
116
                logActions = []string{ovnnb.ACLActionDrop}
×
117
        }
×
118

119
        npName := np.Name
×
120
        nameArray := []rune(np.Name)
×
121
        if !unicode.IsLetter(nameArray[0]) {
×
122
                npName = "np" + np.Name
×
123
        }
×
124

125
        // TODO: ovn acl doesn't support address_set name with '-', now we replace '-' by '.'.
126
        // This may cause conflict if two np with name test-np and test.np. Maybe hash is a better solution,
127
        // but we do not want to lost the readability now.
128
        pgName := strings.ReplaceAll(fmt.Sprintf("%s.%s", npName, np.Namespace), "-", ".")
×
129
        ingressAllowAsNamePrefix := strings.ReplaceAll(fmt.Sprintf("%s.%s.ingress.allow", npName, np.Namespace), "-", ".")
×
130
        ingressExceptAsNamePrefix := strings.ReplaceAll(fmt.Sprintf("%s.%s.ingress.except", npName, np.Namespace), "-", ".")
×
131
        egressAllowAsNamePrefix := strings.ReplaceAll(fmt.Sprintf("%s.%s.egress.allow", npName, np.Namespace), "-", ".")
×
132
        egressExceptAsNamePrefix := strings.ReplaceAll(fmt.Sprintf("%s.%s.egress.except", npName, np.Namespace), "-", ".")
×
133

×
134
        if err = c.OVNNbClient.CreatePortGroup(pgName, map[string]string{networkPolicyKey: np.Namespace + "/" + npName}); err != nil {
×
135
                klog.Errorf("create port group for np %s: %v", key, err)
×
136
                return err
×
137
        }
×
138

139
        namedPortMap := c.namedPort.GetNamedPortByNs(np.Namespace)
×
140
        ports, subnetNames, err := c.fetchSelectedPorts(np.Namespace, &np.Spec.PodSelector)
×
141
        if err != nil {
×
142
                klog.Errorf("fetch ports belongs to np %s: %v", key, err)
×
143
                return err
×
144
        }
×
145

146
        var subnets []*kubeovnv1.Subnet
×
147
        protocolSet := strset.NewWithSize(2)
×
148
        for _, subnetName := range subnetNames {
×
149
                subnet, err := c.subnetsLister.Get(subnetName)
×
150
                if err != nil {
×
151
                        klog.Errorf("failed to get pod's subnet %s, %v", subnetName, err)
×
152
                        return err
×
153
                }
×
154
                subnets = append(subnets, subnet)
×
155

×
156
                if subnet.Spec.Protocol == kubeovnv1.ProtocolDual {
×
157
                        protocolSet.Add(kubeovnv1.ProtocolIPv4, kubeovnv1.ProtocolIPv6)
×
158
                } else {
×
159
                        protocolSet.Add(subnet.Spec.Protocol)
×
160
                }
×
161
        }
162
        klog.Infof("UpdateNp, related subnets protocols %s", protocolSet.String())
×
163

×
164
        if err = c.OVNNbClient.PortGroupSetPorts(pgName, ports); err != nil {
×
165
                klog.Errorf("failed to set ports of port group %s to %v: %v", pgName, ports, err)
×
166
                return err
×
167
        }
×
168

169
        ingressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "to-lport", nil)
×
170
        if err != nil {
×
171
                klog.Errorf("generate operations that clear np %s ingress acls: %v", key, err)
×
172
                return err
×
173
        }
×
174

175
        if hasIngressRule(np) {
×
176
                for _, protocol := range protocolSet.List() {
×
177
                        for idx, npr := range np.Spec.Ingress {
×
178
                                // A single address set must contain addresses of the same type and the name must be unique within table, so IPv4 and IPv6 address set should be different
×
179
                                ingressAllowAsName := fmt.Sprintf("%s.%s.%d", ingressAllowAsNamePrefix, protocol, idx)
×
180
                                ingressExceptAsName := fmt.Sprintf("%s.%s.%d", ingressExceptAsNamePrefix, protocol, idx)
×
181
                                aclName := fmt.Sprintf("np/%s.%s/ingress/%s/%d", npName, np.Namespace, protocol, idx)
×
182

×
183
                                var allows, excepts []string
×
184
                                if len(npr.From) == 0 {
×
185
                                        if protocol == kubeovnv1.ProtocolIPv4 {
×
186
                                                allows = []string{"0.0.0.0/0"}
×
187
                                        } else {
×
188
                                                allows = []string{"::/0"}
×
189
                                        }
×
190
                                } else {
×
191
                                        var allow, except []string
×
192
                                        for _, npp := range npr.From {
×
193
                                                if allow, except, err = c.fetchPolicySelectedAddresses(np.Namespace, protocol, npp); err != nil {
×
194
                                                        klog.Errorf("failed to fetch policy selected addresses, %v", err)
×
195
                                                        return err
×
196
                                                }
×
197
                                                allows = append(allows, allow...)
×
198
                                                excepts = append(excepts, except...)
×
199
                                        }
200
                                }
201
                                klog.Infof("UpdateNp Ingress, allows is %v, excepts is %v, log %v, protocol %v", allows, excepts, logEnable, protocol)
×
202

×
203
                                if err = c.createAsForNetpol(np.Namespace, npName, "ingress", ingressAllowAsName, allows); err != nil {
×
204
                                        klog.Error(err)
×
205
                                        return err
×
206
                                }
×
207
                                if err = c.createAsForNetpol(np.Namespace, npName, "ingress", ingressExceptAsName, excepts); err != nil {
×
208
                                        klog.Error(err)
×
209
                                        return err
×
210
                                }
×
211

212
                                npp := []netv1.NetworkPolicyPort{}
×
213
                                if len(allows) != 0 || len(excepts) != 0 {
×
214
                                        npp = npr.Ports
×
215
                                }
×
216

217
                                ops, err := c.OVNNbClient.UpdateIngressACLOps(key, pgName, ingressAllowAsName, ingressExceptAsName, protocol, aclName, npp, logEnable, logActions, namedPortMap)
×
218
                                if err != nil {
×
219
                                        klog.Errorf("generate operations that add ingress acls to np %s: %v", key, err)
×
220
                                        return err
×
221
                                }
×
222

223
                                ingressACLOps = append(ingressACLOps, ops...)
×
224
                        }
225
                        if len(np.Spec.Ingress) == 0 {
×
226
                                ingressAllowAsName := fmt.Sprintf("%s.%s.all", ingressAllowAsNamePrefix, protocol)
×
227
                                ingressExceptAsName := fmt.Sprintf("%s.%s.all", ingressExceptAsNamePrefix, protocol)
×
228
                                aclName := fmt.Sprintf("np/%s.%s/ingress/%s/all", npName, np.Namespace, protocol)
×
229

×
230
                                if err = c.createAsForNetpol(np.Namespace, npName, "ingress", ingressAllowAsName, nil); err != nil {
×
231
                                        klog.Error(err)
×
232
                                        return err
×
233
                                }
×
234
                                if err = c.createAsForNetpol(np.Namespace, npName, "ingress", ingressExceptAsName, nil); err != nil {
×
235
                                        klog.Error(err)
×
236
                                        return err
×
237
                                }
×
238

239
                                ops, err := c.OVNNbClient.UpdateIngressACLOps(key, pgName, ingressAllowAsName, ingressExceptAsName, protocol, aclName, nil, logEnable, logActions, namedPortMap)
×
240
                                if err != nil {
×
241
                                        klog.Errorf("generate operations that add ingress acls to np %s: %v", key, err)
×
242
                                        return err
×
243
                                }
×
244

245
                                ingressACLOps = append(ingressACLOps, ops...)
×
246
                        }
247
                }
248

249
                if err := c.OVNNbClient.Transact("add-ingress-acls", ingressACLOps); err != nil {
×
250
                        return fmt.Errorf("add ingress acls to %s: %w", pgName, err)
×
251
                }
×
252

253
                if err := c.OVNNbClient.SetACLLog(pgName, logEnable, true); err != nil {
×
254
                        // just log and do not return err here
×
255
                        klog.Errorf("failed to set ingress acl log for np %s, %v", key, err)
×
256
                }
×
257

258
                ass, err := c.OVNNbClient.ListAddressSets(map[string]string{
×
259
                        networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "ingress"),
×
260
                })
×
261
                if err != nil {
×
262
                        klog.Errorf("list np %s address sets: %v", key, err)
×
263
                        return err
×
264
                }
×
265

266
                // The format of asName is like "test.network.policy.test.ingress.except.0" or "test.network.policy.test.ingress.allow.0" for ingress
267
                for _, as := range ass {
×
268
                        values := strings.Split(as.Name, ".")
×
269
                        if len(values) <= 1 {
×
270
                                continue
×
271
                        }
272
                        idxStr := values[len(values)-1]
×
273
                        if idxStr == "all" {
×
274
                                continue
×
275
                        }
276
                        idx, _ := strconv.Atoi(idxStr)
×
277
                        if idx >= len(np.Spec.Ingress) {
×
278
                                if err = c.OVNNbClient.DeleteAddressSet(as.Name); err != nil {
×
279
                                        klog.Errorf("failed to delete np %s address set, %v", key, err)
×
280
                                        return err
×
281
                                }
×
282
                        }
283
                }
284
        } else {
×
285
                if err = c.OVNNbClient.DeleteAcls(pgName, portGroupKey, "to-lport", nil); err != nil {
×
286
                        klog.Errorf("delete np %s ingress acls: %v", key, err)
×
287
                        return err
×
288
                }
×
289

290
                if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
291
                        networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "ingress"),
×
292
                }); err != nil {
×
293
                        klog.Errorf("delete np %s ingress address set: %v", key, err)
×
294
                        return err
×
295
                }
×
296
        }
297

298
        egressACLOps, err := c.OVNNbClient.DeleteAclsOps(pgName, portGroupKey, "from-lport", nil)
×
299
        if err != nil {
×
300
                klog.Errorf("generate operations that clear np %s egress acls: %v", key, err)
×
301
                return err
×
302
        }
×
303

304
        if hasEgressRule(np) {
×
305
                for _, protocol := range protocolSet.List() {
×
306
                        for idx, npr := range np.Spec.Egress {
×
307
                                // A single address set must contain addresses of the same type and the name must be unique within table, so IPv4 and IPv6 address set should be different
×
308
                                egressAllowAsName := fmt.Sprintf("%s.%s.%d", egressAllowAsNamePrefix, protocol, idx)
×
309
                                egressExceptAsName := fmt.Sprintf("%s.%s.%d", egressExceptAsNamePrefix, protocol, idx)
×
310
                                aclName := fmt.Sprintf("np/%s.%s/egress/%s/%d", npName, np.Namespace, protocol, idx)
×
311

×
312
                                var allows, excepts []string
×
313
                                if len(npr.To) == 0 {
×
314
                                        if protocol == kubeovnv1.ProtocolIPv4 {
×
315
                                                allows = []string{"0.0.0.0/0"}
×
316
                                        } else {
×
317
                                                allows = []string{"::/0"}
×
318
                                        }
×
319
                                } else {
×
320
                                        var allow, except []string
×
321
                                        for _, npp := range npr.To {
×
322
                                                if allow, except, err = c.fetchPolicySelectedAddresses(np.Namespace, protocol, npp); err != nil {
×
323
                                                        klog.Errorf("failed to fetch policy selected addresses, %v", err)
×
324
                                                        return err
×
325
                                                }
×
326
                                                allows = append(allows, allow...)
×
327
                                                excepts = append(excepts, except...)
×
328
                                        }
329
                                }
330
                                klog.Infof("UpdateNp Egress %s, allows is %v, excepts is %v, log %v", aclName, allows, excepts, logEnable)
×
331

×
332
                                if err = c.createAsForNetpol(np.Namespace, npName, "egress", egressAllowAsName, allows); err != nil {
×
333
                                        klog.Error(err)
×
334
                                        return err
×
335
                                }
×
336
                                if err = c.createAsForNetpol(np.Namespace, npName, "egress", egressExceptAsName, excepts); err != nil {
×
337
                                        klog.Error(err)
×
338
                                        return err
×
339
                                }
×
340

341
                                npp := []netv1.NetworkPolicyPort{}
×
342
                                if len(allows) != 0 || len(excepts) != 0 {
×
343
                                        npp = npr.Ports
×
344
                                }
×
345

346
                                ops, err := c.OVNNbClient.UpdateEgressACLOps(key, pgName, egressAllowAsName, egressExceptAsName, protocol, aclName, npp, logEnable, logActions, namedPortMap)
×
347
                                if err != nil {
×
348
                                        klog.Errorf("generate operations that add egress acls to np %s: %v", key, err)
×
349
                                        return err
×
350
                                }
×
351

352
                                egressACLOps = append(egressACLOps, ops...)
×
353
                        }
354
                        if len(np.Spec.Egress) == 0 {
×
355
                                egressAllowAsName := fmt.Sprintf("%s.%s.all", egressAllowAsNamePrefix, protocol)
×
356
                                egressExceptAsName := fmt.Sprintf("%s.%s.all", egressExceptAsNamePrefix, protocol)
×
357
                                aclName := fmt.Sprintf("np/%s.%s/egress/%s/all", npName, np.Namespace, protocol)
×
358

×
359
                                if err = c.createAsForNetpol(np.Namespace, npName, "egress", egressAllowAsName, nil); err != nil {
×
360
                                        klog.Error(err)
×
361
                                        return err
×
362
                                }
×
363
                                if err = c.createAsForNetpol(np.Namespace, npName, "egress", egressExceptAsName, nil); err != nil {
×
364
                                        klog.Error(err)
×
365
                                        return err
×
366
                                }
×
367

368
                                ops, err := c.OVNNbClient.UpdateEgressACLOps(key, pgName, egressAllowAsName, egressExceptAsName, protocol, aclName, nil, logEnable, logActions, namedPortMap)
×
369
                                if err != nil {
×
370
                                        klog.Errorf("generate operations that add egress acls to np %s: %v", key, err)
×
371
                                        return err
×
372
                                }
×
373

374
                                egressACLOps = append(egressACLOps, ops...)
×
375
                        }
376
                }
377

378
                if err := c.OVNNbClient.Transact("add-egress-acls", egressACLOps); err != nil {
×
379
                        return fmt.Errorf("add egress acls to %s: %w", pgName, err)
×
380
                }
×
381

382
                if err := c.OVNNbClient.SetACLLog(pgName, logEnable, false); err != nil {
×
383
                        // just log and do not return err here
×
384
                        klog.Errorf("failed to set egress acl log for np %s, %v", key, err)
×
385
                }
×
386

387
                ass, err := c.OVNNbClient.ListAddressSets(map[string]string{
×
388
                        networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "egress"),
×
389
                })
×
390
                if err != nil {
×
391
                        klog.Errorf("list np %s address sets: %v", key, err)
×
392
                        return err
×
393
                }
×
394

395
                // The format of asName is like "test.network.policy.test.egress.except.0" or "test.network.policy.test.egress.allow.0" for egress
396
                for _, as := range ass {
×
397
                        values := strings.Split(as.Name, ".")
×
398
                        if len(values) <= 1 {
×
399
                                continue
×
400
                        }
401
                        idxStr := values[len(values)-1]
×
402
                        if idxStr == "all" {
×
403
                                continue
×
404
                        }
405

406
                        idx, _ := strconv.Atoi(idxStr)
×
407
                        if idx >= len(np.Spec.Egress) {
×
408
                                if err = c.OVNNbClient.DeleteAddressSet(as.Name); err != nil {
×
409
                                        klog.Errorf("delete np %s address set: %v", key, err)
×
410
                                        return err
×
411
                                }
×
412
                        }
413
                }
414
        } else {
×
415
                if err = c.OVNNbClient.DeleteAcls(pgName, portGroupKey, "from-lport", nil); err != nil {
×
416
                        klog.Errorf("delete np %s egress acls: %v", key, err)
×
417
                        return err
×
418
                }
×
419

420
                if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
421
                        networkPolicyKey: fmt.Sprintf("%s/%s/%s", np.Namespace, npName, "egress"),
×
422
                }); err != nil {
×
423
                        klog.Errorf("delete np %s egress address set: %v", key, err)
×
424
                        return err
×
425
                }
×
426
        }
427

428
        for _, subnet := range subnets {
×
429
                if err = c.OVNNbClient.CreateGatewayACL("", pgName, subnet.Spec.Gateway, subnet.Status.U2OInterconnectionIP); err != nil {
×
430
                        klog.Errorf("create gateway acl: %v", err)
×
431
                        return err
×
432
                }
×
433
        }
434
        return nil
×
435
}
436

437
func (c *Controller) handleDeleteNp(key string) error {
×
438
        namespace, name, err := cache.SplitMetaNamespaceKey(key)
×
439
        if err != nil {
×
440
                utilruntime.HandleError(fmt.Errorf("invalid resource key: %s", key))
×
441
                return nil
×
442
        }
×
443

444
        c.npKeyMutex.LockKey(key)
×
445
        defer func() { _ = c.npKeyMutex.UnlockKey(key) }()
×
446
        klog.Infof("handle delete network policy %s", key)
×
447

×
448
        npName := name
×
449
        nameArray := []rune(name)
×
450
        if !unicode.IsLetter(nameArray[0]) {
×
451
                npName = "np" + name
×
452
        }
×
453

454
        pgName := strings.ReplaceAll(fmt.Sprintf("%s.%s", npName, namespace), "-", ".")
×
455
        if err = c.OVNNbClient.DeletePortGroup(pgName); err != nil {
×
456
                klog.Errorf("delete np %s port group: %v", key, err)
×
457
        }
×
458

459
        if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
460
                networkPolicyKey: fmt.Sprintf("%s/%s/%s", namespace, npName, "service"),
×
461
        }); err != nil {
×
462
                klog.Errorf("delete np %s service address set: %v", key, err)
×
463
                return err
×
464
        }
×
465

466
        if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
467
                networkPolicyKey: fmt.Sprintf("%s/%s/%s", namespace, npName, "ingress"),
×
468
        }); err != nil {
×
469
                klog.Errorf("delete np %s ingress address set: %v", key, err)
×
470
                return err
×
471
        }
×
472

473
        if err := c.OVNNbClient.DeleteAddressSets(map[string]string{
×
474
                networkPolicyKey: fmt.Sprintf("%s/%s/%s", namespace, npName, "egress"),
×
475
        }); err != nil {
×
476
                klog.Errorf("delete np %s egress address set: %v", key, err)
×
477
                return err
×
478
        }
×
479

480
        return nil
×
481
}
482

483
func (c *Controller) fetchSelectedPorts(namespace string, selector *metav1.LabelSelector) ([]string, []string, error) {
×
484
        var subnets []string
×
485
        sel, err := metav1.LabelSelectorAsSelector(selector)
×
486
        if err != nil {
×
487
                return nil, nil, fmt.Errorf("error creating label selector, %w", err)
×
488
        }
×
489
        pods, err := c.podsLister.Pods(namespace).List(sel)
×
490
        if err != nil {
×
491
                return nil, nil, fmt.Errorf("failed to list pods, %w", err)
×
492
        }
×
493

494
        ports := make([]string, 0, len(pods))
×
495
        for _, pod := range pods {
×
496
                if pod.Spec.HostNetwork {
×
497
                        continue
×
498
                }
499
                podName := c.getNameByPod(pod)
×
500
                podNets, err := c.getPodKubeovnNets(pod)
×
501
                if err != nil {
×
502
                        return nil, nil, fmt.Errorf("failed to get pod networks, %w", err)
×
503
                }
×
504

505
                for _, podNet := range podNets {
×
506
                        if !isOvnSubnet(podNet.Subnet) {
×
507
                                continue
×
508
                        }
509

510
                        if pod.Annotations[fmt.Sprintf(util.AllocatedAnnotationTemplate, podNet.ProviderName)] == "true" {
×
511
                                ports = append(ports, ovs.PodNameToPortName(podName, pod.Namespace, podNet.ProviderName))
×
512
                                // Pod selected by networkpolicy has its own subnet which is not the default subnet
×
513
                                subnets = append(subnets, podNet.Subnet.Name)
×
514
                        }
×
515
                }
516
        }
517
        subnets = slices.Compact(subnets)
×
518
        return ports, subnets, nil
×
519
}
520

521
func hasIngressRule(np *netv1.NetworkPolicy) bool {
×
522
        for _, pt := range np.Spec.PolicyTypes {
×
523
                if strings.Contains(string(pt), string(netv1.PolicyTypeIngress)) {
×
524
                        return true
×
525
                }
×
526
        }
527
        return np.Spec.Ingress != nil
×
528
}
529

530
func hasEgressRule(np *netv1.NetworkPolicy) bool {
×
531
        for _, pt := range np.Spec.PolicyTypes {
×
532
                if strings.Contains(string(pt), string(netv1.PolicyTypeEgress)) {
×
533
                        return true
×
534
                }
×
535
        }
536
        return np.Spec.Egress != nil
×
537
}
538

539
func (c *Controller) fetchPolicySelectedAddresses(namespace, protocol string, npp netv1.NetworkPolicyPeer) ([]string, []string, error) {
×
540
        selectedAddresses := []string{}
×
541
        exceptAddresses := []string{}
×
542

×
543
        // ingress.from.ipblock or egress.to.ipblock
×
544
        if npp.IPBlock != nil && util.CheckProtocol(npp.IPBlock.CIDR) == protocol {
×
545
                selectedAddresses = append(selectedAddresses, npp.IPBlock.CIDR)
×
546
                if npp.IPBlock.Except != nil {
×
547
                        exceptAddresses = append(exceptAddresses, npp.IPBlock.Except...)
×
548
                }
×
549
        }
550
        if npp.NamespaceSelector == nil && npp.PodSelector == nil {
×
551
                return selectedAddresses, exceptAddresses, nil
×
552
        }
×
553

554
        selectedNs := []string{}
×
555
        if npp.NamespaceSelector == nil {
×
556
                selectedNs = append(selectedNs, namespace)
×
557
        } else {
×
558
                sel, err := metav1.LabelSelectorAsSelector(npp.NamespaceSelector)
×
559
                if err != nil {
×
560
                        return nil, nil, fmt.Errorf("error creating label selector, %w", err)
×
561
                }
×
562
                nss, err := c.namespacesLister.List(sel)
×
563
                if err != nil {
×
564
                        return nil, nil, fmt.Errorf("failed to list ns, %w", err)
×
565
                }
×
566
                for _, ns := range nss {
×
567
                        selectedNs = append(selectedNs, ns.Name)
×
568
                }
×
569
        }
570

571
        var sel labels.Selector
×
572
        if npp.PodSelector == nil {
×
573
                sel = labels.Everything()
×
574
        } else {
×
575
                sel, _ = metav1.LabelSelectorAsSelector(npp.PodSelector)
×
576
        }
×
577

578
        for _, ns := range selectedNs {
×
579
                pods, err := c.podsLister.Pods(ns).List(sel)
×
580
                if err != nil {
×
581
                        return nil, nil, fmt.Errorf("failed to list pod, %w", err)
×
582
                }
×
583
                svcs, err := c.servicesLister.Services(ns).List(labels.Everything())
×
584
                if err != nil {
×
585
                        klog.Errorf("failed to list svc, %v", err)
×
586
                        return nil, nil, fmt.Errorf("failed to list svc, %w", err)
×
587
                }
×
588

589
                for _, pod := range pods {
×
590
                        podNets, err := c.getPodKubeovnNets(pod)
×
591
                        if err != nil {
×
592
                                klog.Errorf("failed to get pod nets %v", err)
×
593
                                return nil, nil, err
×
594
                        }
×
595
                        for _, podNet := range podNets {
×
596
                                podIPAnnotation := pod.Annotations[fmt.Sprintf(util.IPAddressAnnotationTemplate, podNet.ProviderName)]
×
597
                                podIPs := strings.SplitSeq(podIPAnnotation, ",")
×
598
                                for podIP := range podIPs {
×
599
                                        if podIP != "" && util.CheckProtocol(podIP) == protocol {
×
600
                                                selectedAddresses = append(selectedAddresses, podIP)
×
601
                                        }
×
602
                                }
603
                                if len(svcs) == 0 {
×
604
                                        continue
×
605
                                }
606

607
                                svcIPs, err := svcMatchPods(svcs, pod, protocol)
×
608
                                if err != nil {
×
609
                                        return nil, nil, err
×
610
                                }
×
611
                                selectedAddresses = append(selectedAddresses, svcIPs...)
×
612
                        }
613
                }
614
        }
615
        return selectedAddresses, exceptAddresses, nil
×
616
}
617

618
func svcMatchPods(svcs []*corev1.Service, pod *corev1.Pod, protocol string) ([]string, error) {
×
619
        matchSvcs := []string{}
×
620
        // find svc ip by pod's info
×
621
        for _, svc := range svcs {
×
622
                isMatch, err := isSvcMatchPod(svc, pod)
×
623
                if err != nil {
×
624
                        return nil, err
×
625
                }
×
626
                if isMatch {
×
627
                        clusterIPs := util.ServiceClusterIPs(*svc)
×
628
                        protocolClusterIPs := getProtocolSvcIP(clusterIPs, protocol)
×
629
                        if len(protocolClusterIPs) != 0 {
×
630
                                matchSvcs = append(matchSvcs, protocolClusterIPs...)
×
631
                        }
×
632
                }
633
        }
634
        return matchSvcs, nil
×
635
}
636

637
func getProtocolSvcIP(clusterIPs []string, protocol string) []string {
×
638
        protocolClusterIPs := []string{}
×
639
        for _, clusterIP := range clusterIPs {
×
640
                if clusterIP != "" && clusterIP != corev1.ClusterIPNone && util.CheckProtocol(clusterIP) == protocol {
×
641
                        protocolClusterIPs = append(protocolClusterIPs, clusterIP)
×
642
                }
×
643
        }
644
        return protocolClusterIPs
×
645
}
646

647
func isSvcMatchPod(svc *corev1.Service, pod *corev1.Pod) (bool, error) {
×
648
        ss := metav1.SetAsLabelSelector(svc.Spec.Selector)
×
649
        sel, err := metav1.LabelSelectorAsSelector(ss)
×
650
        if err != nil {
×
651
                return false, fmt.Errorf("error fetch label selector, %w", err)
×
652
        }
×
653
        if pod.Labels == nil {
×
654
                return false, nil
×
655
        }
×
656
        if sel.Matches(labels.Set(pod.Labels)) {
×
657
                return true, nil
×
658
        }
×
659
        return false, nil
×
660
}
661

662
func (c *Controller) podMatchNetworkPolicies(pod *corev1.Pod) []string {
×
663
        podNs, err := c.namespacesLister.Get(pod.Namespace)
×
664
        if err != nil {
×
665
                klog.Errorf("failed to get namespace %s: %v", pod.Namespace, err)
×
666
                utilruntime.HandleError(err)
×
667
                return nil
×
668
        }
×
669

670
        nps, err := c.npsLister.NetworkPolicies(corev1.NamespaceAll).List(labels.Everything())
×
671
        if err != nil {
×
672
                klog.Errorf("failed to list network policies: %v", err)
×
673
                utilruntime.HandleError(err)
×
674
                return nil
×
675
        }
×
676

677
        match := []string{}
×
678
        for _, np := range nps {
×
679
                if isPodMatchNetworkPolicy(pod, *podNs, np, np.Namespace) {
×
680
                        match = append(match, cache.MetaObjectToName(np).String())
×
681
                }
×
682
        }
683
        return match
×
684
}
685

686
func (c *Controller) svcMatchNetworkPolicies(svc *corev1.Service) ([]string, error) {
×
687
        // find all match pod
×
688
        sel := labels.Set(svc.Spec.Selector).AsSelector()
×
689
        pods, err := c.podsLister.Pods(svc.Namespace).List(sel)
×
690
        if err != nil {
×
691
                return nil, fmt.Errorf("failed to list pods, %w", err)
×
692
        }
×
693

694
        // find all match netpol
695
        nps, err := c.npsLister.NetworkPolicies(corev1.NamespaceAll).List(labels.Everything())
×
696
        if err != nil {
×
697
                return nil, fmt.Errorf("failed to list netpols, %w", err)
×
698
        }
×
699
        match := set.New[string]()
×
700
        ns, _ := c.namespacesLister.Get(svc.Namespace)
×
701
        for _, pod := range pods {
×
702
                for _, np := range nps {
×
703
                        key := cache.MetaObjectToName(np).String()
×
704
                        if match.Has(key) {
×
705
                                continue
×
706
                        }
707
                        if isPodMatchNetworkPolicy(pod, *ns, np, np.Namespace) {
×
708
                                match.Insert(key)
×
709
                                klog.V(3).Infof("svc %s/%s match np %s", svc.Namespace, svc.Name, key)
×
710
                        }
×
711
                }
712
        }
713
        return match.UnsortedList(), nil
×
714
}
715

716
func isPodMatchNetworkPolicy(pod *corev1.Pod, podNs corev1.Namespace, policy *netv1.NetworkPolicy, policyNs string) bool {
×
717
        sel, _ := metav1.LabelSelectorAsSelector(&policy.Spec.PodSelector)
×
718
        if pod.Labels == nil {
×
719
                pod.Labels = map[string]string{}
×
720
        }
×
721
        if podNs.Name == policyNs && sel.Matches(labels.Set(pod.Labels)) {
×
722
                return true
×
723
        }
×
724
        for _, npr := range policy.Spec.Ingress {
×
725
                for _, npp := range npr.From {
×
726
                        if isPodMatchPolicyPeer(pod, podNs, npp, policyNs) {
×
727
                                return true
×
728
                        }
×
729
                }
730
        }
731
        for _, npr := range policy.Spec.Egress {
×
732
                for _, npp := range npr.To {
×
733
                        if isPodMatchPolicyPeer(pod, podNs, npp, policyNs) {
×
734
                                return true
×
735
                        }
×
736
                }
737
        }
738
        return false
×
739
}
740

741
func isPodMatchPolicyPeer(pod *corev1.Pod, podNs corev1.Namespace, policyPeer netv1.NetworkPolicyPeer, policyNs string) bool {
×
742
        if policyPeer.IPBlock != nil {
×
743
                return false
×
744
        }
×
745
        if policyPeer.NamespaceSelector == nil {
×
746
                if policyNs != podNs.Name {
×
747
                        return false
×
748
                }
×
749
        } else {
×
750
                nsSel, _ := metav1.LabelSelectorAsSelector(policyPeer.NamespaceSelector)
×
751
                if podNs.Labels == nil {
×
752
                        podNs.Labels = map[string]string{}
×
753
                }
×
754
                if !nsSel.Matches(labels.Set(podNs.Labels)) {
×
755
                        return false
×
756
                }
×
757
        }
758

759
        if policyPeer.PodSelector == nil {
×
760
                return true
×
761
        }
×
762

763
        sel, _ := metav1.LabelSelectorAsSelector(policyPeer.PodSelector)
×
764
        if pod.Labels == nil {
×
765
                pod.Labels = map[string]string{}
×
766
        }
×
767
        return sel.Matches(labels.Set(pod.Labels))
×
768
}
769

770
func (c *Controller) namespaceMatchNetworkPolicies(ns *corev1.Namespace) []string {
×
771
        nps, _ := c.npsLister.NetworkPolicies(corev1.NamespaceAll).List(labels.Everything())
×
772
        match := make([]string, 0, len(nps))
×
773
        for _, np := range nps {
×
774
                if isNamespaceMatchNetworkPolicy(ns, np) {
×
775
                        match = append(match, cache.MetaObjectToName(np).String())
×
776
                }
×
777
        }
778
        return match
×
779
}
780

781
func isNamespaceMatchNetworkPolicy(ns *corev1.Namespace, policy *netv1.NetworkPolicy) bool {
×
782
        for _, npr := range policy.Spec.Ingress {
×
783
                for _, npp := range npr.From {
×
784
                        if npp.NamespaceSelector != nil {
×
785
                                nsSel, _ := metav1.LabelSelectorAsSelector(npp.NamespaceSelector)
×
786
                                if ns.Labels == nil {
×
787
                                        ns.Labels = map[string]string{}
×
788
                                }
×
789
                                if nsSel.Matches(labels.Set(ns.Labels)) {
×
790
                                        return true
×
791
                                }
×
792
                        }
793
                }
794
        }
795

796
        for _, npr := range policy.Spec.Egress {
×
797
                for _, npp := range npr.To {
×
798
                        if npp.NamespaceSelector != nil {
×
799
                                nsSel, _ := metav1.LabelSelectorAsSelector(npp.NamespaceSelector)
×
800
                                if ns.Labels == nil {
×
801
                                        ns.Labels = map[string]string{}
×
802
                                }
×
803
                                if nsSel.Matches(labels.Set(ns.Labels)) {
×
804
                                        return true
×
805
                                }
×
806
                        }
807
                }
808
        }
809
        return false
×
810
}
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